From 06a5777609c4b057cb59b22002177a51ee75581e Mon Sep 17 00:00:00 2001 From: alexbelgium Date: Tue, 13 Oct 2026 22:11:16 +0200 Subject: [PATCH] fix(templates): forward the container stop to services supervised by ha_entrypoint When ha_entrypoint.sh is PID 1 (init: false add-ons on images without s6-overlay: comicarr, komga, degoog, ...), terminate() signals only its direct children. Those are the per-service restart-loop subshells, which died on SIGTERM without passing it on; PID 1 then exited and the kernel SIGKILLed every service. No service ever got a chance to shut down cleanly. Each loop now runs its service (and the restart delay) in the background, traps TERM/INT, forwards SIGTERM to that process, waits for it to exit, and leaves the loop instead of restarting it. The "Termination signal received" line the postgres add-ons sed into is unchanged. Implementation drafted by Codex (gpt-5.6-sol), reviewed and tested here. Co-Authored-By: Claude Opus 5.5 --- .templates/ha_entrypoint.sh | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/.templates/ha_entrypoint.sh b/.templates/ha_entrypoint.sh index 0f02dd1ade..96737d07c5 100755 --- a/.templates/ha_entrypoint.sh +++ b/.templates/ha_entrypoint.sh @@ -437,9 +437,31 @@ if $PID1; then ( restart_count=0 max_restarts=5 + # terminate() signals only PID 1's direct children, which are these loop subshells. + # Run each service in the background and forward the stop to it, so it shuts down + # cleanly instead of being SIGKILLed when PID 1 exits, and is not restarted after. + stopping=false + service_pid= + trap 'stopping=true; [ -z "$service_pid" ] || kill -TERM "$service_pid" 2>/dev/null || true' TERM INT + wait_for_service() { + local pid="$service_pid" + if $stopping; then + kill -TERM "$pid" 2>/dev/null || true + fi + _svc_rc=0 + wait "$pid" || _svc_rc=$? + if $stopping; then + wait "$pid" 2>/dev/null || true + service_pid= + return 1 + fi + service_pid= + } while true; do _svc_rc=0 - "$runfile" || _svc_rc=$? + "$runfile" & + service_pid=$! + wait_for_service || break if [ "$_svc_rc" -eq 126 ] && [ -n "${BASHIO_LIB:-}" ]; then echo "Direct exec of $runfile failed (rc=126, likely E2BIG), retrying via source..." _svc_rc=0 @@ -448,7 +470,9 @@ if $PID1; then . "$BASHIO_LIB" 2>/dev/null || true # shellcheck disable=SC1090 . "$runfile" - ) || _svc_rc=$? + ) & + service_pid=$! + wait_for_service || break fi rc=$_svc_rc if [ "$rc" -eq 0 ]; then @@ -461,7 +485,9 @@ if $PID1; then break fi echo -e "\e[38;5;214m$(date) WARNING: $runfile exited (code $rc), restarting (#${restart_count}/${max_restarts}) in 5s...\e[0m" - sleep 5 + sleep 5 & + service_pid=$! + wait_for_service || break done ) & done