post_check: run-to-completion units that exited 0 are ok, not warnings

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
This commit is contained in:
2026-09-23 17:26:33 -04:00
co-authored by Claude Sonnet 5
parent 6142935e29
commit c4d9def8e3
2 changed files with 37 additions and 3 deletions
+28 -3
View File
@@ -7,6 +7,7 @@
# ./deploy.sh --diff [conf] # what would change in /etc
# ./deploy.sh --post-check [conf] # read-only live checks (units, br0, LAN, NAT, dnsmasq, radios, uplink); exit 1 on any warning
# # POSTCHECK_WAIT=<s>: seconds retried probes may wait in total (default 15; 0 = single attempt)
# ./deploy.sh --classify-unit <ActiveState> <Result> <ExecMainStatus> # prints ok|finished|wait|warn (used by post_check; for tests)
# ./deploy.sh render <file> # preview a templated file on stdout
# ./deploy.sh --redact # filter stdin, masking secret values (used by --diff; for tests)
# Idempotent. Netplan (wlan0 + Starlink NIC = NM-managed WANs; eth0 is a LAN
@@ -131,6 +132,15 @@ if [ "$ENABLE_FRIGATE" = 1 ]; then
fi
}
classify_unit() { # classify_unit <ActiveState> <Result> <ExecMainStatus> -> ok | finished | wait | warn
case "$1" in
active) echo ok ;;
activating|reloading) echo wait ;;
inactive) if [ "${2:-}" = success ] && [ "${3:-}" = 0 ]; then echo finished; else echo warn; fi ;;
*) echo warn ;;
esac
}
post_check() { # read-only live checks; every probe is guarded, warns instead of aborting
set_units
echo "== post-deploy check =="
@@ -146,10 +156,19 @@ post_check() { # read-only live checks; every probe is guarded, warns instead o
pending+=("$u")
done
still=("${pending[@]}")
local -A verdict=() detail=()
local k v as res st ls
while :; do
local next=()
for u in "${still[@]}"; do
systemctl is-active --quiet "$u" 2>/dev/null || next+=("$u")
as= res= st= ls=
while IFS='=' read -r k v; do
case "$k" in LoadState) ls=$v ;; ActiveState) as=$v ;; Result) res=$v ;; ExecMainStatus) st=$v ;; esac
done < <(systemctl show -p LoadState,ActiveState,Result,ExecMainStatus "$u" 2>/dev/null || true)
verdict[$u]=$(classify_unit "$as" "$res" "$st")
[ "$ls" = loaded ] || { verdict[$u]=warn; as="${as:-?}(LoadState=${ls:-?})"; }
detail[$u]="ActiveState=${as:-?} Result=${res:-?}"
case "${verdict[$u]}" in ok|finished) ;; *) next+=("$u") ;; esac
done
still=("${next[@]}")
[ ${#still[@]} -eq 0 ] && break
@@ -157,8 +176,11 @@ post_check() { # read-only live checks; every probe is guarded, warns instead o
sleep 1
done
for u in "${pending[@]}"; do
if [[ " ${still[*]:-} " == *" $u "* ]]; then warn "post-deploy: unit $u is not active"
else echo " ok unit $u active"; fi
case "${verdict[$u]:-warn}" in
ok) echo " ok unit $u active" ;;
finished) echo " ok unit $u finished (exit 0)" ;;
*) warn "post-deploy: unit $u is not active (${detail[$u]:-state unknown})" ;;
esac
done
# b. bridge address
has_br0_addr() { local o; o=$(ip -4 -br addr show dev br0 2>/dev/null) || true; [[ $o == *"$GATEWAY_IP/$GATEWAY_PREFIX"* ]]; }
@@ -240,6 +262,9 @@ case "${1:-}" in
--redact) # ./deploy.sh --redact — stdin through redact_secrets (no config, no root)
redact_secrets
exit 0 ;;
--classify-unit) # ./deploy.sh --classify-unit <ActiveState> <Result> <ExecMainStatus>
classify_unit "${2:-}" "${3:-}" "${4:-}"
exit 0 ;;
--post-check) # ./deploy.sh --post-check [conf] — live checks, no root, no install; exit 1 on any warning
load_conf "${2:-$VANLINK_CONF}"
post_check
+9
View File
@@ -184,4 +184,13 @@ elif echo "$pc" | grep -q 'van-nvme-watch'; then bad "--post-check mentions van-
else ok "--post-check skips van-nvme-watch when ENABLE_NVME_WATCH=0"; fi
if grep -q 'USB hub' deploy.sh; then bad "stale 'USB hub' text remains in deploy.sh"; else ok "no stale 'USB hub' text in deploy.sh"; fi
# 12. unit-state classification used by post_check (run-to-completion units are not failures)
for row in "active success 0:ok" "inactive success 0:finished" "failed exit-code 1:warn" \
"activating success 0:wait" "inactive exit-code 1:warn" "inactive success 1:warn"; do
args=${row%%:*}; want=${row##*:}
# shellcheck disable=SC2086
got=$(./deploy.sh --classify-unit $args 2>&1) || true
if [ "$got" = "$want" ]; then ok "--classify-unit $args -> $want"; else bad "--classify-unit $args gave '$got', want '$want'"; fi
done
exit "$fail"