Compare commits
No commits in common. "4f074391e44fccd537d7818f35ba0cbbe011a574" and "f0cb29b553e0c11a82aab8ff7181ff980ccdba16" have entirely different histories.
4f074391e4
...
f0cb29b553
@ -44,20 +44,22 @@ var HTTPSocketPath = sync.OnceValue(func() string {
|
|||||||
|
|
||||||
func pickNetworkConfig(
|
func pickNetworkConfig(
|
||||||
daemonConfig daecommon.Config, creationParams bootstrap.CreationParams,
|
daemonConfig daecommon.Config, creationParams bootstrap.CreationParams,
|
||||||
) *daecommon.NetworkConfig {
|
) (
|
||||||
|
daecommon.NetworkConfig, bool,
|
||||||
|
) {
|
||||||
if len(daemonConfig.Networks) == 1 { // DEPRECATED
|
if len(daemonConfig.Networks) == 1 { // DEPRECATED
|
||||||
if c, ok := daemonConfig.Networks[daecommon.DeprecatedNetworkID]; ok {
|
if c, ok := daemonConfig.Networks[daecommon.DeprecatedNetworkID]; ok {
|
||||||
return &c
|
return c, true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for searchStr, networkConfig := range daemonConfig.Networks {
|
for searchStr, networkConfig := range daemonConfig.Networks {
|
||||||
if creationParams.Matches(searchStr) {
|
if creationParams.Matches(searchStr) {
|
||||||
return &networkConfig
|
return networkConfig, true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return daecommon.NetworkConfig{}, false
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -21,7 +21,8 @@ var _ RPC = (*Daemon)(nil)
|
|||||||
|
|
||||||
type joinedNetwork struct {
|
type joinedNetwork struct {
|
||||||
network.Network
|
network.Network
|
||||||
config *daecommon.NetworkConfig
|
|
||||||
|
userConfig bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Daemon implements all methods of the Daemon interface, plus others used
|
// Daemon implements all methods of the Daemon interface, plus others used
|
||||||
@ -74,23 +75,25 @@ func New(
|
|||||||
ctx = mctx.WithAnnotator(ctx, creationParams)
|
ctx = mctx.WithAnnotator(ctx, creationParams)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
id = creationParams.ID
|
id = creationParams.ID
|
||||||
networkConfig = pickNetworkConfig(daemonConfig, creationParams)
|
networkConfig, _ = pickNetworkConfig(daemonConfig, creationParams)
|
||||||
)
|
)
|
||||||
|
|
||||||
n, err := networkLoader.Load(
|
network, err := networkLoader.Load(
|
||||||
ctx,
|
ctx,
|
||||||
logger.WithNamespace("network"),
|
logger.WithNamespace("network"),
|
||||||
|
networkConfig,
|
||||||
creationParams,
|
creationParams,
|
||||||
&network.Opts{
|
nil,
|
||||||
Config: networkConfig,
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("loading network %q: %w", id, err)
|
return nil, fmt.Errorf("loading network %q: %w", id, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d.networks[id] = joinedNetwork{n, networkConfig}
|
d.networks[id] = joinedNetwork{
|
||||||
|
Network: network,
|
||||||
|
userConfig: true,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return d, nil
|
return d, nil
|
||||||
@ -111,18 +114,21 @@ func New(
|
|||||||
// - network.ErrInvalidConfig
|
// - network.ErrInvalidConfig
|
||||||
func (d *Daemon) CreateNetwork(
|
func (d *Daemon) CreateNetwork(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
name, domain string, ipNet nebula.IPNet, hostName nebula.HostName,
|
name, domain string,
|
||||||
|
ipNet nebula.IPNet,
|
||||||
|
hostName nebula.HostName,
|
||||||
) error {
|
) error {
|
||||||
|
creationParams := bootstrap.NewCreationParams(name, domain)
|
||||||
|
ctx = mctx.WithAnnotator(ctx, creationParams)
|
||||||
|
|
||||||
|
networkConfig, ok := pickNetworkConfig(d.daemonConfig, creationParams)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("couldn't find network config for network being created")
|
||||||
|
}
|
||||||
|
|
||||||
d.l.Lock()
|
d.l.Lock()
|
||||||
defer d.l.Unlock()
|
defer d.l.Unlock()
|
||||||
|
|
||||||
var (
|
|
||||||
creationParams = bootstrap.NewCreationParams(name, domain)
|
|
||||||
networkConfig = pickNetworkConfig(d.daemonConfig, creationParams)
|
|
||||||
)
|
|
||||||
|
|
||||||
ctx = mctx.WithAnnotator(ctx, creationParams)
|
|
||||||
|
|
||||||
if joined, err := alreadyJoined(ctx, d.networks, creationParams); err != nil {
|
if joined, err := alreadyJoined(ctx, d.networks, creationParams); err != nil {
|
||||||
return fmt.Errorf("checking if already joined to network: %w", err)
|
return fmt.Errorf("checking if already joined to network: %w", err)
|
||||||
} else if joined {
|
} else if joined {
|
||||||
@ -133,19 +139,22 @@ func (d *Daemon) CreateNetwork(
|
|||||||
n, err := d.networkLoader.Create(
|
n, err := d.networkLoader.Create(
|
||||||
ctx,
|
ctx,
|
||||||
d.logger.WithNamespace("network"),
|
d.logger.WithNamespace("network"),
|
||||||
|
networkConfig,
|
||||||
creationParams,
|
creationParams,
|
||||||
ipNet,
|
ipNet,
|
||||||
hostName,
|
hostName,
|
||||||
&network.Opts{
|
nil,
|
||||||
Config: networkConfig,
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("creating network: %w", err)
|
return fmt.Errorf("creating network: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d.logger.Info(ctx, "Network created successfully")
|
d.logger.Info(ctx, "Network created successfully")
|
||||||
d.networks[creationParams.ID] = joinedNetwork{n, networkConfig}
|
d.networks[creationParams.ID] = joinedNetwork{
|
||||||
|
Network: n,
|
||||||
|
userConfig: true,
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,17 +166,17 @@ func (d *Daemon) CreateNetwork(
|
|||||||
func (d *Daemon) JoinNetwork(
|
func (d *Daemon) JoinNetwork(
|
||||||
ctx context.Context, newBootstrap network.JoiningBootstrap,
|
ctx context.Context, newBootstrap network.JoiningBootstrap,
|
||||||
) error {
|
) error {
|
||||||
d.l.Lock()
|
|
||||||
defer d.l.Unlock()
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
creationParams = newBootstrap.Bootstrap.NetworkCreationParams
|
creationParams = newBootstrap.Bootstrap.NetworkCreationParams
|
||||||
networkID = creationParams.ID
|
networkConfig, _ = pickNetworkConfig(d.daemonConfig, creationParams)
|
||||||
networkConfig = pickNetworkConfig(d.daemonConfig, creationParams)
|
networkID = creationParams.ID
|
||||||
)
|
)
|
||||||
|
|
||||||
ctx = mctx.WithAnnotator(ctx, newBootstrap.Bootstrap.NetworkCreationParams)
|
ctx = mctx.WithAnnotator(ctx, newBootstrap.Bootstrap.NetworkCreationParams)
|
||||||
|
|
||||||
|
d.l.Lock()
|
||||||
|
defer d.l.Unlock()
|
||||||
|
|
||||||
if joined, err := alreadyJoined(ctx, d.networks, creationParams); err != nil {
|
if joined, err := alreadyJoined(ctx, d.networks, creationParams); err != nil {
|
||||||
return fmt.Errorf("checking if already joined to network: %w", err)
|
return fmt.Errorf("checking if already joined to network: %w", err)
|
||||||
} else if joined {
|
} else if joined {
|
||||||
@ -178,10 +187,9 @@ func (d *Daemon) JoinNetwork(
|
|||||||
n, err := d.networkLoader.Join(
|
n, err := d.networkLoader.Join(
|
||||||
ctx,
|
ctx,
|
||||||
d.logger.WithNamespace("network"),
|
d.logger.WithNamespace("network"),
|
||||||
|
networkConfig,
|
||||||
newBootstrap,
|
newBootstrap,
|
||||||
&network.Opts{
|
nil,
|
||||||
Config: networkConfig,
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
@ -190,14 +198,17 @@ func (d *Daemon) JoinNetwork(
|
|||||||
}
|
}
|
||||||
|
|
||||||
d.logger.Info(ctx, "Network joined successfully")
|
d.logger.Info(ctx, "Network joined successfully")
|
||||||
d.networks[networkID] = joinedNetwork{n, networkConfig}
|
d.networks[networkID] = joinedNetwork{
|
||||||
|
Network: n,
|
||||||
|
userConfig: true,
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func withNetwork[Res any](
|
func withNetwork[Res any](
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
d *Daemon,
|
d *Daemon,
|
||||||
fn func(context.Context, joinedNetwork) (Res, error),
|
fn func(context.Context, network.Network) (Res, error),
|
||||||
) (
|
) (
|
||||||
Res, error,
|
Res, error,
|
||||||
) {
|
) {
|
||||||
@ -242,12 +253,41 @@ func (d *Daemon) GetNetworks(
|
|||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetConfig applies a new NetworkConfig to a joined network. It uses the same
|
||||||
|
// mechanism as the rest of the [network.RPC] methods on the Daemon to choose a
|
||||||
|
// network.
|
||||||
|
//
|
||||||
|
// Besides the errors related to network choosing which are returned by all
|
||||||
|
// other [network.RPC] methods, this may also return ErrUserManagedNetworkConfig
|
||||||
|
// if the network's configuration is not managed by the Daemon, but is instead
|
||||||
|
// provided via the config by the user.
|
||||||
|
func (d *Daemon) SetConfig(
|
||||||
|
ctx context.Context, config daecommon.NetworkConfig,
|
||||||
|
) error {
|
||||||
|
d.l.RLock()
|
||||||
|
defer d.l.RUnlock()
|
||||||
|
|
||||||
|
// 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.networkLoader, d.networks)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if network.userConfig {
|
||||||
|
return ErrUserManagedNetworkConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
return network.SetConfig(ctx, config)
|
||||||
|
}
|
||||||
|
|
||||||
// GetHost implements the method for the network.RPC interface.
|
// GetHost implements the method for the network.RPC interface.
|
||||||
func (d *Daemon) GetHosts(ctx context.Context) ([]bootstrap.Host, error) {
|
func (d *Daemon) GetHosts(ctx context.Context) ([]bootstrap.Host, error) {
|
||||||
return withNetwork(
|
return withNetwork(
|
||||||
ctx,
|
ctx,
|
||||||
d,
|
d,
|
||||||
func(ctx context.Context, n joinedNetwork) ([]bootstrap.Host, error) {
|
func(ctx context.Context, n network.Network) ([]bootstrap.Host, error) {
|
||||||
return n.GetHosts(ctx)
|
return n.GetHosts(ctx)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -263,7 +303,7 @@ func (d *Daemon) GetGarageClientParams(
|
|||||||
ctx,
|
ctx,
|
||||||
d,
|
d,
|
||||||
func(
|
func(
|
||||||
ctx context.Context, n joinedNetwork,
|
ctx context.Context, n network.Network,
|
||||||
) (
|
) (
|
||||||
network.GarageClientParams, error,
|
network.GarageClientParams, error,
|
||||||
) {
|
) {
|
||||||
@ -283,7 +323,7 @@ func (d *Daemon) GetNebulaCAPublicCredentials(
|
|||||||
ctx,
|
ctx,
|
||||||
d,
|
d,
|
||||||
func(
|
func(
|
||||||
ctx context.Context, n joinedNetwork,
|
ctx context.Context, n network.Network,
|
||||||
) (
|
) (
|
||||||
nebula.CAPublicCredentials, error,
|
nebula.CAPublicCredentials, error,
|
||||||
) {
|
) {
|
||||||
@ -298,7 +338,7 @@ func (d *Daemon) RemoveHost(ctx context.Context, hostName nebula.HostName) error
|
|||||||
ctx,
|
ctx,
|
||||||
d,
|
d,
|
||||||
func(
|
func(
|
||||||
ctx context.Context, n joinedNetwork,
|
ctx context.Context, n network.Network,
|
||||||
) (
|
) (
|
||||||
struct{}, error,
|
struct{}, error,
|
||||||
) {
|
) {
|
||||||
@ -320,7 +360,7 @@ func (d *Daemon) CreateHost(
|
|||||||
ctx,
|
ctx,
|
||||||
d,
|
d,
|
||||||
func(
|
func(
|
||||||
ctx context.Context, n joinedNetwork,
|
ctx context.Context, n network.Network,
|
||||||
) (
|
) (
|
||||||
network.JoiningBootstrap, error,
|
network.JoiningBootstrap, error,
|
||||||
) {
|
) {
|
||||||
@ -341,7 +381,7 @@ func (d *Daemon) CreateNebulaCertificate(
|
|||||||
ctx,
|
ctx,
|
||||||
d,
|
d,
|
||||||
func(
|
func(
|
||||||
ctx context.Context, n joinedNetwork,
|
ctx context.Context, n network.Network,
|
||||||
) (
|
) (
|
||||||
nebula.Certificate, error,
|
nebula.Certificate, error,
|
||||||
) {
|
) {
|
||||||
@ -350,7 +390,6 @@ func (d *Daemon) CreateNebulaCertificate(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetConfig implements the method for the network.RPC interface.
|
|
||||||
func (d *Daemon) GetConfig(
|
func (d *Daemon) GetConfig(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
) (
|
) (
|
||||||
@ -360,7 +399,7 @@ func (d *Daemon) GetConfig(
|
|||||||
ctx,
|
ctx,
|
||||||
d,
|
d,
|
||||||
func(
|
func(
|
||||||
ctx context.Context, n joinedNetwork,
|
ctx context.Context, n network.Network,
|
||||||
) (
|
) (
|
||||||
daecommon.NetworkConfig, error,
|
daecommon.NetworkConfig, error,
|
||||||
) {
|
) {
|
||||||
@ -369,26 +408,6 @@ func (d *Daemon) GetConfig(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetConfig implements the method for the network.RPC interface.
|
|
||||||
func (d *Daemon) SetConfig(
|
|
||||||
ctx context.Context, config daecommon.NetworkConfig,
|
|
||||||
) error {
|
|
||||||
_, err := withNetwork(
|
|
||||||
ctx,
|
|
||||||
d,
|
|
||||||
func(ctx context.Context, n joinedNetwork) (struct{}, error) {
|
|
||||||
if n.config != nil {
|
|
||||||
return struct{}{}, ErrUserManagedNetworkConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO needs to check that public addresses aren't being shared
|
|
||||||
// across networks, and whatever else happens in Config.Validate.
|
|
||||||
return struct{}{}, n.SetConfig(ctx, config)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shutdown blocks until all resources held or created by the daemon,
|
// Shutdown blocks until all resources held or created by the daemon,
|
||||||
// including child processes it has started, have been cleaned up.
|
// including child processes it has started, have been cleaned up.
|
||||||
//
|
//
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
package network
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io/fs"
|
|
||||||
"isle/daemon/daecommon"
|
|
||||||
"isle/jsonutil"
|
|
||||||
"isle/toolkit"
|
|
||||||
"path/filepath"
|
|
||||||
)
|
|
||||||
|
|
||||||
// loadStoreConfig writes the given NetworkConfig to the networkStateDir if the
|
|
||||||
// config is non-nil. If the config is nil then a config is read from
|
|
||||||
// networkStateDir, returning the zero value if no config was previously
|
|
||||||
// stored.
|
|
||||||
func loadStoreConfig(
|
|
||||||
networkStateDir toolkit.Dir, config *daecommon.NetworkConfig,
|
|
||||||
) (
|
|
||||||
daecommon.NetworkConfig, error,
|
|
||||||
) {
|
|
||||||
path := filepath.Join(networkStateDir.Path, "config.json")
|
|
||||||
|
|
||||||
if config == nil {
|
|
||||||
config = new(daecommon.NetworkConfig)
|
|
||||||
err := jsonutil.LoadFile(&config, path)
|
|
||||||
if err != nil && !errors.Is(err, fs.ErrNotExist) {
|
|
||||||
return daecommon.NetworkConfig{}, fmt.Errorf(
|
|
||||||
"loading %q: %w", path, err,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return *config, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := jsonutil.WriteFile(*config, path, 0600); err != nil {
|
|
||||||
return daecommon.NetworkConfig{}, fmt.Errorf(
|
|
||||||
"writing to %q: %w", path, err,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return *config, nil
|
|
||||||
}
|
|
@ -59,6 +59,7 @@ type Loader interface {
|
|||||||
Load(
|
Load(
|
||||||
context.Context,
|
context.Context,
|
||||||
*mlog.Logger,
|
*mlog.Logger,
|
||||||
|
daecommon.NetworkConfig,
|
||||||
bootstrap.CreationParams,
|
bootstrap.CreationParams,
|
||||||
*Opts,
|
*Opts,
|
||||||
) (
|
) (
|
||||||
@ -72,6 +73,7 @@ type Loader interface {
|
|||||||
Join(
|
Join(
|
||||||
context.Context,
|
context.Context,
|
||||||
*mlog.Logger,
|
*mlog.Logger,
|
||||||
|
daecommon.NetworkConfig,
|
||||||
JoiningBootstrap,
|
JoiningBootstrap,
|
||||||
*Opts,
|
*Opts,
|
||||||
) (
|
) (
|
||||||
@ -89,11 +91,12 @@ type Loader interface {
|
|||||||
// - hostName: The name of this first host in the network.
|
// - hostName: The name of this first host in the network.
|
||||||
//
|
//
|
||||||
// Errors:
|
// Errors:
|
||||||
// - ErrInvalidConfig - If the Opts.Config field is not valid. It must be
|
// - ErrInvalidConfig - if daemonConfig doesn't have 3 storage allocations
|
||||||
// non-nil and have at least 3 storage allocations.
|
// configured.
|
||||||
Create(
|
Create(
|
||||||
context.Context,
|
context.Context,
|
||||||
*mlog.Logger,
|
*mlog.Logger,
|
||||||
|
daecommon.NetworkConfig,
|
||||||
bootstrap.CreationParams,
|
bootstrap.CreationParams,
|
||||||
nebula.IPNet,
|
nebula.IPNet,
|
||||||
nebula.HostName,
|
nebula.HostName,
|
||||||
@ -185,7 +188,7 @@ func (l *loader) Loadable(
|
|||||||
creationParams := make([]bootstrap.CreationParams, 0, len(networkStateDirs))
|
creationParams := make([]bootstrap.CreationParams, 0, len(networkStateDirs))
|
||||||
|
|
||||||
for _, networkStateDir := range networkStateDirs {
|
for _, networkStateDir := range networkStateDirs {
|
||||||
thisCreationParams, err := loadCreationParams(networkStateDir)
|
thisCreationParams, err := LoadCreationParams(networkStateDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf(
|
return nil, fmt.Errorf(
|
||||||
"loading creation params from %q: %w",
|
"loading creation params from %q: %w",
|
||||||
@ -202,6 +205,7 @@ func (l *loader) Loadable(
|
|||||||
func (l *loader) Load(
|
func (l *loader) Load(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
logger *mlog.Logger,
|
logger *mlog.Logger,
|
||||||
|
networkConfig daecommon.NetworkConfig,
|
||||||
creationParams bootstrap.CreationParams,
|
creationParams bootstrap.CreationParams,
|
||||||
opts *Opts,
|
opts *Opts,
|
||||||
) (
|
) (
|
||||||
@ -222,6 +226,7 @@ func (l *loader) Load(
|
|||||||
ctx,
|
ctx,
|
||||||
logger.WithNamespace("network"),
|
logger.WithNamespace("network"),
|
||||||
l.envBinDirPath,
|
l.envBinDirPath,
|
||||||
|
networkConfig,
|
||||||
networkStateDir,
|
networkStateDir,
|
||||||
networkRuntimeDir,
|
networkRuntimeDir,
|
||||||
opts,
|
opts,
|
||||||
@ -231,6 +236,7 @@ func (l *loader) Load(
|
|||||||
func (l *loader) Join(
|
func (l *loader) Join(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
logger *mlog.Logger,
|
logger *mlog.Logger,
|
||||||
|
networkConfig daecommon.NetworkConfig,
|
||||||
joiningBootstrap JoiningBootstrap,
|
joiningBootstrap JoiningBootstrap,
|
||||||
opts *Opts,
|
opts *Opts,
|
||||||
) (
|
) (
|
||||||
@ -254,6 +260,7 @@ func (l *loader) Join(
|
|||||||
ctx,
|
ctx,
|
||||||
logger.WithNamespace("network"),
|
logger.WithNamespace("network"),
|
||||||
l.envBinDirPath,
|
l.envBinDirPath,
|
||||||
|
networkConfig,
|
||||||
joiningBootstrap,
|
joiningBootstrap,
|
||||||
networkStateDir,
|
networkStateDir,
|
||||||
networkRuntimeDir,
|
networkRuntimeDir,
|
||||||
@ -264,6 +271,7 @@ func (l *loader) Join(
|
|||||||
func (l *loader) Create(
|
func (l *loader) Create(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
logger *mlog.Logger,
|
logger *mlog.Logger,
|
||||||
|
networkConfig daecommon.NetworkConfig,
|
||||||
creationParams bootstrap.CreationParams,
|
creationParams bootstrap.CreationParams,
|
||||||
ipNet nebula.IPNet,
|
ipNet nebula.IPNet,
|
||||||
hostName nebula.HostName,
|
hostName nebula.HostName,
|
||||||
@ -286,6 +294,7 @@ func (l *loader) Create(
|
|||||||
ctx,
|
ctx,
|
||||||
logger.WithNamespace("network"),
|
logger.WithNamespace("network"),
|
||||||
l.envBinDirPath,
|
l.envBinDirPath,
|
||||||
|
networkConfig,
|
||||||
networkStateDir,
|
networkStateDir,
|
||||||
networkRuntimeDir,
|
networkRuntimeDir,
|
||||||
creationParams,
|
creationParams,
|
||||||
|
@ -154,14 +154,6 @@ type Network interface {
|
|||||||
// Network instance. A nil Opts is equivalent to a zero value.
|
// Network instance. A nil Opts is equivalent to a zero value.
|
||||||
type Opts struct {
|
type Opts struct {
|
||||||
GarageAdminToken string // Will be randomly generated if left unset.
|
GarageAdminToken string // Will be randomly generated if left unset.
|
||||||
|
|
||||||
// Config will be used as the configuration of the Network from its
|
|
||||||
// initialization onwards.
|
|
||||||
//
|
|
||||||
// If not given then the most recent NetworkConfig for the network will be
|
|
||||||
// used, either that which it was most recently initialized with or which
|
|
||||||
// was passed to [SetConfig].
|
|
||||||
Config *daecommon.NetworkConfig
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *Opts) withDefaults() *Opts {
|
func (o *Opts) withDefaults() *Opts {
|
||||||
@ -197,61 +189,44 @@ type network struct {
|
|||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
// newNetwork returns an instantiated *network instance. All initialization
|
// instatiateNetwork returns an instantiated *network instance which has not yet
|
||||||
// steps which are common to all *network creation methods (load, join, create)
|
// been initialized.
|
||||||
// are included here as well.
|
func instatiateNetwork(
|
||||||
func newNetwork(
|
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
logger *mlog.Logger,
|
logger *mlog.Logger,
|
||||||
|
networkConfig daecommon.NetworkConfig,
|
||||||
envBinDirPath string,
|
envBinDirPath string,
|
||||||
stateDir toolkit.Dir,
|
stateDir toolkit.Dir,
|
||||||
runtimeDir toolkit.Dir,
|
runtimeDir toolkit.Dir,
|
||||||
dirsMayExist bool,
|
|
||||||
opts *Opts,
|
opts *Opts,
|
||||||
) (
|
) *network {
|
||||||
*network, error,
|
ctx = context.WithoutCancel(ctx)
|
||||||
) {
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
ctx, cancel := context.WithCancel(context.WithoutCancel(ctx))
|
return &network{
|
||||||
|
logger: logger,
|
||||||
var (
|
networkConfig: networkConfig,
|
||||||
n = &network{
|
envBinDirPath: envBinDirPath,
|
||||||
logger: logger,
|
stateDir: stateDir,
|
||||||
envBinDirPath: envBinDirPath,
|
runtimeDir: runtimeDir,
|
||||||
stateDir: stateDir,
|
opts: opts.withDefaults(),
|
||||||
runtimeDir: runtimeDir,
|
workerCtx: ctx,
|
||||||
opts: opts.withDefaults(),
|
workerCancel: cancel,
|
||||||
workerCtx: ctx,
|
|
||||||
workerCancel: cancel,
|
|
||||||
}
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
|
|
||||||
n.networkConfig, err = loadStoreConfig(n.stateDir, n.opts.Config)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("resolving network config: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
secretsDir, err := n.stateDir.MkChildDir("secrets", dirsMayExist)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("creating secrets dir: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
n.secretsStore = secrets.NewFSStore(secretsDir.Path)
|
|
||||||
|
|
||||||
return n, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadCreationParams returns the CreationParams of a Network which was
|
// LoadCreationParams returns the CreationParams of a Network which was
|
||||||
// Created/Joined with the given state directory.
|
// Created/Joined with the given state directory.
|
||||||
func loadCreationParams(
|
//
|
||||||
|
// TODO probably can be private
|
||||||
|
func LoadCreationParams(
|
||||||
stateDir toolkit.Dir,
|
stateDir toolkit.Dir,
|
||||||
) (
|
) (
|
||||||
bootstrap.CreationParams, error,
|
bootstrap.CreationParams, error,
|
||||||
) {
|
) {
|
||||||
var (
|
var (
|
||||||
// TODO store/load the creation params separately from the rest of the
|
// TODO store/load the creation params separately from the rest of
|
||||||
// bootstrap, since the bootstrap contains potentially the entire host
|
// the bootstrap, since the bootstrap contains potentially the
|
||||||
// list of a network, which could be pretty bulky.
|
// entire host list of a network, which could be pretty bulky.
|
||||||
bootstrapFilePath = bootstrap.StateDirPath(stateDir.Path)
|
bootstrapFilePath = bootstrap.StateDirPath(stateDir.Path)
|
||||||
bs bootstrap.Bootstrap
|
bs bootstrap.Bootstrap
|
||||||
)
|
)
|
||||||
@ -269,23 +244,25 @@ func load(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
logger *mlog.Logger,
|
logger *mlog.Logger,
|
||||||
envBinDirPath string,
|
envBinDirPath string,
|
||||||
|
networkConfig daecommon.NetworkConfig,
|
||||||
stateDir toolkit.Dir,
|
stateDir toolkit.Dir,
|
||||||
runtimeDir toolkit.Dir,
|
runtimeDir toolkit.Dir,
|
||||||
opts *Opts,
|
opts *Opts,
|
||||||
) (
|
) (
|
||||||
Network, error,
|
Network, error,
|
||||||
) {
|
) {
|
||||||
n, err := newNetwork(
|
n := instatiateNetwork(
|
||||||
ctx,
|
ctx,
|
||||||
logger,
|
logger,
|
||||||
|
networkConfig,
|
||||||
envBinDirPath,
|
envBinDirPath,
|
||||||
stateDir,
|
stateDir,
|
||||||
runtimeDir,
|
runtimeDir,
|
||||||
true,
|
|
||||||
opts,
|
opts,
|
||||||
)
|
)
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("instantiating Network: %w", err)
|
if err := n.initializeDirs(true); err != nil {
|
||||||
|
return nil, fmt.Errorf("initializing directories: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -308,6 +285,7 @@ func join(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
logger *mlog.Logger,
|
logger *mlog.Logger,
|
||||||
envBinDirPath string,
|
envBinDirPath string,
|
||||||
|
networkConfig daecommon.NetworkConfig,
|
||||||
joiningBootstrap JoiningBootstrap,
|
joiningBootstrap JoiningBootstrap,
|
||||||
stateDir toolkit.Dir,
|
stateDir toolkit.Dir,
|
||||||
runtimeDir toolkit.Dir,
|
runtimeDir toolkit.Dir,
|
||||||
@ -315,17 +293,18 @@ func join(
|
|||||||
) (
|
) (
|
||||||
Network, error,
|
Network, error,
|
||||||
) {
|
) {
|
||||||
n, err := newNetwork(
|
n := instatiateNetwork(
|
||||||
ctx,
|
ctx,
|
||||||
logger,
|
logger,
|
||||||
|
networkConfig,
|
||||||
envBinDirPath,
|
envBinDirPath,
|
||||||
stateDir,
|
stateDir,
|
||||||
runtimeDir,
|
runtimeDir,
|
||||||
false,
|
|
||||||
opts,
|
opts,
|
||||||
)
|
)
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("instantiating Network: %w", err)
|
if err := n.initializeDirs(false); err != nil {
|
||||||
|
return nil, fmt.Errorf("initializing directories: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := secrets.Import(
|
if err := secrets.Import(
|
||||||
@ -345,6 +324,7 @@ func create(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
logger *mlog.Logger,
|
logger *mlog.Logger,
|
||||||
envBinDirPath string,
|
envBinDirPath string,
|
||||||
|
networkConfig daecommon.NetworkConfig,
|
||||||
stateDir toolkit.Dir,
|
stateDir toolkit.Dir,
|
||||||
runtimeDir toolkit.Dir,
|
runtimeDir toolkit.Dir,
|
||||||
creationParams bootstrap.CreationParams,
|
creationParams bootstrap.CreationParams,
|
||||||
@ -354,6 +334,12 @@ func create(
|
|||||||
) (
|
) (
|
||||||
Network, error,
|
Network, error,
|
||||||
) {
|
) {
|
||||||
|
if len(networkConfig.Storage.Allocations) < 3 {
|
||||||
|
return nil, ErrInvalidConfig.WithData(
|
||||||
|
"At least three storage allocations are required.",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
nebulaCACreds, err := nebula.NewCACredentials(creationParams.Domain, ipNet)
|
nebulaCACreds, err := nebula.NewCACredentials(creationParams.Domain, ipNet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("creating nebula CA cert: %w", err)
|
return nil, fmt.Errorf("creating nebula CA cert: %w", err)
|
||||||
@ -361,23 +347,18 @@ func create(
|
|||||||
|
|
||||||
garageRPCSecret := toolkit.RandStr(32)
|
garageRPCSecret := toolkit.RandStr(32)
|
||||||
|
|
||||||
n, err := newNetwork(
|
n := instatiateNetwork(
|
||||||
ctx,
|
ctx,
|
||||||
logger,
|
logger,
|
||||||
|
networkConfig,
|
||||||
envBinDirPath,
|
envBinDirPath,
|
||||||
stateDir,
|
stateDir,
|
||||||
runtimeDir,
|
runtimeDir,
|
||||||
false,
|
|
||||||
opts,
|
opts,
|
||||||
)
|
)
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("instantiating Network: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(n.networkConfig.Storage.Allocations) < 3 {
|
if err := n.initializeDirs(false); err != nil {
|
||||||
return nil, ErrInvalidConfig.WithData(
|
return nil, fmt.Errorf("initializing directories: %w", err)
|
||||||
"At least three storage allocations are required.",
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = daecommon.SetGarageRPCSecret(ctx, n.secretsStore, garageRPCSecret)
|
err = daecommon.SetGarageRPCSecret(ctx, n.secretsStore, garageRPCSecret)
|
||||||
@ -410,6 +391,16 @@ func create(
|
|||||||
return n, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *network) initializeDirs(mayExist bool) error {
|
||||||
|
secretsDir, err := n.stateDir.MkChildDir("secrets", mayExist)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("creating secrets dir: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
n.secretsStore = secrets.NewFSStore(secretsDir.Path)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (n *network) periodically(
|
func (n *network) periodically(
|
||||||
label string,
|
label string,
|
||||||
fn func(context.Context) error,
|
fn func(context.Context) error,
|
||||||
@ -1025,10 +1016,6 @@ func (n *network) GetConfig(context.Context) (daecommon.NetworkConfig, error) {
|
|||||||
func (n *network) SetConfig(
|
func (n *network) SetConfig(
|
||||||
ctx context.Context, config daecommon.NetworkConfig,
|
ctx context.Context, config daecommon.NetworkConfig,
|
||||||
) error {
|
) error {
|
||||||
if _, err := loadStoreConfig(n.stateDir, &config); err != nil {
|
|
||||||
return fmt.Errorf("storing new config: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
prevBootstrap, err := n.reload(ctx, &config, nil)
|
prevBootstrap, err := n.reload(ctx, &config, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("reloading config: %w", err)
|
return fmt.Errorf("reloading config: %w", err)
|
||||||
|
@ -17,7 +17,7 @@ func TestCreate(t *testing.T) {
|
|||||||
network = h.createNetwork(t, "primus", nil)
|
network = h.createNetwork(t, "primus", nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
gotCreationParams, err := loadCreationParams(network.stateDir)
|
gotCreationParams, err := LoadCreationParams(network.stateDir)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(
|
assert.Equal(
|
||||||
t, gotCreationParams, network.getBootstrap(t).NetworkCreationParams,
|
t, gotCreationParams, network.getBootstrap(t).NetworkCreationParams,
|
||||||
@ -25,30 +25,31 @@ func TestCreate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestLoad(t *testing.T) {
|
func TestLoad(t *testing.T) {
|
||||||
t.Run("given config", func(t *testing.T) {
|
var (
|
||||||
var (
|
h = newIntegrationHarness(t)
|
||||||
h = newIntegrationHarness(t)
|
network = h.createNetwork(t, "primus", &createNetworkOpts{
|
||||||
network = h.createNetwork(t, "primus", nil)
|
manualShutdown: true,
|
||||||
networkConfig = network.getConfig(t)
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
network.opts.Config = &networkConfig
|
t.Log("Shutting down network")
|
||||||
network.restart(t)
|
assert.NoError(t, network.Shutdown())
|
||||||
|
|
||||||
assert.Equal(t, networkConfig, network.getConfig(t))
|
t.Log("Calling Load")
|
||||||
})
|
loadedNetwork, err := load(
|
||||||
|
h.ctx,
|
||||||
|
h.logger.WithNamespace("loadedNetwork"),
|
||||||
|
getEnvBinDirPath(),
|
||||||
|
network.getConfig(t),
|
||||||
|
network.stateDir,
|
||||||
|
h.mkDir(t, "runtime"),
|
||||||
|
network.opts,
|
||||||
|
)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
t.Run("load previous config", func(t *testing.T) {
|
t.Cleanup(func() {
|
||||||
var (
|
t.Log("Shutting down loadedNetwork")
|
||||||
h = newIntegrationHarness(t)
|
assert.NoError(t, loadedNetwork.Shutdown())
|
||||||
network = h.createNetwork(t, "primus", nil)
|
|
||||||
networkConfig = network.getConfig(t)
|
|
||||||
)
|
|
||||||
|
|
||||||
network.opts.Config = nil
|
|
||||||
network.restart(t)
|
|
||||||
|
|
||||||
assert.Equal(t, networkConfig, network.getConfig(t))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +61,13 @@ func TestJoin(t *testing.T) {
|
|||||||
secondus = h.joinNetwork(t, primus, "secondus", nil)
|
secondus = h.joinNetwork(t, primus, "secondus", nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
assert.Equal(t, primus.getHostsByName(t), secondus.getHostsByName(t))
|
primusHosts, err := primus.GetHosts(h.ctx)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
secondusHosts, err := secondus.GetHosts(h.ctx)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, primusHosts, secondusHosts)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("with alloc", func(t *testing.T) {
|
t.Run("with alloc", func(t *testing.T) {
|
||||||
@ -77,10 +84,28 @@ func TestJoin(t *testing.T) {
|
|||||||
t.Log("reloading primus' hosts")
|
t.Log("reloading primus' hosts")
|
||||||
assert.NoError(t, primus.Network.(*network).reloadHosts(h.ctx))
|
assert.NoError(t, primus.Network.(*network).reloadHosts(h.ctx))
|
||||||
|
|
||||||
assert.Equal(t, primus.getHostsByName(t), secondus.getHostsByName(t))
|
primusHosts, err := primus.GetHosts(h.ctx)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
secondusHosts, err := secondus.GetHosts(h.ctx)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, primusHosts, secondusHosts)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNetwork_GetConfig(t *testing.T) {
|
||||||
|
var (
|
||||||
|
h = newIntegrationHarness(t)
|
||||||
|
network = h.createNetwork(t, "primus", nil)
|
||||||
|
)
|
||||||
|
|
||||||
|
config, err := network.GetConfig(h.ctx)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, config, network.getConfig(t))
|
||||||
|
}
|
||||||
|
|
||||||
func TestNetwork_SetConfig(t *testing.T) {
|
func TestNetwork_SetConfig(t *testing.T) {
|
||||||
allocsToRoles := func(
|
allocsToRoles := func(
|
||||||
hostName nebula.HostName, allocs []bootstrap.GarageHostInstance,
|
hostName nebula.HostName, allocs []bootstrap.GarageHostInstance,
|
||||||
@ -234,22 +259,4 @@ func TestNetwork_SetConfig(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotContains(t, layout.Roles, removedRole)
|
assert.NotContains(t, layout.Roles, removedRole)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("changes reflected after restart", func(t *testing.T) {
|
|
||||||
var (
|
|
||||||
h = newIntegrationHarness(t)
|
|
||||||
network = h.createNetwork(t, "primus", &createNetworkOpts{
|
|
||||||
numStorageAllocs: 4,
|
|
||||||
})
|
|
||||||
networkConfig = network.getConfig(t)
|
|
||||||
)
|
|
||||||
|
|
||||||
networkConfig.Storage.Allocations = networkConfig.Storage.Allocations[:3]
|
|
||||||
assert.NoError(t, network.SetConfig(h.ctx, networkConfig))
|
|
||||||
|
|
||||||
network.opts.Config = nil
|
|
||||||
network.restart(t)
|
|
||||||
|
|
||||||
assert.Equal(t, networkConfig, network.getConfig(t))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -203,7 +203,7 @@ func (h *integrationHarness) createNetwork(
|
|||||||
t *testing.T,
|
t *testing.T,
|
||||||
hostNameStr string,
|
hostNameStr string,
|
||||||
opts *createNetworkOpts,
|
opts *createNetworkOpts,
|
||||||
) *integrationHarnessNetwork {
|
) integrationHarnessNetwork {
|
||||||
t.Logf("Creating as %q", hostNameStr)
|
t.Logf("Creating as %q", hostNameStr)
|
||||||
opts = opts.withDefaults()
|
opts = opts.withDefaults()
|
||||||
|
|
||||||
@ -222,7 +222,6 @@ func (h *integrationHarness) createNetwork(
|
|||||||
|
|
||||||
networkOpts = &Opts{
|
networkOpts = &Opts{
|
||||||
GarageAdminToken: "admin_token",
|
GarageAdminToken: "admin_token",
|
||||||
Config: &networkConfig,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -230,6 +229,7 @@ func (h *integrationHarness) createNetwork(
|
|||||||
h.ctx,
|
h.ctx,
|
||||||
logger,
|
logger,
|
||||||
getEnvBinDirPath(),
|
getEnvBinDirPath(),
|
||||||
|
networkConfig,
|
||||||
stateDir,
|
stateDir,
|
||||||
runtimeDir,
|
runtimeDir,
|
||||||
opts.creationParams,
|
opts.creationParams,
|
||||||
@ -241,7 +241,16 @@ func (h *integrationHarness) createNetwork(
|
|||||||
t.Fatalf("creating Network: %v", err)
|
t.Fatalf("creating Network: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
nh := &integrationHarnessNetwork{
|
if !opts.manualShutdown {
|
||||||
|
t.Cleanup(func() {
|
||||||
|
t.Logf("Shutting down Network %q", hostNameStr)
|
||||||
|
if err := network.Shutdown(); err != nil {
|
||||||
|
t.Logf("Shutting down Network %q failed: %v", hostNameStr, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return integrationHarnessNetwork{
|
||||||
network,
|
network,
|
||||||
h.ctx,
|
h.ctx,
|
||||||
logger,
|
logger,
|
||||||
@ -250,17 +259,6 @@ func (h *integrationHarness) createNetwork(
|
|||||||
runtimeDir,
|
runtimeDir,
|
||||||
networkOpts,
|
networkOpts,
|
||||||
}
|
}
|
||||||
|
|
||||||
if !opts.manualShutdown {
|
|
||||||
t.Cleanup(func() {
|
|
||||||
t.Logf("Shutting down Network %q", hostNameStr)
|
|
||||||
if err := nh.Shutdown(); err != nil {
|
|
||||||
t.Logf("Shutting down Network %q failed: %v", hostNameStr, err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return nh
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type joinNetworkOpts struct {
|
type joinNetworkOpts struct {
|
||||||
@ -281,10 +279,10 @@ func (o *joinNetworkOpts) withDefaults() *joinNetworkOpts {
|
|||||||
|
|
||||||
func (h *integrationHarness) joinNetwork(
|
func (h *integrationHarness) joinNetwork(
|
||||||
t *testing.T,
|
t *testing.T,
|
||||||
network *integrationHarnessNetwork,
|
network integrationHarnessNetwork,
|
||||||
hostNameStr string,
|
hostNameStr string,
|
||||||
opts *joinNetworkOpts,
|
opts *joinNetworkOpts,
|
||||||
) *integrationHarnessNetwork {
|
) integrationHarnessNetwork {
|
||||||
opts = opts.withDefaults()
|
opts = opts.withDefaults()
|
||||||
hostName := nebula.HostName(hostNameStr)
|
hostName := nebula.HostName(hostNameStr)
|
||||||
|
|
||||||
@ -303,7 +301,6 @@ func (h *integrationHarness) joinNetwork(
|
|||||||
runtimeDir = h.mkDir(t, "runtime")
|
runtimeDir = h.mkDir(t, "runtime")
|
||||||
networkOpts = &Opts{
|
networkOpts = &Opts{
|
||||||
GarageAdminToken: "admin_token",
|
GarageAdminToken: "admin_token",
|
||||||
Config: &networkConfig,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -312,6 +309,7 @@ func (h *integrationHarness) joinNetwork(
|
|||||||
h.ctx,
|
h.ctx,
|
||||||
logger,
|
logger,
|
||||||
getEnvBinDirPath(),
|
getEnvBinDirPath(),
|
||||||
|
networkConfig,
|
||||||
joiningBootstrap,
|
joiningBootstrap,
|
||||||
stateDir,
|
stateDir,
|
||||||
runtimeDir,
|
runtimeDir,
|
||||||
@ -321,7 +319,16 @@ func (h *integrationHarness) joinNetwork(
|
|||||||
t.Fatalf("joining network: %v", err)
|
t.Fatalf("joining network: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
nh := &integrationHarnessNetwork{
|
if !opts.manualShutdown {
|
||||||
|
t.Cleanup(func() {
|
||||||
|
t.Logf("Shutting down Network %q", hostNameStr)
|
||||||
|
if err := joinedNetwork.Shutdown(); err != nil {
|
||||||
|
t.Logf("Shutting down Network %q failed: %v", hostNameStr, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return integrationHarnessNetwork{
|
||||||
joinedNetwork,
|
joinedNetwork,
|
||||||
h.ctx,
|
h.ctx,
|
||||||
logger,
|
logger,
|
||||||
@ -330,34 +337,6 @@ func (h *integrationHarness) joinNetwork(
|
|||||||
runtimeDir,
|
runtimeDir,
|
||||||
networkOpts,
|
networkOpts,
|
||||||
}
|
}
|
||||||
|
|
||||||
if !opts.manualShutdown {
|
|
||||||
t.Cleanup(func() {
|
|
||||||
t.Logf("Shutting down Network %q", hostNameStr)
|
|
||||||
if err := nh.Shutdown(); err != nil {
|
|
||||||
t.Logf("Shutting down Network %q failed: %v", hostNameStr, err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return nh
|
|
||||||
}
|
|
||||||
|
|
||||||
func (nh *integrationHarnessNetwork) restart(t *testing.T) {
|
|
||||||
t.Log("Shutting down network (restart)")
|
|
||||||
require.NoError(t, nh.Network.Shutdown())
|
|
||||||
|
|
||||||
t.Log("Loading network (restart)")
|
|
||||||
var err error
|
|
||||||
nh.Network, err = load(
|
|
||||||
nh.ctx,
|
|
||||||
nh.logger,
|
|
||||||
getEnvBinDirPath(),
|
|
||||||
nh.stateDir,
|
|
||||||
nh.runtimeDir,
|
|
||||||
nh.opts,
|
|
||||||
)
|
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (nh *integrationHarnessNetwork) getConfig(t *testing.T) daecommon.NetworkConfig {
|
func (nh *integrationHarnessNetwork) getConfig(t *testing.T) daecommon.NetworkConfig {
|
||||||
|
@ -26,23 +26,15 @@ type RPC interface {
|
|||||||
|
|
||||||
GetNetworks(context.Context) ([]bootstrap.CreationParams, error)
|
GetNetworks(context.Context) ([]bootstrap.CreationParams, error)
|
||||||
|
|
||||||
// SetConfig extends the [network.RPC] method of the same name such that
|
|
||||||
// [ErrUserManagedNetworkConfig] is returned if the picked network is
|
|
||||||
// configured as part of the [daecommon.Config] which the Daemon was
|
|
||||||
// initialized with.
|
|
||||||
//
|
|
||||||
// See the `network.RPC` documentation in this interface for more usage
|
|
||||||
// details.
|
|
||||||
SetConfig(context.Context, daecommon.NetworkConfig) error
|
SetConfig(context.Context, daecommon.NetworkConfig) error
|
||||||
|
|
||||||
// All network.RPC methods are automatically implemented by Daemon using the
|
// All network.RPC methods are automatically implemented by Daemon using the
|
||||||
// currently joined network. If no network is joined then any call to these
|
// currently joined network. If no network is joined then any call to these
|
||||||
// methods will return ErrNoNetwork.
|
// methods will return ErrNoNetwork.
|
||||||
//
|
//
|
||||||
// If more than one Network is joined then all calls to these methods must
|
// All calls to these methods must be accompanied with a context produced by
|
||||||
// be accompanied with a context produced by WithNetwork, in order to choose
|
// WithNetwork, in order to choose the network. These methods may return
|
||||||
// the network. These methods may return these errors, in addition to those
|
// these errors, in addition to those documented on the individual methods:
|
||||||
// documented on the individual methods:
|
|
||||||
//
|
//
|
||||||
// Errors:
|
// Errors:
|
||||||
// - ErrNoNetwork
|
// - ErrNoNetwork
|
||||||
|
Loading…
Reference in New Issue
Block a user