v0.39.0 — DR-recipe completion: live PBS coord + drop role/restic_repo_coord from v1 drive shape

Live PBS coord: new internal/pbs/live_reporter.go (LiveSnapshotReporter implements
hub.PBSReporter via the cheap Client.Snapshots() list with last-known-good fallback,
bounded by an 8s timeout, list-only — never triggers a verify). Closes the gap where
the recipe's pbs block was omitted whenever the verify-loop SnapshotStore was empty
(one-shot collect + the first ~6h after a daemon restart). SnapshotStore.Get added
(per-datastore LKG). Wired into the collector in both runDaemon and runSelftestHub;
the verify loop keeps Recording into the SAME shared store via one hoisted pbsTargets.

v1 host-half drive shape: dropped drives[].role (hub/operator-owned manifest concept,
not host-derivable) and drives[].restic_repo_coord (named a backup tier that doesn't
exist). Drive shape is now {durable_id, mount_path, intent, fs_type?, total_bytes}.
Hub reads drives as json.RawMessage → no hub struct change; goldens re-pinned
byte-identical (agent + hub copies).

Tests: live_reporter_test.go (T1 load-bearing coord-without-verify + T2..T6),
TestDRRecipeHostHalf_V1DriveShape; each companion demonstrated to fail pre-fix then
reverted. go build/vet/test green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-16 20:25:09 +02:00
parent 8abc1b8852
commit fbe113011d
8 changed files with 414 additions and 23 deletions
+15
View File
@@ -72,6 +72,21 @@ func (s *SnapshotStore) Record(datastore string, snaps []hub.PBSSnapshot) {
s.byDatastore[datastore] = snaps
}
// Get returns a copy of the last-known-good snapshot set for ONE datastore (nil when absent or
// empty). It is the per-datastore fallback the live reporter reaches for when a live list fails —
// distinct from PBSSnapshots, which aggregates every datastore.
func (s *SnapshotStore) Get(datastore string) []hub.PBSSnapshot {
s.mu.Lock()
defer s.mu.Unlock()
src := s.byDatastore[datastore]
if len(src) == 0 {
return nil
}
out := make([]hub.PBSSnapshot, len(src))
copy(out, src)
return out
}
// PBSSnapshots implements hub.PBSReporter — all known snapshots across datastores.
func (s *SnapshotStore) PBSSnapshots(context.Context) []hub.PBSSnapshot {
s.mu.Lock()