agent v0.37.0: re-assert mounted-but-DISABLED units (live felhom-usb fix)

The skip-if-mounted optimization defeated the actual root cause: felhom-usb is
mounted now but its unit is `disabled`, so a host reboot would not auto-mount
it. ReassertEnrolledMounts now skips ONLY the durable steady state (mounted AND
enabled) via the pure shouldReassertMount; a mounted-but-disabled unit is
re-asserted so enable --now re-creates the wants-symlink. Enabled-state read by
privilege-free Lstat of the multi-user.target.wants symlink (unitEnabled) — no
systemctl is-enabled subprocess, no new sudoers entry.

Tests: TestShouldReassertMount (4 combos), TestUnitEnabled (wants-symlink).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-16 17:55:48 +02:00
parent a621f4c5a0
commit 3e39dbb4f8
4 changed files with 96 additions and 12 deletions
+10 -4
View File
@@ -28,10 +28,13 @@ rewrite the unit.
errors when the UUID is absent so a caller skips a gone drive instead of fail-mounting.
- `storage.parseFelhomMountUnit` (`mountunit.go`) — pure inverse of `renderMountUnit`, gated on a
`Managed by felhom-agent` marker; extracts Name/UUID/Where/Type/Options, ignores foreign units.
- `(*SudoHostOps).ReassertEnrolledMounts(ctx)` (`hostops.go`) — for each enrolled `.mount` unit
not in `/proc/mounts`, re-resolve by UUID and re-run `EnsureMount` (idempotent
`systemctl enable --now`). Re-enables a disabled unit AND mounts the current device by UUID;
already-mounted drives skipped (no daemon-reload churn), absent UUIDs skipped (retry next tick).
- `(*SudoHostOps).ReassertEnrolledMounts(ctx)` (`hostops.go`) — for each enrolled `.mount` unit,
re-resolve by UUID and re-run `EnsureMount` (idempotent `systemctl enable --now`). Skips ONLY the
durable steady state (mounted AND enabled), via the pure `shouldReassertMount`; a
**mounted-but-DISABLED** unit (the exact live felhom-usb state — serves now, but a reboot would not
auto-mount it) is still re-asserted so the wants-symlink is re-created. Enabled-state read with a
privilege-free `os.Lstat` of the `multi-user.target.wants` symlink (`unitEnabled`) — no
`systemctl is-enabled` subprocess / no new sudoers entry. Absent UUIDs skipped (retry next tick).
- `main.go` — runs `ReassertEnrolledMounts` at startup **before** `ReassertGuestBinds`, and again
ahead of the bind re-assert on the periodic 20s tick, so host mounts are live before the guest
binds re-establish.
@@ -46,6 +49,9 @@ rewrite the unit.
(`/dev/sdb1`, `store:`, `byid:`, `""` all rejected).
- `TestParseFelhomMountUnit``renderMountUnit``parseFelhomMountUnit` round-trip + rejects a
non-felhom unit.
- `TestShouldReassertMount` — the four mounted/enabled combinations; pins that mounted-but-disabled
(the live bug) re-asserts and only mounted+enabled is skipped.
- `TestUnitEnabled` — wants-symlink presence ⇒ enabled (privilege-free `Lstat`).
## Task A2 — verdict: enrolling a NEW drive does NOT need an LXC restart