hub v0.7.4: ingest agent pbs_snapshots (slice 6 Phase B)

Accept + persist the now-populated host-report pbs_snapshots. hostPBSSnapshot mirror in
hostReportPayload (persisted via report_json, no schema change); a FAILED PBS verify is
logged prominently (loudest offsite-DR signal). Shared golden updated byte-identical with
felhom-agent; TestHostPBSSnapshot_GoldenContract added. Build/deploy deferred (backward-compatible).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-09 17:15:58 +02:00
parent 8db15bac16
commit 5bc4c3d967
5 changed files with 104 additions and 23 deletions
+28 -4
View File
@@ -258,13 +258,30 @@ type hostReportPayload struct {
ControllerVersion string `json:"controller_version"`
} `json:"guests"`
StorageTargets []hostStorageTarget `json:"storage_targets"`
Backups []hostBackup `json:"backups"` // slice 6
RestoreTests []hostRestoreTest `json:"restore_tests"` // slice 6
Backups []hostBackup `json:"backups"` // slice 6
RestoreTests []hostRestoreTest `json:"restore_tests"` // slice 6
PBSSnapshots []hostPBSSnapshot `json:"pbs_snapshots"` // slice 6 Phase B
Cloudflared struct {
Status string `json:"status"`
} `json:"cloudflared"`
}
// hostPBSSnapshot mirrors the agent's hub.PBSSnapshot wire contract (slice 6 Phase B). The
// hub persists it via report_json and surfaces a FAILED verify prominently (the loudest
// offsite-DR signal — same treatment as a failed restore-test).
type hostPBSSnapshot struct {
Namespace string `json:"namespace"`
BackupType string `json:"backup_type"`
BackupID string `json:"backup_id"`
BackupTime string `json:"backup_time"`
SizeBytes int64 `json:"size_bytes"`
Owner string `json:"owner"`
Protected bool `json:"protected"`
Encrypted bool `json:"encrypted"`
VerifyState string `json:"verify_state"`
VerifyUPID string `json:"verify_upid,omitempty"`
}
// hostBackup / hostRestoreTest mirror the agent's hub.Backup / hub.RestoreTest wire
// contract field-for-field (slice 6, doc 03 §8). DUPLICATED contract — the golden stays
// byte-identical with felhom-agent's copy and the key-set tests guard drift. The hub
@@ -444,9 +461,16 @@ func (h *Handler) handleHostReport(w http.ResponseWriter, r *http.Request) {
hostID, bk.TargetID, bk.VMID, bk.Error)
}
}
// pbs_snapshots (slice 6 Phase B): a FAILED PBS verify is the loudest offsite-DR signal.
for _, ps := range rep.PBSSnapshots {
if ps.VerifyState == "failed" {
h.logger.Printf("[WARN] host %s PBS verify FAILED: %s/%s ns=%s owner=%s",
hostID, ps.BackupType, ps.BackupID, ps.Namespace, ps.Owner)
}
}
h.logger.Printf("[INFO] host-report from %s (%d guests, %d storage targets, %d backups, %d restore-tests, %d bytes)",
hostID, len(rep.Guests), len(rep.StorageTargets), len(rep.Backups), len(rep.RestoreTests), len(body))
h.logger.Printf("[INFO] host-report from %s (%d guests, %d storage targets, %d backups, %d restore-tests, %d pbs-snapshots, %d bytes)",
hostID, len(rep.Guests), len(rep.StorageTargets), len(rep.Backups), len(rep.RestoreTests), len(rep.PBSSnapshots), len(body))
blocked := false
if cc, err := h.store.GetCustomerConfig(custID); err == nil && cc != nil && cc.Status == "blocked" {