Files
felhom-controller/REPORT.md
T

4.1 KiB

REPORT — FileBrowser no-op recreate fix (F2) + drop restic binary (F1)

Repo: felhom-controller · Version: v0.81.0v0.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/oldCompose from disk before the writes.
  • Re-read finalConfig/finalCompose after the writes — so the integrations' ReapplyConfigForTarget("filebrowser") edits to config.yaml are included in the comparison.
  • New pure helper fbNeedsRecreate(oldCfg, newCfg, oldCompose, newCompose) bool (byte-equality on both files) drives the decision. changedup -d --force-recreate --remove-orphans; otherwise a plain up -d --remove-orphans (ensures running, no bounce).
  • Preserved: the restore-mode DB reset stays gated on sourcesChanged && resetDBOnChange; when it runs it sets changed = true (a down -v removed 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 fbNeedsRecreate to always return true (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 via the golden bootstrap mechanism: docker pull …:0.82.0 into the guest, set /etc/felhom-controller-image0.82.0, systemctl restart felhom-controller-bootstrap.service.

  • docker psgitea.dooplex.hu/admin/felhom-controller:0.82.0 Up … (healthy)
  • F1: docker exec felhom-controller command -v resticNO-RESTIC
  • F2 (no-op): deploying 0.82.0 restarted the controller; its startup sync logged FileBrowser sync — no config/compose change, ensured running without recreate (3 storage path(s)), and FileBrowser StartedAt stayed 2026-06-23T18:15:47 (UNCHANGED — not bounced) ✓
  • F2 (change path): dirtied the on-disk config.yaml + restarted the controller → log FileBrowser mounts synced (recreated) — 3 storage path(s), config updated, FileBrowser StartedAt advanced to 2026-06-24T09:05:53 (recreated on a real change) ✓. The sync regenerated config.yaml back to canonical (test line gone), FileBrowser + controller healthy — state restored.

Method: invoked the exact server-side sync (controller restart → syncFileBrowserMounts) on the live guest; no browser tool needed for this check (it's container-lifecycle, observed via docker inspect).