package glm import ( "errors" "fmt" "io/fs" "isle/daemon/daecommon" "os" ) // targetAllocs is expected to have already been validated to be internally // consistent, ie on conflicts between ports or directories within itself. func validateTargetAllocs( activeAllocs, targetAllocs []daecommon.ConfigStorageAllocation, ) error { for _, targetAlloc := range targetAllocs { var alreadyActive bool for _, activeAlloc := range activeAllocs { switch { case targetAlloc.RPCPort == activeAlloc.RPCPort && targetAlloc.DataPath == activeAlloc.DataPath && targetAlloc.MetaPath == activeAlloc.MetaPath: alreadyActive = true break // Changing the value of all fields besides these is supported. case targetAlloc.RPCPort == activeAlloc.RPCPort: return fmt.Errorf( "RPC port %d is already being used", activeAlloc.RPCPort, ) case targetAlloc.DataPath == activeAlloc.DataPath: return fmt.Errorf( "Data path %q is already being used", activeAlloc.DataPath, ) case targetAlloc.MetaPath == activeAlloc.MetaPath: return fmt.Errorf( "Meta path %q is already being used", activeAlloc.MetaPath, ) } } if !alreadyActive { for _, dir := range []string{ targetAlloc.DataPath, targetAlloc.MetaPath, } { entries, err := os.ReadDir(dir) if errors.Is(err, fs.ErrNotExist) { continue } else if err != nil { return fmt.Errorf("reading contents of %q: %w", dir, err) } if len(entries) > 0 { return fmt.Errorf( "directory %q is already being used, please provide the path to an empty directory", dir, ) } } } // targetAlloc validated } return nil }