add Phase 2A container and recovery readiness gates

This commit is contained in:
makearmy 2026-07-12 18:59:45 -04:00
parent da03be61a9
commit a9fec0d83d
15 changed files with 629 additions and 30 deletions

View file

@ -92,6 +92,40 @@ validate_health_url_file() {
return 0
}
capture_container_fingerprint() {
output=$1
: > "$output"
docker ps -aq | while IFS= read -r cid; do
[ -n "$cid" ] || continue
base=$(docker inspect --format \
'{{.Name}}|{{.Id}}|{{.Config.Image}}|{{.Image}}|{{.State.Status}}|{{if .State.Health}}{{.State.Health.Status}}{{else}}no-healthcheck{{end}}|{{.State.StartedAt}}|{{.HostConfig.NetworkMode}}|{{.HostConfig.RestartPolicy.Name}}|{{index .Config.Labels "com.docker.compose.project"}}' \
"$cid" 2>/dev/null)
inspect_rc=$?
health_hash=$(docker inspect --format '{{json .Config.Healthcheck}}' "$cid" 2>/dev/null | sha256sum | awk '{print $1}')
hash_rc=$?
if [ "$inspect_rc" -ne 0 ] || [ "$hash_rc" -ne 0 ] || [ -z "$base" ] || [ -z "$health_hash" ]; then return 1; fi
printf '%s|healthcheck_sha256=%s\n' "${base#/}" "$health_hash"
done | LC_ALL=C sort > "$output"
pipeline_status="${PIPESTATUS[*]}"
case "$pipeline_status" in '0 0 0') return 0 ;; *) return 1 ;; esac
}
verify_container_disposition() {
output=$1
(cd "$script_dir/container-disposition" && sha256sum -c SHA256SUMS) \
> "$record/container-disposition-checksum-latest.txt" 2>&1
rc=$?
[ "$rc" -eq 0 ] || { fail 'container disposition checksum failed' 43; return $?; }
capture_container_fingerprint "$output"
rc=$?
[ "$rc" -eq 0 ] || { fail 'cannot capture current container fingerprint' 43; return $?; }
diff -u "$validated_preflight/container-fingerprint.psv" "$output" \
> "$record/container-disposition-latest.diff" 2>&1
rc=$?
[ "$rc" -eq 0 ] || { fail 'container identity, state, health, startup, network, restart policy, or health-check identity changed' 43; return $?; }
return 0
}
capture_failed_unit_fingerprint() {
output=$1
: > "$output"
@ -222,17 +256,7 @@ rerun_volatile_checks() {
df -hT / /boot /var/cache/pacman/pkg /tmp > "$record/volatile-disk-space.txt" 2>&1
rc=$?
[ "$rc" -eq 0 ] || { fail 'cannot verify current disk space' "$rc"; return $?; }
while IFS= read -r container; do
[ -n "$container" ] || continue
running=$(docker inspect -f '{{.State.Running}}' "$container" 2>/dev/null)
health=$(docker inspect -f '{{if .State.Health}}{{.State.Health.Status}}{{else}}no-healthcheck{{end}}' "$container" 2>/dev/null)
printf '%s|running=%s|health=%s\n' "$container" "${running:-missing}" "${health:-unknown}" \
>> "$record/volatile-container-health.txt"
if [ "$running" != true ] || [ "$health" = unhealthy ]; then
fail "previously running container is unavailable: $container" 43
return $?
fi
done < "$validated_preflight/running-containers-before.txt"
verify_container_disposition "$record/volatile-container-fingerprint.psv" || return $?
: > "$record/volatile-public-health.txt"
while IFS= read -r url; do
metrics=$(curl --fail --silent --show-error --max-redirs 0 \
@ -319,6 +343,8 @@ main() {
rc=$?; [ "$rc" -eq 0 ] || { fail 'cannot capture installed package inventory' "$rc"; return $?; }
cp "$validated_preflight/bootloader-inventory.txt" "$validated_preflight/kernel-initramfs-before.txt" \
"$validated_preflight/running-containers-before.txt" "$validated_preflight/containers-all.psv" \
"$validated_preflight/container-fingerprint.psv" "$validated_preflight/sonarr-unhealthy.allowlist.psv" \
"$validated_preflight/directus-stopped.allowlist.psv" "$validated_preflight/restart-policy-no.psv" \
"$validated_preflight/critical-units-baseline.psv" "$validated_preflight/database-baseline.psv" "$record/"
rc=$?; [ "$rc" -eq 0 ] || { fail 'cannot copy essential rollback baseline evidence' "$rc"; return $?; }
verify_failed_unit_disposition "$record/failed-units-before-fingerprint.psv" || return $?