#!/usr/bin/env bats # Seam: fleet-wide quadlet laws learned the hard way. # 1. Every registry image is digest-pinned. A rolling tag (":latest", # ":9-alpine", ":nightly") lets a rebuild move under a running # service at the next restart/reboot with nobody approving it, and it # makes a CVE audit ungradeable (you cannot score a tag). Locally # built images (localhost/*, franksdank/*) are exempt: their build # IS the pin, and they never pull. # 2. No unit carries a key the podman 5.7.0 quadlet generator rejects. # The generator aborts the WHOLE batch on an unsupported key, so one # bad file silently un-generates every other unit in that manager - # live 2026-10-21: HostAddr= in prometheus.container orphaned # prometheus.service while its container kept running, and the next # deploy died on "Unit prometheus.service not found". load helpers @test "every registry Image= is digest-pinned across all three hosts" { bad="" while IFS= read -r unit; do while IFS= read -r img; do case "$img" in localhost/*|franksdank/*) continue ;; esac case "$img" in *@sha256:*) ;; *) bad="$bad$unit: $img"$'\n' ;; esac done < <(sed -n 's/^Image=//p' "$unit") done < <(find "$REPO_ROOT"/dankserver "$REPO_ROOT"/dankclaw "$REPO_ROOT"/frankbook-pro \ -path '*/quadlet/*.container' -not -path '*.AGENTTRASH*') [ -z "$bad" ] || { printf 'unpinned images:\n%s' "$bad" >&2; return 1; } } @test "no unit uses a key the 5.7.0 quadlet generator rejects (batch killer)" { # HostAddr rejected by podman 5.7.0 (live 2026-10-21); Device= and # Command= are the older v1 findings, guarded host-locally too. # Keep this list current with every generator finding. bad="" while IFS= read -r unit; do for key in HostAddr Device Command; do grep -q "^${key}=" "$unit" && bad="$bad$unit: ${key}="$'\n' done done < <(find "$REPO_ROOT"/dankserver "$REPO_ROOT"/dankclaw "$REPO_ROOT"/frankbook-pro \ -path '*/quadlet/*.container' -not -path '*.AGENTTRASH*') [ -z "$bad" ] || { printf 'generator-rejected keys:\n%s' "$bad" >&2; return 1; } }