syncFileBrowserMounts no longer force-recreates FileBrowser unconditionally: captures config.yaml+compose before writes, re-reads final content after, and recreates only when they actually changed (new pure helper fbNeedsRecreate). Controller restarts / no-op storage syncs now issue a plain up -d and do NOT bounce the customer's file UI. Restore-mode DB reset still forces a recreate. Dockerfile: removed the unused restic apt package (disk-tier restic moved to the host agent; no controller code execs the binary). ResticSchedule/migrateResticToRsync config+settings paths untouched (still live in the dashboard). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FpBYrZCt9sFDqLgbG5GRGD
3.2 KiB
REPORT — FileBrowser no-op recreate fix (F2) + drop restic binary (F1)
Repo: felhom-controller · Version: v0.81.0 → v0.82.0 · Date: 2026-06-24
Baseline: main @ 036a6078b (CHANGELOG top v0.81.0), trunk-based, no branches.
Two findings from TEST-REPORT-stable-path-sysdrive-restart-2026-06-23.md, both validated at source.
F2 — gate the FileBrowser recreate on an actual change
Root cause: syncFileBrowserMounts (internal/web/handlers.go) ran
docker compose up -d --force-recreate --remove-orphans unconditionally. The existing
sourcesChanged flag gated only the restore-mode DB reset (down -v); the force-recreate fired on
every controller restart and every storage sync even when config.yaml/compose were byte-identical —
bouncing the customer's file-access UI, contradicting the "Vezérlő újraindítása → apps keep running"
promise (the 3.4 reproduction in the test report).
Fix:
- Capture
oldConfig/oldComposefrom disk before the writes. - Re-read
finalConfig/finalComposeafter the writes — so the integrations'ReapplyConfigForTarget("filebrowser")edits toconfig.yamlare included in the comparison. - New pure helper
fbNeedsRecreate(oldCfg, newCfg, oldCompose, newCompose) bool(byte-equality on both files) drives the decision.changed→up -d --force-recreate --remove-orphans; otherwise a plainup -d --remove-orphans(ensures running, no bounce). - Preserved: the restore-mode DB reset stays gated on
sourcesChanged && resetDBOnChange; when it runs it setschanged = true(adown -vremoved the container, so it must be recreated). - First-ever run (no old files → empty bytes) differs from generated content →
changed = true→ creates it.
Files: internal/web/handlers.go (helper + gate; added bytes import).
F1 — drop the unused restic binary from the image
controller/Dockerfile: removed the restic \ apt line and its # - restic: … comment. Disk-tier
restic moved to the host agent; no controller code execs the binary. Left untouched (still live in
the dashboard/UI): ResticSchedule config, migrateResticToRsync settings migration, and the
Method/backup-dir-name string references.
Tests
- Added
TestFbNeedsRecreate(internal/web/filebrowser_gate_test.go): unchanged → false (no recreate); config differs → true; compose differs → true; first run (no old files) → true. - Red-proof: hard-wiring
fbNeedsRecreateto always returntrue(the old unconditional behaviour) makes the "unchanged → no recreate" case fail; restoring the byte-equality gate turns it green. - Web package top-level tests: +1 (added
TestFbNeedsRecreate). - Green gate:
go build ./...✓ ·go vet ./...✓ ·go test ./...✓ (all packages ok).
Deploy & verify (guest 9201 / felhom-pve)
- Deployed image:
gitea.dooplex.hu/admin/felhom-controller:0.82.0— status filled after live deploy docker exec felhom-controller command -v restic→NO-RESTIC(F1)- FileBrowser
StartedAtUNCHANGED across a no-op sync / controller restart (F2) - Sanity: a real config change (drive enroll/deregister) DID recreate FileBrowser (StartedAt changed)