Host report keeps the last backup across a restart; Secure Boot meta-package leaves the Proxmox lane
gates / gates (push) Successful in 1m7s
gates / gates (push) Successful in 1m7s
Found in the 2026-10-09 kernel-night read-back: - demo-felhom: the kernel step restarted the host 4 minutes after the night backup; the in-memory backup list was empty after the restart, so the hub alarmed "host tier: newest backup is 48h old". The report now adds R-894's saved newest success per tier (one shared instance). - demo-hp: proxmox-secure-boot-support pulled shim-signed-common into the ring-0 Proxmox plan; the step was refused R6 and the kernel step skipped. It joins HOST_SLOW_RE with shim and GRUB. Red-proved: TestCollectBackups_SavedSuccessSurvivesARestart, TestR894_LastKnownBackupsIsWiredIntoTheDaemon, test_ring0_pending_pve_leaves_the_secure_boot_meta_out. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -103,6 +103,29 @@ func (s *BackupSuccessState) LastKnownSuccess(target string, vmid int) (time.Tim
|
||||
return e.at, ok
|
||||
}
|
||||
|
||||
// KnownBackupSuccesses returns every saved success as a host-report record (the collector's
|
||||
// KnownBackupReporter, so the hub keeps its evidence across a restart). Only the tier, guest and start
|
||||
// time are known; the archive name is not saved and stays empty. Sorted for a stable report.
|
||||
func (s *BackupSuccessState) KnownBackupSuccesses() []hub.Backup {
|
||||
if s == nil {
|
||||
return nil
|
||||
}
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
out := make([]hub.Backup, 0, len(s.last))
|
||||
for _, e := range s.last {
|
||||
out = append(out, hub.Backup{TargetID: e.target, VMID: e.vmid, Success: true, CrashConsistent: true,
|
||||
StartedAt: e.at.Format(time.RFC3339), UncoveredVolumes: []string{}})
|
||||
}
|
||||
sort.Slice(out, func(i, j int) bool {
|
||||
if out[i].TargetID != out[j].TargetID {
|
||||
return out[i].TargetID < out[j].TargetID
|
||||
}
|
||||
return out[i].VMID < out[j].VMID
|
||||
})
|
||||
return out
|
||||
}
|
||||
|
||||
func (s *BackupSuccessState) saveLocked() error {
|
||||
entries := make([]backupSuccessJSON, 0, len(s.last))
|
||||
for _, e := range s.last {
|
||||
|
||||
@@ -57,3 +57,20 @@ func TestBackupSuccessState_CorruptFileIsEmpty(t *testing.T) {
|
||||
t.Fatal("a corrupt file must read as nothing known")
|
||||
}
|
||||
}
|
||||
|
||||
// The saved successes come back as host-report records: success, tier, guest, start time (R-894 → the
|
||||
// host report, 2026-10-09). A new state read from the same file gives the same records (the restart case).
|
||||
func TestBackupSuccessState_KnownBackupSuccessesSurviveAReopen(t *testing.T) {
|
||||
path := filepath.Join(t.TempDir(), "backup-success-state.json")
|
||||
s := NewBackupSuccessState(path)
|
||||
if err := s.RecordBackupSuccess("felhom-backup", hub.Backup{VMID: 9201, Success: true, StartedAt: "2026-10-09T02:40:16Z"}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got := NewBackupSuccessState(path).KnownBackupSuccesses()
|
||||
if len(got) != 1 || !got[0].Success || got[0].TargetID != "felhom-backup" || got[0].VMID != 9201 || got[0].StartedAt != "2026-10-09T02:40:16Z" {
|
||||
t.Fatalf("got %+v", got)
|
||||
}
|
||||
if got[0].UncoveredVolumes == nil {
|
||||
t.Fatal("uncovered_volumes must marshal as [], not null")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user