Impl-2b: resolve a raw candidate's fs-UUID via /disks/candidates (enroll fix)
runStorageInit/runStorageAttach resolved the fs UUID only via agent.Disks(),
which does NOT include a raw (unenrolled, non-PVE-storage) device — so a raw
candidate could be offered but never enrolled ("no fs identifier"). New
resolveEnrollUUID falls back to the raw-device scan (/disks/candidates), which
reports each free disk's durable_id (uuid:<fs-uuid>). Both enroll paths use it;
legacy re-attach (drive in /disks) still works. Test + red-proof.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,7 @@ import (
|
||||
// without a live agent). *agentapi.Client satisfies it.
|
||||
type diskAgent interface {
|
||||
Disks(ctx context.Context) (agentapi.DisksResponse, error)
|
||||
ListCandidates(ctx context.Context) (agentapi.CandidatesResult, error)
|
||||
FormatDisk(ctx context.Context, device, fstype string, confirmed bool, durableID string) (agentapi.FormatResult, error)
|
||||
AssignDisk(ctx context.Context, uuid, where, fstype, options string) error
|
||||
EjectDisk(ctx context.Context, where string) (agentapi.EjectResult, error)
|
||||
@@ -63,6 +64,31 @@ func fsUUIDForDevice(disks agentapi.DisksResponse, device string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// resolveEnrollUUID resolves a device's filesystem UUID for enrollment. A RAW candidate (Impl-2b) is
|
||||
// NOT in the /disks list (it has no PVE storage / isn't enrolled), so fsUUIDForDevice can't see it —
|
||||
// fall back to the raw-device scan (/disks/candidates), which reports each free disk's durable_id
|
||||
// (uuid:<fs-uuid>). Matches the whole disk OR its FS-bearing node (mount_source, e.g. /dev/sdd1).
|
||||
// Returns "" only if the device truly has no resolvable fs UUID.
|
||||
func resolveEnrollUUID(ctx context.Context, agent diskAgent, device string) string {
|
||||
if disks, err := agent.Disks(ctx); err == nil {
|
||||
if u := fsUUIDForDevice(disks, device); u != "" {
|
||||
return u
|
||||
}
|
||||
}
|
||||
cands, err := agent.ListCandidates(ctx)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
for _, c := range append(append([]agentapi.DiskCandidate{}, cands.Initialize...), cands.Attach...) {
|
||||
if c.Device == device || c.MountSource == device {
|
||||
if rest, ok := strings.CutPrefix(c.DurableID, "uuid:"); ok {
|
||||
return rest
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// storageInitResult is the outcome of an init attempt (JSON-rendered to the wizard).
|
||||
type storageInitResult struct {
|
||||
Registered bool `json:"registered"`
|
||||
@@ -107,12 +133,9 @@ func (s *Server) runStorageInit(ctx context.Context, agent diskAgent, device, fs
|
||||
if !fr.Formatted {
|
||||
return storageInitResult{}, fmt.Errorf("az eszköz nem lett megformázva (%s)", fr.Reason)
|
||||
}
|
||||
// 2. Resolve the NEW fs UUID (re-list disks; the device's storage now carries a fresh UUID).
|
||||
disks, err := agent.Disks(ctx)
|
||||
if err != nil {
|
||||
return storageInitResult{}, fmt.Errorf("formázás kész, de a meghajtólista nem olvasható: %w", err)
|
||||
}
|
||||
uuid := fsUUIDForDevice(disks, device)
|
||||
// 2. Resolve the NEW fs UUID. A freshly-formatted RAW device isn't in /disks (not enrolled yet), so
|
||||
// resolve via the raw-device scan too (Impl-2b) — the device now appears there with its new durable_id.
|
||||
uuid := resolveEnrollUUID(ctx, agent, device)
|
||||
if uuid == "" {
|
||||
return storageInitResult{}, fmt.Errorf("formázás kész, de az új fájlrendszer-azonosító nem feloldható — frissítsen és használja a Csatolás funkciót")
|
||||
}
|
||||
@@ -145,11 +168,9 @@ func (s *Server) attachIntoGuest(ctx context.Context, agent diskAgent, where str
|
||||
// runStorageAttach mounts an existing-filesystem device (non-destructive — never touches the gate)
|
||||
// and registers it. The UUID is resolved server-side from the device.
|
||||
func (s *Server) runStorageAttach(ctx context.Context, agent diskAgent, device, fstype, where, label string, setDefault bool) (storageInitResult, error) {
|
||||
disks, err := agent.Disks(ctx)
|
||||
if err != nil {
|
||||
return storageInitResult{}, fmt.Errorf("a meghajtólista nem olvasható: %w", err)
|
||||
}
|
||||
uuid := fsUUIDForDevice(disks, device)
|
||||
// Resolve the fs UUID. Works for a legacy re-attach (drive in /disks) AND a raw candidate (Impl-2b:
|
||||
// not in /disks — resolved via the raw-device scan's durable_id).
|
||||
uuid := resolveEnrollUUID(ctx, agent, device)
|
||||
if uuid == "" {
|
||||
return storageInitResult{}, fmt.Errorf("a kiválasztott meghajtóhoz nem található fájlrendszer-azonosító (csak fájlrendszerrel rendelkező meghajtó csatolható)")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user