isle/go/daemon/network.go
Brian Picciano 16aca610b4 Add multi-network support to daemon
It's still not possible to pick a network from the command-line, so this
is a bit broken, but the daemon component should handle it correctly at
least.
2024-09-23 19:04:14 +02:00

132 lines
2.9 KiB
Go

package daemon
import (
"context"
"fmt"
"isle/bootstrap"
"isle/daemon/network"
"isle/toolkit"
)
func networkStateDir(
networksStateDir toolkit.Dir, networkID string, mayExist bool,
) (
toolkit.Dir, error,
) {
return networksStateDir.MkChildDir(networkID, mayExist)
}
func networkRuntimeDir(
networksRuntimeDir toolkit.Dir, networkID string, mayExist bool,
) (
toolkit.Dir, error,
) {
return networksRuntimeDir.MkChildDir(networkID, mayExist)
}
func networkDirs(
networksStateDir, networksRuntimeDir toolkit.Dir,
networkID string,
mayExist bool,
) (
stateDir, runtimeDir toolkit.Dir, err error,
) {
h := new(toolkit.MkDirHelper)
stateDir, _ = h.Maybe(
networkStateDir(networksStateDir, networkID, mayExist),
)
runtimeDir, _ = h.Maybe(
networkRuntimeDir(networksRuntimeDir, networkID, mayExist),
)
err = h.Err()
return
}
// loadableNetworks returns the CreationParams for each Network which is able to
// be loaded.
func loadableNetworks(
networksStateDir toolkit.Dir,
) (
[]bootstrap.CreationParams, error,
) {
networkStateDirs, err := networksStateDir.ChildDirs()
if err != nil {
return nil, fmt.Errorf(
"listing children of %q: %w", networksStateDir.Path, err,
)
}
creationParams := make([]bootstrap.CreationParams, 0, len(networkStateDirs))
for _, networkStateDir := range networkStateDirs {
thisCreationParams, err := network.LoadCreationParams(networkStateDir)
if err != nil {
return nil, fmt.Errorf(
"loading creation params from %q: %w",
networkStateDir.Path,
err,
)
}
creationParams = append(creationParams, thisCreationParams)
}
return creationParams, nil
}
func pickNetwork(
ctx context.Context,
networks map[string]network.Network,
networksStateDir toolkit.Dir,
) (
network.Network, error,
) {
if len(networks) == 0 {
return nil, ErrNoNetwork
}
creationParams, err := loadableNetworks(networksStateDir)
if err != nil {
return nil, fmt.Errorf("getting loadable networks: %w", err)
}
var (
networkSearchStr = getNetworkSearchStr(ctx)
matchingNetworkIDs = make([]string, 0, len(networks))
)
for _, creationParam := range creationParams {
if networkSearchStr == "" || creationParam.Matches(networkSearchStr) {
matchingNetworkIDs = append(matchingNetworkIDs, creationParam.ID)
}
}
if len(matchingNetworkIDs) == 0 {
return nil, ErrNoMatchingNetworks
} else if len(matchingNetworkIDs) > 1 {
return nil, ErrMultipleMatchingNetworks
}
return networks[matchingNetworkIDs[0]], nil
}
func alreadyJoined(
ctx context.Context,
networks map[string]network.Network,
creationParams bootstrap.CreationParams,
) (
bool, error,
) {
for networkID, network := range networks {
existingCreationParams, err := network.GetNetworkCreationParams(ctx)
if err != nil {
return false, fmt.Errorf(
"getting creation params of network %q: %w", networkID, err,
)
} else if existingCreationParams.Conflicts(creationParams) {
return true, nil
}
}
return false, nil
}