Kill all tasks on shutdown and startup
BindsTo will kill all the tasks when systemctl stop box is executed. But when restarted, it keeps the tasks running. Because of this behavior, we kill the tasks on startup and stop of the box code.
This commit is contained in:
@@ -1063,6 +1063,8 @@ function run(appId, args, progressCallback, callback) {
|
||||
return stop(app, args, progressCallback, callback);
|
||||
case apps.ISTATE_PENDING_RESTART:
|
||||
return restart(app, args, progressCallback, callback);
|
||||
case apps.ISTATE_INSTALLED: // can only happen when we have a bug in our code while testing/development
|
||||
return updateApp(app, { installationState: apps.ISTATE_INSTALLED, error: null, health: null }, callback);
|
||||
default:
|
||||
debugApp(app, 'apptask launched with invalid command');
|
||||
return callback(new BoxError(BoxError.INTERNAL_ERROR, 'Unknown install command in apptask:' + app.installationState));
|
||||
|
||||
+4
-1
@@ -66,7 +66,7 @@ function uninitialize(callback) {
|
||||
|
||||
async.series([
|
||||
cron.stopJobs,
|
||||
platform.stop
|
||||
platform.stopAllTasks
|
||||
], callback);
|
||||
}
|
||||
|
||||
@@ -109,6 +109,9 @@ function notifyUpdate(callback) {
|
||||
|
||||
// each of these tasks can fail. we will add some routes to fix/re-run them
|
||||
function runStartupTasks() {
|
||||
// stop all the systemd tasks
|
||||
platform.stopAllTasks(NOOP_CALLBACK);
|
||||
|
||||
// configure nginx to be reachable by IP
|
||||
reverseProxy.writeDefaultConfig(NOOP_CALLBACK);
|
||||
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@
|
||||
|
||||
exports = module.exports = {
|
||||
start: start,
|
||||
stop: stop,
|
||||
stopAllTasks: stopAllTasks,
|
||||
|
||||
// exported for testing
|
||||
_isReady: false
|
||||
@@ -73,7 +73,7 @@ function start(callback) {
|
||||
});
|
||||
}
|
||||
|
||||
function stop(callback) {
|
||||
function stopAllTasks(callback) {
|
||||
tasks.stopAllTasks(callback);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,4 +37,4 @@ if [[ "${cmd}" == "clear" ]]; then
|
||||
else
|
||||
# this make not succeed if volume is a mount point
|
||||
rmdir "${volume_dir}" || true
|
||||
fi
|
||||
fi
|
||||
|
||||
+16
-17
@@ -2,6 +2,9 @@
|
||||
|
||||
set -eu -o pipefail
|
||||
|
||||
readonly script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
readonly task_worker="${script_dir}/../taskworker.js"
|
||||
|
||||
if [[ ${EUID} -ne 0 ]]; then
|
||||
echo "This script should be run as root." > /dev/stderr
|
||||
exit 1
|
||||
@@ -21,24 +24,20 @@ readonly task_id="$1"
|
||||
readonly logfile="$2"
|
||||
readonly nice="$3"
|
||||
|
||||
readonly id=$(id -u yellowtent)
|
||||
readonly service_name="cloudron-task-${task_id}"
|
||||
|
||||
systemctl reset-failed "${service_name}" || true
|
||||
|
||||
# keep the env vars in sync with box.service
|
||||
systemd-run --unit "${service_name}" \
|
||||
-p BindsTo=box.service \
|
||||
--pipe \
|
||||
--wait \
|
||||
--property=OOMScoreAdjust=-1000 \
|
||||
--nice "${nice}" \
|
||||
--uid=${id} \
|
||||
--gid=${id} \
|
||||
-E HOME=/home/yellowtent \
|
||||
-E USER=yellowtent \
|
||||
-E DEBUG=box:* \
|
||||
-E BOX_ENV=cloudron \
|
||||
-E NODE_ENV=production \
|
||||
/home/yellowtent/box/src/taskworker.js "${task_id}" "${logfile}"
|
||||
readonly id=$(id -u $SUDO_USER)
|
||||
|
||||
# Note: BindsTo will kill this task when the box is stopped. but will not kill this task when restarted!
|
||||
# For this reason, we have code to kill the tasks both on shutdown and startup
|
||||
if [[ "$BOX_ENV" == "cloudron" ]]; then
|
||||
binds_to="-p BindsTo=box.service"
|
||||
else
|
||||
binds_to=""
|
||||
fi
|
||||
|
||||
systemd-run --unit "${service_name}" --pipe --wait --property=OOMScoreAdjust=-1000 --nice "${nice}" --uid=${id} --gid=${id} \
|
||||
${binds_to} -E HOME=${HOME} -E USER=${SUDO_USER} -E DEBUG=${DEBUG} -E BOX_ENV=${BOX_ENV} -E NODE_ENV=production \
|
||||
"${task_worker}" "${task_id}" "${logfile}"
|
||||
|
||||
|
||||
@@ -19,7 +19,11 @@ fi
|
||||
|
||||
task_id="$1"
|
||||
|
||||
service_name="cloudron-task-${task_id}"
|
||||
|
||||
systemctl kill --signal=SIGTERM "${service_name}"
|
||||
if [[ "${task_id}" == "all" ]]; then
|
||||
systemctl list-units --full --no-legend cloudron-task-* # just to show who was running
|
||||
systemctl kill --signal=SIGTERM cloudron-task-* || true
|
||||
else
|
||||
readonly service_name="cloudron-task-${task_id}"
|
||||
systemctl kill --signal=SIGTERM "${service_name}" || true
|
||||
fi
|
||||
|
||||
|
||||
+7
-5
@@ -38,7 +38,6 @@ exports = module.exports = {
|
||||
};
|
||||
|
||||
let assert = require('assert'),
|
||||
async = require('async'),
|
||||
BoxError = require('./boxerror.js'),
|
||||
debug = require('debug')('box:tasks'),
|
||||
path = require('path'),
|
||||
@@ -144,7 +143,9 @@ function startTask(id, options, callback) {
|
||||
|
||||
let killTimerId = null, timedOut = false;
|
||||
|
||||
shell.sudo('startTask', [ START_TASK_CMD, id, logFile, options.nice || 0 ], {}, function (error) {
|
||||
gTasks[id] = shell.sudo('startTask', [ START_TASK_CMD, id, logFile, options.nice || 0 ], { preserveEnv: true }, function (error) {
|
||||
if (!gTasks[id]) return; // ignore task exit since we are shutting down. see stopAllTasks
|
||||
|
||||
const code = error ? error.code : 0;
|
||||
const signal = error ? error.signal : 0;
|
||||
|
||||
@@ -200,9 +201,10 @@ function stopTask(id, callback) {
|
||||
function stopAllTasks(callback) {
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
async.eachSeries(Object.keys(gTasks), function (id, iteratorDone) {
|
||||
stopTask(id, () => iteratorDone()); // ignore any error
|
||||
}, callback);
|
||||
debug('stopTask: stopping all tasks');
|
||||
|
||||
gTasks = {}; // this signals startTask() to not set completion status as "crashed"
|
||||
shell.sudo('stopTask', [ STOP_TASK_CMD, 'all' ], {}, callback);
|
||||
}
|
||||
|
||||
function listByTypePaged(type, page, perPage, callback) {
|
||||
|
||||
@@ -22,7 +22,9 @@ scripts=("${SOURCE_DIR}/src/scripts/clearvolume.sh" \
|
||||
"${SOURCE_DIR}/src/scripts/collectlogs.sh" \
|
||||
"${SOURCE_DIR}/src/scripts/configurecollectd.sh" \
|
||||
"${SOURCE_DIR}/src/scripts/remotesupport.sh" \
|
||||
"${SOURCE_DIR}/src/scripts/backupupload.js" \
|
||||
"${SOURCE_DIR}/src/scripts/starttask.sh" \
|
||||
"${SOURCE_DIR}/src/scripts/stoptask.sh" \
|
||||
"${SOURCE_DIR}/src/scripts/rmmailbox.sh" \
|
||||
"${SOURCE_DIR}/src/scripts/configurelogrotate.sh")
|
||||
|
||||
for script in "${scripts[@]}"; do
|
||||
|
||||
Reference in New Issue
Block a user