Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
3.2 KiB
REPORT — controller v0.72.0: FileBrowser converges on boot-recreate (2026-06-16)
Deployed: controller v0.72.0 on guest 9201 / felhom-pve (bootstrap-managed; healthy).
Commit (trunk): 6ea2538 (Task B) + c8d…-era REPORT update.
Live-accepted: two REAL host reboots of felhom-pve — FileBrowser re-synced after the drive-backed
apps were recreated, both times; all drive-backed apps recovered with zero manual intervention.
Task B — the gap
Follow-up to v0.71.0's guest-reboot recovery. A host-reboot test found processGuestBootChange
recreated the drive-backed app stacks (so their ${HDD_PATH} binds re-resolved against the now-live
drives) but never re-synced FileBrowser. FileBrowser is base-infra: it binds each drive's
userdata directory but has no HDD_PATH, so it is not in the boot-recreate set — its mounts went
stale after a reboot (the early first-boot bring-up bound them before the drives were live).
Fix
In processGuestBootChange (internal/web/intermediary.go), after pollLiveBinds confirms the
live binds and the drive-backed apps are recreated, the boot-recreate path now triggers
go s.SyncFileBrowserMounts() so FileBrowser converges against the now-live drives. The recreate loop
was refactored into a pure, seam-testable helper:
func recreateDriveBackedApps(stacks []bootStack, presentStable map[string]bool,
recreate func(bootStack), syncFB func()) (recreated, skipped int)
syncFB is invoked exactly once, AFTER all recreates — the FileBrowser sync can never run before the
drive-backed apps are back.
Tests (non-hollow, seam = the FB sync)
TestRecreateDriveBackedApps_SyncsFileBrowserAfterRecreate— records the call sequence; assertssyncFBruns exactly once and strictly AFTER everyrecreate. Red-proofed (stubbing out thesyncFB()call makes it fail).TestRecreateDriveBackedApps_SyncsEvenWithNoRecreate— FileBrowser still converges when nothing needed recreating (e.g. binds already present).
go build, go vet, go test ./... all green on the build server (192.168.0.180).
Live acceptance — real host reboot ×2 on felhom-pve
Both reboots: processGuestBootChange fired on the new boot-id, confirmed the live binds, recreated
every drive-backed app, then ran the FileBrowser sync. Captured controller logs:
[gate] boot 1781625729-1612: live bind confirmed — recreating drive-backed app … onto /mnt/felhom-drives/felhom-flash (×8 apps)
[gate] boot 1781625729-1612: re-syncing FileBrowser mounts against the live binds
[web] FileBrowser mounts synced — 3 storage path(s), config updated
(reboot #2 identical on boot-id 1781625955-1516.) Post-reboot FileBrowser binds all three drives
non-stale — felhom-usb, felhom-flash, felhom-data → /srv/felhom-* — and the underlying agent
tolerated a /dev/sdb↔/dev/sdc reshuffle by mounting each drive by UUID (agent v0.37.0, Task A).
The earlier first-boot Failed to recreate FileBrowser line (drives not yet live) is the exact pre-fix
symptom; the boot-recreate path now recovers it.
Demo dashboard has no password set → controller API is open on the in-guest path; no secrets committed.