From c72329cb22c281ef0d687fcf615f3ade25a56d21 Mon Sep 17 00:00:00 2001 From: Luke Childs Date: Wed, 15 Jul 2020 09:30:57 +0700 Subject: [PATCH] Add power cycle functionality (#21) * Related: https://github.com/getumbrel/umbrel/pull/28 * Related: https://github.com/getumbrel/umbrel-dashboard/pull/130 * Add shutdown support * Add reboot support * Remove old comments * Use POST --- README.md | 4 +++- logic/disk.js | 8 +++----- logic/system.js | 22 +++++++++++++++++++++- routes/v1/system.js | 12 ++++++++++++ utils/const.js | 2 ++ 5 files changed, 41 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 076f96d..eb72d84 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,8 @@ Set the following environment variables directly or by placing them in `.env` fi | `PORT` | Port where manager should listen for requests | `3006` | | `DEVICE_HOST` | IP or domain from where [`umbrel-dashboard`](https://github.com/getumbrel/umbrel-dashboard) will request | `http://umbrel.local` | | `USER_FILE` | Path to the user's data file (automatically created on user registration) | `/db/user.json` | +| `SHUTDOWN_SIGNAL_FILE` | Path to write a file to signal a system shutdown | `/signals/shutdown` | +| `REBOOT_SIGNAL_FILE` | Path to write a file to signal a system reboot | `/signals/reboot` | | `MIDDLEWARE_API_URL` | IP or domain where [`umbrel-middleware`](https://github.com/getumbrel/umbrel-middleware) is listening | `http://localhost` | | `MIDDLEWARE_API_PORT` | Port where [`umbrel-middleware`](https://github.com/getumbrel/umbrel-middleware) is listening | `3005` | | `JWT_PUBLIC_KEY_FILE` | Path to the JWT public key (automatically created) | `/db/jwt-public-key/jwt.pem` | @@ -73,4 +75,4 @@ Umbrel Manager is inspired by and built upon the work done by [Casa](https://git [![License](https://img.shields.io/github/license/getumbrel/umbrel-manager?color=%235351FB)](https://github.com/getumbrel/umbrel-manager/blob/master/LICENSE) -[getumbrel.com](https://getumbrel.com) \ No newline at end of file +[getumbrel.com](https://getumbrel.com) diff --git a/logic/disk.js b/logic/disk.js index 23179cc..778f0d6 100644 --- a/logic/disk.js +++ b/logic/disk.js @@ -100,14 +100,12 @@ function writeJWTPublicKeyFile(data) { return diskService.writeKeyFile(constants.JWT_PUBLIC_KEY_FILE, data); } -// Send a signal to shutdown async function shutdown() { await diskService.writeFile(constants.SHUTDOWN_SIGNAL_FILE, 'true'); } -// Send a signal to relaunch the manager. -async function relaunch() { - await diskService.writeFile(constants.RELAUNCH_SIGNAL_FILE, 'true'); +async function reboot() { + await diskService.writeFile(constants.REBOOT_SIGNAL_FILE, 'true'); } // Read the contends of a file. @@ -164,7 +162,7 @@ module.exports = { writeJWTPrivateKeyFile, writeJWTPublicKeyFile, shutdown, - relaunch, + reboot, readUtf8File, readJsonFile, writeMigrationStatusFile, diff --git a/logic/system.js b/logic/system.js index 602dc10..684fabe 100644 --- a/logic/system.js +++ b/logic/system.js @@ -11,7 +11,27 @@ async function getHiddenServiceUrl() { } }; +async function requestShutdown() { + try { + await diskLogic.shutdown(); + return "Shutdown requested"; + } catch (error) { + throw new NodeError('Unable to request shutdown'); + } +}; + +async function requestReboot() { + try { + await diskLogic.reboot(); + return "Reboot requested"; + } catch (error) { + throw new NodeError('Unable to request reboot'); + } +}; + module.exports = { - getHiddenServiceUrl + getHiddenServiceUrl, + requestShutdown, + requestReboot }; diff --git a/routes/v1/system.js b/routes/v1/system.js index 1bcef9e..794a504 100644 --- a/routes/v1/system.js +++ b/routes/v1/system.js @@ -15,4 +15,16 @@ router.get('/dashboard-hidden-service', auth.jwt, safeHandler(async (req, res) = return res.status(constants.STATUS_CODES.OK).json(url); })); +router.post('/shutdown', auth.jwt, safeHandler(async (req, res) => { + const result = await systemLogic.requestShutdown(); + + return res.status(constants.STATUS_CODES.OK).json(result); +})); + +router.post('/reboot', auth.jwt, safeHandler(async (req, res) => { + const result = await systemLogic.requestReboot(); + + return res.status(constants.STATUS_CODES.OK).json(result); +})); + module.exports = router; diff --git a/utils/const.js b/utils/const.js index 4b44508..a3063fb 100644 --- a/utils/const.js +++ b/utils/const.js @@ -3,6 +3,8 @@ module.exports = { REQUEST_CORRELATION_NAMESPACE_KEY: 'umbrel-manager-request', REQUEST_CORRELATION_ID_KEY: 'reqId', USER_FILE: process.env.USER_FILE || '/db/user.json', + SHUTDOWN_SIGNAL_FILE: process.env.SHUTDOWN_SIGNAL_FILE || '/signals/shutdown', + REBOOT_SIGNAL_FILE: process.env.REBOOT_SIGNAL_FILE || '/signals/reboot', JWT_PUBLIC_KEY_FILE: process.env.JWT_PUBLIC_KEY_FILE || '/db/jwt-public-key/jwt.pem', JWT_PRIVATE_KEY_FILE: process.env.JWT_PRIVATE_KEY_FILE || '/db/jwt-private-key/jwt.key', DOCKER_COMPOSE_DIRECTORY: process.env.DOCKER_COMPOSE_DIRECTORY || '/docker-compose',