← back to Homesonspec
prune: fail-open per-builder (|| true vs pipefail abort) + SNAP_DIR anchor guard + 30d manifest retention (verifier findings) — TK-10236
53ff55422c2e78e19b9f955509a503295670d47e · 2026-08-05 08:15:43 -0700 · Steve Abrams
Files touched
M ops/prune-snapshot-cache.sh
Diff
commit 53ff55422c2e78e19b9f955509a503295670d47e
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed Aug 5 08:15:43 2026 -0700
prune: fail-open per-builder (|| true vs pipefail abort) + SNAP_DIR anchor guard + 30d manifest retention (verifier findings) — TK-10236
---
ops/prune-snapshot-cache.sh | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/ops/prune-snapshot-cache.sh b/ops/prune-snapshot-cache.sh
index f05a8cf9..e932e1d8 100755
--- a/ops/prune-snapshot-cache.sh
+++ b/ops/prune-snapshot-cache.sh
@@ -24,6 +24,12 @@ RETAIN_MIN=$((RETAIN_DAYS*1440))
gb(){ awk -v b="${1:-0}" 'BEGIN{printf "%.2f", b/1073741824}'; }
[ -d "$SNAP" ] || { echo "ERROR: snapshot dir not found: $SNAP"; exit 1; }
+# Destructive-script anchor: refuse to run outside the expected snapshots tree so a mis-set
+# SNAP_DIR (e.g. "/") can never turn the glob + find-delete loose on the wider filesystem.
+case "$SNAP" in
+ */homesonspec/var/snapshots|*/homesonspec/var/snapshots/) : ;;
+ *) echo "ERROR: SNAP_DIR '$SNAP' is outside the homesonspec snapshots tree — refusing to run"; exit 1 ;;
+esac
MANIFEST="$SNAP/../prune-manifest-$(date +%Y%m%d-%H%M%S).log"
now_mode=$([ $APPLY -eq 1 ] && echo PRUNE || echo DRY-RUN)
echo "== homesonspec snapshot-cache retention ($now_mode) =="
@@ -45,11 +51,16 @@ for d in "$SNAP"/*/; do
total_files=$((total_files+cnt)); total_bytes=$((total_bytes+bytes))
if [ $APPLY -eq 1 ]; then
find "$d" -type f -mmin +"$RETAIN_MIN" -printf '%p\n' 2>/dev/null >> "$MANIFEST"
- find "$d" -type f -mmin +"$RETAIN_MIN" -delete 2>/dev/null
+ # || true: a live crawler deleting/replacing a file between enumerate and delete makes
+ # find exit 1; under `set -uo pipefail` that would silently abort the loop, leaving the
+ # remaining builders unpruned while cron reports success. Fail-open per builder instead.
+ find "$d" -type f -mmin +"$RETAIN_MIN" -delete 2>/dev/null || true
fi
done
echo ""
printf "%s TOTAL: %d files, %sG\n" "$now_mode" "$total_files" "$(gb "$total_bytes")"
[ -n "$skipped" ] && echo "skipped (active crawl, <${LIVE_MIN}m writes):$skipped"
[ $APPLY -eq 1 ] && echo "deleted-path manifest: $MANIFEST"
+# retain manifests 30 days so /var doesn't accumulate them (apply-mode only; dry-run writes nothing)
+[ $APPLY -eq 1 ] && find "$SNAP/.." -maxdepth 1 -name 'prune-manifest-*.log' -mtime +30 -delete 2>/dev/null || true
[ $APPLY -eq 0 ] && echo "(dry-run — nothing deleted. Re-run with --apply to prune.)"
← 5c1b5c47 ops: minute-precision retention (find -mtime +N truncates to
·
back to Homesonspec
·
workers: exp_backoff_restart_delay to cap PG-outage restart 033d4dbb →