Files
felhom-controller/REPORT.md
T
admin 9cd566ded7 v0.82.0: gate FileBrowser recreate on actual change (F2); drop unused restic binary (F1)
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
2026-06-24 11:01:18 +02:00

52 lines
3.2 KiB
Markdown

# 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`/`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. `changed``up -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 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 `StartedAt` UNCHANGED across a no-op sync / controller restart (F2)
- Sanity: a real config change (drive enroll/deregister) DID recreate FileBrowser (StartedAt changed)