docs(diagnosis): post-F9 storage-registration gap (read-only diagnosis, no fix)
HDD attached at the agent layer (F9 bind) but never entered the controller storage registry: enroll/register flows (runStorageInit/runStorageAttach/handleStorageRegister) are the only paths that call registerStoragePath, and F9 attached via the agent directly; AutoDiscoverStoragePaths is a one-time seed scanning only deployed-app HDD_PATHs. So the HDD is 'Nem regisztrált' + absent from the deploy dropdown (GetSchedulableStoragePaths). Verdict: F9 NOT closed. Fix direction: auto-register-on-attach + clearer manual register.
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
# DIAGNOSIS — post-F9 storage-registration gap (read-only; no system changes made)
|
||||
|
||||
**Date:** 2026-06-14. **Scope:** why the HDD (`felhom-usb`) is attached + written-to by RomM yet badged
|
||||
"Nem regisztrált" and absent from the deploy dropdown. **Method:** live SSH (read-only) + controller
|
||||
source. **No state changed** — no registration, deploy, restart, or edits. Diagnosis only; fix to be specced next.
|
||||
|
||||
## TL;DR
|
||||
F9 attached the HDD at the **agent/guest layer** (the `pct set -mpN` bind). The controller's **storage
|
||||
registry** (`settings.json → storage_paths`) is a **separate layer** that F9 never touched. The controller
|
||||
registers a drive only through its own enroll flows (`runStorageInit` / `runStorageAttach` /
|
||||
`handleStorageRegister`), each of which calls `registerStoragePath`. In the F9 session the drive was
|
||||
attached by calling the **agent's `/disks/guest-attach` directly** (and RomM got `HDD_PATH=/mnt/felhom-usb`
|
||||
via a manual `deploy` value) — both bypass the controller's registry. Auto-discovery can't backfill it
|
||||
(it's a one-time seed that only scans deployed-app `HDD_PATH`s, never the agent's attached-drive list).
|
||||
Result: attached + in use, but unregistered → not selectable for a new app. **F9 is NOT closed.**
|
||||
|
||||
## Q1 — Real storage topology (what each path maps to)
|
||||
| Name (UI) | Host path | Device | Size / free | What it is |
|
||||
|---|---|---|---|---|
|
||||
| `Tárhely (felhom-data)` ★ (registered) | `/mnt/sys_drive/felhom-data` | `/dev/mapper/pve-vm--9201--disk--0` | 32 G / **~29 G** | the **internal OS-disk volume** (rootfs disk-0). The "28.7 GB szabad" in the dropdown = this. |
|
||||
| `felhom-usb` (NOT registered) | `/mnt/felhom-usb` | `/dev/sdb1` | **916 G / 870 G** | the **HDD**, guest-attached (mp1), 2.1 MB used |
|
||||
|
||||
Evidence: `pct config 9201` → `mp1: /mnt/felhom-usb/felhom-data,mp=/mnt/felhom-usb`; guest `df` → `/mnt/sys_drive`
|
||||
on `…disk--0` (32 G, 29 G avail) vs `/mnt/felhom-usb` on `/dev/sdb1` (916 G, 870 G avail). The registry
|
||||
(`settings.json`) lists only `{"path":"/mnt/sys_drive/felhom-data","label":"Tárhely (felhom-data)","is_default":true,"added_at":"2026-06-13T22:22:50Z"}`.
|
||||
**Confirmed: the "28.7 GB" option is the internal volume, not the HDD.**
|
||||
|
||||
## Q2 — Where RomM's data is + how it got an HDD path
|
||||
- RomM's `app.yaml` (`/opt/docker/stacks/romm/app.yaml`): `env.HDD_PATH: /mnt/felhom-usb`, `deployed: true`,
|
||||
`locked_fields: [HDD_PATH]`. Its data dirs live under `/mnt/felhom-usb/felhom-data/appdata/romm/…` (the HDD).
|
||||
- **How it got set:** the `HDD_PATH` deploy field was filled with `/mnt/felhom-usb` when RomM was (re)deployed
|
||||
onto the HDD during the F9 P3/restore test. The deploy path validates `os.Stat(HDD_PATH)` exists
|
||||
(`stacks/deploy.go` path-field check) — it does, because F9 had bound `/mnt/felhom-usb` into the guest — but
|
||||
**the deploy does NOT register the path** in `storage_paths`. So RomM references the HDD path *directly*,
|
||||
entirely independent of the registry. That's how "RomM uses the HDD" coexists with "HDD unregistered."
|
||||
|
||||
## Q3 — Why `felhom-usb` is "Nem regisztrált"
|
||||
The registry (`settings.json storage_paths`) contains **only** `/mnt/sys_drive/felhom-data`; `/mnt/felhom-usb`
|
||||
is absent. Nothing registered it, at any layer:
|
||||
- **F9's attach is agent-layer only.** `ReassertGuestBinds` / `handleDiskGuestAttach` → `guestbind.go AttachBind`
|
||||
do `pct set -mpN` (the bind). They never call the controller's `registerStoragePath`. In the F9 session the
|
||||
drive was attached by calling the agent `/disks/guest-attach` **directly**, bypassing the controller enroll flow.
|
||||
- **Deploy doesn't register.** Setting `HDD_PATH` on RomM only validates existence (above), no registry write.
|
||||
- **Auto-discovery can't backfill it** — two reasons in `settings.AutoDiscoverStoragePaths` (`internal/settings/settings.go:584`):
|
||||
1. **One-time seed:** `if len(s.StoragePaths) > 0 { return // already configured }` (≈:592). The registry already
|
||||
holds `sys_drive` (seeded 2026-06-13), so discovery is now **permanently inert** on every restart.
|
||||
2. **Wrong source even if it ran:** it's fed by `discoverHDDPaths(StacksDir)` (`cmd/controller/main.go:1337`,
|
||||
called once at startup, `main.go:126`), which scans **deployed apps' `HDD_PATH`** — never the agent's
|
||||
`/disks` attached-drive list. A drive attached out-of-band (or whose app was deployed after startup) is invisible.
|
||||
|
||||
So: **registration is decoupled from attach; auto-discovery is a one-shot startup seed of app `HDD_PATH`s; the
|
||||
agent-layer F9 bind and the manual deploy both bypass registration** → the HDD stays unregistered.
|
||||
|
||||
## Q4 — Why the deploy dropdown excludes the HDD
|
||||
The deploy dropdown is populated from `s.settings.GetSchedulableStoragePaths()` (`internal/web/handlers.go:323`),
|
||||
i.e. **registered paths only**. `/mnt/felhom-usb` is not in the registry → not schedulable → absent. So a new
|
||||
app (Calibre) can only be pointed at `sys_drive` (the 31 G internal volume). The "Nem regisztrált" badge is the
|
||||
storage page (`storageWizardPageHandler`) merging the agent `/disks` (attached, `guest_attached=true`) against
|
||||
`GetStoragePaths()` (registry) and flagging the difference (`storage_handlers.go` `Registered` field;
|
||||
`settings.html` `window.__registeredPaths`).
|
||||
|
||||
## Q5 — Intended registration-vs-attach behavior (per the code)
|
||||
The controller's design intends **register + attach as one operator-driven enroll operation**, NOT an automatic
|
||||
side-effect of an agent bind:
|
||||
- `runStorageInit` (format a blank/new drive) and `runStorageAttach` (mount an existing-fs drive — the "Csatolás"
|
||||
button) both do: assign (host mount) → **`registerStoragePath`** → `attachIntoGuest`→`agent.GuestAttach`
|
||||
(`internal/web/storage_handlers.go:83-158`). The comment is explicit: *"the StoragePath **registration is the
|
||||
durable intent**, so a transient attach failure is logged (not fatal) — P3 self-heal completes it."*
|
||||
- For an **already-mounted, unregistered** drive (exactly `felhom-usb`'s state), there is a dedicated action:
|
||||
`POST /api/storage/register` → `handleStorageRegister` (`storage_handlers.go:442`, the "Regisztrálás" button),
|
||||
commented: *"the natural primary action for a mounted-but-unregistered data drive (e.g. **felhom-usb**): the
|
||||
customer's intent is to USE the existing data, not wipe it… registering a host-only mount otherwise leaves it
|
||||
guest-invisible (the exact gap that produced the 'nem elérhető' banner)."* It registers + attaches into the guest.
|
||||
|
||||
So per the code, registration is meant to come **through these controller flows**. There is **no reconciliation
|
||||
that auto-registers a drive the agent attached out-of-band** — which is precisely the F9 case (the agent's
|
||||
re-assert / a direct guest-attach binds the drive without ever invoking the controller's register step).
|
||||
|
||||
## Q6 — The "felhom-data" naming collision
|
||||
Deliberate convention, but genuinely confusing. `felhom-data` is BOTH:
|
||||
1. the **path tail of the internal volume's registered path** (`/mnt/sys_drive/felhom-data`), surfaced as the
|
||||
label `Tárhely (felhom-data)`, and
|
||||
2. the **per-drive Felhom namespace subdirectory** created on EVERY user-data drive by the agent's `AttachBind`
|
||||
(`guestbind.go:29 felhomDataNS = "felhom-data"`, "matches `appbackup.FelhomDataDir`") — hence `/mnt/felhom-usb/felhom-data/…`.
|
||||
So `felhom-data` denotes both a specific volume and the generic namespace. Risk: the label `Tárhely (felhom-data)`
|
||||
reads as generic but is specifically the OS-disk volume; meanwhile the HDD also has a `felhom-data` dir. A clearer
|
||||
label (e.g. "Belső SSD" for the internal volume vs the drive's own name for the HDD) would remove the ambiguity.
|
||||
|
||||
## Recommended fix direction (to spec next — NOT implemented here)
|
||||
1. **Auto-register on attach (primary).** Make a drive the agent has attached into the guest become a registered
|
||||
storage path automatically, so F9's attach is usable end-to-end. Options: (a) the controller's startup/periodic
|
||||
storage reconcile consults the **agent `/disks`** and registers any `guest_attached=true` user-data drive missing
|
||||
from the registry (extend beyond the app-`HDD_PATH` scan); and/or (b) the enroll/re-assert path that binds a
|
||||
drive also performs `registerStoragePath`. Also **remove the one-time-seed gate** (or make discovery additive,
|
||||
not "return if any path exists") so it can pick up drives added after the first run.
|
||||
2. **Keep `handleStorageRegister` as the explicit fallback** ("Regisztrálás" button) for the mounted-but-unregistered
|
||||
case, and make the "Nem regisztrált" badge clearly actionable. For the **immediate** demo state, this button
|
||||
(`POST /api/storage/register {where:/mnt/felhom-usb}`) would register felhom-usb + make it selectable — no fix needed to recover now.
|
||||
3. **Clarify the `felhom-data` label** (Q6) to disambiguate the internal volume from the per-drive namespace.
|
||||
Recommended: **both** auto-register-on-attach AND the clearer manual path — auto so the normal flow "just works",
|
||||
manual for out-of-band/edge cases.
|
||||
|
||||
## Verdict on F9 — NOT closed
|
||||
F9 made the HDD present + writable **inside the guest** (agent layer), but did not make it **usable for new apps
|
||||
through the UI** (controller registry layer). The deploy dropdown is gated on the registry; the registry is
|
||||
unaware of the agent-attached drive. **F9 should remain open (or spawn an F9b)** until: attach ⇒ auto-registered
|
||||
⇒ a NEW app (e.g. Calibre) can be deployed to the HDD through the normal deploy UI with its data landing on
|
||||
`/dev/sdb1` persistently. Today that round-trip fails at the dropdown.
|
||||
Reference in New Issue
Block a user