fix(check-backup-freshness): age PBS snapshots by their name, not the directory mtime
PBS rewrites index.json.blob inside a snapshot directory at every verify (the next 02:30, then every 30 days per verification.cfg outdated-after 30) and on notes/protect edits, which moves the directory mtime forward. Measured: ana-pve/vm/101's 2026-10-04T10:00:04Z snapshot read as 2026-10-06. A covered guest whose backups stopped would have alarmed up to a day late, then gone quiet for ~2 days after each monthly re-verify. The age now comes from the snapshot name (its backup start time). Verified: the default run exits 0 with 28 fresh PBS groups and vm/101 dated 2026-10-04. Positive control BACKUP_MAX_AGE_HOURS=5 flags 10 groups by name age, exit 1.
This commit is contained in:
@@ -232,10 +232,17 @@ for want in $EXPECTED_NH3; do
|
||||
done
|
||||
|
||||
# --- Layer: PBS VM images (newest per guest, all namespaces) ---
|
||||
# ⚠ The age comes from the snapshot's NAME (its backup time, e.g. 2026-10-04T10:00:04Z),
|
||||
# never from the directory's mtime (2026-10-06). PBS rewrites index.json.blob inside the
|
||||
# snapshot dir at every verify (first one at the next 02:30, then every 30 days, from
|
||||
# verification.cfg outdated-after 30) and on notes or protect edits, which moves the
|
||||
# dir mtime forward. Measured: ana-pve/vm/101's 10-04 snapshot read "2026-10-06" here.
|
||||
# A guest whose backups had stopped would alarm up to a day late, then go quiet again
|
||||
# for ~2 days after each monthly re-verify.
|
||||
pbs=$($SSH pbs-ana 'for ns in /mnt/pbs-datastore/ns/*/; do n=$(basename "$ns")
|
||||
for d in vm ct; do for g in "$ns$d"/*/; do [ -d "$g" ] || continue
|
||||
nb=$(ls -d "$g"20*T* 2>/dev/null | sort | tail -1)
|
||||
[ -n "$nb" ] && echo "$n/$d/$(basename "$g") $(stat -c %Y "$nb")"
|
||||
[ -n "$nb" ] && echo "$n/$d/$(basename "$g") $(date -d "$(basename "$nb")" +%s)"
|
||||
done; done; done' 2>/dev/null)
|
||||
if [ -z "$pbs" ]; then errors+=("PBS-ANA: unreachable or no snapshots"); else
|
||||
for ns in "${!NS_NODE[@]}"; do load_jobs "$ns" || errors+=("coverage for namespace '$ns' UNREADABLE — nothing in it will be suppressed"); done
|
||||
|
||||
Reference in New Issue
Block a user