Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HxLA1mZurFq9kt8hneFeCs
4.6 KiB
REPORT — agent v0.51.0: local vzdump retention default (--prune-backups keep-last=3)
Date: 2026-06-30
Task: TASK.md — local vzdump retention default. The preventive counterpart to the hub's host_disk
(v0.23.0) + storage_fill (v0.25.0) detectors — completing the disk-pressure arc.
Baseline
| value | |
|---|---|
| felhom-agent | v0.50.0 → v0.51.0 |
| Commits | 06e0bc9 (agent) · felhom.eu fdcbc04 (host-install seed) |
| Deployed | felhom-agent 0.51.0 on felhom-pve (prior binary backed up .bak-0.50.0); clean restart 46/46 caps |
| VzdumpOptions prune passthrough | added — VzdumpOptions.PruneBackups → PVE --prune-backups on the vzdump POST |
What changed
The agent's periodic local whole-guest vzdump now prunes its own old archives, so a box can't refill its own root via its own backups (the felhom-pve incident's root cause — that vzdump carried no retention).
internal/proxmox/mutate.go:VzdumpOptions.PruneBackups→--prune-backups(vmid+storage scoped, so PVE prunes only THIS guest's archives on THIS storage).internal/backup/runner.go:NewBackupRunnergainsretention;localPruneSpecapplies it ONLY when the target is a non-PBS storage (resolved viaListStorage). Fail-safe: an unconfirmable target type (lookup error / not found) SKIPS pruning rather than risk pruning PBS. Only the periodic local-API runner sets retention; restore-test/selftest runners pass "".internal/config/config.go:backup.local_backup_retentionwithKeepLast()clamped ≥1 (0/unset/negative → default 3) +PruneBackupsSpec()→keep-last=N. Wired into the local-API runner.- Seeding:
felhom.eu scripts/felhom-host-install.shseedslocal_backup_retention: 3; the code default also protects any box where it's unset (KeepLast → 3) from day 0. - F2-b stale-vzdump-lock recovery untouched.
Tests — go build ./... && go vet ./... && go test ./... GREEN (Linux build server)
- flag-present — a local-target backup carries
--prune-backups keep-last=3; companion: a no-retention runner emits NO prune option (dumps would accumulate). - PBS never pruned (scope) — a PBS target gets no prune; companion: the same retention on a local target IS applied (the gate keys on storage type, not luck). Plus fail-safe-on-unknown-target.
- clamp —
LocalBackupRetention0/negative/unset →KeepLast()≥1 (default 3); a no-clamp impl emittingkeep-last=0would prune the fresh backup → FAILS the ≥1 assertion.
Live validation (felhom-pve, real backups — demo dumps expendable)
Triggered the agent's local whole-guest backup of guest 9201 via the local-API POST /backup (the exact
path the controller's periodic backup uses; the retention-enabled runner). Pre-state: local held 2 archives
for 9201 (the host_disk task had already pruned the original ~13 to 2), PBS held 8 snapshots, root 24% used.
- Backup #1 → local count 2 → 3 (no deletion yet; 3 ≤ keep-last=3 — the prune flag is exercised but retains all 3).
- Each subsequent backup → prune fired, local count held at 3 while the retention window slid
(the oldest rotates out as a new one lands):
- after #1:
…10_07_19,…11_22_20,…19_45_54 - after #2:
…11_22_20,…19_45_54,…19_51_07(…10_07_19pruned) - after a further:
…19_45_54,…19_51_07,…19_57_03(…11_22_20pruned) Count never exceeded 3 despite repeated backups (the old no-retention behaviour grew to ~13/18).
- after #1:
- The real PVE command carried the flag (from the vzdump task log):
vzdump 9201 --mode snapshot --storage local --compress zstd --prune-backups 'keep-last=3' --notes-template 'felhom local-api' - PBS untouched: felhom-pbs still 8 snapshots for 9201 (the per-run flag never touched the offsite repo). Root stayed bounded (24% → 31%, not growing unbounded).
This demonstrates the retention working on real data: repeated local backups stay bounded at keep-last=3 (oldest rotates out) instead of accumulating, and PBS is never pruned.
Observations
- The disk-pressure arc is now complete: detectors (hub host_disk v0.23.0 + storage_fill v0.25.0) + preventive (this agent-side local-vzdump retention). A box can no longer silently refill its own root via its own backups, and if any storage still fills, the operator is paged.
- Remaining disk follow-ons (not blockers): thin-pool metadata exhaustion alerting and per-storage-type thresholds (both noted in the storage_fill report).
No secrets. Demo backup archives are expendable; PBS offsite retention is a separate lifecycle (untouched).