From eaf926f42eecfc9816845eff033b2a3a847652b3 Mon Sep 17 00:00:00 2001 From: Sebastien Clement Date: Wed, 10 Feb 2021 15:22:30 +0100 Subject: [PATCH] :hammer: Add auto start/stop addons before/after backup --- .../rootfs/opt/nextcloud_backup/error_code.md | 8 +- .../opt/nextcloud_backup/public/js/index.js | 8 ++ .../rootfs/opt/nextcloud_backup/routes/api.js | 36 ++++--- .../opt/nextcloud_backup/tools/cronTools.js | 40 +++++--- .../nextcloud_backup/tools/hassioApiTools.js | 99 ++++++++++++++++++- .../opt/nextcloud_backup/tools/webdavTools.js | 8 +- 6 files changed, 161 insertions(+), 38 deletions(-) diff --git a/nextcloud_backup/rootfs/opt/nextcloud_backup/error_code.md b/nextcloud_backup/rootfs/opt/nextcloud_backup/error_code.md index e3c23e1..e0736a6 100644 --- a/nextcloud_backup/rootfs/opt/nextcloud_backup/error_code.md +++ b/nextcloud_backup/rootfs/opt/nextcloud_backup/error_code.md @@ -1,9 +1,11 @@ # Error Codes -- `1` => Fail to downlaod snap +- `1` => Fail to download snap - `2` => Nextcloud config invalid -- `3` => Can't connect to nextcloud +- `3` => Can't connect to Nextcloud - `4` => Upload snap fail - `5` => Fail create new snap - `6` => Fail to clean -- `7` => Fail to Download snap \ No newline at end of file +- `7` => Fail to download snap +- `8` => Fail to stop addon +- `9` => Fail to start addon \ No newline at end of file diff --git a/nextcloud_backup/rootfs/opt/nextcloud_backup/public/js/index.js b/nextcloud_backup/rootfs/opt/nextcloud_backup/public/js/index.js index 30239c6..8463c36 100644 --- a/nextcloud_backup/rootfs/opt/nextcloud_backup/public/js/index.js +++ b/nextcloud_backup/rootfs/opt/nextcloud_backup/public/js/index.js @@ -126,6 +126,14 @@ function update_status() { printStatusWithBar('Creating Snapshot', data.progress); buttons.addClass("disabled"); break; + case "stopping": + printStatusWithBar('Stopping addons', data.progress); + buttons.addClass("disabled"); + break; + case "starting": + printStatusWithBar('Starting addons', data.progress); + buttons.addClass("disabled"); + break; } if (data.last_backup != null) { let last_back_status = $('#last_back_status'); diff --git a/nextcloud_backup/rootfs/opt/nextcloud_backup/routes/api.js b/nextcloud_backup/rootfs/opt/nextcloud_backup/routes/api.js index d906345..633bcba 100644 --- a/nextcloud_backup/rootfs/opt/nextcloud_backup/routes/api.js +++ b/nextcloud_backup/rootfs/opt/nextcloud_backup/routes/api.js @@ -142,32 +142,36 @@ router.post("/manual-backup", function (req, res, next) { router.post("/new-backup", function (req, res, next) { let status = statusTools.getStatus(); - if (status.status === "creating" && status.status === "upload" && status.status === "download") { + if (status.status === "creating" || status.status === "upload" || status.status === "download" || status.status === "stopping" || status.status === "starting") { res.status(503); res.send(); return; } - hassioApiTools - .getVersion() - .then((version) => { - let name = settingsTools.getFormatedName(true, version); - hassioApiTools - .createNewBackup(name) - .then((id) => { - hassioApiTools - .downloadSnapshot(id) - .then(() => { - webdav.uploadFile(id, webdav.getConf().back_dir + pathTools.manual + name + ".tar").catch(); - }) - .catch(() => { + hassioApiTools.stopAddons() + .then(() => { + hassioApiTools.getVersion() + .then((version) => { + let name = settingsTools.getFormatedName(true, version); + hassioApiTools.createNewBackup(name) + .then((id) => { + hassioApiTools + .downloadSnapshot(id) + .then(() => { + webdav.uploadFile(id, webdav.getConf().back_dir + pathTools.manual + name + ".tar") + .then(() => { + hassioApiTools.startAddons().catch(() => { + }) + }); + }); }); - }) - .catch(() => { }); }) .catch(() => { + hassioApiTools.startAddons().catch(() => { + }); }); + res.status(201); res.send(); }); diff --git a/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/cronTools.js b/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/cronTools.js index b90915a..62e8fb7 100644 --- a/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/cronTools.js +++ b/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/cronTools.js @@ -83,21 +83,31 @@ class CronContainer { _createBackup() { logger.debug("Cron triggered !"); let status = statusTools.getStatus(); - if (status.status === "creating" || status.status === "upload" || status.status === "download") return; - hassioApiTools - .getVersion() - .then((version) => { - let name = settingsTools.getFormatedName(false, version) - hassioApiTools - .createNewBackup(name) - .then((id) => { - hassioApiTools - .downloadSnapshot(id) - .then(() => { - webdav.uploadFile(id, webdav.getConf().back_dir + pathTools.auto + name + ".tar").catch(); - }).catch(); - }).catch(); - }).catch(); + if (status.status === "creating" || status.status === "upload" || status.status === "download" || status.status === "stopping" || status.status === "starting") + return; + hassioApiTools.stopAddons() + .then(() => { + hassioApiTools.getVersion() + .then((version) => { + let name = settingsTools.getFormatedName(false, version); + hassioApiTools.createNewBackup(name) + .then((id) => { + hassioApiTools + .downloadSnapshot(id) + .then(() => { + webdav.uploadFile(id, webdav.getConf().back_dir + pathTools.auto + name + ".tar") + .then(() => { + hassioApiTools.startAddons().catch(() => { + }); + }); + }); + }); + }); + }) + .catch(() => { + hassioApiTools.startAddons().catch(() => { + }); + }); } _clean() { diff --git a/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/hassioApiTools.js b/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/hassioApiTools.js index 576ff12..64ce9a0 100644 --- a/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/hassioApiTools.js +++ b/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/hassioApiTools.js @@ -284,7 +284,7 @@ function createNewBackup(name) { folders: folders }, }; - if(settingsTools.getSettings().password_protected === "true"){ + if (settingsTools.getSettings().password_protected === "true") { option.json.password = settingsTools.getSettings().password_protect_value } @@ -393,7 +393,7 @@ function uploadSnapshot(path) { fs.unlinkSync(path); status.status = "error"; status.error_code = 4; - status.message = `Fail to upload backup to home assitant (${err}) !`; + status.message = `Fail to upload backup to home assistant (${err}) !`; statusTools.setStatus(status); logger.error(status.message); reject(status.message); @@ -401,6 +401,99 @@ function uploadSnapshot(path) { }); } +function stopAddons() { + return new Promise(((resolve, reject) => { + logger.info('Stopping addons...') + let status = statusTools.getStatus(); + status.status = "stopping"; + status.progress = -1; + status.message = null; + status.error_code = null; + statusTools.setStatus(status); + let promises = []; + let token = process.env.HASSIO_TOKEN; + let option = { + headers: { "X-HASSIO-KEY": token }, + responseType: "json", + }; + let addons_slug = settingsTools.getSettings().auto_stop_addon + for (let addon of addons_slug) { + if (addon !== "") { + logger.debug(`... Stopping addon ${addon}`) + promises.push(got.post(`http://hassio/addons/${addon}/stop`, option)); + } + + } + Promise.allSettled(promises).then(values => { + let error = null; + for (let val of values) + if (val.status === "rejected") + error = val.reason; + + if (error) { + status.status = "error"; + status.error_code = 8; + status.message = `Fail to stop addons(${error}) !`; + statusTools.setStatus(status); + logger.error(status.message); + reject(status.message); + } else { + logger.info('... Ok') + resolve(); + } + }); + })); +} + +function startAddons() { + return new Promise(((resolve, reject) => { + logger.info('Starting addons...'); + let status = statusTools.getStatus(); + status.status = "starting"; + status.progress = -1; + status.message = null; + status.error_code = null; + statusTools.setStatus(status); + let promises = []; + let token = process.env.HASSIO_TOKEN; + let option = { + headers: { "X-HASSIO-KEY": token }, + responseType: "json", + }; + let addons_slug = settingsTools.getSettings().auto_stop_addon + for (let addon of addons_slug) { + if (addon !== "") { + logger.debug(`... Starting addon ${addon}`) + promises.push(got.post(`http://hassio/addons/${addon}/start`, option)); + } + } + Promise.allSettled(promises).then(values => { + let error = null; + for (let val of values) + if (val.status === "rejected") + error = val.reason; + + if (error) { + let status = statusTools.getStatus(); + status.status = "error"; + status.error_code = 9; + status.message = `Fail to start addons (${error}) !`; + statusTools.setStatus(status); + logger.error(status.message); + reject(status.message); + } else { + logger.info('... Ok') + status.status = "idle"; + status.progress = -1; + status.message = null; + status.error_code = null; + statusTools.setStatus(status); + resolve(); + } + }); + })); +} + exports.getVersion = getVersion; exports.getAddonList = getAddonList; exports.getFolderList = getFolderList; @@ -408,4 +501,6 @@ exports.getSnapshots = getSnapshots; exports.downloadSnapshot = downloadSnapshot; exports.createNewBackup = createNewBackup; exports.uploadSnapshot = uploadSnapshot; +exports.stopAddons = stopAddons; +exports.startAddons = startAddons; exports.clean = clean; diff --git a/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/webdavTools.js b/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/webdavTools.js index 155010c..c7c9a7e 100644 --- a/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/webdavTools.js +++ b/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/webdavTools.js @@ -194,13 +194,17 @@ class WebdavTools { if (this.client == null) { this.confIsValid() .then(() => { - this._startUpload(id, path).catch((err) => reject(err)); + this._startUpload(id, path) + .then(()=> resolve()) + .catch((err) => reject(err)); }) .catch((err) => { reject(err); }); } else - this._startUpload(id, path).catch((err) => reject(err)); + this._startUpload(id, path) + .then(()=> resolve()) + .catch((err) => reject(err)); }); }