c9d5ed575c
Protected whatever --keep says: the controller floor, the vouched golden, the vouched agent and min_agent (the hub's Configuration page), every image of ours the vouched golden baked (its bake.log), the hub manifest's image. The dry-run prints each kept version and why. tests/test-prune-plan.sh pins it without network (red-proofed). No --apply was run. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
43 lines
3.1 KiB
Bash
Executable File
43 lines
3.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Decision 62 (Felhom R-750): a version IN USE is never in the delete plan, whatever --keep says; --keep defaults to
|
|
# 20; an unreadable in-use list refuses the prune. No network, no token: the script's test seams
|
|
# (PRUNE_TEST_VERSIONS, PRUNE_TEST_PROTECT) replace the registry API and the hub. Never passes --apply.
|
|
# COMPANION RED-PROOF: case 2 runs the same plan with an EMPTY in-use list and must see 0.262.0 in the delete plan —
|
|
# proof that case 1's pass comes from the protection and not from the fixture.
|
|
set -uo pipefail
|
|
HERE="$(cd "$(dirname "$0")" && pwd)"; S="$HERE/../gitea-image-prune.sh"
|
|
T="$(mktemp -d)"; trap 'rm -rf "$T"' EXIT
|
|
fail=0; ok() { echo "PASS $*"; }; bad() { echo "FAIL $*"; fail=1; }
|
|
|
|
# 25 controller releases 0.261.0 .. 0.285.0 (oldest first), plus :latest and two digest manifests
|
|
python3 - "$T/versions.json" <<'PY'
|
|
import json, sys
|
|
v = [{"name": "felhom-controller", "version": "0.%d.0" % n, "created_at": "2026-09-%02dT10:00:00Z" % (n - 260)} for n in range(261, 286)]
|
|
v += [{"name": "felhom-controller", "version": "latest", "created_at": "2026-09-30T12:00:00Z"},
|
|
{"name": "felhom-controller", "version": "sha256:" + "a" * 64, "created_at": "2026-09-30T12:00:00Z"}]
|
|
json.dump(v, open(sys.argv[1], "w"))
|
|
PY
|
|
printf 'felhom-controller 0.262.0 the controller floor (fixture)\n' > "$T/protect"
|
|
: > "$T/empty"
|
|
run() { PRUNE_TEST_VERSIONS="$T/versions.json" PRUNE_TEST_PROTECT="$1" bash "$S" --repo felhom-controller prune --no-sizes --log "$T/log" 2>&1; }
|
|
|
|
# 1. default keep 20 + an OLD in-use version kept
|
|
out="$(run "$T/protect")"; rc=$?
|
|
plan="$(printf '%s\n' "$out" | sed -n '/Would delete/,/DRY-RUN/p')"
|
|
[[ $rc -eq 0 ]] || bad "case 1 rc=$rc"
|
|
printf '%s\n' "$out" | grep -q 'keep-last 20' && ok "--keep defaults to 20" || bad "--keep did not default to 20"
|
|
printf '%s\n' "$out" | grep -q 'Would delete 4 tag(s); keep 20; protect 2' && ok "plan: delete 4, keep 20, protect 2 (latest + the floor)" || bad "plan counts: $(printf '%s\n' "$out" | grep 'Would delete')"
|
|
printf '%s\n' "$plan" | grep -qE '^ +0\.262\.0' && bad "the in-use 0.262.0 is in the delete plan" || ok "the in-use 0.262.0 is not in the delete plan"
|
|
printf '%s\n' "$out" | grep -q 'PROTECTED 0.262.0 — the controller floor (fixture)' && ok "the plan says why 0.262.0 is kept" || bad "no reason printed for 0.262.0"
|
|
printf '%s\n' "$out" | grep -q 'DRY-RUN — nothing deleted' && ok "dry-run" || bad "not a dry-run"
|
|
|
|
# 2. RED-PROOF: the same plan with nothing in use deletes 0.262.0
|
|
out="$(run "$T/empty")"
|
|
printf '%s\n' "$out" | sed -n '/Would delete/,/DRY-RUN/p' | grep -qE '^ +0\.262\.0' && ok "red: without the in-use list 0.262.0 WOULD be deleted" || bad "red-proof: 0.262.0 not deleted even without protection — the test proves nothing"
|
|
|
|
# 3. an unreadable in-use list refuses (never 'protect nothing')
|
|
out="$(PRUNE_TEST_VERSIONS="$T/versions.json" HUB_PW= HUB_URL=http://127.0.0.1:9 FELHOM_EU=/nonexistent bash "$S" --repo felhom-controller prune --no-sizes --log "$T/log" 2>&1)"; rc=$?
|
|
[[ $rc -eq 3 ]] && printf '%s\n' "$out" | grep -q 'REFUSING to prune' && ok "unreadable in-use list -> refused (exit 3)" || bad "case 3 rc=$rc: $(printf '%s\n' "$out" | tail -2)"
|
|
|
|
exit $fail
|