From bb9bca4d83f23decbb3b0d487bf194b8690cf896 Mon Sep 17 00:00:00 2001 From: Johnathan Corgan Date: Thu, 23 Jul 2026 19:50:07 +0000 Subject: [PATCH] Accept a degraded systemd as a booted one in the deb-install boot wait The boot check piped `systemctl is-system-running --wait` into `grep -qE 'running|degraded'`, but the script runs `set -o pipefail` and is-system-running exits non-zero for `degraded`. So the pipeline failed on a degraded system even though grep matched, and the wait looped to its timeout. The older distros reach `running` (exit 0) and passed; debian:trixie and ubuntu:26.04 reach `degraded` because a unit that cannot run in a container (systemd-modules-load) fails, so they timed out at every ceiling -- which is why the earlier timeout increase did nothing. Capture the state string and test it directly instead of trusting the pipeline exit, so a degraded-but-booted system is accepted as intended. Validated: all five distros pass, including the two that previously failed. --- testing/deb-install/test.sh | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/testing/deb-install/test.sh b/testing/deb-install/test.sh index daa7d96..432ef1c 100755 --- a/testing/deb-install/test.sh +++ b/testing/deb-install/test.sh @@ -32,7 +32,7 @@ REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" CACHE_DIR="$SCRIPT_DIR/.cache" DEB_CACHE_DIR="$CACHE_DIR/deb" -# Timeouts +# Timeouts. Each wait loop below exits as soon as its condition is met. BOOT_TIMEOUT=30 SERVICE_TIMEOUT=20 DAEMON_TIMEOUT=15 @@ -75,11 +75,19 @@ start_systemd_container_with_tun() { } wait_for_systemd() { - local name="$1" + local name="$1" state for _i in $(seq 1 "$BOOT_TIMEOUT"); do - if docker exec "$name" systemctl is-system-running --wait 2>/dev/null | grep -qE 'running|degraded'; then - return 0 - fi + # `is-system-running` exits non-zero for `degraded` (a unit failed to + # start -- e.g. systemd-modules-load, which cannot load kernel modules + # inside a container -- even though the system did finish booting). This + # script runs `set -o pipefail`, so a piped `grep` would inherit that + # non-zero exit and reject an acceptable state, which timed out the + # newest distros (they reach `degraded`, older ones reach `running`). + # Capture the state string and test it directly instead of the pipe. + state=$(docker exec "$name" systemctl is-system-running --wait 2>/dev/null || true) + case "$state" in + running | degraded) return 0 ;; + esac sleep 1 done # A boot that never reached `running` or `degraded` is not a warning: every