agent v0.51.0: local vzdump retention default (--prune-backups keep-last=3)

The preventive counterpart to host_disk + storage_fill detectors: the periodic local
whole-guest vzdump now prunes its own old archives (keep-last=3, clamped >=1) so a box
can't refill its own root via its own backups. Local target only — PBS never pruned
(resolved via ListStorage; fail-safe skip on unknown). Seeded in host-install.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HxLA1mZurFq9kt8hneFeCs
This commit is contained in:
2026-06-30 19:44:07 +02:00
parent 79eb0a8486
commit 06e0bc9c25
8 changed files with 212 additions and 16 deletions
+25
View File
@@ -181,6 +181,31 @@ type BackupConfig struct {
// its newest successful backup is older than this (or none exists). 0 → default (24h). The
// hub-served per-guest policy is slice 10; this is the agent-local cadence.
BackupCadenceSeconds int `json:"backup_cadence_seconds"`
// LocalBackupRetention is keep-last=N for the per-run `--prune-backups` on a LOCAL vzdump target —
// so the agent's own local whole-guest backups can't pile up and refill root (the felhom-pve incident;
// the host_disk + storage_fill checkers are the detectors, this is the preventive default). 0/unset →
// default 3; ALWAYS clamped to ≥1 by KeepLast() so a mis-config can never prune the fresh backup.
// NEVER applied to a PBS target (offsite retention is a separate lifecycle).
LocalBackupRetention int `json:"local_backup_retention"`
}
// defaultLocalBackupKeepLast is the local vzdump retention default (newest N restore points kept).
const defaultLocalBackupKeepLast = 3
// KeepLast returns the effective local-backup keep-last, clamped to ≥1 (0/unset → default 3, negative →
// default). The clamp is load-bearing: keep-last=0 would tell PVE to prune EVERY archive, including the
// one just made — a mis-config must never self-destruct the fresh backup.
func (b BackupConfig) KeepLast() int {
if b.LocalBackupRetention < 1 {
return defaultLocalBackupKeepLast
}
return b.LocalBackupRetention
}
// PruneBackupsSpec returns the PVE `--prune-backups` value for the local vzdump (e.g. "keep-last=3").
func (b BackupConfig) PruneBackupsSpec() string {
return fmt.Sprintf("keep-last=%d", b.KeepLast())
}
// BackupCadence returns the per-guest /backup/due window: positive as-is, else 24h default.