v0.95.0: enrollment wizards use the raw-device scan /disks/candidates (Impl-2b)
Both wizards now source candidates from the agent's Impl-2a raw-device scan (GET /disks/candidates, proxied) instead of the Observe-based /api/disks — so a brand-new non-PVE-storage drive is finally discoverable + enrollable end-to-end. agentapi.ListCandidates + a passthrough proxy (no controller-side filtering; the agent's unclaimed filter is authoritative). storage_init renders `initialize`, storage_attach renders `attach`; the enroll flow + Impl-1 guarded mkfs unchanged. Tests + go build/vet/test clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -28,6 +28,8 @@ func (s *Server) ServeDiskAPI(w http.ResponseWriter, r *http.Request) {
|
||||
switch {
|
||||
case r.URL.Path == "/api/disks" && r.Method == http.MethodGet:
|
||||
s.agentDisksListHandler(w, r)
|
||||
case r.URL.Path == "/api/disks/candidates" && r.Method == http.MethodGet:
|
||||
s.agentDiskCandidatesHandler(w, r)
|
||||
case r.URL.Path == "/api/disks/assign" && r.Method == http.MethodPost:
|
||||
s.agentDiskAssignHandler(w, r)
|
||||
case r.URL.Path == "/api/disks/eject" && r.Method == http.MethodPost:
|
||||
@@ -110,6 +112,25 @@ func (s *Server) agentDisksListHandler(w http.ResponseWriter, r *http.Request) {
|
||||
writeDiskJSON(w, http.StatusOK, true, "", resp)
|
||||
}
|
||||
|
||||
// agentDiskCandidatesHandler proxies GET /api/disks/candidates → agent GET /disks/candidates (Impl-2b):
|
||||
// the raw-device scan (Impl-2a) that feeds the enrollment wizards. The agent's unclaimed-disk filter
|
||||
// already excludes claimed/OS/enrolled disks (fail-safe), so the controller passes the list through
|
||||
// untouched — no controller-side filtering.
|
||||
func (s *Server) agentDiskCandidatesHandler(w http.ResponseWriter, r *http.Request) {
|
||||
client, err := s.agentClient()
|
||||
if err != nil {
|
||||
writeDiskJSON(w, http.StatusServiceUnavailable, false, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
resp, err := client.ListCandidates(r.Context())
|
||||
if err != nil {
|
||||
s.logger.Printf("[ERROR] [web] disk candidates via agent failed: %v", err)
|
||||
writeDiskJSON(w, http.StatusBadGateway, false, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
writeDiskJSON(w, http.StatusOK, true, "", resp)
|
||||
}
|
||||
|
||||
// sortDisksForView orders the agent's disk list deterministically (user-data → system → backup →
|
||||
// unrecognized; alphabetical by storage name within each tier). A stable Go-side contract beats
|
||||
// relying on map iteration order or template JS alone.
|
||||
|
||||
Reference in New Issue
Block a user