docs: REPORT.md for v0.51.0 (offsite-backup UI + double-nest fix)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,48 +1,43 @@
|
|||||||
# REPORT — felhom-controller: slice 10 (external user-data drives) — controller side
|
# REPORT — felhom-controller v0.51.0
|
||||||
|
|
||||||
**Version:** 0.50.0 · **Date:** 2026-06-12 · pairs with **felhom-agent v0.25.0–v0.27.0**
|
Offsite-backup UI (felhom-pbs = real DR) + Model-A double-nest fix. Pairs with felhom-agent v0.28.0
|
||||||
|
(whole-guest backup re-targeted to the offsite PBS tier). Live-deployed in guest 9201 on demo-felhom.
|
||||||
|
|
||||||
The controller's half of slice 10 (the agent owns the host-side execution + self-heal; see
|
## Backups page — whole-guest backup shown as real DR
|
||||||
felhom-agent's REPORT for P1 spike / P2 passthrough / P2 activation endpoint / P3 self-heal). All
|
- `backupTargetLabel` returns **"Biztonsági szerver – külön hardver (PBS)"** for a PBS-stored backup
|
||||||
live-validated on guest 9201; golden rebaked to 0.50.0.
|
(detected via `backupIsPBS` on the target id / archive volid), so the customer sees the backup
|
||||||
|
survives a host hardware failure.
|
||||||
|
- The app-data section's **"Távoli mentés"** card stops reading "nincs beállítva": new
|
||||||
|
`guestBackupView.Offsite` flag drives it to **"külön hardveren (PBS)"** with a ✓ when the whole-guest
|
||||||
|
backup landed on PBS.
|
||||||
|
- The restore-test "Visszaállítás ellenőrizve" trust signal is unchanged (already wired).
|
||||||
|
- Live: agent `/backup/status` reports `target_id=felhom-pbs`; `/restore-test/status` reports
|
||||||
|
`pass:true, verified:"boot+running", source_tier:"pbs"` → the page renders the PBS label, the offsite
|
||||||
|
card, and verified-restorable.
|
||||||
|
|
||||||
## P2C — enroll passes the drive into the guest (v0.48.0)
|
## Model-A double-nest fix
|
||||||
- `agentapi.GuestAttach(where)` → agent `POST /disks/guest-attach`. `runStorageInit` /
|
- Under slice-10 Model A the host agent binds `<drive>/felhom-data` onto the guest mountpoint, so an
|
||||||
`runStorageAttach` / `handleStorageRegister` call `attachIntoGuest` after recording the StoragePath
|
enrolled drive's in-guest mount IS the felhom-data namespace root (basename need not be `felhom-data`,
|
||||||
(best-effort; a transient failure is logged — P3 self-heal completes it). Closes Branch A: an enrolled
|
e.g. `/mnt/felhom-usb`). The backup path helpers were re-prepending `felhom-data`, producing
|
||||||
drive becomes usable in the guest (app `HDD_PATH` writes land on `/dev/sdb1`; the "nem elérhető"
|
`.../felhom-data/felhom-data/...` on the host (confirmed live: `/mnt/felhom-usb/felhom-data/felhom-data/...`).
|
||||||
banner clears).
|
- `appbackup` path helpers now take a **namespace ROOT** (no internal `felhom-data` join) plus a new
|
||||||
|
`NamespaceRoot(drivePath, inGuestDrive)`. `backup.Manager.namespaceRoot`/`AppNamespaceRoot` resolve
|
||||||
|
provenance (`drivePath != systemDataPath` ⟺ a registered in-guest drive → namespace root as-is; the
|
||||||
|
SSD-only `systemDataPath` fallback appends `felhom-data`).
|
||||||
|
- All parallel constructions updated coherently so writes, deletion (`GetStackBackupData`,
|
||||||
|
`RemoveStack` backups-base + `ProtectedHDDPaths` — legacy double-nest dirs KEPT protected), the
|
||||||
|
wipe-warning secondary scan, and export all agree. `api.router` passes the namespace root across the
|
||||||
|
package boundary. Result: a drive-resident app's DB-dump lands single-nested at `<drive>/backups/...`
|
||||||
|
in-guest = `<drive>/felhom-data/backups/...` on the host.
|
||||||
|
- New `appbackup` test asserts no doubled `felhom-data` segment for an in-guest drive and exactly one
|
||||||
|
for the system fallback. Full `go build ./...` + tests green.
|
||||||
|
|
||||||
## Activation-UX (v0.49.0)
|
## Decommission (P3) — NO controller change
|
||||||
- The host-side live inject is blocked on unprivileged LXC, so a drive enrolled into a *running* guest
|
- Permanent decommission is operator-signature-gated (never customer-confirmable), so it is wired
|
||||||
activates at the next guest boot. Per decision: enroll persists (no forced reboot) + a user-triggered
|
entirely agent-side (hub jobs-queue → signed-jobs runner). The controller deliberately exposes no
|
||||||
restart.
|
decommission UI. (felhom-agent v0.28.0.)
|
||||||
- `pendingActivationDrives()` flags registered drives the agent reports present+attached but which
|
|
||||||
aren't a live mount in the container. The settings page shows a banner + a batched **"Újraindítás
|
|
||||||
most (~30 mp)"** button → `POST /api/storage/activate` → `agentapi.GuestReboot` → agent
|
|
||||||
`POST /guest/reboot`. Live-validated: activate → guest reboots → drive active.
|
|
||||||
|
|
||||||
## P4 — dual-role drives + backup-aware wipe warning (v0.50.0)
|
## Live deploy
|
||||||
- **4A:** a user-data drive is appdata AND backup-target-eligible (not locked to one role) — surfaced
|
- `gitea.dooplex.hu/admin/felhom-controller:0.51.0` running + healthy in guest 9201 (bootstrap-launched
|
||||||
in the drive overview's per-card purpose note. `felhom-pbs`/system/backup roles unchanged.
|
via `/etc/felhom-controller-image`; prior 0.50.0). Startup clean (catalog sync, health ok,
|
||||||
- **4B:** `handleStorageImpact` now also returns `backup_copies` — apps whose cross-drive (secondary)
|
FileBrowser mounts synced).
|
||||||
backups are stored on the drive (`backupCopiesOnPath` scans `felhom-data/backups/secondary/<app>`,
|
|
||||||
skipping the shared restic repo / `_infra`). The type-to-confirm wipe/eject modal names them ("Ez a
|
|
||||||
meghajtó más alkalmazások biztonsági másolatait is tárolja — a törlés ezeket is eltávolítja"). The
|
|
||||||
wipe stays **customer-confirmable** (the copies are redundant; originals live on the source drive).
|
|
||||||
- **OUT OF SCOPE:** the cross-drive backup ENGINE (restic USB1↔USB2, scheduling, pruning) — a follow-on
|
|
||||||
slice (needs a 2nd physical drive to validate). The 4B detection is forward-compatible (empty until
|
|
||||||
the engine writes there).
|
|
||||||
|
|
||||||
## Live validation (9201)
|
|
||||||
- P2C: app bytes on `/dev/sdb1`, banner `[PASS] 1 connected, 0 disconnected`.
|
|
||||||
- Activation: `/api/storage/activate` → reboot → drive active.
|
|
||||||
- P4: `/api/storage/impact?where=/mnt/felhom-usb` → `backup_copies:[]`; after creating
|
|
||||||
`felhom-data/backups/secondary/immich` → `backup_copies:["immich"]` (detection live).
|
|
||||||
- `go test ./internal/{web,agentapi}/` green; golden rebaked to 0.50.0, build guest purged.
|
|
||||||
|
|
||||||
## Note (carried from P2)
|
|
||||||
The controller's app/backup path helpers still join `felhom-data` under the registered drive path; in
|
|
||||||
Model A the in-guest mount IS the felhom-data namespace, so backup paths double-nest
|
|
||||||
(`felhom-data/felhom-data/...`) — functional but untidy. Reconcile when wiring app-data-backup-to-drive
|
|
||||||
(not in this slice; app `HDD_PATH` data lands correctly today).
|
|
||||||
|
|||||||
Reference in New Issue
Block a user