Files
felhom-agent/REPORT.md
T

4.1 KiB
Raw Blame History

REPORT — agent v0.81.0: NAS verify-before-commit (retry=0 + classifier + detached verify job) — DEPLOYED

Date: 2026-07-11 · Class: implementation (agent half of the cross-repo "NAS verify-before-commit + page redesign" task). Baseline v0.80.0 (300f06722b) → v0.81.0 (added9d), live on felhom-pve. Pairs with controller v0.113.0 + host-install v1.13.0. Full task-wide record (red-proof outcomes, live AE transcripts, teardown): felhom-controller/REPORT.md. Evidence base: SPIKE-nas-verify-2026-07-11 (b57f6c1).

What shipped (agent)

  • retry=0 in the production NFS option string (netmount.go mountOptions, Q4-vi): a dead-NAS on-demand access fails clean in ~3.8 s (ENODEV) instead of a 91 s wedge; verify failures classify as No route to host instead of a diagnostic-free systemd timeout. SMB unchanged (mount.cifs rejects retry=). Installed units are NOT rewritten (none existed on the demo anyway).
  • internal/storage/netverify.goClassifyNetVerifyFailure(journalTail, tcpReachable): pure, first-match table on the Q4 VERBATIM substrings → unreachable | nfs_export | smb_auth | smb_share | timeout | mount_failed; nfs_export deliberately merges not-found/not-permitted (NFSv4 identical strings). String-based BY DESIGN — every mount failure exits rc=32.
  • Detached verify job (localapi/netverifyjob.go, formatjob shape but IN-MEMORY single slot — a restart empties the slot; GET /netstorage/verify-status phase none is the CONTROLLER's rollback signal, Scenario F): add = decode → role-gate → sync fast-fail (full spec validation
    • 2 s TCP pre-probe; unreachable = HTTP 502 {code:unreachable}, NOTHING installed) → SMB creds (0600) → EnsureNetworkMount → detached verify: trigger read through the automount, success judged from /proc/mounts ONLY (§8: EACCES on a 0700 export is a GOOD mount), failure = journal classification + auto-rollback (RemoveNetworkMount + creds). Single-flight: second add = 409.
  • Unprivileged journal read (journalctl -u <unit> -n 20 -o cat, NO sudo, NO new sudoers grant): needs the systemd-journal group (host-install v1.13.0; existing hosts: usermod -aG systemd-journal felhom-agent). Unavailable ⇒ degrade to mount_failed + hint, still rolled back.
  • New exports: storage.NetworkMountedAt, storage.NetworkEndpointReachable. REUSE.md updated (helpers + the in-memory-vs-persisted job pattern row + the four Server net-verify seams).

Tests + red-proofs (agent side; outcomes verbatim in felhom-controller/REPORT.md)

A1 retry=0 (revert → fail) · A2 classifier table incl. merged nfs_export + empty-journal degradation (exit-code mutant → every non-generic row fails) · A3 rollback effects via fakes (drop rollback → removed=[] + creds linger) · A4 §8 truth table (readability mutant → both rows fail) · A5 pre-probe zero-install (skip probe → 200-with-install) · A6 single-flight + no-job shape (drop check → 409 lost). Green gate go build && go vet && go test ./... PASS (known TestGenerateRecoveryCode wordlist flake hit once, clean on re-run).

Deployed + verified (felhom-pve)

.bak-0.80.0 kept → install -m0755usermod -aG systemd-journal felhom-agentsystemctl restart felhom-agent. Verified: felhom-agent 0.81.0; id felhom-agent…,999(systemd-journal); clean start journal (enrolled drive re-bound, local-api listening, desired-state gen 10). Live proof the journal path works: Scenario A's failure detail carried the REAL mount.nfs4 … reason given by server: No such file or directory lines read unprivileged.

NOT published: 0.81.0 is deployed on the demo only — no Gitea publish, Day-0 manifest untouched (the publish train is the operator's separate decision); Peti's box untouched.

Observations

  • Pre-existing (2026-07-08, unrelated): lanresolver: cannot list provisioned guests: permission denied/var/lib/felhom-agent/guests is root-0700 under the non-root agent.
  • RemoveNetworkMount leaves the empty mountpoint dir + a not-found failed residual unit listing (until reset-failed/reboot) — cosmetic, documented in the task report.