Merge pull request #6 from 45Drives/dev-josh

Set up packaging and get ready for first release
This commit is contained in:
Josh Boudreau 2021-05-31 14:23:31 -03:00 committed by GitHub
commit e67c23a0e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 569 additions and 44 deletions

12
.gitignore vendored
View File

@ -1 +1,13 @@
# IDE
.vscode
# deb packaging
debian/cockpit-navigator
debian/cockpit-navigator.substvars
debian/cockpit-navigator.postrm.debhelper
debian/debhelper-build-stamp
debian/files
debian/.debhelper
# build output
dist

View File

@ -1,2 +1,59 @@
# Cockpit Navigator
A File System Browser for Cockpit.
A File System Browser for Cockpit.
## Features
With no command line use needed, you can:
* Navigate the entire filesystem,
* Create, delete, and rename files,
* Edit file contents,
* Edit file ownership and permissions,
* Create symbolic links to files and directories.
### Browsing Filesystem
![User Interface](doc/ui_root.png)
### Editing Properties
![Edit Preferences](doc/ui_prefs.png)
### Editing Content
![Edit Contents](doc/ui_editor.png)
# Installation
## From Github Release
### Ubuntu
1. `$ wget https://github.com/45Drives/cockpit-navigator/releases/download/v0.1.0/cockpit-navigator_0.1.0-1focal_all.deb`
1. `# apt install ./cockpit-navigator_0.1.0-1focal_all.deb`
### EL7
1. `# yum install https://github.com/45Drives/cockpit-navigator/releases/download/v0.1.0/cockpit-navigator-0.1.0.el7.noarch.rpm`
### EL8
1. `# dnf install https://github.com/45Drives/cockpit-navigator/releases/download/v0.1.0/cockpit-navigator-0.1.0.el8.noarch.rpm`
## From Source
1. `$ git clone https://github.com/45Drives/cockpit-navigator.git`
1. `$ cd cockpit-navigator`
1. `$ git checkout <version>` (v0.1.0 is latest)
1. `# make install`
## From 45Drives Repositories
### Ubuntu
1. Import GPG Key
```sh
wget -qO - http://images.45drives.com/repo/keys/aptpubkey.asc | sudo apt-key add -
```
2. Add 45drives.list
```sh
cd /etc/apt/sources.list.d
sudo wget http://images.45drives.com/repo/debian/45drives.list
sudo apt update
```
3. Install Package
```sh
sudo apt install cockpit-navigator
```
### EL7
1. Add Repository
```sh
cd /etc/yum.repos.d
sudo wget http://images.45drives.com/repo/centos/45drives-centos.repo
sudo yum clean all
```
2. Install Package
```sh
sudo yum install cockpit-navigator
```

5
debian/changelog vendored Normal file
View File

@ -0,0 +1,5 @@
cockpit-navigator (0.1.0-1focal) focal; urgency=medium
* Initial packaging of cockpit-navigator for Ubuntu Focal.
-- Josh Boudreau <jboudreau@45drives.com> Fri, 28 May 2021 3:58:00 -0300

13
debian/control vendored Normal file
View File

@ -0,0 +1,13 @@
Source: cockpit-navigator
Section: utils
Priority: optional
Maintainer: Josh Boudreau <jboudreau@45drives.com>
Build-Depends: debhelper-compat (= 12)
Standards-Version: 4.4.1
Homepage: https://github.com/45Drives/cockpit-navigator
Package: cockpit-navigator
Architecture: all
Depends: ${shlibs:Depends}, ${misc:Depends},
cockpit, python3
Description: A File System Browser for Cockpit.

35
debian/copyright vendored Normal file
View File

@ -0,0 +1,35 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: cockpit-navigator
Upstream-Contact: Josh Boudreau <jboudreau@45drives.com>
Source: https://github.com/45Drives/cockpit-navigator
Files: *
Copyright: 2021 Josh Boudreau <jboudreau@45drives.com>
License: GPL-3.0+
Files: navigator/navigator.*
Copyright: 2021 Sam Silver <ssilver@45drives.com>
License: GPL-3.0+
Files: navigator/navigator.js
Copyright: 2021 Dawson Della Valle <ddellavalle@45drives.com>
License: GPL-3.0+
Files: debian/*
Copyright: 2021 Josh Boudreau <jboudreau@45drives.com>
License: GPL-3.0+
License: GPL-3.0+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with the Onboard package. If not, please have a look at
/usr/share/common-licenses or <http://www.gnu.org/licenses/>.

23
debian/rules vendored Executable file
View File

@ -0,0 +1,23 @@
#!/usr/bin/make -f
# See debhelper(7) (uncomment to enable)
# output every command that modifies files on the build system.
#export DH_VERBOSE = 1
# see FEATURE AREAS in dpkg-buildflags(1)
#export DEB_BUILD_MAINT_OPTIONS = hardening=+all
# see ENVIRONMENT in dpkg-buildflags(1)
# package maintainers to append CFLAGS
#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic
# package maintainers to append LDFLAGS
#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
%:
dh $@
# dh_make generated override targets
# This is example for Cmake (See https://bugs.debian.org/641051 )
#override_dh_auto_configure:
# dh_auto_configure -- # -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH)

1
debian/source/format vendored Normal file
View File

@ -0,0 +1 @@
3.0 (native)

BIN
doc/ui_editor.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
doc/ui_prefs.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
doc/ui_root.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

17
docker/el7 Normal file
View File

@ -0,0 +1,17 @@
FROM centos:7
LABEL description="Container in which to build el7 applications"
ENV TZ=America/Glace_Bay
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN yum install -y gcc rpm-build rpm-devel rpmlint make python python3 bash coreutils diffutils patch rpmdevtools
RUN mkdir -p /home/rpm/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS,tmp}
RUN echo %_topdir /home/rpm/rpmbuild > /etc/rpm/macros
RUN echo %_tmppath %{_topdir}/tmp >> /etc/rpm/macros
RUN chmod -R 777 /home/rpm
RUN ln -fs /usr/bin/python3 /usr/bin/python

15
docker/el8 Normal file
View File

@ -0,0 +1,15 @@
FROM centos:8
LABEL description="Container in which to build el8 applications"
ENV TZ=America/Glace_Bay
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN dnf install -y gcc rpm-build rpm-devel rpmlint make python3 bash diffutils patch rpmdevtools
RUN mkdir -p /home/rpm/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS,tmp}
RUN echo %_topdir /home/rpm/rpmbuild > /etc/rpm/macros
RUN echo %_tmppath %{_topdir}/tmp >> /etc/rpm/macros
RUN chmod -R 777 /home/rpm

8
docker/ubuntu Normal file
View File

@ -0,0 +1,8 @@
FROM ubuntu:focal
LABEL description="Container in which to build ubuntu applications"
ENV TZ=America/Glace_Bay
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt update && apt install -y make build-essential fakeroot devscripts debhelper python3

36
el/cockpit-navigator.spec Normal file
View File

@ -0,0 +1,36 @@
Name: cockpit-navigator
Version: 0.1.0
Release: 1%{?dist}
Summary: A File System Browser for Cockpit.
License: GPL-3.0+
URL: github.com/45drives/cockpit-navigator/blob/main/README.md
Source0: %{name}-%{version}.tar.gz
BuildArch: noarch
Requires: cockpit python3
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
%description
Cockpit Navigator
A File System Browser for Cockpit.
%prep
%setup -q
%build
# empty
%install
rm -rf %{buildroot}
mkdir -p %{buildroot}
cp -a * %{buildroot}
%clean
rm -rf %{buildroot}
%files
/usr/share/cockpit/navigator/*
%changelog
* Fri May 28 2021 Josh Boudreau <jboudreau@45drives.com> 0.1.0-1
- First Build

View File

@ -21,6 +21,9 @@ all: default
install:
mkdir -p $(DESTDIR)/usr/share/cockpit/
cp -rpf navigator $(DESTDIR)/usr/share/cockpit
ifeq ($(EL7),1)
sed -i "s/pf-c-button/btn/g;s/pf-m-primary/btn-primary/g;s/pf-m-secondary/btn-default/g;s/pf-m-danger/btn-danger/g" $(DESTDIR)/usr/share/cockpit/navigator/navigator.html
endif
uninstall:
rm -rf $(DESTDIR)/usr/share/cockpit/navigator

View File

@ -53,6 +53,14 @@
--symlink-symbol-color: var(--navigation);
}
html {
height: 100%;
}
body {
height: 100%;
}
.pf-c-button:disabled[data-theme="dark"] {
background-color: var(--border);
}
@ -249,10 +257,18 @@ input[type="text"] {
border-radius: var(--nav-border-radius);
}
.min-width-0 {
min-width: 0;
}
.nav-info-column-filename {
flex: 1;
margin: 0 12px 0 12px;
font-weight: bolder;
font-size: 150%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.nav-property-pair {
@ -332,6 +348,7 @@ input[type="text"] {
padding: 5px;
color: var(--font);
background-color: var(--textarea-bg);
font-family: 'Courier New', Courier, monospace;
}
.nav-footer {
@ -419,3 +436,14 @@ input:checked + .slider:before {
.slider.round:before {
border-radius: 50%;
}
.nav-icon-decorated {
position: relative;
}
.nav-icon-decoration {
position: absolute;
font-size: 60%;
top: -10%;
left: -30%;
}

View File

@ -24,6 +24,7 @@
<link href="../base1/cockpit.css" type="text/css" rel="stylesheet">
<link href="navigator.css" type="text/css" rel="stylesheet">
<link href="fontawesome/css/all.min.css" rel="stylesheet">
<script src="fontawesome/attribution.js"></script>
<script src="../base1/cockpit.js"></script>
<script src="../manifests.js"></script>
<script src="../*/po.js"></script>
@ -38,24 +39,28 @@
<div class="flex-col outer-container">
<div class="flex-row">
<div class="nav-btn-group">
<button class="pf-c-button pf-m-secondary" id="nav-back-btn"><i class="fas fa-arrow-left"></i></button>
<button class="pf-c-button pf-m-secondary" id="nav-back-btn" title="Back"><i class="fas fa-arrow-left"></i></button>
<div class="horizontal-spacer"></div>
<button class="pf-c-button pf-m-secondary" id="nav-forward-btn"><i class="fas fa-arrow-right"></i></button>
<button class="pf-c-button pf-m-secondary" id="nav-forward-btn" title="Forward"><i class="fas fa-arrow-right"></i></button>
<div class="horizontal-spacer"></div>
<button class="pf-c-button pf-m-secondary" id="nav-up-dir-btn"><i class="fas fa-arrow-up"></i></button>
<button class="pf-c-button pf-m-secondary" id="nav-up-dir-btn" title="Up"><i class="fas fa-arrow-up"></i></button>
<div class="horizontal-spacer"></div>
<button class="pf-c-button pf-m-secondary" id="nav-refresh-btn"><i class="fas fa-sync"></i></button>
<button class="pf-c-button pf-m-secondary" id="nav-refresh-btn" title="Refresh"><i class="fas fa-sync"></i></button>
</div>
<div class="horizontal-spacer"></div>
<input type="text" list="possible-paths-list" autocomplete="off" class="navigation-bar" id="pwd"></input>
<input type="text" list="possible-paths-list" autocomplete="off" class="navigation-bar" id="pwd" title="Navigation Bar"></input>
<datalist id="possible-paths-list">
<select id="possible-paths">
</select>
</datalist>
<div class="horizontal-spacer"></div>
<button class="pf-c-button pf-m-primary" id="nav-mkdir-btn"><i class="fas fa-folder-plus"></i></button>
<div class="horizontal-spacer"></div>
<button class="pf-c-button pf-m-primary" id="nav-touch-btn"><i class="fas fa-file-medical"></i></button>
<div class="nav-btn-group">
<button class="pf-c-button pf-m-primary" id="nav-mkdir-btn" title="New Directory"><i class="fas fa-folder-plus"></i></button>
<div class="horizontal-spacer"></div>
<button class="pf-c-button pf-m-primary" id="nav-touch-btn" title="New File"><i class="fas fa-file-medical"></i></button>
<div class="horizontal-spacer"></div>
<button class="pf-c-button pf-m-primary" id="nav-ln-btn" title="New Symbolic Link"><i class="fas fa-link nav-icon-decorated"><i class="fas fa-plus nav-icon-decoration"></i></i></button>
</div>
</div>
<div class="vertical-spacer"></div>
<div class="flex-row inner-container">
@ -63,23 +68,23 @@
<div class="edit-file-contents nav-hidden" id="nav-edit-contents-view">
<div class="editor-header" id="nav-edit-contents-header"></div>
<div class="vertical-spacer"></div>
<textarea id="nav-edit-contents-textarea"></textarea>
<textarea id="nav-edit-contents-textarea" spellcheck="false"></textarea>
<div class="vertical-spacer"></div>
<div class="nav-btn-group">
<button class="pf-c-button pf-m-danger editor-btn" id="nav-cancel-edit-contents-btn"><i class="fas fa-times"></i></button>
<button class="pf-c-button pf-m-danger editor-btn" id="nav-cancel-edit-contents-btn" title="Cancel"><i class="fas fa-times"></i></button>
<div class="horizontal-spacer"></div>
<button class="pf-c-button pf-m-primary editor-btn" id="nav-continue-edit-contents-btn"><i class="fas fa-save"></i></button>
<button class="pf-c-button pf-m-primary editor-btn" id="nav-continue-edit-contents-btn" title="Save"><i class="fas fa-save"></i></button>
</div>
</div>
<div class="horizontal-spacer"></div>
<div class="nav-info-column" id="nav-info-column">
<div class="nav-info-column min-width-0" id="nav-info-column">
<div id="nav-show-properties">
<div class="flex-row space-between">
<div class="nav-info-column-filename"></div>
<div class="nav-btn-group">
<button class="pf-c-button pf-m-danger" id="nav-delete-btn"><i class="fas fa-trash-alt"></i></button>
<button class="pf-c-button pf-m-danger" id="nav-delete-btn" title="Delete"><i class="fas fa-trash-alt"></i></button>
<div class="horizontal-spacer"></div>
<button class="pf-c-button pf-m-primary" id="nav-edit-properties-btn"><i class="fas fa-sliders-h"></i></button>
<button class="pf-c-button pf-m-primary" id="nav-edit-properties-btn" title="Edit Properties"><i class="fas fa-sliders-h"></i></button>
</div>
</div>
<div class="nav-info-column-properties" id="nav-info-column-properties"></div>
@ -130,9 +135,9 @@
</div>
<div class="vertical-spacer"></div>
<div class="nav-btn-group">
<button class="pf-c-button pf-m-danger" id="nav-cancel-edit-btn"><i class="fas fa-times"></i></button>
<button class="pf-c-button pf-m-danger" id="nav-cancel-edit-btn" title="Cancel"><i class="fas fa-times"></i></button>
<div class="horizontal-spacer"></div>
<button class="pf-c-button pf-m-primary" id="nav-apply-edit-btn"><i class="fas fa-save"></i></button>
<button class="pf-c-button pf-m-primary" id="nav-apply-edit-btn" title="Save Changes"><i class="fas fa-save"></i></button>
</div>
</div>
</div>
@ -142,7 +147,7 @@
<span id="nav-num-dirs">-</span> Directories, <span id="nav-num-files">-</span> Files
</div>
<div class="spacer-stretchy"></div>
<a href="https://45drives.com" target="_blank">
<a href="https://45drives.com" target="_blank" title="Visit 45Drives.com">
<img src="branding/logo-light.svg" id="logo-45d"><span class="logo-45">45</span><span class="logo-drives">Drives</span>
</a>
<div class="spacer-stretchy"></div>
@ -150,7 +155,7 @@
<div class="nav-btn-group">
<i class="fas fa-low-vision" id="nav-show-hidden-icon"></i>
<div class="horizontal-spacer-sm"></div>
<label class="switch">
<label class="switch" title="Show Hidden Files">
<input type="checkbox" id="nav-show-hidden">
<span class="slider round"></span>
</label>
@ -161,7 +166,7 @@
<div class="nav-btn-group">
<i class="fas fa-sun" id="houston-theme-icon"></i>
<div class="horizontal-spacer-sm"></div>
<label class="switch">
<label class="switch" title="Toggle Dark/Light">
<input type="checkbox" id="toggle-theme">
<span class="slider round"></span>
</label>

View File

@ -163,6 +163,7 @@ class NavEntry {
this.stat = stat;
this.dom_element.addEventListener("click", this);
this.is_hidden_file = this.filename().startsWith('.');
this.dom_element.title = this.filename();
}
/**
@ -287,7 +288,8 @@ class NavEntry {
show_properties(extra_properties = "") {
var selected_name_fields = document.getElementsByClassName("nav-info-column-filename");
for (let elem of selected_name_fields) {
elem.innerText = this.filename();
elem.innerHTML = this.filename();
elem.title = this.filename();
}
var html = "";
html += property_entry_html("Mode", this.stat["mode-str"]);
@ -366,19 +368,24 @@ class NavFile extends NavEntry {
}
async show_edit_file_contents() {
for (let button of document.getElementsByTagName("button")) {
if (!button.classList.contains("editor-btn"))
button.disabled = true;
}
document.getElementById("pwd").disabled = true;
this.nav_window_ref.disable_buttons_for_editing();
var proc_output = await cockpit.spawn(["file", "--mime-type", this.path_str()], {superuser: "try"});
var fields = proc_output.split(':');
var type = fields[1].trim();
if(!(type.match(/^text/) || type.match(/^inode\/x-empty$/) || this.stat["size"] === 0)){
if(!window.confirm("File is of type `" + type + "`. Are you sure you want to edit it?"))
if (!(type.match(/^text/) || type.match(/^inode\/x-empty$/) || this.stat["size"] === 0)) {
if (!window.confirm("File is of type `" + type + "`. Are you sure you want to edit it?")) {
this.nav_window_ref.enable_buttons();
return;
}
}
var contents = "";
try {
contents = await cockpit.file(this.path_str(), {superuser: "try"}).read();
} catch (e) {
this.nav_window_ref.enable_buttons();
window.alert(e.message);
return;
}
var contents = await cockpit.spawn(["cat", this.path_str()], {superuser: "try"});
document.getElementById("nav-edit-contents-textarea").value = contents;
document.getElementById("nav-cancel-edit-contents-btn").onclick = this.hide_edit_file_contents.bind(this);
document.getElementById("nav-continue-edit-contents-btn").onclick = this.write_to_file.bind(this);
@ -389,7 +396,11 @@ class NavFile extends NavEntry {
async write_to_file() {
var new_contents = document.getElementById("nav-edit-contents-textarea").value;
await cockpit.script("echo -n \"$1\" > $2", [new_contents, this.path_str()], {superuser: "try"});
try {
await cockpit.file(this.path_str(), {superuser: "try"}).replace(new_contents); // cockpit.script("echo -n \"$1\" > $2", [new_contents, this.path_str()], {superuser: "try"});
} catch (e) {
window.alert(e.message);
}
this.nav_window_ref.refresh();
this.hide_edit_file_contents();
}
@ -397,10 +408,7 @@ class NavFile extends NavEntry {
hide_edit_file_contents() {
document.getElementById("nav-edit-contents-view").style.display = "none";
document.getElementById("nav-contents-view").style.display = "flex";
for (let button of document.getElementsByTagName("button")) {
button.disabled = false;
}
document.getElementById("pwd").disabled = false;
this.nav_window_ref.enable_buttons();
}
}
@ -443,20 +451,26 @@ class NavFileLink extends NavFile{
}
async show_edit_file_contents() {
for (let button of document.getElementsByTagName("button")) {
if (!button.classList.contains("editor-btn"))
button.disabled = true;
}
this.nav_window_ref.disable_buttons_for_editing();
document.getElementById("pwd").disabled = true;
var target_path = this.get_link_target_path();
var proc_output = await cockpit.spawn(["file", "--mime-type", target_path], {superuser: "try"});
var fields = proc_output.split(':');
var type = fields[1].trim();
if(!(type.match(/^text/) || type.match(/^inode\/x-empty$/) || this.stat["size"] === 0)){
if(!window.confirm("File is of type `" + type + "`. Are you sure you want to edit it?"))
if (!(type.match(/^text/) || type.match(/^inode\/x-empty$/) || this.stat["size"] === 0)) {
if (!window.confirm("File is of type `" + type + "`. Are you sure you want to edit it?")) {
this.nav_window_ref.enable_buttons();
return;
}
}
var contents = "";
try {
contents = await cockpit.file(this.path_str(), {superuser: "try"}).read();
} catch(e) {
this.nav_window_ref.enable_buttons();
window.alert(e.message);
return;
}
var contents = await cockpit.spawn(["cat", target_path], {superuser: "try"});
document.getElementById("nav-edit-contents-textarea").value = contents;
document.getElementById("nav-cancel-edit-contents-btn").onclick = this.hide_edit_file_contents.bind(this);
document.getElementById("nav-continue-edit-contents-btn").onclick = this.write_to_file.bind(this);
@ -468,7 +482,11 @@ class NavFileLink extends NavFile{
async write_to_file() {
var target_path = this.get_link_target_path();
var new_contents = document.getElementById("nav-edit-contents-textarea").value;
await cockpit.script("echo -n \"$1\" > $2", [new_contents, target_path], {superuser: "try"});
try {
await cockpit.file(target_path, {superuser: "try"}).replace(new_contents);
} catch (e) {
window.alert(e.message);
}
this.nav_window_ref.refresh();
this.hide_edit_file_contents();
}
@ -916,6 +934,29 @@ class NavWindow {
this.refresh();
}
async ln() {
var link_target = window.prompt("Link Target: ");
if (link_target === null)
return;
var link_name = window.prompt("Link Name: ");
if (link_name === null)
return;
if (link_name.includes("/")) {
window.alert("Link name can't contain `/`.");
return;
}
var link_path = this.pwd().path_str() + "/" + link_name;
var proc = cockpit.spawn(
["ln", "-sn", link_target, link_path],
{superuser: "try", err: "out"}
);
proc.fail((e, data) => {
window.alert(data);
});
await proc;
this.refresh();
}
/**
*
* @param {Event} e
@ -993,6 +1034,7 @@ class NavWindow {
}
this.refresh();
}
async get_system_users() {
var proc = cockpit.spawn(["getent", "passwd"], {err: "ignore", superuser: "try"});
var list = document.getElementById("possible-owners");
@ -1009,6 +1051,7 @@ class NavWindow {
list.appendChild(option);
}
}
async get_system_groups() {
var proc = cockpit.spawn(["getent", "group"], {err: "ignore", superuser: "try"});
var list = document.getElementById("possible-groups");
@ -1025,6 +1068,21 @@ class NavWindow {
list.appendChild(option);
}
}
disable_buttons_for_editing() {
for (let button of document.getElementsByTagName("button")) {
if (!button.classList.contains("editor-btn"))
button.disabled = true;
}
document.getElementById("pwd").disabled = true;
}
enable_buttons() {
for (let button of document.getElementsByTagName("button")) {
button.disabled = false;
}
document.getElementById("pwd").disabled = false;
}
}
let nav_window = new NavWindow();
@ -1036,6 +1094,7 @@ function set_up_buttons() {
document.getElementById("nav-refresh-btn").addEventListener("click", nav_window.refresh.bind(nav_window));
document.getElementById("nav-mkdir-btn").addEventListener("click", nav_window.mkdir.bind(nav_window));
document.getElementById("nav-touch-btn").addEventListener("click", nav_window.touch.bind(nav_window));
document.getElementById("nav-ln-btn").addEventListener("click", nav_window.ln.bind(nav_window));
document.getElementById("nav-delete-btn").addEventListener("click", nav_window.delete_selected.bind(nav_window));
document.getElementById("nav-edit-properties-btn").addEventListener("click", nav_window.show_edit_selected.bind(nav_window));
document.getElementById("nav-cancel-edit-btn").addEventListener("click", nav_window.hide_edit_selected.bind(nav_window));

View File

@ -68,8 +68,8 @@ def main():
sys.exit(1)
try:
nodes = os.listdir(sys.argv[1])
except:
print("No such file or directory")
except Exception as e:
print(e)
sys.exit(1)
response = {
".": get_stat(sys.argv[1]),

20
package-all.sh Executable file
View File

@ -0,0 +1,20 @@
#!/usr/bin/env bash
# Copyright (C) 2021 Joshua Boudreau <jboudreau@45drives.com>
#
# This file is part of Cockpit Navigator.
#
# Cockpit Navigator is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Cockpit Navigator is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Cockpit Navigator. If not, see <https://www.gnu.org/licenses/>.
./package-deb.sh && ./package-el7.sh && ./package-el8.sh

58
package-deb.sh Executable file
View File

@ -0,0 +1,58 @@
#!/usr/bin/env bash
# Copyright (C) 2021 Joshua Boudreau <jboudreau@45drives.com>
#
# This file is part of Cockpit Navigator.
#
# Cockpit Navigator is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Cockpit Navigator is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Cockpit Navigator. If not, see <https://www.gnu.org/licenses/>.
if [[ "$#" == 1 && "$1" == "clean" ]]; then
pushd debian
rm -f cockpit-navigator.postrm.debhelper cockpit-navigator.substvars debhelper-build-stamp files
rm -rf .debhelper cockpit-navigator
popd
rm -rf dist/ubuntu
exit 0
fi
command -v docker > /dev/null 2>&1 || {
echo "Please install docker.";
exit 1;
}
# if docker image DNE, build it
if [[ "$(docker images -q cockpit-navigator-ubuntu-builder 2> /dev/null)" == "" ]]; then
docker build -t cockpit-navigator-ubuntu-builder - < docker/ubuntu
res=$?
if [ $res -ne 0 ]; then
echo "Building docker image failed."
exit $res
fi
fi
mkdir -p dist/ubuntu
# mirror current directory to working directory in container, and mirror dist/ubuntu to .. for deb output
docker run -u $(id -u):$(id -g) -w /home/deb/build -it -v$(pwd):/home/deb/build -v$(pwd)/dist/ubuntu:/home/deb --rm cockpit-navigator-ubuntu-builder dpkg-buildpackage -us -uc -b
res=$?
if [ $res -ne 0 ]; then
echo "Packaging failed."
exit $res
fi
rmdir dist/ubuntu/build
echo "deb is in dist/ubuntu/"
exit 0

65
package-el7.sh Executable file
View File

@ -0,0 +1,65 @@
#!/usr/bin/env bash
# Copyright (C) 2021 Joshua Boudreau <jboudreau@45drives.com>
#
# This file is part of Cockpit Navigator.
#
# Cockpit Navigator is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Cockpit Navigator is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Cockpit Navigator. If not, see <https://www.gnu.org/licenses/>.
if [[ "$#" == 1 && "$1" == "clean" ]]; then
rm -rf dist/tmp
rm -rf dist/el7
exit 0
fi
command -v docker > /dev/null 2>&1 || {
echo "Please install docker.";
exit 1;
}
# if docker image DNE, build it
if [[ "$(docker images -q cockpit-navigator-el7-builder 2> /dev/null)" == "" ]]; then
docker build -t cockpit-navigator-el7-builder - < docker/el7
res=$?
if [ $res -ne 0 ]; then
echo "Building docker image failed."
exit $res
fi
fi
mkdir -p dist/{el7,tmp}
SOURCE_DIR_NAME=cockpit-navigator-$(grep Version el/cockpit-navigator.spec --color=never | awk '{print $2}')
SOURCE_DIR=dist/tmp/$SOURCE_DIR_NAME
mkdir -p $SOURCE_DIR
make DESTDIR=$SOURCE_DIR EL7=1 install
pushd $SOURCE_DIR/..
tar -czvf $SOURCE_DIR_NAME.tar.gz $SOURCE_DIR_NAME
popd
# build rpm from source tar and place it dist/el7 by mirroring dist/el7 to rpmbuild/RPMS
docker run -u $(id -u):$(id -g) -w /home/rpm/rpmbuild -it -v$(pwd)/dist/tmp:/home/rpm/rpmbuild/SOURCES -v$(pwd)/dist/el7:/home/rpm/rpmbuild/RPMS -v$(pwd)/el:/home/rpm/rpmbuild/SPECS --rm cockpit-navigator-el7-builder rpmbuild -ba SPECS/cockpit-navigator.spec
res=$?
if [ $res -ne 0 ]; then
echo "Packaging failed."
exit $res
fi
rm -rf dist/tmp
echo "rpm is in dist/el7/"
exit 0

65
package-el8.sh Executable file
View File

@ -0,0 +1,65 @@
#!/usr/bin/env bash
# Copyright (C) 2021 Joshua Boudreau <jboudreau@45drives.com>
#
# This file is part of Cockpit Navigator.
#
# Cockpit Navigator is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Cockpit Navigator is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Cockpit Navigator. If not, see <https://www.gnu.org/licenses/>.
if [[ "$#" == 1 && "$1" == "clean" ]]; then
rm -rf dist/tmp
rm -rf dist/el8
exit 0
fi
command -v docker > /dev/null 2>&1 || {
echo "Please install docker.";
exit 1;
}
# if docker image DNE, build it
if [[ "$(docker images -q cockpit-navigator-el8-builder 2> /dev/null)" == "" ]]; then
docker build -t cockpit-navigator-el8-builder - < docker/el8
res=$?
if [ $res -ne 0 ]; then
echo "Building docker image failed."
exit $res
fi
fi
mkdir -p dist/{el8,tmp}
SOURCE_DIR_NAME=cockpit-navigator-$(grep Version el/cockpit-navigator.spec --color=never | awk '{print $2}')
SOURCE_DIR=dist/tmp/$SOURCE_DIR_NAME
mkdir -p $SOURCE_DIR
make DESTDIR=$SOURCE_DIR install
pushd $SOURCE_DIR/..
tar -czvf $SOURCE_DIR_NAME.tar.gz $SOURCE_DIR_NAME
popd
# build rpm from source tar and place it dist/el8 by mirroring dist/el8 to rpmbuild/RPMS
docker run -u $(id -u):$(id -g) -w /home/rpm/rpmbuild -it -v$(pwd)/dist/tmp:/home/rpm/rpmbuild/SOURCES -v$(pwd)/dist/el8:/home/rpm/rpmbuild/RPMS -v$(pwd)/el:/home/rpm/rpmbuild/SPECS --rm cockpit-navigator-el8-builder rpmbuild -ba SPECS/cockpit-navigator.spec
res=$?
if [ $res -ne 0 ]; then
echo "Packaging failed."
exit $res
fi
rm -rf dist/tmp
echo "rpm is in dist/el8/"
exit 0