netstorage: verify-before-commit orchestration — agentapi verify fields, uid-1000 re-exec probe, detached add job, orphan rows

Controller half of the verify pipeline (SPIKE-nas-verify b57f6c1): AddNetStorage
gains verify/job fields + typed NetAddRefusedError; NetVerifyStatus polls the
agent slot; --netprobe hidden re-exec mode (SysProcAttr.Credential uid/gid 1000,
no shell) proves in-guest writability; the add handler starts a detached
single-flight job (agent_add → verifying → probing → registering LAST) with full
rollback on any failure incl. verify-lost-after-restart (Scenario F); §3.2
Hungarian error map server-side; live-but-unregistered shares surface as remove-
only 'Árva megosztás' rows.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
2026-07-11 09:59:33 +02:00
parent 3db9126121
commit bb8737a81f
10 changed files with 962 additions and 46 deletions
@@ -288,8 +288,11 @@ func (s *Server) ServeStorageAPI(w http.ResponseWriter, r *http.Request) {
case r.URL.Path == "/api/storage/decommission" && r.Method == http.MethodPost:
s.handleStorageDecommission(w, r)
// NAS network storage (Part A2) — distinct from the drive lifecycle above (proxy to agent /netstorage/*).
// Add is verify-before-commit: it starts a detached orchestration job the UI polls on add/status.
case r.URL.Path == "/api/storage/netstorage/add" && r.Method == http.MethodPost:
s.handleNetStorageAdd(w, r)
case r.URL.Path == "/api/storage/netstorage/add/status" && r.Method == http.MethodGet:
s.handleNetStorageAddStatus(w, r)
case r.URL.Path == "/api/storage/netstorage" && r.Method == http.MethodGet:
s.handleNetStorageList(w, r)
case r.URL.Path == "/api/storage/netstorage/remove" && r.Method == http.MethodPost: