This commit is contained in:
@@ -80,6 +80,9 @@ func (s *Service) execCommand(name string, args ...string) (string, error) {
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil && useSudo {
|
||||
// Log that sudo failed
|
||||
log.Printf("sudo command failed, trying direct execution: %s %v (error: %v, stderr: %s)", name, args, err, stderr.String())
|
||||
|
||||
// If sudo failed, try running the command directly
|
||||
// (user might already have permissions or be root)
|
||||
directCmd := exec.Command(name, args...)
|
||||
@@ -89,13 +92,17 @@ func (s *Service) execCommand(name string, args ...string) (string, error) {
|
||||
|
||||
if directErr := directCmd.Run(); directErr == nil {
|
||||
// Direct execution succeeded, return that result
|
||||
log.Printf("direct command execution succeeded (without sudo)")
|
||||
return strings.TrimSpace(directStdout.String()), nil
|
||||
}
|
||||
// Both sudo and direct failed, return the original sudo error
|
||||
return "", fmt.Errorf("%s: %v: %s", name, err, stderr.String())
|
||||
// Both sudo and direct failed, return detailed error
|
||||
log.Printf("both sudo and direct execution failed - sudo error: %v, direct error: %v", err, directErr)
|
||||
log.Printf("sudo stderr: %s, direct stderr: %s", stderr.String(), directStderr.String())
|
||||
return "", fmt.Errorf("%s: sudo failed (%v: %s), direct execution also failed (%v: %s)", name, err, stderr.String(), directErr, directStderr.String())
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Printf("command execution failed: %s %v (error: %v, stderr: %s)", name, args, err, stderr.String())
|
||||
return "", fmt.Errorf("%s: %v: %s", name, err, stderr.String())
|
||||
}
|
||||
|
||||
@@ -224,19 +231,41 @@ func (s *Service) CreatePool(name string, vdevs []string, options map[string]str
|
||||
}
|
||||
|
||||
args = append(args, name)
|
||||
args = append(args, vdevs...)
|
||||
|
||||
// Normalize vdev paths - ensure they start with /dev/ if they don't already
|
||||
normalizedVdevs := make([]string, 0, len(vdevs))
|
||||
for _, vdev := range vdevs {
|
||||
vdev = strings.TrimSpace(vdev)
|
||||
if vdev == "" {
|
||||
continue
|
||||
}
|
||||
// If vdev doesn't start with /dev/ or /, assume it's a device name and add /dev/
|
||||
if !strings.HasPrefix(vdev, "/dev/") && !strings.HasPrefix(vdev, "/") {
|
||||
vdev = "/dev/" + vdev
|
||||
}
|
||||
normalizedVdevs = append(normalizedVdevs, vdev)
|
||||
}
|
||||
|
||||
if len(normalizedVdevs) == 0 {
|
||||
return fmt.Errorf("no valid vdevs provided after normalization")
|
||||
}
|
||||
|
||||
args = append(args, normalizedVdevs...)
|
||||
|
||||
// Log the command we're about to run for debugging
|
||||
log.Printf("executing: %s %v", s.zpoolPath, args)
|
||||
// Note: execCommand will use sudo automatically for zpool commands
|
||||
log.Printf("executing zpool create: %s %v", s.zpoolPath, args)
|
||||
log.Printf("pool name: %s, original vdevs: %v, normalized vdevs: %v", name, vdevs, normalizedVdevs)
|
||||
|
||||
// Create the pool (without mountpoint to avoid mount errors)
|
||||
createOutput, err := s.execCommand(s.zpoolPath, args...)
|
||||
|
||||
// Log the command output for debugging
|
||||
if err != nil {
|
||||
log.Printf("zpool create failed - output: %s, error: %v", createOutput, err)
|
||||
log.Printf("zpool create command failed - output: %s, error: %v", createOutput, err)
|
||||
log.Printf("this error might be a false positive - checking if pool was actually created...")
|
||||
} else {
|
||||
log.Printf("zpool create succeeded - output: %s", createOutput)
|
||||
log.Printf("zpool create command succeeded - output: %s", createOutput)
|
||||
}
|
||||
|
||||
// CRITICAL: Always check if pool exists, even if creation reported an error
|
||||
@@ -250,6 +279,7 @@ func (s *Service) CreatePool(name string, vdevs []string, options map[string]str
|
||||
}
|
||||
|
||||
if existingPools, listErr := s.ListPools(); listErr == nil {
|
||||
log.Printf("checking pool existence (attempt %d/%d): found %d pools", i+1, 3, len(existingPools))
|
||||
for _, pool := range existingPools {
|
||||
if pool.Name == name {
|
||||
poolExists = true
|
||||
@@ -257,6 +287,8 @@ func (s *Service) CreatePool(name string, vdevs []string, options map[string]str
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.Printf("warning: failed to list pools during existence check (attempt %d): %v", i+1, listErr)
|
||||
}
|
||||
|
||||
if poolExists {
|
||||
@@ -275,12 +307,16 @@ func (s *Service) CreatePool(name string, vdevs []string, options map[string]str
|
||||
err = nil
|
||||
} else if err != nil {
|
||||
// Pool doesn't exist and we have an error - return it with full context
|
||||
log.Printf("error: pool %s creation failed and pool does not exist: %v", name, err)
|
||||
return fmt.Errorf("failed to create pool %s: %v", name, err)
|
||||
log.Printf("error: pool %s creation failed and pool does not exist", name)
|
||||
log.Printf("error details: %v", err)
|
||||
log.Printf("command that failed: %s %v", s.zpoolPath, args)
|
||||
log.Printf("command output: %s", createOutput)
|
||||
return fmt.Errorf("failed to create pool %s: %v (command: %s %v)", name, err, s.zpoolPath, args)
|
||||
} else {
|
||||
// No error reported but pool doesn't exist - this shouldn't happen
|
||||
log.Printf("warning: pool %s creation reported no error but pool does not exist", name)
|
||||
return fmt.Errorf("pool %s creation reported success but pool was not found", name)
|
||||
log.Printf("command output: %s", createOutput)
|
||||
return fmt.Errorf("pool %s creation reported success but pool was not found (command: %s %v)", name, s.zpoolPath, args)
|
||||
}
|
||||
|
||||
// Pool created successfully - now set mountpoint and mount if needed
|
||||
|
||||
Reference in New Issue
Block a user