Files
felhom-controller/REPORT.md
T

98 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# REPORT — R-67: the NAS share appears in FileBrowser (controller v0.160.0, 2026-07-22)
**Spec:** the R-67 prompt (Phase-0 probe + implementation, controller-only, v0.159.0 → v0.160.0).
**Commit:** `59cd260` on `main` · image `felhom-controller:0.160.0` · deployed to **demo-felhom
9201** and **demo-hp 9201**, both healthy. No agent changes; MinAgent unchanged.
## 1. Phase-0 probe — GO
On demo-hp, with the Felhom-Share automount confirmed IDLE (autofs trigger present in the guest's
/proc/mounts, `timeout=60`, no cifs mount):
`docker run --rm -v /mnt/felhom-drives/Felhom-Share:/probe:rslave alpine ls -la /probe`
listed the REAL share content (demo-felhom's `teszt/` + macOS dotfiles) and left cifs mounted in
the guest. **An in-container access through an rslave bind wakes the idle trigger** — one
namespace further than the spike's in-guest proof. The design shipped exactly as specified; the
fallback fork was not needed.
## 2. What shipped
`syncFileBrowserMounts`' path loop extracted into the pure **`buildFileBrowserPaths`**
(`fbPathDeps`: mount probe / FS classifier / skeleton fn / logger — every edge seamed), returning
BOTH the mount lines and the config source set so a source can never render without its mount.
- **Network branch:** bind = the share ROOT, `…/<name>:/srv/<name>:rslave` (`:rslave`
load-bearing — automount wake / idle-unmount propagate into the RUNNING container). No
`EnsureUserdataSkeleton`, no userdata scoping, nothing written toward the NAS. The drive-absent
gate does NOT apply (idle is healthy — the old gate skipped an idle share forever); the gate is
the **stub** classifier verdict via the existing `Server.classifyFSPath` seam: stub ⇒ excluded
from mounts AND sources this pass + WARN (`namespace sees a local stub, not the NAS`). autofs /
network / unknown / nil-classifier include (fail open). **The stub rationale:** an exposed local
stub dir accepts uploads that the real mount later SHADOWS — the customer's files silently
vanish from view; exclusion-until-recovery is the only safe rendering.
- **Drives:** behavior byte-identical (userdata scoping, skeleton, drive-absent gate, always in
the source list) — asserted by test, and observed live (§4).
- **Triggers:** NAS add-success (`runNetAdd` done) + remove (`handleNetStorageRemove`) now call
`SyncFileBrowserMounts()` (same debounced/H5-mutexed path as the drive flows). Removal drops
source + mount next sync; F2 change detection forces the recreate.
- Renderers unchanged: `RenderFileBrowserCompose` already takes fully-formed mount lines
(propagation rides in the line), `RenderFileBrowserConfig` already names sources by `Label`.
## 3. Tests + red-proofs
`filebrowser_network_test.go`: **A** (drive line byte-identical with/without the share — the B
invariant; share ROOT `:rslave` line exact; both sources in config; skeleton called for the drive
ONLY), **B** (stub ⇒ absent from mounts + sources, drive intact, warn logged), **C** (autofs /
network / unknown / nil classifier all include — idle is not a detached drive), **D** (removal
leaves no trace; `fbNeedsRecreate` sees the change).
**Red-proof A** (network paths routed through the drive branch): FAIL —
`skeleton calls = [/mnt/felhom-drives/hdd_1 /mnt/felhom-drives/Felhom-Share]` — the NAS path
visibly receiving a skeleton — plus the share line degrading to a `userdata` subtree without
`:rslave`. Restored, green.
**Red-proof B** (stub gate dropped): FAIL — the stub share leaked into mounts AND the source
list, and the warn disappeared. Restored, green.
Green gate (`go build ./... && go vet ./... && go test ./...`): clean. No template changes → no
template gates in play.
## 4. Live leg (real surfaces; methods named)
**demo-hp (the mounting side):**
- Startup sync recreated FileBrowser: compose carries
`/mnt/felhom-drives/Felhom-Share:/srv/Felhom-Share:rslave`, config carries
`path: "/srv/Felhom-Share"` named „Hálózati tárhely: Felhom-Share"; log:
`FileBrowser mounts synced (recreated) — 2 storage path(s)`; container healthy.
- **Content:** `docker exec filebrowser ls /srv/Felhom-Share` → demo-felhom's real content
(`teszt/` + dotfiles), uid/gid 1000, group-writable.
- **Upload round-trip:** wrote `r67-test.txt` as **uid 1000 inside the filebrowser container**
(the exact mount namespace + process identity FileBrowser uses) → the file appeared on
demo-felhom at `/mnt/felhom-drives/hdd_1/shares/Share/r67-test.txt` (19 B, uid 1000) → deleted
from demo-hp → gone on demo-felhom. **Residual:** FileBrowser's HTTP/auth layer was NOT driven —
its admin credential is customer/day-0-held (admin/admin and the operator demo password both
401); the browser click-through is the operator's residual, as is a look at the sidebar.
- **Dead-NAS:** samba stack stopped on demo-felhom → demo-hp's in-container access returned a
clean `ls: /srv/Felhom-Share: Host is down` in ~11 s wall (incl. ssh) — an error, not a hang
(the soft/retry=0 recipe's promise held). `docker compose start` on samba → demo-hp listed the
share again immediately, **zero intervention** (the `:rslave` + automount recovery working as
designed).
**demo-felhom (drives-only, the regression side):** startup sync logged
`no config/compose change, ensured running without recreate (1 storage path(s))` — the render was
byte-identical, FileBrowser untouched (Up 22 hours), zero `:rslave` lines in its compose. The B
invariant held in production.
**Screenshots by description:** demo-hp's FileBrowser sidebar now has a second entry „Hálózati
tárhely: Felhom-Share" beside the NVMe drive source; entering it shows the `teszt` folder from
demo-felhom. During the dead-NAS minute the source errors instead of spinning.
**Access notes:** demo-hp via the hub-vaulted G1 break-glass again (file→file, shredded after,
incl. the hub-DB copy). Probe + all execs left nothing behind (`r67-test.txt` deleted; alpine
image remains in the guest's docker cache — inert).
## 5. Follow-ups
- Operator: FileBrowser click-through on demo-hp (sidebar + upload via the UI) — CC lacks the
FileBrowser admin credential by design.
- ROADMAP: **R-67 → SHIPPED**, coupled to R-64 (browsing was its missing UX half);
`network-storage-nas.md` gained the „Browsing (FileBrowser)" paragraph.