diff options
-rw-r--r-- | NeoRuntime/Runtime/luxcena_neo/neo_behaviour.py | 4 | ||||
-rwxr-xr-x | bin/luxcena-neo-cli.sh | 114 | ||||
-rw-r--r-- | src/SelfUpdater/index.js | 94 |
3 files changed, 137 insertions, 75 deletions
diff --git a/NeoRuntime/Runtime/luxcena_neo/neo_behaviour.py b/NeoRuntime/Runtime/luxcena_neo/neo_behaviour.py index 6ae58fe..2eef444 100644 --- a/NeoRuntime/Runtime/luxcena_neo/neo_behaviour.py +++ b/NeoRuntime/Runtime/luxcena_neo/neo_behaviour.py @@ -266,7 +266,7 @@ class BooleanVariable(Variable): except: print("Attempted to set {} to \"{}\", which is not a valid bool...".format(self.name, value)) -class Trigger(self): +class Trigger(Variable): def __init__(self, name: str, **kwargs): super().__init__(name, False, VariableType.TRIGGER, **kwargs) @@ -278,4 +278,4 @@ class Trigger(self): if value: value = False super(BooleanVariable, type(self)).value.fset(self, value) except: - print("Attempted to set {} to \"{}\", which is not a valid bool...".format(self.name, value))
\ No newline at end of file + print("Attempted to set {} to \"{}\", which is not a valid bool...".format(self.name, value)) diff --git a/bin/luxcena-neo-cli.sh b/bin/luxcena-neo-cli.sh index 161293e..7346b3a 100755 --- a/bin/luxcena-neo-cli.sh +++ b/bin/luxcena-neo-cli.sh @@ -5,64 +5,85 @@ usage() { exit 1 } +function TPUT() { + if [ -t 1 ]; then + shift + tput $@ + fi +} + function startLuxcenaNeo() { header "Start Luxcena NEO" execCommand "systemctl start luxcena-neo" 1 } function header() { - tput setaf 3 - printf "\n[ ] $1" - tput sgr0 + TPUT setaf 3 + if [ -t 1 ]; then + printf "\n[ ] $1" + else + printf "\n- $1" + fi + TPUT sgr0 } function commandError() { trap - 1 cat /tmp/luxcena-neo-update.log - tput setaf 1 + TPUT setaf 1 printf "\n\nInstall failed.\n" - tput sgr0 + TPUT sgr0 startLuxcenaNeo exit 1 } -function execCommand() { - tput sc - tput setaf 4 - printf " ($1)" - tput sgr0 - bash -c "$1 > /tmp/luxcena-neo-update.log 2>&1" & - - PID=$! - +function spinner() { i=1 sp="/-\|" - while ps a | awk '{print $1}' | grep -q "$PID"; do - tput cub $(tput cols) - tput cuf 1 + while ps a | awk '{print $1}' | grep -q "$1"; do + TPUT cub $(TPUT cols) + TPUT cuf 1 printf "${sp:i++%${#sp}:1}" - tput cuf $(tput cols) + TPUT cuf $(TPUT cols) sleep 0.09 done - tput cub $(tput cols) - tput cuf 1 + TPUT cub $(TPUT cols) + TPUT cuf 1 +} + +function execCommand() { + TPUT sc + TPUT setaf 4 + if [ -t 1 ]; then + printf " ($1)" + else + printf "\n>> $1 " + fi + TPUT sgr0 + bash -c "$1 > /tmp/luxcena-neo-update.log 2>&1" & + + PID=$! + + if [ -t 1 ]; then + spinner $PID + fi wait $PID commandSucc=$? if [ $commandSucc -eq 0 ]; then - tput setaf 2 + TPUT setaf 2 printf "✓" - tput sgr0 - tput rc - tput el + TPUT sgr0 + TPUT rc + TPUT el else - tput setaf 1 + TPUT setaf 1 printf "x" - tput sgr0 - tput cuf $(tput cols) + TPUT sgr0 + TPUT cuf $(TPUT cols) printf "\n" if [ $# -eq 1 ] || [ $2 -eq "0" ]; then commandError @@ -71,20 +92,20 @@ function execCommand() { } function dlgYN() { - tput sc - tput setaf 4 + TPUT sc + TPUT setaf 4 printf "$1 (y/n)? " while : do read -n 1 -p "" YNQuestionAnswer if [[ $YNQuestionAnswer == "y" ]]; then - tput rc; tput el + TPUT rc; TPUT el printf ". $1?: \e[0;32mYes\e[0m\n" - tput sc + TPUT sc eval $2=1 # Set parameter 2 of input to the return value break elif [[ $YNQuestionAnswer == "n" ]]; then - tput rc; tput el + TPUT rc; TPUT el printf ". $1?: \e[0;31mNo\e[0m\n" eval $2=0 # Set parameter 2 of input to the return value break @@ -108,10 +129,17 @@ printf "\e[37mLuxcena-\e[31mn\e[32me\e[34mo\e[37m-cli \e[90m[args: '$*']\n\n\e[0 action=$1 if [ "$action" == "update" ]; then - - tput rev + PATH=/bin:$PATH + PATH=/sbin:$PATH + PATH=/usr/local/sbin:$PATH + PATH=/usr/local/bin:$PATH + PATH=/usr/sbin:$PATH + PATH=/usr/bin:$PATH + PATH=/usr/sbin:$PATH + + TPUT rev printf '%s\n' "Luxcena-neo Updater" - tput sgr0 + TPUT sgr0 printf '\e[93m%s\e[0m\n' "-------------------" if [ "$EUID" -ne 0 ]; then @@ -131,7 +159,7 @@ if [ "$action" == "update" ]; then execCommand "git clone -b $repoBranch $repoUrl $UPDATEDIR" header "Create backup" - execCommand "mkdir -p /opt/luxcena-neo/backup" + execCommand "mkdir -p /var/luxcena-neo/backup" BACKUPDIR=$(mktemp -d -p /var/luxcena-neo/backup backup.XXXXXX) execCommand "cp -R /opt/luxcena-neo/ $BACKUPDIR" @@ -171,11 +199,11 @@ if [ "$action" == "update" ]; then exit 0 elif [ "$action" == "uninstall" ]; then - tput setab 1 + TPUT setab 1 printf '%s\n' "Luxcena Neo Uninstaller..." - tput sgr0 + TPUT sgr0 printf '\e[93m%s\e[0m' "--------------------------" - tput setaf 8 + TPUT setaf 8 printf "By uninstalling Luxcena-Neo you might loose all data, including your scripts.\n\n" dlgYN "Are you sure you want to uninstall?" res @@ -192,14 +220,14 @@ elif [ "$action" == "uninstall" ]; then execCommand "rm -f /usr/bin/luxcena-neo.sh" execCommand "rm -f /usr/bin/lux-neo" - tput setaf 2 + TPUT setaf 2 printf "\nEverything should now be gone.\n" printf "/etc/luxcena-neo and /var/log/luxcena-neo is not removed.\n" - tput sgr0 - tput setaf 8 + TPUT sgr0 + TPUT setaf 8 printf "Well, some dependencies still exists. Those are:\n" printf " - packages (nodejs python3 python3-pip)\n" - tput sgr0 + TPUT sgr0 fi elif [ "$action" == "start" ]; then diff --git a/src/SelfUpdater/index.js b/src/SelfUpdater/index.js index 447da3f..84b0ee3 100644 --- a/src/SelfUpdater/index.js +++ b/src/SelfUpdater/index.js @@ -42,6 +42,10 @@ class Updater { this.step = null; this.command = null; this.event = new EventEmitter(); + + this.updatedir = null; + this.backupdir = null; + this.backupcomplete = false; this.updatelog = []; } @@ -64,6 +68,10 @@ class Updater { this.updatelog = []; this.step = null; this.command = null; + this.updatedir = null; + this.backupdir = null; + this.backupcomplete = false; + if (!isInstalledInDefaultLocation()) { return {success: false, reason: "not installed in default location", detail: __appdir}; } @@ -71,42 +79,46 @@ class Updater { this.event.emit("start"); neoModules.neoRuntimeManager.stopMode(); - let updatedir = null; - let backupdir = null; + try { // Download update - this.setStep("Downloading update"); + this.setStep("Downloading update (1/8)"); this.setCommand("Create updatedir"); - updatedir = createUniqueDir("/tmp", "luxcena-neo.update"); - await this.downloadUpdate(updatedir); + this.updatedir = createUniqueDir("/tmp", "luxcena-neo.update"); + await this.downloadUpdate(this.updatedir); // Create backup - this.setStep("Creating backup"); + this.setStep("Creating backup (2/8)"); this.setCommand("Create backupdir"); - backupdir = createUniqueDir("/var/luxcena-neo/backups", "backup"); - this.setCommand(`Copy ${__appdir} into ${backupdir}`); - await fs.copySync(__appdir, backupdir); + this.backupdir = createUniqueDir("/var/luxcena-neo/backups", "backup"); + this.setCommand(`Copy ${__appdir} into ${this.backupdir}`); + await fs.copy(__appdir, this.backupdir); + this.backupcomplete = true; // Install update - this.setStep("Installing update"); - this.setCommand(`Copy ${updatedir} into /opt/luxcena-neo`); - await fs.copySync(updatedir, __appdir); + this.setStep("Installing update (3/8)"); + this.setCommand(`Copy ${this.updatedir} into /opt/luxcena-neo`); + await fs.copy(this.updatedir, __appdir); // Install dependencies - this.setStep("Installing dependencies"); + this.setStep("Installing dependencies (4/8)"); await this.installDependencies(); // Create python virtualenv - this.setStep("Making virtualenv"); + this.setStep("Making virtualenv (5/8)"); await this.makeVirtualenv(); // Build source code - this.setStep("Building source"); - this.build(); + this.setStep("Building source (6/8)"); + await this.build(); + + // Cleanup + this.setStep("Cleaning up (7/8)"); + await this.cleanup(); // Restart self, systemd service restart policy will start us up again. - this.setStep("Stopping luxcena neo service in the hope that systemd will restart it."); - this.command("process.exit(0)"); + this.setStep("Stopping luxcena neo service in the hope that systemd will restart it. (8/8)"); + this.setCommand("EXIT"); process.exit(0); } catch (e) { @@ -121,7 +133,18 @@ class Updater { } this.updatelog.push(logText); - // Restore here + try { + if (this.backupcomplete && (this.backupdir != null)) { + this.setStep("Restoring backup"); + this.setCommand(`Copy ${this.backupdir} into /opt/luxcena-neo`); + await fs.copy(this.backupdir, __appdir); + } + this.setStep("Cleaning up"); + await this.cleanup(); + } catch (e) { + this.updatelog.push(e.toString()); + console.log(e); + } this.event.emit("error", this.updatelog); neoModules.neoRuntimeManager.startMode(); @@ -187,11 +210,11 @@ class Updater { async makeVirtualenv() { this.setCommand("Deleting old virtualenv"); if (fs.existsSync(`${__appdir}/NeoRuntime/Runtime/venv`)) { - fs.unlinkSync(`${__appdir}/NeoRuntime/Runtime/venv`); + await fs.remove(`${__appdir}/NeoRuntime/Runtime/venv`); } await this.run("virtualenv", ["-p", "/usr/bin/python3", `${__appdir}/NeoRuntime/Runtime/venv`]); - await this.run("sh", ["-c", `source ${__appdir}/NeoRuntime/Runtime/venv/bin/activate && pip install rpi_ws281x`]); + await this.run("sh", ["-c", `. ${__appdir}/NeoRuntime/Runtime/venv/bin/activate && pip install rpi_ws281x`]); } async build() { @@ -202,12 +225,23 @@ class Updater { async installSystemdService() { this.setCommand("Deleting old systemd service"); - fs.unlinkSync("/etc/systemd/system/luxcena-neo.service"); + await fs.remove("/etc/systemd/system/luxcena-neo.service"); this.setCommand("Installing new systemd service"); - fs.copySync("/opt/luxcena-neo/bin/luxcena-neo.service", "/etc/systemd/system/luxcena-neo.service"); + await fs.copy("/opt/luxcena-neo/bin/luxcena-neo.service", "/etc/systemd/system/luxcena-neo.service"); await this.run("systemctl", ["daemon-reload"]); await this.run("systemctl", ["enable", "luxcena-neo"]); - } + } + + async cleanup() { + if (this.updatedir != null) { + this.setCommand(`Removing temporary update files ${this.updatedir}`); + await fs.remove(this.updatedir); + } + if (this.backupdir != null) { + this.setCommand(`Removing ${this.backupdir}, thinking everything went fine :)`); + await fs.remove(this.backupdir); + } + } } @@ -221,10 +255,11 @@ class VersionChecker { this.checkFrequency = neoModules.userData.config.SelfUpdater.checkVersionInterval * 86400000; // Takes in days. this.repoBranch = neoModules.userData.config.SelfUpdater.branch; - this.remotePackageJSON = "https://raw.githubusercontent.com" + url.parse(this.repoLink).pathname + "/" + this.repoBranch + "/package.json"; + this.remotePackageJSON = "https://raw.githubusercontent.com/JakobST1n/Luxcena-Neo/" + this.repoBranch + "/package.json"; this.newVersion = false; - this.newestVersion = this.checkVersion(this.remotePackageJSON); + this.newestVersion = this.version; + this.checkVersion(this.remotePackageJSON); this.updateChecker = setInterval(() => { let newVersion = this.checkVersion(this.remotePackageJSON); @@ -237,15 +272,14 @@ class VersionChecker { request.get(this.remotePackageJSON, (error, response, body) => { if (!error && response.statusCode === 200) { let remotePackageJSON = JSON.parse(body); - let newestVersion = remotePackageJSON["version"]; - if (newestVersion != this.version) { + this.newestVersion = remotePackageJSON["version"]; + if (this.newestVersion != this.version) { logger.notice("A new version is available on \"" + this.repoBranch + "\" (v" + this.version + ")"); this.newVersion = true; } else { - logger.info(`Running newest version (${newestVersion})`); + logger.info(`Running newest version (${this.newestVersion})`); this.newVersion = false; } - this.newestVersion = newestVersion; } else { logger.notice("Could not find latest version! Please check you internet connection."); } |