diff --git a/go/cmd/entrypoint/daemon.go b/go/cmd/entrypoint/daemon.go index c8b8c04..906a25a 100644 --- a/go/cmd/entrypoint/daemon.go +++ b/go/cmd/entrypoint/daemon.go @@ -7,6 +7,7 @@ import ( "isle/daemon" "isle/daemon/daecommon" + "isle/daemon/network" ) // TODO it would be good to have an `isle daemon config-check` kind of command, @@ -49,9 +50,17 @@ var subCmdDaemon = subCmd{ return fmt.Errorf("loading daemon config: %w", err) } - daemonInst, err := daemon.New( - ctx, logger, daemonConfig, envBinDirPath, nil, + networkLoader, err := network.NewLoader( + ctx, + logger.WithNamespace("loader"), + envBinDirPath, + nil, ) + if err != nil { + return fmt.Errorf("instantiating network loader: %w", err) + } + + daemonInst, err := daemon.New(ctx, logger, networkLoader, daemonConfig) if err != nil { return fmt.Errorf("starting daemon: %w", err) } diff --git a/go/daemon/children/children.go b/go/daemon/children/children.go index 6e00c2d..980da82 100644 --- a/go/daemon/children/children.go +++ b/go/daemon/children/children.go @@ -17,18 +17,6 @@ import ( "isle/toolkit" ) -// Opts are optional parameters which can be passed in when initializing a new -// Children instance. A nil Opts is equivalent to a zero value. -type Opts struct{} - -func (o *Opts) withDefaults() *Opts { - if o == nil { - o = new(Opts) - } - - return o -} - // Children manages all child processes of a network. Child processes are // comprised of: // - nebula @@ -39,7 +27,6 @@ type Children struct { binDirPath string runtimeDir toolkit.Dir garageAdminToken string - opts Opts garageRPCSecret string @@ -59,12 +46,9 @@ func New( runtimeDir toolkit.Dir, garageAdminToken string, hostBootstrap bootstrap.Bootstrap, - opts *Opts, ) ( *Children, error, ) { - opts = opts.withDefaults() - logger.Info(ctx, "Loading secrets") garageRPCSecret, err := daecommon.GetGarageRPCSecret(ctx, secretsStore) if err != nil && !errors.Is(err, secrets.ErrNotFound) { @@ -76,7 +60,6 @@ func New( binDirPath: binDirPath, runtimeDir: runtimeDir, garageAdminToken: garageAdminToken, - opts: *opts, garageRPCSecret: garageRPCSecret, } diff --git a/go/daemon/daemon.go b/go/daemon/daemon.go index 1a5ae2f..63fca06 100644 --- a/go/daemon/daemon.go +++ b/go/daemon/daemon.go @@ -7,11 +7,9 @@ import ( "errors" "fmt" "isle/bootstrap" - "isle/daemon/children" "isle/daemon/daecommon" "isle/daemon/network" "isle/nebula" - "isle/toolkit" "sort" "sync" @@ -19,26 +17,6 @@ import ( "dev.mediocregopher.com/mediocre-go-lib.git/mlog" ) -// Opts are optional parameters which can be passed in when initializing a new -// Daemon instance. A nil Opts is equivalent to a zero value. -type Opts struct { - ChildrenOpts *children.Opts - // Defaults to that returned by daecommon.GetEnvVars. - EnvVars daecommon.EnvVars -} - -func (o *Opts) withDefaults() *Opts { - if o == nil { - o = new(Opts) - } - - if o.EnvVars == (daecommon.EnvVars{}) { - o.EnvVars = daecommon.GetEnvVars() - } - - return o -} - var _ RPC = (*Daemon)(nil) type joinedNetwork struct { @@ -65,12 +43,8 @@ type joinedNetwork struct { // canceled. type Daemon struct { logger *mlog.Logger + networkLoader network.Loader daemonConfig daecommon.Config - envBinDirPath string - opts *Opts - - networksStateDir toolkit.Dir - networksRuntimeDir toolkit.Dir l sync.RWMutex networks map[string]joinedNetwork @@ -80,77 +54,37 @@ type Daemon struct { func New( ctx context.Context, logger *mlog.Logger, + networkLoader network.Loader, daemonConfig daecommon.Config, - envBinDirPath string, - opts *Opts, ) ( *Daemon, error, ) { - opts = opts.withDefaults() - - if err := migrateToMultiNetworkStateDirectory( - ctx, - logger.WithNamespace("migration-multi-network-state-dir"), - opts.EnvVars, - ); err != nil { - return nil, fmt.Errorf( - "migrating to multi-network state directory: %w", err, - ) - } - d := &Daemon{ logger: logger, + networkLoader: networkLoader, daemonConfig: daemonConfig, - envBinDirPath: envBinDirPath, - opts: opts, networks: map[string]joinedNetwork{}, } - { - h := new(toolkit.MkDirHelper) - d.networksStateDir, _ = h.Maybe( - d.opts.EnvVars.StateDir.MkChildDir("networks", true), - ) - - d.networksRuntimeDir, _ = h.Maybe( - d.opts.EnvVars.RuntimeDir.MkChildDir("networks", true), - ) - - if err := h.Err(); err != nil { - return nil, fmt.Errorf("creating networks sub-directories: %w", err) - } - } - - loadableNetworks, err := loadableNetworks(d.networksStateDir) + loadableNetworks, err := networkLoader.Loadable(ctx) if err != nil { return nil, fmt.Errorf("listing loadable networks: %w", err) } for _, creationParams := range loadableNetworks { - id := creationParams.ID ctx = mctx.WithAnnotator(ctx, creationParams) - networkStateDir, networkRuntimeDir, err := networkDirs( - d.networksStateDir, d.networksRuntimeDir, id, true, + var ( + id = creationParams.ID + networkConfig, _ = pickNetworkConfig(daemonConfig, creationParams) ) - if err != nil { - return nil, fmt.Errorf( - "creating sub-directories for network %q: %w", id, err, - ) - } - networkConfig, _ := pickNetworkConfig(daemonConfig, creationParams) - - network, err := network.Load( + network, err := networkLoader.Load( ctx, logger.WithNamespace("network"), networkConfig, - d.envBinDirPath, - networkStateDir, - networkRuntimeDir, - &network.Opts{ - ChildrenOpts: d.opts.ChildrenOpts, - }, + creationParams, + nil, ) if err != nil { return nil, fmt.Errorf("loading network %q: %w", id, err) @@ -187,9 +121,7 @@ func (d *Daemon) CreateNetwork( creationParams := bootstrap.NewCreationParams(name, domain) ctx = mctx.WithAnnotator(ctx, creationParams) - networkConfig, ok := pickNetworkConfig( - d.daemonConfig, creationParams, - ) + networkConfig, ok := pickNetworkConfig(d.daemonConfig, creationParams) if !ok { return errors.New("couldn't find network config for network being created") } @@ -203,31 +135,15 @@ func (d *Daemon) CreateNetwork( return ErrAlreadyJoined } - networkStateDir, networkRuntimeDir, err := networkDirs( - d.networksStateDir, d.networksRuntimeDir, creationParams.ID, false, - ) - if err != nil { - return fmt.Errorf( - "creating sub-directories for network %q: %w", - creationParams.ID, - err, - ) - } - d.logger.Info(ctx, "Creating network") - n, err := network.Create( + n, err := d.networkLoader.Create( ctx, d.logger.WithNamespace("network"), networkConfig, - d.envBinDirPath, - networkStateDir, - networkRuntimeDir, creationParams, ipNet, hostName, - &network.Opts{ - ChildrenOpts: d.opts.ChildrenOpts, - }, + nil, ) if err != nil { return fmt.Errorf("creating network: %w", err) @@ -267,27 +183,13 @@ func (d *Daemon) JoinNetwork( return ErrAlreadyJoined } - networkStateDir, networkRuntimeDir, err := networkDirs( - d.networksStateDir, d.networksRuntimeDir, networkID, false, - ) - if err != nil { - return fmt.Errorf( - "creating sub-directories for network %q: %w", networkID, err, - ) - } - d.logger.Info(ctx, "Joining network") - n, err := network.Join( + n, err := d.networkLoader.Join( ctx, d.logger.WithNamespace("network"), networkConfig, newBootstrap, - d.envBinDirPath, - networkStateDir, - networkRuntimeDir, - &network.Opts{ - ChildrenOpts: d.opts.ChildrenOpts, - }, + nil, ) if err != nil { return fmt.Errorf( @@ -313,7 +215,7 @@ func withNetwork[Res any]( d.l.RLock() defer d.l.RUnlock() - network, err := pickNetwork(ctx, d.networks, d.networksStateDir) + network, err := pickNetwork(ctx, d.networkLoader, d.networks) if err != nil { var zero Res return zero, err @@ -368,7 +270,7 @@ func (d *Daemon) SetConfig( // TODO needs to check that public addresses aren't being shared // across networks, and whatever else happens in Config.Validate. - network, err := pickNetwork(ctx, d.networks, d.networksStateDir) + network, err := pickNetwork(ctx, d.networkLoader, d.networks) if err != nil { return err } diff --git a/go/daemon/network.go b/go/daemon/network.go index 8a25fb4..138fde4 100644 --- a/go/daemon/network.go +++ b/go/daemon/network.go @@ -5,78 +5,12 @@ import ( "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, + networkLoader network.Loader, networks map[string]joinedNetwork, - networksStateDir toolkit.Dir, ) ( joinedNetwork, error, ) { @@ -84,7 +18,7 @@ func pickNetwork( return joinedNetwork{}, ErrNoNetwork } - creationParams, err := loadableNetworks(networksStateDir) + creationParams, err := networkLoader.Loadable(ctx) if err != nil { return joinedNetwork{}, fmt.Errorf("getting loadable networks: %w", err) } diff --git a/go/daemon/network/loader.go b/go/daemon/network/loader.go new file mode 100644 index 0000000..d6a280e --- /dev/null +++ b/go/daemon/network/loader.go @@ -0,0 +1,305 @@ +//go:generate mockery --name Loader --inpackage --filename loader_mock.go + +package network + +import ( + "context" + "fmt" + "isle/bootstrap" + "isle/daemon/daecommon" + "isle/nebula" + "isle/toolkit" + + "dev.mediocregopher.com/mediocre-go-lib.git/mlog" +) + +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 +} + +// Loader is responsible for joining/creating Networks and making them loadable +// later. +type Loader interface { + + // Loadable returns the CreationParams for all Networks which can be Loaded. + Loadable(context.Context) ([]bootstrap.CreationParams, error) + + // Load initializes and returns a Network instance for a network which was + // previously joined or created, and which has the given CreationParams. + Load( + context.Context, + *mlog.Logger, + daecommon.NetworkConfig, + bootstrap.CreationParams, + *Opts, + ) ( + Network, error, + ) + + // Join initializes and returns a Network instance for an existing network + // which was not previously joined to on this host. Once Join has been + // called for a particular network it will error on subsequent calls for + // that same network, Load should be used instead. + Join( + context.Context, + *mlog.Logger, + daecommon.NetworkConfig, + JoiningBootstrap, + *Opts, + ) ( + Network, error, + ) + + // Create initializes and returns a Network for a brand new network which + // uses the given creation parameters. + // + // - name: Human-readable name of the network. + // - domain: Primary domain name that network services are served under. + // - ipNet: An IP subnet, in CIDR form, which will be the overall range of + // possible IPs in the network. The first IP in this network range will + // become this first host's IP. + // - hostName: The name of this first host in the network. + // + // Errors: + // - ErrInvalidConfig - if daemonConfig doesn't have 3 storage allocations + // configured. + Create( + context.Context, + *mlog.Logger, + daecommon.NetworkConfig, + bootstrap.CreationParams, + nebula.IPNet, + nebula.HostName, + *Opts, + ) ( + Network, error, + ) +} + +// LoaderOpts are optional parameters which can be passed in when initializing a +// new Loader instance. A nil LoaderOpts is equivalent to a zero value. +type LoaderOpts struct { + // Defaults to that returned by daecommon.GetEnvVars. + EnvVars daecommon.EnvVars +} + +func (o *LoaderOpts) withDefaults() *LoaderOpts { + if o == nil { + o = new(LoaderOpts) + } + + if o.EnvVars == (daecommon.EnvVars{}) { + o.EnvVars = daecommon.GetEnvVars() + } + + return o +} + +type loader struct { + envBinDirPath string + networksStateDir toolkit.Dir + networksRuntimeDir toolkit.Dir +} + +// NewLoader returns a new Loader which will use the given directories to load +// and create Network instances. +func NewLoader( + ctx context.Context, + logger *mlog.Logger, + envBinDirPath string, + opts *LoaderOpts, +) ( + Loader, error, +) { + opts = opts.withDefaults() + + if err := migrateToMultiNetworkStateDirectory( + ctx, + logger.WithNamespace("migration-multi-network-state-dir"), + opts.EnvVars.StateDir, + ); err != nil { + return nil, fmt.Errorf( + "migrating to multi-network state directory: %w", err, + ) + } + + h := new(toolkit.MkDirHelper) + networksStateDir, _ := h.Maybe( + opts.EnvVars.StateDir.MkChildDir("networks", true), + ) + + networksRuntimeDir, _ := h.Maybe( + opts.EnvVars.RuntimeDir.MkChildDir("networks", true), + ) + + if err := h.Err(); err != nil { + return nil, fmt.Errorf("creating networks sub-directories: %w", err) + } + + return &loader{ + envBinDirPath, + networksStateDir, + networksRuntimeDir, + }, nil +} + +func (l *loader) Loadable( + ctx context.Context, +) ( + []bootstrap.CreationParams, error, +) { + networkStateDirs, err := l.networksStateDir.ChildDirs() + if err != nil { + return nil, fmt.Errorf( + "listing children of %q: %w", l.networksStateDir.Path, err, + ) + } + + creationParams := make([]bootstrap.CreationParams, 0, len(networkStateDirs)) + + for _, networkStateDir := range networkStateDirs { + thisCreationParams, err := 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 (l *loader) Load( + ctx context.Context, + logger *mlog.Logger, + networkConfig daecommon.NetworkConfig, + creationParams bootstrap.CreationParams, + opts *Opts, +) ( + Network, error, +) { + networkID := creationParams.ID + + networkStateDir, networkRuntimeDir, err := networkDirs( + l.networksStateDir, l.networksRuntimeDir, networkID, true, + ) + if err != nil { + return nil, fmt.Errorf( + "creating sub-directories for network %q: %w", networkID, err, + ) + } + + return load( + ctx, + logger.WithNamespace("network"), + l.envBinDirPath, + networkConfig, + networkStateDir, + networkRuntimeDir, + opts, + ) +} + +func (l *loader) Join( + ctx context.Context, + logger *mlog.Logger, + networkConfig daecommon.NetworkConfig, + joiningBootstrap JoiningBootstrap, + opts *Opts, +) ( + Network, error, +) { + var ( + creationParams = joiningBootstrap.Bootstrap.NetworkCreationParams + networkID = creationParams.ID + ) + + networkStateDir, networkRuntimeDir, err := networkDirs( + l.networksStateDir, l.networksRuntimeDir, networkID, false, + ) + if err != nil { + return nil, fmt.Errorf( + "creating sub-directories for network %q: %w", networkID, err, + ) + } + + return join( + ctx, + logger.WithNamespace("network"), + l.envBinDirPath, + networkConfig, + joiningBootstrap, + networkStateDir, + networkRuntimeDir, + opts, + ) +} + +func (l *loader) Create( + ctx context.Context, + logger *mlog.Logger, + networkConfig daecommon.NetworkConfig, + creationParams bootstrap.CreationParams, + ipNet nebula.IPNet, + hostName nebula.HostName, + opts *Opts, +) ( + Network, error, +) { + networkID := creationParams.ID + + networkStateDir, networkRuntimeDir, err := networkDirs( + l.networksStateDir, l.networksRuntimeDir, networkID, false, + ) + if err != nil { + return nil, fmt.Errorf( + "creating sub-directories for network %q: %w", networkID, err, + ) + } + + return create( + ctx, + logger.WithNamespace("network"), + l.envBinDirPath, + networkConfig, + networkStateDir, + networkRuntimeDir, + creationParams, + ipNet, + hostName, + opts, + ) +} diff --git a/go/daemon/network/loader_mock.go b/go/daemon/network/loader_mock.go new file mode 100644 index 0000000..54004f3 --- /dev/null +++ b/go/daemon/network/loader_mock.go @@ -0,0 +1,155 @@ +// Code generated by mockery v2.43.1. DO NOT EDIT. + +package network + +import ( + context "context" + bootstrap "isle/bootstrap" + + daecommon "isle/daemon/daecommon" + + mlog "dev.mediocregopher.com/mediocre-go-lib.git/mlog" + + mock "github.com/stretchr/testify/mock" + + nebula "isle/nebula" +) + +// MockLoader is an autogenerated mock type for the Loader type +type MockLoader struct { + mock.Mock +} + +// Create provides a mock function with given fields: _a0, _a1, _a2, _a3, _a4, _a5, _a6 +func (_m *MockLoader) Create(_a0 context.Context, _a1 *mlog.Logger, _a2 daecommon.NetworkConfig, _a3 bootstrap.CreationParams, _a4 nebula.IPNet, _a5 nebula.HostName, _a6 *Opts) (Network, error) { + ret := _m.Called(_a0, _a1, _a2, _a3, _a4, _a5, _a6) + + if len(ret) == 0 { + panic("no return value specified for Create") + } + + var r0 Network + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *mlog.Logger, daecommon.NetworkConfig, bootstrap.CreationParams, nebula.IPNet, nebula.HostName, *Opts) (Network, error)); ok { + return rf(_a0, _a1, _a2, _a3, _a4, _a5, _a6) + } + if rf, ok := ret.Get(0).(func(context.Context, *mlog.Logger, daecommon.NetworkConfig, bootstrap.CreationParams, nebula.IPNet, nebula.HostName, *Opts) Network); ok { + r0 = rf(_a0, _a1, _a2, _a3, _a4, _a5, _a6) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(Network) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *mlog.Logger, daecommon.NetworkConfig, bootstrap.CreationParams, nebula.IPNet, nebula.HostName, *Opts) error); ok { + r1 = rf(_a0, _a1, _a2, _a3, _a4, _a5, _a6) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Join provides a mock function with given fields: _a0, _a1, _a2, _a3, _a4 +func (_m *MockLoader) Join(_a0 context.Context, _a1 *mlog.Logger, _a2 daecommon.NetworkConfig, _a3 JoiningBootstrap, _a4 *Opts) (Network, error) { + ret := _m.Called(_a0, _a1, _a2, _a3, _a4) + + if len(ret) == 0 { + panic("no return value specified for Join") + } + + var r0 Network + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *mlog.Logger, daecommon.NetworkConfig, JoiningBootstrap, *Opts) (Network, error)); ok { + return rf(_a0, _a1, _a2, _a3, _a4) + } + if rf, ok := ret.Get(0).(func(context.Context, *mlog.Logger, daecommon.NetworkConfig, JoiningBootstrap, *Opts) Network); ok { + r0 = rf(_a0, _a1, _a2, _a3, _a4) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(Network) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *mlog.Logger, daecommon.NetworkConfig, JoiningBootstrap, *Opts) error); ok { + r1 = rf(_a0, _a1, _a2, _a3, _a4) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Load provides a mock function with given fields: _a0, _a1, _a2, _a3, _a4 +func (_m *MockLoader) Load(_a0 context.Context, _a1 *mlog.Logger, _a2 daecommon.NetworkConfig, _a3 bootstrap.CreationParams, _a4 *Opts) (Network, error) { + ret := _m.Called(_a0, _a1, _a2, _a3, _a4) + + if len(ret) == 0 { + panic("no return value specified for Load") + } + + var r0 Network + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *mlog.Logger, daecommon.NetworkConfig, bootstrap.CreationParams, *Opts) (Network, error)); ok { + return rf(_a0, _a1, _a2, _a3, _a4) + } + if rf, ok := ret.Get(0).(func(context.Context, *mlog.Logger, daecommon.NetworkConfig, bootstrap.CreationParams, *Opts) Network); ok { + r0 = rf(_a0, _a1, _a2, _a3, _a4) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(Network) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *mlog.Logger, daecommon.NetworkConfig, bootstrap.CreationParams, *Opts) error); ok { + r1 = rf(_a0, _a1, _a2, _a3, _a4) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Loadable provides a mock function with given fields: _a0 +func (_m *MockLoader) Loadable(_a0 context.Context) ([]bootstrap.CreationParams, error) { + ret := _m.Called(_a0) + + if len(ret) == 0 { + panic("no return value specified for Loadable") + } + + var r0 []bootstrap.CreationParams + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) ([]bootstrap.CreationParams, error)); ok { + return rf(_a0) + } + if rf, ok := ret.Get(0).(func(context.Context) []bootstrap.CreationParams); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]bootstrap.CreationParams) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NewMockLoader creates a new instance of MockLoader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockLoader(t interface { + mock.TestingT + Cleanup(func()) +}) *MockLoader { + mock := &MockLoader{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/go/daemon/migrations.go b/go/daemon/network/migrations.go similarity index 82% rename from go/daemon/migrations.go rename to go/daemon/network/migrations.go index dfa12e8..d2e1936 100644 --- a/go/daemon/migrations.go +++ b/go/daemon/network/migrations.go @@ -1,12 +1,12 @@ -package daemon +package network import ( "context" "errors" "fmt" "io/fs" - "isle/daemon/daecommon" "isle/jsonutil" + "isle/toolkit" "os" "path/filepath" @@ -16,13 +16,13 @@ import ( // DEPRECATED func migrateToMultiNetworkStateDirectory( - ctx context.Context, logger *mlog.Logger, envVars daecommon.EnvVars, + ctx context.Context, + logger *mlog.Logger, + stateDir toolkit.Dir, ) error { var ( - legacyBootstrapPath = filepath.Join( - envVars.StateDir.Path, "bootstrap.json", - ) - legacySecretsPath = filepath.Join(envVars.StateDir.Path, "secrets") + legacyBootstrapPath = filepath.Join(stateDir.Path, "bootstrap.json") + legacySecretsPath = filepath.Join(stateDir.Path, "secrets") ) if _, err := os.Stat(legacyBootstrapPath); errors.Is(err, fs.ErrNotExist) { @@ -47,9 +47,7 @@ func migrateToMultiNetworkStateDirectory( var ( networkStateDirPath = filepath.Join( - envVars.StateDir.Path, - "networks", - bootstrapBody.NetworkCreationParams.ID, + stateDir.Path, "networks", bootstrapBody.NetworkCreationParams.ID, ) newBootstrapPath = filepath.Join(networkStateDirPath, "bootstrap.json") diff --git a/go/daemon/network/network.go b/go/daemon/network/network.go index 5088660..25c8771 100644 --- a/go/daemon/network/network.go +++ b/go/daemon/network/network.go @@ -153,8 +153,6 @@ type Network interface { // Opts are optional parameters which can be passed in when initializing a new // Network instance. A nil Opts is equivalent to a zero value. type Opts struct { - ChildrenOpts *children.Opts - GarageAdminToken string // Will be randomly generated if left unset. } @@ -218,6 +216,8 @@ func instatiateNetwork( // LoadCreationParams returns the CreationParams of a Network which was // Created/Joined with the given state directory. +// +// TODO probably can be private func LoadCreationParams( stateDir toolkit.Dir, ) ( @@ -240,13 +240,11 @@ func LoadCreationParams( return bs.NetworkCreationParams, nil } -// Load initializes and returns a Network instance for a network which was -// previously joined or created, and which has the given ID. -func Load( +func load( ctx context.Context, logger *mlog.Logger, - networkConfig daecommon.NetworkConfig, envBinDirPath string, + networkConfig daecommon.NetworkConfig, stateDir toolkit.Dir, runtimeDir toolkit.Dir, opts *Opts, @@ -283,16 +281,12 @@ func Load( return n, nil } -// Join initializes and returns a Network instance for an existing network which -// was not previously joined to on this host. Once Join has been called for a -// particular network it will error on subsequent calls for that same network, -// Load should be used instead. -func Join( +func join( ctx context.Context, logger *mlog.Logger, + envBinDirPath string, networkConfig daecommon.NetworkConfig, joiningBootstrap JoiningBootstrap, - envBinDirPath string, stateDir toolkit.Dir, runtimeDir toolkit.Dir, opts *Opts, @@ -326,24 +320,11 @@ func Join( return n, nil } -// Create initializes and returns a Network for a brand new network which uses -// the given creation parameters. -// -// - name: Human-readable name of the network. -// - domain: Primary domain name that network services are served under. -// - ipNet: An IP subnet, in CIDR form, which will be the overall range of -// possible IPs in the network. The first IP in this network range will -// become this first host's IP. -// - hostName: The name of this first host in the network. -// -// Errors: -// - ErrInvalidConfig - if daemonConfig doesn't have 3 storage allocations -// configured. -func Create( +func create( ctx context.Context, logger *mlog.Logger, - networkConfig daecommon.NetworkConfig, envBinDirPath string, + networkConfig daecommon.NetworkConfig, stateDir toolkit.Dir, runtimeDir toolkit.Dir, creationParams bootstrap.CreationParams, @@ -488,7 +469,6 @@ func (n *network) initialize( n.runtimeDir, n.opts.GarageAdminToken, n.currBootstrap, - n.opts.ChildrenOpts, ) if err != nil { return fmt.Errorf("creating child processes: %w", err) diff --git a/go/daemon/network/network_it_test.go b/go/daemon/network/network_it_test.go index 7f30398..248c304 100644 --- a/go/daemon/network/network_it_test.go +++ b/go/daemon/network/network_it_test.go @@ -36,11 +36,11 @@ func TestLoad(t *testing.T) { assert.NoError(t, network.Shutdown()) t.Log("Calling Load") - loadedNetwork, err := Load( + loadedNetwork, err := load( h.ctx, h.logger.WithNamespace("loadedNetwork"), - network.getConfig(t), getEnvBinDirPath(), + network.getConfig(t), network.stateDir, h.mkDir(t, "runtime"), network.opts, diff --git a/go/daemon/network/network_it_util_test.go b/go/daemon/network/network_it_util_test.go index a540ba8..7e30624 100644 --- a/go/daemon/network/network_it_util_test.go +++ b/go/daemon/network/network_it_util_test.go @@ -225,11 +225,11 @@ func (h *integrationHarness) createNetwork( } ) - network, err := Create( + network, err := create( h.ctx, logger, - networkConfig, getEnvBinDirPath(), + networkConfig, stateDir, runtimeDir, opts.creationParams, @@ -305,12 +305,12 @@ func (h *integrationHarness) joinNetwork( ) t.Logf("Joining as %q", hostNameStr) - joinedNetwork, err := Join( + joinedNetwork, err := join( h.ctx, logger, + getEnvBinDirPath(), networkConfig, joiningBootstrap, - getEnvBinDirPath(), stateDir, runtimeDir, networkOpts,