feat(discord): systemd user service with a supervised run; brakes exit 3 and are never retried (#1509)

QUEUE row 17, MVP iteration 2. scripts/discord-service.sh renders and
installs mosaic-discord@<binding> from packages/discord/systemd/. The
unit's main process is `run --supervised`, which applies the new recover
policy first: a lock whose owner is gone is cleared and only the STOP
written for that is removed; an operator STOP or a held binding refuses
with exit 3, which RestartPreventExitStatus never retries. `recover` is
also a CLI verb. First cut used ExecStartPre and looped live, since systemd
honours the never-retry status only from the main process; replaced and
re-verified before any message traffic. Suite 40/40, 95 node tests.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
2026-09-13 14:39:11 -05:00
co-authored by Claude Fable 5.1
parent dc5902aafd
commit 436ba6ed6b
15 changed files with 630 additions and 30 deletions
+39 -1
View File
@@ -25,7 +25,7 @@ echo "toolchain: node $(node --version)"
echo
# --- syntax ---
for f in packages/discord/src/*.mjs packages/discord/tests/*.mjs scripts/discord.sh; do
for f in packages/discord/src/*.mjs packages/discord/tests/*.mjs packages/discord/fixtures/*.mjs scripts/discord.sh scripts/discord-service.sh; do
case "$f" in
*.sh) bash -n "$f" >/dev/null 2>&1 ;;
*) node --check "$f" >/dev/null 2>&1 ;;
@@ -71,6 +71,44 @@ check "scripts/discord.sh --help exits 0" $?
scripts/discord.sh check >/dev/null 2>&1
[ $? -eq 4 ]
check "scripts/discord.sh check without a binding exits 4" $?
scripts/discord.sh recover >/dev/null 2>&1
[ $? -eq 4 ]
check "scripts/discord.sh recover without a binding exits 4" $?
# --- the service unit: rendered from the template, never touching systemd here ---
UNITS="$SANDBOX/units"
scripts/discord-service.sh >/dev/null 2>&1
[ $? -eq 4 ]
check "scripts/discord-service.sh without a command exits 4" $?
REPO_DIR="$(pwd)"
scripts/discord-service.sh render >"$SANDBOX/unit.rendered" 2>/dev/null \
&& grep -qF "ExecStart=$REPO_DIR/scripts/discord.sh run %i --supervised" "$SANDBOX/unit.rendered" \
&& ! grep -q '^ExecStartPre=' "$SANDBOX/unit.rendered" \
&& grep -qx 'RestartPreventExitStatus=3' "$SANDBOX/unit.rendered" \
&& grep -qx 'Restart=on-failure' "$SANDBOX/unit.rendered" \
&& grep -qx 'KillSignal=SIGTERM' "$SANDBOX/unit.rendered" \
&& ! grep -q '@REPO@\|@PATH@' "$SANDBOX/unit.rendered"
check "service unit renders with the repository path, a supervised run as the main process, and exit 3 never retried" $?
scripts/discord-service.sh install --dir "$UNITS" --no-reload >"$SANDBOX/install.1" 2>&1 \
&& [ -f "$UNITS/[email protected]" ] \
&& grep -q '^written:' "$SANDBOX/install.1" \
&& cmp -s "$UNITS/[email protected]" "$SANDBOX/unit.rendered" \
&& [ "$(stat -c %a "$UNITS/[email protected]")" = "644" ] \
&& [ -z "$(ls -A "$UNITS" | grep -v '^[email protected]$')" ]
check "service install writes the rendered unit (0644) and leaves no temp file" $?
scripts/discord-service.sh install --dir "$UNITS" --no-reload >"$SANDBOX/install.2" 2>&1 && grep -q '^unchanged:' "$SANDBOX/install.2"
check "service install a second time reports unchanged" $?
if command -v systemd-analyze >/dev/null 2>&1; then
cp "$UNITS/[email protected]" "$UNITS/[email protected]"
systemd-analyze --user verify "$UNITS/[email protected]" >"$SANDBOX/verify.log" 2>&1 && ! grep -qi 'warning\|error\|fail' "$SANDBOX/verify.log"
check "systemd-analyze verify accepts the rendered unit" $?
rm -f "$UNITS/[email protected]"
fi
scripts/discord-service.sh uninstall --dir "$UNITS" --no-reload >/dev/null 2>&1 && [ ! -e "$UNITS/[email protected]" ]
check "service uninstall removes the unit file" $?
scripts/discord-service.sh install --dir "$UNITS" --no-reload --bogus >/dev/null 2>&1
[ $? -eq 4 ]
check "service install with an unknown flag exits 4" $?
echo
echo "discord suite: $PASS passed, $FAIL failed"