controller v0.71.0: fix guest-reboot recovery (boot-race + agent-path blocker)
Live diagnosis of drive-backed apps stuck Exited after a pct reboot pinned THREE sub-causes, fixed together (hardening the existing processGuestBootChange, not a parallel mechanism): 1. Agent-path blocker (live root cause): agentClient() returned "agent not configured" (cfg.LocalAPI.Endpoint empty), so processGuestBootChange AND the whole drive gate bailed at the first guard. bootstrap.json had a complete local_api block, but MaybeIngest returned immediately on "already configured" so a controller.yaml seeded before local_api existed never got the agent path. Fix: MaybeIngest now calls ensureLocalAPI on the already-configured path, merging local_api from bootstrap.json into the existing controller.yaml when missing (no hub re-pull, config preserved; idempotent + fail-safe). 2. Boot-race readiness gate: processGuestBootChange sampled BoundUnderParent once during fast startup, racing the ~18s rebind, recreated nothing, burned its boot-id one-shot. Fix: gate on the REAL live in-guest bind -- driveBindLive checks /mnt/felhom-drives/<drive> is a mountpoint in the controller's own /mnt rslave /proc/self/mountinfo; pollLiveBinds waits for it (bounded ~120s) before recreating via the normal pipeline. shouldRecreateOnBoot stays state-independent so stuck-Exited create-time-failure apps are included. 3. Single-shot fragility: processGuestBootChange ran only once at startup; a briefly-unreachable agent right after a guest reboot stranded recovery. Fix: driveGateLoop runs it every periodic tick too (idempotent, boot-id gated). Tests (non-hollow, pre-fix companions, red-proofed): pollLiveBinds waits then reports live / never-live stays absent / single early sample misses; ensureLocalAPI merges local_api into a configured controller.yaml that lacks it / no-ops when present. Live-accepted with repeated pct reboot 9201. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -655,7 +655,14 @@ not just those with HDD data. Non-HDD apps can configure destination, method, an
|
||||
> rslave `/proc/self/mountinfo`?) and **waits** for it (`pollLiveBinds`, bounded ~120s) before recreating
|
||||
> — including apps stuck `Exited` with a create-time mount failure (`shouldRecreateOnBoot` is
|
||||
> state-independent). The **guest-only reboot path** (which the host-reboot sweep never exercised) is now
|
||||
> covered; drives that never go live in the window are left to the drive-absent gate.
|
||||
> covered; drives that never go live in the window are left to the drive-absent gate. `processGuestBootChange`
|
||||
> also runs on every periodic `driveGateLoop` tick now (idempotent, boot-id gated) so a momentarily-unreachable
|
||||
> agent right after a guest reboot no longer permanently strands recovery.
|
||||
> **Agent-path prerequisite (also v0.71.0):** the whole drive gate needs `cfg.LocalAPI.Endpoint` (the
|
||||
> per-guest agent local API). `bootstrap.MaybeIngest` now calls `ensureLocalAPI` on the already-configured
|
||||
> path — merging `local_api` from `bootstrap.json` into an existing controller.yaml that lacks it (seeded
|
||||
> before `local_api` existed) — because without it `agentClient()` returns "agent not configured" and the
|
||||
> entire gate + boot recovery silently die.
|
||||
>
|
||||
> **⚠️ Rebuilt on the agent-delegated disk model (v0.43.0), made ROLE-AWARE in v0.44.0, UX-polished in
|
||||
> v0.45.0.** After the 8C
|
||||
|
||||
Reference in New Issue
Block a user