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:
@@ -24,6 +24,8 @@ type fakeBackupAPI struct {
|
||||
cfgErr error
|
||||
content []proxmox.StorageContent
|
||||
contentErr error
|
||||
storages []proxmox.Storage // returned by ListStorage (the local-prune scope gate)
|
||||
storageErr error
|
||||
vzdumps []proxmox.VzdumpOptions
|
||||
logLines []string // returned by TaskLogTail (e.g. "INFO: backup mode: stop")
|
||||
waitGate chan struct{} // if non-nil, WaitTask blocks until closed (8B.2 watcher timing)
|
||||
@@ -45,6 +47,9 @@ func (f *fakeBackupAPI) GuestConfig(_ context.Context, _ int) (proxmox.GuestConf
|
||||
func (f *fakeBackupAPI) StorageContent(_ context.Context, _ string) ([]proxmox.StorageContent, error) {
|
||||
return f.content, f.contentErr
|
||||
}
|
||||
func (f *fakeBackupAPI) ListStorage(_ context.Context) ([]proxmox.Storage, error) {
|
||||
return f.storages, f.storageErr
|
||||
}
|
||||
func (f *fakeBackupAPI) TaskLogTail(_ context.Context, _ string, _ int) ([]string, error) {
|
||||
return f.logLines, nil
|
||||
}
|
||||
@@ -73,7 +78,7 @@ func TestBackup_SuccessResolvesArchiveAndBulkGap(t *testing.T) {
|
||||
{VolID: "local:backup/other-9002.tar.zst", Content: "backup", VMID: 9002, Size: 7, CTime: 999},
|
||||
},
|
||||
}
|
||||
r := NewBackupRunner(api, "local", "", "felhom test", quiet())
|
||||
r := NewBackupRunner(api, "local", "", "felhom test", "", quiet())
|
||||
rec, err := r.Backup(context.Background(), 9001)
|
||||
if err != nil {
|
||||
t.Fatalf("Backup: %v", err)
|
||||
@@ -107,7 +112,7 @@ func TestBackup_ReportsActualModeFromTaskLog(t *testing.T) {
|
||||
content: []proxmox.StorageContent{{VolID: "v", Content: "backup", VMID: 9001, Size: 10, CTime: 1}},
|
||||
logLines: []string{"INFO: CT Name: spike", "INFO: backup mode: stop", "INFO: Finished"},
|
||||
}
|
||||
r := NewBackupRunner(api, "local", proxmox.ModeSnapshot, "", quiet())
|
||||
r := NewBackupRunner(api, "local", proxmox.ModeSnapshot, "", "", quiet())
|
||||
rec, err := r.Backup(context.Background(), 9001)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -119,7 +124,7 @@ func TestBackup_ReportsActualModeFromTaskLog(t *testing.T) {
|
||||
|
||||
func TestBackup_VzdumpFailureReturnsFailedRecord(t *testing.T) {
|
||||
api := &fakeBackupAPI{vzdumpErr: errors.New("vzdump boom")}
|
||||
r := NewBackupRunner(api, "local", "", "", quiet())
|
||||
r := NewBackupRunner(api, "local", "", "", "", quiet())
|
||||
rec, err := r.Backup(context.Background(), 9001)
|
||||
if err == nil {
|
||||
t.Fatal("expected error")
|
||||
@@ -135,7 +140,7 @@ func TestPickRestoreCandidate_NewestOrEmpty(t *testing.T) {
|
||||
{VolID: "b", Content: "backup", CTime: 99},
|
||||
{VolID: "iso", Content: "iso", CTime: 999}, // not a backup → ignored
|
||||
}}
|
||||
r := NewBackupRunner(api, "local", "", "", quiet())
|
||||
r := NewBackupRunner(api, "local", "", "", "", quiet())
|
||||
vol, err := r.PickRestoreCandidate(context.Background())
|
||||
if err != nil || vol != "b" {
|
||||
t.Fatalf("pick = %q,%v want newest 'b'", vol, err)
|
||||
|
||||
Reference in New Issue
Block a user