agent v0.85.0 WIP: F12/F11/F10/F9/F2/F1 boot-recovery plane + appliance self-heal (pre-build)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017CDMFpFx84pfviCTVuGGhf
This commit is contained in:
2026-07-12 07:48:49 +02:00
parent bec4bac076
commit bc4eda926b
18 changed files with 1249 additions and 104 deletions
+6 -1
View File
@@ -28,9 +28,14 @@ var SnippetPath = filepath.Join(SnippetDir, SnippetName)
// snippetBody is the tiny wrapper PVE execs as `<script> <vmid> <phase>`. It delegates to the agent
// binary so the heal LOGIC is the unit-tested Go, never duplicated (divergence-proof) shell. Executable.
// The wrapper NEVER exec's and ALWAYS exits 0 (CAMPAIGN-3 F10/rc255 belt): a hook that exits nonzero
// aborts the guest start. `exec` would surface the binary's exit code to PVE; instead we run it as a
// child, swallow any nonzero (missing/crashed binary, OOM-kill), and `exit 0` unconditionally. The Go
// side has its own recover + per-phase timeout — this is the second belt at the shell layer.
const snippetBody = `#!/bin/sh
# felhom-agent guest pre-start self-heal hook (C1 net). PVE calls: <script> <vmid> <phase>.
exec ` + AgentBin + ` guest-hook "$1" "$2"
` + AgentBin + ` guest-hook "$1" "$2" || true
exit 0
`
// InstallSnippet writes the pre-start hook wrapper into the PVE snippets dir (idempotent, root-owned,
+2 -2
View File
@@ -42,8 +42,8 @@ func PostStartNetworkReassert(ctx context.Context, vmid string) {
// real host surface).
func postStartNetworkReassert(ctx context.Context, vmid string, ops netReasserter, sees func(ctx context.Context, vmid, path string) bool) {
for _, res := range ops.ReassertNetworkAutomounts(ctx) {
if res.Err != nil || res.Action == storage.NetReassertSkipNone {
continue // already reported by the ops logger / nothing expected in the guest
if !res.Remediates() {
continue // foreign/errored rows expect nothing in the guest (already logged by the ops layer)
}
if sees(ctx, vmid, res.Where) {
fmt.Fprintf(os.Stderr, "felhom-agent guest-hook: vmid %s post-start — network share %s visible in guest (%s)\n",
+2 -2
View File
@@ -18,12 +18,12 @@ func (f *fakeReasserter) ReassertNetworkAutomounts(context.Context) []storage.Ne
}
// The post-start core must run the reassert pass and verify guest visibility for every share the
// pass acted on (or found actively mounted) — and never for skip-none/errored rows.
// pass acted on (or found actively mounted) — and never for foreign/errored rows.
func TestPostStartNetworkReassert_Core(t *testing.T) {
ops := &fakeReasserter{results: []storage.NetReassertResult{
{Name: "media", Where: "/mnt/felhom-drives/media", Action: storage.NetReassertRearmed},
{Name: "active", Where: "/mnt/felhom-drives/active", Action: storage.NetReassertSkipActive},
{Name: "gone", Where: "/mnt/felhom-drives/gone", Action: storage.NetReassertSkipNone},
{Name: "foreign", Where: "/mnt/felhom-drives/foreign", Action: storage.NetReassertSkipForeign},
}}
var verified []string
postStartNetworkReassert(context.Background(), "9201", ops, func(_ context.Context, vmid, path string) bool {