Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4.2 KiB
REPORT — raw-drive first-class support (agent v0.55.0 → v0.58.0)
Date: 2026-07-01 · Repo: felhom-agent · Class: Risky/supervised (drive health/enroll path).
Surfaced by the first live raw-drive enrollment (controller Impl-2b): the agent's enroll + tracking
machinery assumed every drive is a PVE storage (visible in Observe()). A raw (non-PVE-storage) drive
enrolled via the new wizard was therefore mounted+bound but not intent-tracked, not health-tracked, and
shown "disconnected". This slice makes raw drives first-class end-to-end.
1. Baseline → target
felhom-agent 91f6a26 (v0.55.0, Impl-2a) → v0.58.0. Companion: controller v0.95.0 (Impl-2b).
2. Changes (all internal/localapi/disks.go + wiring), newest first
- v0.58.0 — the
/disksregistry-union row (Impl-2a) now reportsGuestPath(StablePathForRaw) +BoundUnderParent(boundUnderParent), like the Observe path — a registry-only drive read as "Leválasztva" despite being bound live. Commit3825664. - v0.57.0 —
ReassertGuestBindsbuilds its durable-id→mount map fromObserve()only → a raw drive's guest-bind was never re-asserted (post-reboot/re-mount). Augment from the mount table (raw/mnt/<name>→ device fs-UUID viaHostReader, skipping the/mnt/felhom-drivesbind); Observe failure no longer aborts. Plus a latent wiring fix:buildLocalAPIServernever passedOptions.HostReader, sos.hostwas nil in production — the v0.56.0 fallback + the role gate's host classification silently no-op'd; now wired toNewProcHostReader(). Commits67e2144+6448b80. - v0.56.0 —
durableIDForMountwasObserve()-only, so a raw drive's enroll/eject intent + guest-bind went unrecorded ("durable-id unresolved"). Fall back to resolving the mount's device fs-UUID (HostReader.Mounts+ResolveUUID) →uuid:<fs-uuid>(same scheme as Observe). Commite593fb2.
3. Green gate + tests
go build ./..., go vet ./..., go test ./... — clean at each version. New tests:
TestDurableIDForMount_RawFallback (+ red-proof: Observe-only → ""). The ReassertGuestBinds +
/disks-row changes are covered by the live end-to-end (§5).
4. Published + deployed
Gitea felhom-agent/0.58.0 (sha 5ea7f63bb1617fa8412c1977b57369cd184bc1d6c1e6d6cf4f723835ebc06078);
deployed to felhom-pve (backup .bak-0.57.0), active. (0.56/0.57 also published; rollback binaries kept.)
5. Live validation (felhom-pve + the real controller UI)
The raw /dev/sdd SD card, enrolled via the wizard (controller Impl-2b), ends up fully first-class:
| Property | Evidence |
|---|---|
| Mounted + bound | /mnt/teszt_enroll (raw) + /mnt/felhom-drives/teszt_enroll (bind) live. |
| Intent recorded | drive-intents.json → uuid:f2236136… = enrolled; journal drive intent recorded … durable_id=uuid:f2236136… (no "unresolved" — the v0.56.0 fallback fired once HostReader was wired). |
| Guest-bind recorded | guest-binds.json → 9201: […, uuid:f2236136…]; journal guest-bind recorded. |
| Health-tracked | watchdog (RegistryKnownTargets) detected a drop + self-healed (re-mounted). |
/disks status |
row reports state=attached, guest_path=/mnt/felhom-drives/teszt_enroll, bound_under_parent=true. |
| Controller UI | shows "Aktív" (USB), alongside felhom-usb + felhom-flash — all Active, no false detach. |
6. NOT done / follow-ups
- The raw drive's
.mountunit is named by its UUID (assign setsMountSpec.Name = uuid), so the agent-view Name is the UUID; the controller shows its own label ("teszt_enroll"). Cosmetic. - Init slow-format completion is a controller concern (
runStorageInitshould poll/disks/format/status) — see controller REPORT. - Impl-3 — shared-box operator gate for self-serve format.
7. Observations
- Root theme: making a drive first-class without a PVE storage touches every seam that keyed off
Observe()— candidates (Impl-2a), watchdog Known (Impl-2a), UUID resolution, intent + guest-bind recording, guest-bind re-assert, and the/disksstatus row. All now resolve raw mounts viaHostReader(mount table + by-uuid), consistent with theuuid:<fs-uuid>scheme Observe derives.