hub v0.131.0: the tunnel status is true (R-841: three states, tunnel_down after two not_running reports, unknown never alarms); OS updates per layer (guest/host separate approved sets, host candidate leaves out kernel/boot/firmware, host_release in the box block), the fleet view and four hourly operator alarms (11 §8 steps 3+4); red-proofs in audits/os-host-lane-2026-10-04
gates / gates (push) Successful in 30s

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:
2026-10-04 13:05:00 +02:00
parent 0ed2e8de4c
commit 88b0a2e761
24 changed files with 1254 additions and 149 deletions
+9 -5
View File
@@ -21,7 +21,11 @@ func TestOSUpdate_DesiredBlockMatchesTheGolden(t *testing.T) {
svc := &osupdates.Service{Store: st, ApproveAfter: 0, NightsRequired: 0, Logger: log.New(os.Stderr, "", 0)}
h.SetOSUpdateService(svc)
rel := `[{"name":"libc6","version":"2.41-12+deb13u4","origin":"Debian"},{"name":"openssl","version":"3.5.7-1~deb13u3","origin":"Debian-Security"}]`
if err := st.SaveOSRelease(storeRelease("os-20261004-120000", rel)); err != nil {
if err := st.SaveOSRelease(storeRelease("os-guest-20261004-120000", "guest", rel)); err != nil {
t.Fatal(err)
}
hrel := `[{"name":"libssl3t64","version":"3.5.7-1~deb13u3","origin":"Debian-Security"}]`
if err := st.SaveOSRelease(storeRelease("os-host-20261004-120000", "host", hrel)); err != nil {
t.Fatal(err)
}
rr := do(h, http.MethodGet, "/hosts/h1/desired-state", "HKEY1", "")
@@ -66,18 +70,18 @@ func TestOSReport_SelfScoped(t *testing.T) {
if rr := do(h, http.MethodPost, "/hosts/h1/os-report", "HKEY2", body); rr.Code != http.StatusForbidden {
t.Fatalf("cross-host report → %d, want 403", rr.Code)
}
if r, _ := st.LatestOSReport("h1"); r != nil {
if r, _ := st.LatestOSReport("h1", "guest"); r != nil {
t.Fatal("a refused report was stored")
}
if rr := do(h, http.MethodPost, "/hosts/h1/os-report", "HKEY1", body); rr.Code != http.StatusOK {
t.Fatalf("own report → %d %s", rr.Code, rr.Body.String())
}
if r, _ := st.LatestOSReport("h1"); r == nil || r.Outcome != "applied" {
if r, _ := st.LatestOSReport("h1", "guest"); r == nil || r.Outcome != "applied" {
t.Fatalf("report not stored: %+v", r)
}
}
func storeRelease(id, pkgs string) store.OSRelease {
func storeRelease(id, layer, pkgs string) store.OSRelease {
at, _ := time.Parse(time.RFC3339, "2026-10-04T12:00:00Z")
return store.OSRelease{ID: id, Fingerprint: "fp", ApprovedAt: at, ApprovedBy: "auto", PackagesJSON: pkgs}
return store.OSRelease{ID: id, Layer: layer, Fingerprint: "fp-" + layer, ApprovedAt: at, ApprovedBy: "auto", PackagesJSON: pkgs}
}