docs: REPORT + README — storage lifecycle + acceptance sweep (controller half)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,42 +1,39 @@
|
|||||||
# REPORT — intermediary-mount re-architecture (controller half) → v0.67.5 (2026-06-15)
|
# REPORT — storage lifecycle completion + acceptance sweep (controller half) → v0.68.1 (2026-06-15)
|
||||||
|
|
||||||
## Type
|
## Type
|
||||||
Controller half of the intermediary-mount re-architecture (pairs with agent v0.35.1 + catalog repoint).
|
Finished the storage lifecycle on the intermediary-mount model + drove a full live acceptance sweep
|
||||||
Built + Linux-gated (`go vet`/`go test ./...` green) + deployed to demo guest 9201, which was then
|
(incl. a real host reboot). Built + Linux-gated + deployed to guest 9201 per commit. Pairs with agent
|
||||||
migrated live. Drives are now visible in-guest ONLY at the STABLE path `/mnt/felhom-drives/<name>` (the
|
v0.36.7. Full audit: `felhom.eu/documentation/audits/storage-lifecycle-acceptance-2026-06-15.md`.
|
||||||
host swaps the backing drive underneath it — no per-drive `pct` mp, no guest reboot for attach/detach).
|
|
||||||
Design: `felhom.eu/documentation/audits/SPIKE-intermediary-mount-2026-06-15.md`.
|
|
||||||
|
|
||||||
## What changed (internal/web/intermediary.go + storage_handlers.go + api/router.go + settings.go)
|
## What changed (controller)
|
||||||
- **HDD_PATH repoint.** The registered storage path + every app's HDD_PATH + FileBrowser source are now
|
- **v0.68.0** — H2/H3/M1/M3 + deterministic boot-id:
|
||||||
the stable `/mnt/felhom-drives/<name>`; the AGENT still operates on the raw `/mnt/<name>` (mapped via
|
- **Boot-id determinism** (`processGuestBootChange` + `settings.LastGuestBootID`): the agent reports
|
||||||
`agentWhere()` at the assign/attach/eject/decommission call sites). Enroll binds-under-the-parent
|
`guest_boot_id`; on change the controller recreates drive-backed apps deterministically (replaces the
|
||||||
BEFORE register (the controller only sees the drive at the stable path post-attach). New
|
fragile container-uptime sample, which missed apps stopped at the sample instant).
|
||||||
`settings.RepointStoragePath`; `agentapi.DiskInfo` gains `GuestPath`/`BoundUnderParent`.
|
- **H2** decommission UI button (migrate / decommission-anyway type-to-confirm); **H3** one-click
|
||||||
- **Drive-absent GATE** (`planDriveGates` pure core + `driveGateLoop` 30s, replacing the retired
|
re-enroll of a decommissioned drive (`handleStorageReconnect` decommissioned branch); **M1**
|
||||||
watchdog). An ABSENT external drive (only `/mnt/felhom-drives/<name>` paths — never SSD/system) stops +
|
`defaultPromotionTarget` (auto-promote on decommission-of-default, BLOCK if it's the only drive);
|
||||||
blocks its apps (`StoppedStacks` = gate-stopped set); a RETURNED drive re-attaches + auto-restarts
|
**M3** migrate merge-walk re-asserts 2775 setgid on userdata dirs (`isUserdataDir`).
|
||||||
them. `present` keys on `BoundUnderParent` (guest-usable), not host-mount. Start-gate in `actionStack`
|
- Fixed the H1 `{path}`/`{where}` JS body mismatch.
|
||||||
refuses to start an app whose drive is absent.
|
- **v0.68.1** — boot-id recreate ALL deployed drive-backed present apps **state-independent** (v0.68.0
|
||||||
- **Guest-reboot convergence** (`recreateBootStaleApps`, one-time at startup after a bounded stack-scan
|
filtered on container state and **missed 5 apps** docker hadn't auto-restarted yet — caught in the live
|
||||||
wait): docker auto-starts app containers on a guest reboot possibly before the agent re-propagates the
|
host-reboot test).
|
||||||
drive, so they bind the empty stable dir; the controller (which restarts with the guest) recreates
|
|
||||||
present drive-backed apps that are boot-stale/exited/restarting onto the populated path.
|
|
||||||
- **H1 endpoints routed** (were 404): `POST /api/storage/{disconnect,reconnect,restart-apps}` → host-side
|
|
||||||
eject/reconnect (no guest reboot).
|
|
||||||
|
|
||||||
Version path v0.67.0 → .5 (`.1` gate-only-externals, `.2` BoundUnderParent, `.3`/`.4`/`.5` startup
|
Non-hollow tests + companions: `TestShouldRecreateOnBoot` (old sample missed a stale/stopped app),
|
||||||
recreate hardening). Non-hollow tests + companions: `TestPlanDriveGates` (5 states incl. SSD-never-gated),
|
`TestDefaultPromotionTarget`, `TestIsUserdataDir`.
|
||||||
`TestAgentWhere`, `TestRunStorageInit_Success` (agent gets RAW, registry gets STABLE).
|
|
||||||
|
|
||||||
## Live migration (guest 9201) + verification
|
## Acceptance sweep (live) — per-item PASS in the audit doc
|
||||||
8 deployed apps (all on felhom-flash) repointed (app.yaml HDD_PATH rewrite + controller-driven
|
HOST REBOOT (✅ ordering + auto-start + convergence, no manual intervention), guest reboot ×3, drive-yank
|
||||||
down/up recreate, which decrypts the `ENC:` secrets) + registry repointed + FileBrowser re-synced + the
|
fail-close (no leak), capability-proof fail-close, confinement, controller redeploy (rslave explicit),
|
||||||
legacy `mp2` deleted. **A guest reboot self-converges**: the startup recreate logged + rebound the
|
two-drive isolation, **H2 decommission**, **H3 re-enroll** (after the agent v0.36.1 raw-stays-mounted
|
||||||
drive-backed apps onto `/mnt/felhom-drives/felhom-flash` with no manual intervention. End state: **25
|
fix), **M1 default reassignment**, rapid eject/reconnect (single bind after the agent double-bind
|
||||||
containers healthy** (komga healthcheck pre-existing quirk), confinement + data integrity verified.
|
root-cause fix). E14/E15 migrate-all not re-run live (M3 unit-tested + 2775 convention verified live).
|
||||||
|
|
||||||
## Known residuals (documented)
|
## End state
|
||||||
- Startup recreate is state-sampled; an app cleanly stopped at the exact sample instant may need one
|
Both external drives registered at `/mnt/felhom-drives/<name>`, felhom-flash default, 25 containers
|
||||||
manual start (1/8 once). Deterministic fix = a guest-boot-id signal from the agent (future).
|
healthy. controller v0.68.1 deployed (golden/bootstrap image tag mechanism).
|
||||||
- felhom-usb left on its legacy bind (no deployed apps + stale `decommissioned` intent).
|
|
||||||
|
## Known residuals
|
||||||
|
- Boot-id first-sight bounce (fresh controller recreates apps once on first start — one-time per
|
||||||
|
data-volume lifetime).
|
||||||
|
- E14/E15 full migrate-all round-trip not re-run live (data-merge risk; M3 unit-tested).
|
||||||
|
|||||||
+10
-2
@@ -636,8 +636,16 @@ not just those with HDD data. Non-HDD apps can configure destination, method, an
|
|||||||
> a returned drive re-attaches + auto-restarts them; `actionStack` refuses to start an app whose drive
|
> a returned drive re-attaches + auto-restarts them; `actionStack` refuses to start an app whose drive
|
||||||
> is absent ("tárhely nem elérhető"). SSD/system paths are never gated.
|
> is absent ("tárhely nem elérhető"). SSD/system paths are never gated.
|
||||||
> - **H1 endpoints** `POST /api/storage/{disconnect,reconnect,restart-apps}` drive the host-side
|
> - **H1 endpoints** `POST /api/storage/{disconnect,reconnect,restart-apps}` drive the host-side
|
||||||
> eject/reconnect (no guest reboot). A guest reboot self-converges (`recreateBootStaleApps` recreates
|
> eject/reconnect (no guest reboot).
|
||||||
> boot-stale drive-backed apps onto the re-propagated drive once the agent re-binds it).
|
> - **Lifecycle (v0.68.x):** a "Leszerelés" button decommissions a drive (migrate-then-decommission OR
|
||||||
|
> decommission-anyway type-to-confirm — non-destructive, never touches the parent mp); a
|
||||||
|
> "Visszacsatlakoztatás" button one-click re-enrolls a decommissioned/ejected drive (clears the marker,
|
||||||
|
> re-binds under the parent, restarts gate-stopped apps). Decommissioning the DEFAULT auto-promotes
|
||||||
|
> another schedulable drive (`defaultPromotionTarget`), or BLOCKS if it's the only one. Eject and
|
||||||
|
> decommission keep the RAW drive mounted (logical retire) so re-enroll re-binds it.
|
||||||
|
> - **Guest-reboot convergence is DETERMINISTIC** via the agent's `guest_boot_id`: the controller persists
|
||||||
|
> `LastGuestBootID` and, when it changes, recreates EVERY deployed drive-backed app onto the
|
||||||
|
> re-propagated drive (`processGuestBootChange` — no fragile container-uptime sampling).
|
||||||
>
|
>
|
||||||
> **⚠️ Rebuilt on the agent-delegated disk model (v0.43.0), made ROLE-AWARE in v0.44.0, UX-polished in
|
> **⚠️ Rebuilt on the agent-delegated disk model (v0.43.0), made ROLE-AWARE in v0.44.0, UX-polished in
|
||||||
> v0.45.0.** After the 8C
|
> v0.45.0.** After the 8C
|
||||||
|
|||||||
Reference in New Issue
Block a user