Files
felhom-controller/REPORT.md
T
admin 5eb25c3861 docs: Phase 1 gate — REPORT/CONTEXT/README for v0.52.0 double-nest fix
REPORT.md overwritten with the Phase-1 gate run (catalog template fix + agreement
test + live RomM migration on guest 9201, gate PASSED). CONTEXT.md dated entry.
README HDD_PATH/felhom-data convention note corrected for Model-A single-nesting.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 09:38:42 +02:00

4.6 KiB
Raw Blame History

REPORT — felhom-controller v0.52.0 (Phase 1 GATE: deploy-side double-nest fix)

Completes the Model-A double-nest reconciliation deferred in v0.48.0 and half-fixed in v0.51.0. v0.51.0 fixed the backup-helper side (NamespaceRoot provenance); this slice fixes the deploy/compose side and locks the two together. Validated live on guest 9201 (demo-felhom).

This is the GATE for the larger per-app-recovery-unit / Tier-2 slice — Phases 24 build on a proven single-nested, agreeing path layout. Per plan: Phase 1 shipped + validated first.

Root cause (corrected from the spec's assumption)

The extra felhom-data segment was not built in controller deploy.goDeployStack passes HDD_PATH through verbatim, and the deploy storage dropdown only ever offers registered in-guest drives (GetSchedulableStoragePaths), never the system-data path. The segment was hardcoded in the app-catalog compose templates as ${HDD_PATH}/felhom-data/appdata/<app>. On a Model-A in-guest drive the guest mount /mnt/<drive> already IS the host's <drive>/felhom-data namespace, so that segment double-nested to <drive>/felhom-data/felhom-data/appdata/<app> on disk — diverging from where the (v0.51.0) backup helpers look: AppDataDir(NamespaceRoot(HDD_PATH,true)) = /mnt/<drive>/appdata/<app>, single-nested.

Changes

  • Catalog (app-catalog-felhom.eu, the behavioral fix): exhaustive grep confirmed exactly four HDD templates carried the segment — romm, nextcloud, immich, paperless-ngx. All changed ${HDD_PATH}/felhom-data/appdata/<app>${HDD_PATH}/appdata/<app> (volume mounts + header comments).
  • Controller (test-only, no runtime change): internal/stacks/hddpath_agreement_test.go resolves a compose's ${HDD_PATH} bind mounts via the real deploy-side ParseComposeHDDMounts and asserts they are byte-identical to the backup-side AppDataDir(NamespaceRoot(HDD_PATH,true)) — no doubled felhom-data, deploy↔backup locked so they can't drift again. go test ./internal/stacks/... and ./internal/appbackup/... pass; go build ./... clean.
  • No controller image rebuild. The controller passes HDD_PATH through unchanged and already resolved the single-nested path since v0.51.0, so no runtime change was needed. The controller in guest 9201 stays :0.51.0 (functionally current); v0.52.0 marks the catalog gate + test and rolls into the next image build (Phase 2). The controller is golden-image/bootstrap-managed — not rebaked for a no-op.

Live validation (guest 9201, demo-felhom, root@felhom-pve)

  • Only one live HDD app: RomM (the others aren't drive-deployed). HDD_PATH=/mnt/felhom-usb; data was at the doubled /mnt/felhom-usb/felhom-data/appdata/romm.
  • Catalog fix delivered by the real mechanism: the controller's periodic git-sync logged "Sablonok frissítve — frissítve: immich, nextcloud, paperless-ngx, romm" and updated all four on-disk stack files to ${HDD_PATH}/appdata/<app> (single-nest) — confirmed in /opt/docker/stacks/*/docker-compose.yml.
  • RomM migrated (stop → move → verify → redeploy, ordered, reversible mv, never delete-then-move): captured RomM's runtime env from the running containers into a guest-only temp file (secrets never left the guest), docker compose down (named DB/redis volumes preserved), moved /mnt/felhom-usb/felhom-data/appdata/romm/mnt/felhom-usb/appdata/romm, verified file count unchanged, then recreated with the fixed compose + captured env.
  • Result: RomM binds the single-nest paths (/mnt/felhom-usb/appdata/romm/{library,resources}), all three containers healthy, DB connected (the captured creds worked), in-guest HTTP/1.1 200 OK, "Application startup complete". Old namespace /mnt/felhom-usb/felhom-data/appdata/ confirmed empty; backups already single-nested at /mnt/felhom-usb/backups/primary. Controller untouched & healthy throughout.

Gate outcome — PASSED

A drive-app lands single-nested AND the backup helpers resolve the identical path — proven live (not REPORT-only): the deploy-resolver and the backup helper agree by test and by the live RomM binds, the catalog fix propagated via real git-sync, and no doubled felhom-data remains. Cleared to start Phase 2.

Not done (intentionally deferred to Phases 24)

Per-app recovery unit (backup/<app>), Tier 2 off-drive copy (auto-enabled, durable-id target, rootfs headroom guard), secret preserve-vs-regenerate classing, FileBrowser scoping, deploy-UI DB-on-SSD note, monitoring storage sort/descriptions. The README's backup-paths section still describes the stale restic/secondary layout — to be rewritten when Tier 2 is built.