R-1124 + R-1012: forget a decommissioned drive that is gone; name an orphan thin device in a backup failure
gates / gates (push) Successful in 47s
gates / gates (push) Successful in 47s
R-1124: ForgetRetiredDrives (start-up + the 20 s tick) disables and removes the host mount unit of a DECOMMISSIONED drive whose disk is absent and unmounted; the agent then no longer lists it. A present decommissioned drive keeps its unit (one-click re-enroll). The file goes only through the new felhom-priv-apply verb `unit-forget`, which re-checks marker, disabled, unmounted and absent as root. R-1012: the read-only root helper felhom-thin-check <vg> <pool> (bundle) lists the pool's thin ids (metadata snapshot reserved and released) next to LVM's before and after. BackupRunner.SetThinCheck runs it before a snapshot-mode backup (log) and again after a failure, appending the finding in plain words to the error the controller mails to the operator. Two reads, intersected; fails open; never removes. Red-proofs: felhom.eu audits/agent-allowlist-rotation-2026-10-17/P1/. Code only; the CHANGELOG entry follows the release. Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -59,6 +59,7 @@ import (
|
||||
"gitea.dooplex.hu/admin/felhom-agent/internal/selfupdate"
|
||||
"gitea.dooplex.hu/admin/felhom-agent/internal/signedjobs"
|
||||
"gitea.dooplex.hu/admin/felhom-agent/internal/storage"
|
||||
"gitea.dooplex.hu/admin/felhom-agent/internal/thincheck"
|
||||
"gitea.dooplex.hu/admin/felhom-agent/internal/vzpartial"
|
||||
"gitea.dooplex.hu/admin/felhom-agent/internal/wgtunnel"
|
||||
)
|
||||
@@ -1425,6 +1426,9 @@ func runDaemon(cfg config.Config, logger *slog.Logger, logRing *applog.Ring) int
|
||||
// re-assert below sees its unit.
|
||||
localSrv.EnsureInternalPlace(ctx)
|
||||
if mountReasserter != nil {
|
||||
// R-1124: a decommissioned drive that is gone loses its host mount unit first (start-up and every tick), so
|
||||
// no later boot waits for it and the re-assert below no longer lists it.
|
||||
mountReasserter.ForgetRetiredDrives(ctx, intentReader)
|
||||
mountReasserter.ReassertEnrolledMounts(ctx)
|
||||
}
|
||||
// F9: on startup (the host's bring-up/reconcile trigger), re-assert any enrolled guest data-drive
|
||||
@@ -1463,6 +1467,7 @@ func runDaemon(cfg config.Config, logger *slog.Logger, logRing *applog.Ring) int
|
||||
// unit re-disabled at runtime), then re-assert the guest binds against the now-live mounts.
|
||||
localSrv.EnsureInternalPlace(ctx) // `16` §5: a record written since the last tick (the signed job)
|
||||
if mountReasserter != nil {
|
||||
mountReasserter.ForgetRetiredDrives(ctx, intentReader) // R-1124: decommissioned + gone → unit removed
|
||||
mountReasserter.ReassertEnrolledMounts(ctx)
|
||||
}
|
||||
localSrv.ReassertGuestBinds(ctx)
|
||||
@@ -2061,8 +2066,12 @@ func buildLocalAPIServer(cfg config.Config, px *proxmox.Client, store *backup.St
|
||||
},
|
||||
Logger: logger,
|
||||
}
|
||||
// R-1012: an orphan thin device (a full host root during a snapshot) is NAMED in the backup failure the controller
|
||||
// mails to the operator, through the read-only root helper. Never removed — the repair stays a human step.
|
||||
thinChecker := &thincheck.Checker{API: px, Runner: &proxmox.ExecRunner{Mode: gaMode, SudoPath: cfg.Privileged.SudoPath}, Logger: logger}
|
||||
for _, r := range tierRunners {
|
||||
r.SetBeforeBackup(func(ctx context.Context, storage string, vmid int) { cleaner.Clean(ctx, storage, vmid) })
|
||||
r.SetThinCheck(func(ctx context.Context, vmid int) string { return thincheck.Describe(thinChecker.Check(ctx, vmid)) })
|
||||
}
|
||||
srv.SetPartialSweep(func(ctx context.Context, vmid int) {
|
||||
for _, t := range tierTargets {
|
||||
|
||||
Reference in New Issue
Block a user