Old kernels removed by the box (R-1368, wrapper mode kernel-cleanup); security profiles refreshed after a kernel change (R-1388, mode profile-refresh); Go 1.27.4 (R-1391)
gates / gates (push) Successful in 40s

This commit is contained in:
admin committed 2026-11-14 12:11:06 +01:00
1 parent 91a2924ad0
commit cc63dd5204
11 files changed
+1542 -10

No files matched your search

+31 -1
View File
@@ -251,6 +251,8 @@ func main() {
os.Exit(runSelftestOSUpdate(context.Background(), cfg, logger, vmid))
case "os-facts":
os.Exit(runSelftestFacts(context.Background(), cfg, logger, vmid))
case "kernel-cleanup-dry-run":
os.Exit(runSelftestKernelCleanupDryRun(context.Background(), cfg, logger, vmid))
case "live-restore":
os.Exit(runSelftestLiveRestore(context.Background(), cfg, logger, vmid))
case "pbs-verify":
@@ -1284,6 +1286,8 @@ func runDaemon(cfg config.Config, logger *slog.Logger, logRing *applog.Ring) int
}
return release, nil
}}
daemonCtx := ctx
profileGate := func() (func(), string, bool) { return heavyOps.TryAcquire("os-profile-refresh") }
// Agent v0.143.0 (R-840): the config bundle — the box's root-owned files by a signed job; the wrapper verifies it.
bundleExec := osupdate.ConfigUpdateExecutor{Leg: osLeg, URLTemplate: suCfg.URLTemplate, Username: suCfg.Username, Token: suCfg.Token,
// The capability probe confirms from the agent's side: `sudo -l` lists every command the new sudoers grants.
@@ -1294,7 +1298,13 @@ func runDaemon(cfg config.Config, logger *slog.Logger, logRing *applog.Ring) int
names = append(names, d.Name)
}
logger.Warn("osupdate: capability probe after the config bundle", "ok", ok, "total", total, "degraded", strings.Join(names, ","))
// R-1388: a new wrapper may know the profile refresh the old one refused — ask again (its own goroutine:
// it may wait for the heavy-op gate, and the signed job must not wait with it).
go osLeg.ProfileRefresh(daemonCtx, "config bundle installed", profileGate, 12, 5*time.Minute)
}}
// R-1388 / R-1301 (`11` §5.12): after a start, load the security profiles from a fresh compile when the box runs
// another kernel than at the last refresh (the wrapper keeps that record and answers "not needed" otherwise).
go osLeg.ProfileRefresh(daemonCtx, "agent start", profileGate, 12, 5*time.Minute)
// R-1285: the NEW agent runs the bundle policy pass once after its self-update commits — in the normal two-job
// delivery the bundle was installed by the OLD process, which has no such pass (measured 2026-10-26).
wireBundlePolicyAfterCommit(selfUpdateMgr, bundleExec, logger, version)
@@ -3928,10 +3938,12 @@ func (f *selftestFlag) Set(v string) error {
f.mode = "os-update"
case "os-facts", "live-restore": // agent v0.142.0
f.mode = v
case "kernel-cleanup-dry-run": // R-1368: what the clean-up of old kernels WOULD do; changes nothing
f.mode = v
case "wgtunnel": // dispatched since S3 but refused here until 2026-10-04 (TestSelftestFlag_AcceptsEveryDispatchedMode)
f.mode = "wgtunnel"
default:
return fmt.Errorf("invalid --selftest value %q (want read|task|hub|storage|backup|restore-test|restore-test-due|pbs-verify|lanresolver|wgtunnel|bring-up|provision|escrow-create|escrow-consume|identity-consume|controller-swap|os-update|os-facts|live-restore)", v)
return fmt.Errorf("invalid --selftest value %q (want read|task|hub|storage|backup|restore-test|restore-test-due|pbs-verify|lanresolver|wgtunnel|kernel-cleanup-dry-run|bring-up|provision|escrow-create|escrow-consume|identity-consume|controller-swap|os-update|os-facts|live-restore)", v)
}
return nil
}
@@ -4052,6 +4064,24 @@ func runSelftestFacts(ctx context.Context, cfg config.Config, logger *slog.Logge
return 0
}
// runSelftestKernelCleanupDryRun asks the root wrapper what the clean-up of old kernels WOULD do on this box (R-1368,
// `11` §5.11.1): the keep set, the removal set, and the refusal or "not run" reason. It changes nothing.
//
// sudo -u felhom-agent felhom-agent --config … --selftest=kernel-cleanup-dry-run
func runSelftestKernelCleanupDryRun(ctx context.Context, cfg config.Config, logger *slog.Logger, vmid int) int {
px, _ := newProxmoxClient(cfg)
leg := newOSLeg(cfg, nil, px, logger)
raw, err := leg.KernelCleanupDryRun(ctx, vmid)
if err != nil {
fmt.Fprintln(os.Stderr, "selftest=kernel-cleanup-dry-run:", err)
return 1
}
var v any
_ = json.Unmarshal(raw, &v)
printJSON("kernel clean-up — DRY RUN (nothing was changed)", v)
return 0
}
// runSelftestLiveRestore is the ONE-TIME live-restore step (`09` decision 87) as a debug action — the night leg does
// the same before a ring-0 Docker step. It prints the container ids before and after (they must not change).
//