agent v0.33.0: C1 net — pre-start self-heal hook + decommission mp-delete
Pre-start PVE hookscript (internal/guesthook) creates host-root placeholders for absent bind-mount sources so the guest always boots (fail-closed); decommission now pct set --delete's the dead mp (GuestBinder.DetachBind) so a missing source can't brick the next reboot (B3 C1 bug). Non-hollow tests + companions. Installed + registered per-guest by the provision back-half. Transitional ahead of the intermediary-mount re-architecture which makes C1 structural. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,32 @@
|
||||
All notable changes to **felhom-agent** are recorded here. Update on every code
|
||||
change that gets pushed.
|
||||
|
||||
## v0.33.0 — C1 net: pre-start self-heal hook + decommission mp-delete (2026-06-15)
|
||||
|
||||
The transitional defense for the C1 brick (B3 critical bug) ahead of the intermediary-mount
|
||||
re-architecture (which makes C1 structural). Two independent nets:
|
||||
|
||||
- **Pre-start self-heal hook** (`internal/guesthook`): a PVE `pre-start` hookscript runs
|
||||
`felhom-agent guest-hook <vmid> <phase>` which, for every BIND mountpoint whose source path is
|
||||
missing, creates an empty **host-root-owned** placeholder dir so the bind succeeds and the guest
|
||||
always boots — fail-closed (host uid 0 is unmapped in the unprivileged-LXC userns, so the guest
|
||||
can't write to the placeholder; a returning drive shadows it). It CREATES rather than DELETEs
|
||||
because `pct set --delete` in pre-start would take the config lock the start task already holds
|
||||
(dead-times-out → still bricks); the heal logic is in unit-tested Go, the wrapper just delegates.
|
||||
Installed + registered per-guest by the provision back-half (`InstallSnippet`/`Register`).
|
||||
- **Decommission mp-delete** (`GuestBinder.DetachBind` + `handleDiskDecommission`): decommission now
|
||||
runs `pct set <vmid> --delete mpN` on the slot binding the drive (lock-safe on the running guest),
|
||||
so its now-missing source can't brick the next reboot. The old handler unmounted but left the dead
|
||||
`mpN` in config — the exact B3 C1 bug. Eject keeps its mp (temporary; the hook covers a
|
||||
reboot-while-ejected).
|
||||
|
||||
Tests (non-hollow, each with a companion that fails the pre-fix/trivial impl):
|
||||
`internal/guesthook/heal_test.go` (selector ignores storage volumes + present binds, heals only the
|
||||
absent one; "return nothing"/"return all" both fail) and `TestDecommission_DeletesGuestMount`
|
||||
(asserts the correct slot is `--delete`d; pre-fix never calls DetachBind → fails).
|
||||
|
||||
Sudoers: new `FELHOM_GUESTHOOK` alias (snippet install, `pct set --hookscript`, `pct set --delete mpN`).
|
||||
|
||||
## v0.32.0 — self-serve decommission + intent-aware re-assert (B2a) (2026-06-14)
|
||||
|
||||
Customer-self-serve storage decommission (no operator signature; non-destructive — never formats),
|
||||
|
||||
Reference in New Issue
Block a user