agent v0.37.0: host-reboot remount re-resolves enrolled drives by fs-UUID

TASK A — close out the reboot story (agent half). Root cause (pinned live on
felhom-pve): an enrolled .mount unit left `disabled` by a prior detach never
auto-mounts at boot, and kernel re-enumeration can move a drive's node
(/dev/sdb->sdc). Fix re-asserts every enrolled mount by filesystem UUID at
startup + on the periodic tick.

- ResolveStorageDevice: resolve uuid:<fs-uuid> -> current /dev node via
  /dev/disk/by-uuid (never a cached node); errors if absent.
- parseFelhomMountUnit: pure inverse of renderMountUnit (marker-gated).
- (*SudoHostOps).ReassertEnrolledMounts: re-run EnsureMount (enable --now) for
  any enrolled unit not in /proc/mounts; idempotent, skips mounted/absent.
- main.go: runs before ReassertGuestBinds at startup + on the 20s tick.
- tests (Linux, seam=device resolution): letter-move tolerated (sdb->sdc) +
  red-proof companion, absent/scheme rejection, render->parse round-trip.

TASK A2 verdict: enrolling a NEW drive does NOT need an LXC restart — the path
lands on the live AttachDrive (shared parent, named live slots), not RebootGuest.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-16 17:49:00 +02:00
parent 437f096d9d
commit a621f4c5a0
8 changed files with 305 additions and 40 deletions
+7
View File
@@ -58,6 +58,13 @@ and no shell**; tests use a fake (no real root in the suite).
(`What=/dev/disk/by-uuid/<UUID>`, enabled so they survive reboot) — not raw fstab or a
transient `mount`. Benign re-mount is idempotent; **detach** (stop+disable) is destructive
and routes through the gate.
- **Host-reboot remount re-resolution (v0.37.0):** at startup (before binding drives into the
guest) and on the periodic tick, `ReassertEnrolledMounts` re-asserts every enrolled `.mount`
unit that isn't currently mounted: it re-resolves the drive's `uuid:<fs-uuid>` durable id to
its **current** `/dev` node by re-scanning `/dev/disk/by-uuid` (`ResolveStorageDevice`, never a
cached node) and re-runs the idempotent `enable --now`. This re-enables a unit a prior detach
left `disabled` AND tolerates kernel re-enumeration moving a drive's letter (`/dev/sdb``sdc`)
— the reshuffle is a no-op. Already-mounted drives and genuinely-absent UUIDs are skipped.
- **Every argument is validated before any command is constructed** (`validate.go`): UUIDs
against a strict hex regex, mount paths confined + traversal-checked, SMART devices
whitelisted to raw disks, LVM names charset-checked. The adversarial matrix in