Browse Source

fix: accurate error messages for explicitly specified unavailable ports

When a port is explicitly specified via CLI flags but is unavailable, the error message
now correctly reports the originally requested port instead of reporting a fallback port
that was calculated internally.

The issue was that the config file applied after CLI flag parsing caused isFlagPassed()
to return true for ports loaded from the config file (since flag.Visit() was called during
config file application), incorrectly marking them as explicitly specified.

Solution: Capture which port flags were explicitly passed on the CLI BEFORE the config file
is applied, storing them in the explicitPortFlags map. This preserves the accurate
distinction between user-specified ports and defaults/config-file ports.

Example:
- User runs: weed mini -dir=. -s3.port=22
- Now correctly shows: 'port 22 for S3 (specified by flag s3.port) is not available'
- Previously incorrectly showed: 'port 8334 for S3...' (some calculated fallback)
pull/7838/head
Chris Lu 2 months ago
parent
commit
34aced3526
  1. 16
      weed/command/mini.go

16
weed/command/mini.go

@ -55,6 +55,8 @@ var (
miniWebDavOptions WebDavOption miniWebDavOptions WebDavOption
miniAdminOptions AdminOptions miniAdminOptions AdminOptions
createdInitialIAM bool // Track if initial IAM config was created from env vars createdInitialIAM bool // Track if initial IAM config was created from env vars
// Track which port flags were explicitly passed on CLI before config file is applied
explicitPortFlags map[string]bool
) )
func init() { func init() {
@ -387,8 +389,8 @@ func ensurePortAvailableOnIP(portPtr *int, serviceName string, ip string, reserv
original := *portPtr original := *portPtr
// Check if this port was explicitly specified by the user
isExplicitPort := isFlagPassed(flagName)
// Check if this port was explicitly specified by the user (from CLI, before config file was applied)
isExplicitPort := explicitPortFlags[flagName]
// Skip if this port is reserved for gRPC calculation // Skip if this port is reserved for gRPC calculation
if reservedPorts[original] { if reservedPorts[original] {
@ -408,9 +410,11 @@ func ensurePortAvailableOnIP(portPtr *int, serviceName string, ip string, reserv
// Check on both the specific IP and on all interfaces (0.0.0.0) for maximum reliability // Check on both the specific IP and on all interfaces (0.0.0.0) for maximum reliability
if !isPortOpenOnIP(ip, original) || !isPortAvailable(original) { if !isPortOpenOnIP(ip, original) || !isPortAvailable(original) {
// If explicitly specified, fail immediately with the originally requested port
if isExplicitPort { if isExplicitPort {
return fmt.Errorf("port %d for %s (specified by flag %s) is not available on %s and cannot be used", original, serviceName, flagName, ip) return fmt.Errorf("port %d for %s (specified by flag %s) is not available on %s and cannot be used", original, serviceName, flagName, ip)
} }
// For default ports, try to find an alternative
glog.Warningf("Port %d for %s is not available on %s, finding alternative port...", original, serviceName, ip) glog.Warningf("Port %d for %s is not available on %s, finding alternative port...", original, serviceName, ip)
newPort := findAvailablePortOnIP(ip, original+1, 100, reservedPorts) newPort := findAvailablePortOnIP(ip, original+1, 100, reservedPorts)
if newPort == 0 { if newPort == 0 {
@ -666,6 +670,14 @@ func saveMiniConfiguration(dataFolder string) error {
func runMini(cmd *Command, args []string) bool { func runMini(cmd *Command, args []string) bool {
// Capture which port flags were explicitly passed on CLI BEFORE config file is applied
// This is necessary to distinguish user-specified ports from defaults or config file options
explicitPortFlags = make(map[string]bool)
portFlagNames := []string{"master.port", "filer.port", "volume.port", "s3.port", "webdav.port", "admin.port"}
for _, flagName := range portFlagNames {
explicitPortFlags[flagName] = isFlagPassed(flagName)
}
// Load configuration from file if it exists // Load configuration from file if it exists
configOptions, err := loadMiniConfigurationFile(*miniDataFolders) configOptions, err := loadMiniConfigurationFile(*miniDataFolders)
if err != nil { if err != nil {

Loading…
Cancel
Save