2020-08-06 14:36:25 -07:00
|
|
|
#!/bin/bash
|
|
|
|
|
|
|
|
|
|
set -eu -o pipefail
|
|
|
|
|
|
2020-08-06 22:04:46 -07:00
|
|
|
readonly script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
|
readonly task_worker="${script_dir}/../taskworker.js"
|
|
|
|
|
|
2020-08-06 14:36:25 -07:00
|
|
|
if [[ ${EUID} -ne 0 ]]; then
|
|
|
|
|
echo "This script should be run as root." > /dev/stderr
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if [[ $# -eq 0 ]]; then
|
|
|
|
|
echo "No arguments supplied"
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if [[ "$1" == "--check" ]]; then
|
|
|
|
|
echo "OK"
|
|
|
|
|
exit 0
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
readonly task_id="$1"
|
|
|
|
|
readonly logfile="$2"
|
|
|
|
|
readonly nice="$3"
|
2024-02-19 17:01:54 +01:00
|
|
|
readonly memory_limit_mb="$4" # SI units
|
2024-07-19 13:05:09 +02:00
|
|
|
readonly oom_score_adjust="$5"
|
2020-08-06 14:36:25 -07:00
|
|
|
|
2025-06-16 18:19:30 +02:00
|
|
|
readonly id=$(id -u $SUDO_USER)
|
|
|
|
|
|
2020-08-09 07:07:19 -07:00
|
|
|
readonly service_name="box-task-${task_id}"
|
2020-08-06 14:36:25 -07:00
|
|
|
|
2025-06-16 18:19:30 +02:00
|
|
|
systemctl reset-failed "${service_name}" 2>/dev/null || true
|
2020-08-08 11:10:02 -07:00
|
|
|
|
2025-06-16 14:20:07 +02:00
|
|
|
options="-p TimeoutStopSec=10s -p MemoryMax=${memory_limit_mb}M -p OOMScoreAdjust=${oom_score_adjust} --wait"
|
2020-08-07 00:15:24 -07:00
|
|
|
|
2025-06-16 18:14:21 +02:00
|
|
|
# systemd-run is used to create resource limited tasks. the tasks are in separate cgroup and won't get affected by box start/stop
|
2025-06-17 22:30:34 +02:00
|
|
|
# this design is because tasks should not run when box code is stopped. if dashboard is down, nothing should run -in background.
|
|
|
|
|
# besides, if tasks continue running, box code needs complex reconcilation code on start up.
|
|
|
|
|
# To achieve above design, we could use BindsTo=box.service. While this stops all tasks on systemctl stop, it restarts tasks on systemctl restart.
|
|
|
|
|
# Another approach was to use --scope but this is incompatible with --wait (and then we have to start polling status to get exit code)
|
|
|
|
|
|
|
|
|
|
# it seems systemd-run does not return the exit status of the process despite --wait but atleast it waits
|
|
|
|
|
if ! systemd-run --unit "${service_name}" --wait --uid=${id} --gid=${id} \
|
|
|
|
|
-p TimeoutStopSec=2s -p MemoryMax=${memory_limit_mb}M -p OOMScoreAdjust=${oom_score_adjust} --nice "${nice}" \
|
|
|
|
|
--setenv HOME=${HOME} --setenv USER=${SUDO_USER} --setenv DEBUG=box:* --setenv BOX_ENV=${BOX_ENV} --setenv NODE_ENV=production \
|
|
|
|
|
"${task_worker}" "${task_id}" "${logfile}"; then
|
2022-11-23 12:53:21 +01:00
|
|
|
echo "Service ${service_name} failed to run" # this only happens if the path to task worker itself is wrong
|
2022-11-02 22:39:25 +01:00
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
exit_code=$(systemctl show "${service_name}" -p ExecMainCode | sed 's/ExecMainCode=//g')
|
2020-08-08 11:10:02 -07:00
|
|
|
|
|
|
|
|
echo "Service ${service_name} finished with exit code ${exit_code}"
|
|
|
|
|
exit "${exit_code}"
|