diff --git a/CHANGELOG.md b/CHANGELOG.md index 85f21ee..fffa833 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ ## Changelog +### v0.79.0 — disk view: key the "registered" check on the stable path (2026-06-23) +- Follow-up to v0.78.0. The storage disk-view JS (`settings.html` `regBadge`/`actions`) decided whether + a drive was registered by looking up its **raw** `mount_path` (`/mnt/`) in the registry — but + since v0.78.0 the registry correctly stores the **stable** path (`/mnt/felhom-drives/`), so an + enrolled, working drive showed a spurious **"Nem regisztrált"** badge + **"Regisztrálás"** button. +- Fix: new `regKey(d)` = `d.guest_path || d.mount_path` (the agent already reports the stable + `guest_path` per disk); `regBadge`/`actions` now key on it. `registerDrive()` still posts the RAW + `mount_path` (the agent operates on raw; `handleStorageRegister` maps it to stable). Display-only. + ### v0.78.0 — storage register: use the STABLE intermediary path, not the raw path (2026-06-23) - **Bug:** `handleStorageRegister` (the "Regisztrálás" action for an already-mounted, unregistered drive) registered the **raw** `/mnt/` host path verbatim, unlike its siblings `runStorageInit`/ diff --git a/REPORT.md b/REPORT.md index 85f178b..574ec5c 100644 --- a/REPORT.md +++ b/REPORT.md @@ -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/` path verbatim, while `runStorageInit`/`runStorageAttach` register the **stable** -intermediary path `/mnt/felhom-drives/`. 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/`), 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/` 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). diff --git a/controller/internal/web/templates/settings.html b/controller/internal/web/templates/settings.html index d9ebe63..504b620 100644 --- a/controller/internal/web/templates/settings.html +++ b/controller/internal/web/templates/settings.html @@ -441,9 +441,14 @@ window.__registeredPaths=[{{range .StoragePaths}}{{if .Path}}"{{.Path}}",{{end}} return '🔒Védett'; } function dataBadge(d){ return d.data_bearing ? 'Adatot tartalmaz' : ''; } + // regKey is the path a drive is REGISTERED under: the STABLE intermediary path (guest_path, + // /mnt/felhom-drives/) the agent reports, else the raw mount_path (legacy). The registry + // stores the STABLE path (handleStorageRegister/runStorageInit), so checking the raw mount_path + // alone made an enrolled drive read as "Nem regisztrált" + show a spurious Regisztrálás button. + function regKey(d){ return d.guest_path || d.mount_path; } function regBadge(d, registered){ if(!d.mount_path) return ''; - return registered[d.mount_path] ? 'Regisztrálva' : 'Nem regisztrált'; + return registered[regKey(d)] ? 'Regisztrálva' : 'Nem regisztrált'; } // appBackingTag marks the storages that actually hold deployed apps: the internal SSD (app // databases + Docker) and the external user-data drives (large app files). Keyed on the agent's @@ -476,7 +481,9 @@ window.__registeredPaths=[{{range .StoragePaths}}{{if .Path}}"{{.Path}}",{{end}} var btns = ''; // A mounted-but-unregistered user-data drive: the natural intent is to USE it → Regisztrálás is // the PRIMARY action (no format, no eject). Leválasztás/Törlés stay available but secondary. - if(!registered[d.mount_path]){ + // Registration is keyed on the STABLE path (regKey) — the registry stores that, not the raw mp; + // registerDrive() still posts the RAW mp (the agent operates on raw, the handler maps to stable). + if(!registered[regKey(d)]){ btns += ' '; } btns += '';