isle/go/daemon/network/glm/validate.go

70 lines
1.7 KiB
Go

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
}