v0.79.0: disk view keys the "registered" check on the stable path

Follow-up to v0.78.0. The disk-view JS (settings.html regBadge/actions) checked
registration by the raw mount_path, but the registry stores the stable path since
v0.78.0 — so enrolled drives showed a spurious "Nem regisztrált" badge + Register
button. Fix: regKey(d) = d.guest_path || d.mount_path (agent reports the stable
guest_path per disk); registerDrive still posts the raw path. Display-only.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PsnU2ASocYrvzqE82YDYW
This commit is contained in:
2026-06-23 17:42:37 +02:00
parent 081c1cd77f
commit a9f0de4c63
3 changed files with 49 additions and 68 deletions
+31 -66
View File
@@ -1,75 +1,40 @@
# REPORT — controller v0.78.0: storage register uses the STABLE path (not the raw path)
# REPORT — controller v0.79.0: disk view keys "registered" on the stable path
## Baseline
- felhom-controller `main` @ `66d8462`, **v0.77.0 → v0.78.0**. Trunk-based, `main`.
- Fixes the diagnosis `felhom.eu/documentation/audits/DIAGNOSE-drive-bind-after-reprovision-2026-06-23.md`
(§4/§5). Agent untouched (it already binds drives at the stable path).
- felhom-controller `main` @ `081c1cd`, **v0.78.0 → v0.79.0**. Trunk-based, `main`.
- Follow-up to v0.78.0 (stable-path registration). Same path-model mismatch, on the **display** side.
## Problem
`handleStorageRegister` (the "Regisztrálás" action for an already-mounted, unregistered drive) registered
the **raw** `/mnt/<name>` path verbatim, while `runStorageInit`/`runStorageAttach` register the **stable**
intermediary path `/mnt/felhom-drives/<name>`. In the intermediary model the drive is live in the guest
only at the stable path, so the controller watched an empty placeholder dir on the guest rootfs →
"Rendszermeghajtón" badge (~31 GB), `0 connected / N disconnected`, and a stuck "activation pending"
banner. The real drives were fine the whole time.
## Problem (operator-reported, screenshot)
After v0.78.0, the storage disk view tagged both enrolled, working drives **"Nem regisztrált"** and
showed a **"Regisztrálás"** button — even though the registry holds them and the selftest reports them
`2 connected`. Root cause: the disk-view JS (`settings.html`) decided "registered?" by looking up the
drive's **raw** `mount_path` (`/mnt/felhom-flash`) in `window.__registeredPaths`, but v0.78.0 made the
registry store the **stable** path (`/mnt/felhom-drives/felhom-flash`), so the raw-key lookup always
missed. (Before v0.78.0 it read "Regisztrálva" because the registry held the raw path — looked right but
the drive was broken.)
## Fix (`controller/internal/web/storage_handlers.go`, `handleStorageRegister`)
- `stable := stablePathForName(path.Base(req.Where))``registerStoragePath(stable, …)` (was
`registerStoragePath(req.Where, …)`), mirroring `runStorageInit`/`runStorageAttach`.
- `attachIntoGuest(req.Where)` unchanged — the agent still operates on the **raw** path.
- Success `[INFO]` log + the `writeDiskJSON` payload now report the stable registered path (+ raw).
- No change to `runStorageInit`/`runStorageAttach`/`registerStoragePath` or any other behavior.
## Fix (`controller/internal/web/templates/settings.html`, disk-view JS)
- New `regKey(d)` = `d.guest_path || d.mount_path` — the agent already reports each drive's STABLE
in-guest path as `guest_path` (`/mnt/felhom-drives/<name>`), which is what the registry stores.
- `regBadge(d, registered)` and `actions(d, registered)` now key the "is registered" check on
`regKey(d)` instead of `d.mount_path`. So an enrolled drive reads **"Regisztrálva"** and the spurious
Register button is hidden.
- `registerDrive()` still posts the RAW `mount_path` (unchanged) — the agent operates on raw, and
`handleStorageRegister` maps it to the stable path. Display-only change; no Go/handler change.
## Tests + red-proof
- `go build ./... && go vet ./... && go test ./...`**all green** before and after.
- New `TestHandleStorageRegister_RegistersStablePath` (`storage_handlers_test.go`): drives the HTTP
handler with `where=/mnt/felhom-flash`, asserts the registry holds `/mnt/felhom-drives/felhom-flash`
and the JSON reports stable `where` + raw. PASS.
- **Red-proof:** reverted the handler to `registerStoragePath(req.Where, …)` → the test FAILED
(`got "/mnt/felhom-flash"`) → re-applied the fix → green. ✅
- Existing `TestRunStorageInit_Success` / `TestRunStorageAttach_Success` (which assert stable registration
+ raw guest-attach) kept green, unmodified.
- `internal/web` test count: +1 (the new register test). Full suite green.
## Tests
- `go build ./... && go vet ./... && go test ./...`**all green** (incl. `TestTemplatesParse`, which
forces the edited template to parse).
## Deploy (v0.78.0 → guest 9201)
- Built + pushed `gitea.dooplex.hu/admin/felhom-controller:0.78.0` on 192.168.0.180 (`build.sh 0.78.0
--push`, 142M). Deployed to 9201: `docker pull` → `printf … > /etc/felhom-controller-image` → restart
`felhom-controller-bootstrap.service`. `docker ps` → `:0.78.0 Up (healthy)` (was `:0.77.0`).
## Deploy (v0.79.0 → guest 9201)
- _(filled at deploy)_ built+pushed `:0.79.0` on 192.168.0.180; deployed to 9201 (pull →
`/etc/felhom-controller-image` → restart `felhom-controller-bootstrap.service`); `:0.79.0 Up (healthy)`.
## 9201 registry remediation (non-destructive — drive never unmounted)
The registry held the two stale RAW entries `/mnt/felhom-flash` + `/mnt/felhom-usb`. Remediated through
the real server pipeline:
1. Re-registered both via the FIXED `POST /api/storage/register` (in-guest `docker exec … curl
127.0.0.1:8080`; auth+CSRF skipped, no password set) → response `where=/mnt/felhom-drives/felhom-flash`
(+`raw=/mnt/felhom-flash`) and `…/felhom-usb` — confirming the fix end-to-end.
2. Deregistered the two raw entries via `POST /settings/storage/remove` (deregister-only — `RemoveStoragePath`,
**NOT** eject; the host drive mounts were never touched). Registry now holds ONLY the two stable paths.
3. Removed the orphaned rootfs placeholder trees `/mnt/felhom-flash` + `/mnt/felhom-usb` in the guest
(verified 0 files — only an empty userdata skeleton from the buggy raw registration — and verified NOT
mounts before `rm -rf`). Guest `/mnt` now: `felhom-drives` + `sys_drive` only.
## Verification (§6-C) — server-side pipeline + rendered page (NOT browser)
- **Registry:** `settings.json` `storage_paths` = `/mnt/felhom-drives/felhom-flash` +
`/mnt/felhom-drives/felhom-usb` (stable only).
- **Selftest:** `[PASS] Storage paths: 2 connected, 0 disconnected` (was `[WARN] 0 connected, 2
disconnected`); `[PASS] System data path: /mnt/sys_drive`.
- **Per-path device resolution (what the UI renders):** `/mnt/felhom-drives/felhom-flash` →
`/dev/sdc1[/felhom-data] 117.1G`; `/mnt/felhom-drives/felhom-usb` → `/dev/sdb1[/felhom-data] 915.8G` —
both a DIFFERENT block device from `/` (`overlay`), so the system-drive check is false.
- **Rendered `/monitoring` HTML** (the bytes the browser renders): "aktiválásra vár" banner = **0
occurrences**; "Rendszermeghajtón" badge = **0 occurrences**; storage bars show `felhom-flash` /
`felhom-usb` at `117 GB` / `916 GB`.
- **Method:** verified via the controller's server-side selftest + the exact server-rendered page HTML +
the per-path device resolution the page calls — NOT claude-in-chrome. The only residual is the
browser's visual render of that verified HTML.
- **Regression:** the correct `runStorageInit`/`runStorageAttach` paths are unchanged (unit tests green);
not re-run live to avoid mutating a real drive.
## Verification
- _(filled at verify)_ disk view: both drives show **"Regisztrálva"**, NO "Regisztrálás" button; storage
selftest still `2 connected`; no "Rendszermeghajtón", no activation banner (v0.78.0 state intact).
## Observations (recorded, NOT acted on)
1. `pendingActivationDrives` (`storage_handlers.go`) keys `attached` by the agent's raw `MountPath` and
compares to the registered `sp.Path`. With stable registration the activation banner clears, but the
function no longer detects a genuinely not-yet-propagated drive. The intermediary model activates LIVE
(no reboot), so the "~30 mp újraindítás" banner copy is likely obsolete; activation detection should
key off `GuestPath`/`BoundUnderParent` like `planDriveGates`, or the banner be retired. Follow-up.
2. The free-form settings storage-add (`handlers.go`) registers a user-typed path verbatim; a raw
`/mnt/<name>` typed there would hit the same shape. Advanced manual flow, out of scope.
- `pendingActivationDrives` still keys off the agent's raw `MountPath` (the "~30 mp újraindítás" banner);
obsolete in the live-activating intermediary model — key off `GuestPath`/`BoundUnderParent` or retire.
- The free-form settings storage-add registers a user-typed path verbatim (advanced manual flow).