isle/go/daemon/config.go

131 lines
2.7 KiB
Go
Raw Normal View History

package daemon
import (
"context"
"errors"
"fmt"
"io/fs"
"isle/bootstrap"
"isle/daemon/daecommon"
"isle/daemon/network"
"os"
"path/filepath"
"slices"
"strings"
"sync"
)
func getDefaultHTTPSocketDirPath() string {
path, err := firstExistingDir(
"/tmp",
"/run",
"/var/run",
"/dev/shm",
2022-10-26 19:47:39 +00:00
)
if err != nil {
panic(fmt.Sprintf("Failed to find directory for HTTP socket: %v", err))
}
return path
}
// HTTPSocketPath returns the path to the daemon's HTTP socket which is used for
// RPC and other functionality.
var HTTPSocketPath = sync.OnceValue(func() string {
return envOr(
"ISLE_DAEMON_HTTP_SOCKET_PATH",
func() string {
return filepath.Join(
getDefaultHTTPSocketDirPath(), "isle-daemon.sock",
)
},
)
})
func pickNetworkConfig(
networkConfigs map[string]daecommon.NetworkConfig,
creationParams bootstrap.CreationParams,
) *daecommon.NetworkConfig {
if len(networkConfigs) == 1 { // DEPRECATED
if c, ok := networkConfigs[daecommon.DeprecatedNetworkID]; ok {
return &c
}
}
for searchStr, networkConfig := range networkConfigs {
if creationParams.Matches(searchStr) {
return &networkConfig
}
}
return nil
}
func validateConfig(
ctx context.Context,
networkLoader network.Loader,
daemonConfig daecommon.Config,
loadableNetworks []bootstrap.CreationParams,
) error {
givenConfigs := daemonConfig.Networks
daemonConfig.Networks = map[string]daecommon.NetworkConfig{}
for _, creationParams := range loadableNetworks {
id := creationParams.ID
if c := pickNetworkConfig(givenConfigs, creationParams); c != nil {
daemonConfig.Networks[id] = *c
continue
}
c, err := networkLoader.StoredConfig(ctx, id)
if err != nil {
return fmt.Errorf("getting stored config for %q: %w", id, err)
}
daemonConfig.Networks[id] = c
}
return daemonConfig.Validate()
}
////////////////////////////////////////////////////////////////////////////////
// Jigs
func envOr(name string, fallback func() string) string {
if v := os.Getenv(name); v != "" {
return v
}
return fallback()
}
func firstExistingDir(paths ...string) (string, error) {
var errs []error
for _, path := range paths {
stat, err := os.Stat(path)
switch {
case errors.Is(err, fs.ErrExist):
continue
case err != nil:
errs = append(
errs, fmt.Errorf("checking if path %q exists: %w", path, err),
)
case !stat.IsDir():
errs = append(
errs, fmt.Errorf("path %q exists but is not a directory", path),
)
default:
return path, nil
}
}
err := fmt.Errorf(
"no directory found at any of the following paths: %s",
strings.Join(paths, ", "),
)
if len(errs) > 0 {
err = errors.Join(slices.Insert(errs, 0, err)...)
}
return "", err
}