Re-organize some reload logic
This commit is contained in:
parent
88ffa97c0f
commit
433328524d
@ -25,19 +25,21 @@ const (
|
|||||||
garageGlobalBucketBootstrapHostsDirPath = "bootstrap/hosts"
|
garageGlobalBucketBootstrapHostsDirPath = "bootstrap/hosts"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (n *network) getGarageClientParams(
|
func getGarageClientParams(
|
||||||
ctx context.Context, currBootstrap bootstrap.Bootstrap,
|
ctx context.Context,
|
||||||
|
secretsStore secrets.Store,
|
||||||
|
currBootstrap bootstrap.Bootstrap,
|
||||||
) (
|
) (
|
||||||
GarageClientParams, error,
|
GarageClientParams, error,
|
||||||
) {
|
) {
|
||||||
creds, err := daecommon.GetGarageS3APIGlobalBucketCredentials(
|
creds, err := daecommon.GetGarageS3APIGlobalBucketCredentials(
|
||||||
ctx, n.secretsStore,
|
ctx, secretsStore,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return GarageClientParams{}, fmt.Errorf("getting garage global bucket creds: %w", err)
|
return GarageClientParams{}, fmt.Errorf("getting garage global bucket creds: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
rpcSecret, err := daecommon.GetGarageRPCSecret(ctx, n.secretsStore)
|
rpcSecret, err := daecommon.GetGarageRPCSecret(ctx, secretsStore)
|
||||||
if err != nil && !errors.Is(err, secrets.ErrNotFound) {
|
if err != nil && !errors.Is(err, secrets.ErrNotFound) {
|
||||||
return GarageClientParams{}, fmt.Errorf("getting garage rpc secret: %w", err)
|
return GarageClientParams{}, fmt.Errorf("getting garage rpc secret: %w", err)
|
||||||
}
|
}
|
||||||
@ -155,12 +157,17 @@ func garageInitializeGlobalBucket(
|
|||||||
return creds, nil
|
return creds, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *network) getGarageBootstrapHosts(
|
func getGarageBootstrapHosts(
|
||||||
ctx context.Context, currBootstrap bootstrap.Bootstrap,
|
ctx context.Context,
|
||||||
|
logger *mlog.Logger,
|
||||||
|
secretsStore secrets.Store,
|
||||||
|
currBootstrap bootstrap.Bootstrap,
|
||||||
) (
|
) (
|
||||||
map[nebula.HostName]bootstrap.Host, error,
|
map[nebula.HostName]bootstrap.Host, error,
|
||||||
) {
|
) {
|
||||||
garageClientParams, err := n.getGarageClientParams(ctx, currBootstrap)
|
garageClientParams, err := getGarageClientParams(
|
||||||
|
ctx, secretsStore, currBootstrap,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("getting garage client params: %w", err)
|
return nil, fmt.Errorf("getting garage client params: %w", err)
|
||||||
}
|
}
|
||||||
@ -202,13 +209,13 @@ func (n *network) getGarageBootstrapHosts(
|
|||||||
obj.Close()
|
obj.Close()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
n.logger.Warn(ctx, "Object contains invalid json", err)
|
logger.Warn(ctx, "Object contains invalid json", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
host, err := authedHost.Unwrap(currBootstrap.CAPublicCredentials)
|
host, err := authedHost.Unwrap(currBootstrap.CAPublicCredentials)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
n.logger.Warn(ctx, "Host could not be authenticated", err)
|
logger.Warn(ctx, "Host could not be authenticated", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
hosts[host.Name] = host
|
hosts[host.Name] = host
|
||||||
@ -220,10 +227,14 @@ func (n *network) getGarageBootstrapHosts(
|
|||||||
// putGarageBoostrapHost places the <hostname>.json.signed file for this host
|
// putGarageBoostrapHost places the <hostname>.json.signed file for this host
|
||||||
// into garage so that other hosts are able to see relevant configuration for
|
// into garage so that other hosts are able to see relevant configuration for
|
||||||
// it.
|
// it.
|
||||||
func (n *network) putGarageBoostrapHost(
|
func putGarageBoostrapHost(
|
||||||
ctx context.Context, currBootstrap bootstrap.Bootstrap,
|
ctx context.Context,
|
||||||
|
secretsStore secrets.Store,
|
||||||
|
currBootstrap bootstrap.Bootstrap,
|
||||||
) error {
|
) error {
|
||||||
garageClientParams, err := n.getGarageClientParams(ctx, currBootstrap)
|
garageClientParams, err := getGarageClientParams(
|
||||||
|
ctx, secretsStore, currBootstrap,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("getting garage client params: %w", err)
|
return fmt.Errorf("getting garage client params: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -166,8 +166,7 @@ func (o *Opts) withDefaults() *Opts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type network struct {
|
type network struct {
|
||||||
logger *mlog.Logger
|
logger *mlog.Logger
|
||||||
networkConfig daecommon.NetworkConfig
|
|
||||||
|
|
||||||
envBinDirPath string
|
envBinDirPath string
|
||||||
stateDir toolkit.Dir
|
stateDir toolkit.Dir
|
||||||
@ -179,6 +178,7 @@ type network struct {
|
|||||||
|
|
||||||
l sync.RWMutex
|
l sync.RWMutex
|
||||||
children *children.Children
|
children *children.Children
|
||||||
|
networkConfig daecommon.NetworkConfig
|
||||||
currBootstrap bootstrap.Bootstrap
|
currBootstrap bootstrap.Bootstrap
|
||||||
|
|
||||||
shutdownCh chan struct{}
|
shutdownCh chan struct{}
|
||||||
@ -455,8 +455,8 @@ func (n *network) initialize(
|
|||||||
// Do this now so that everything is stable before returning. This also
|
// Do this now so that everything is stable before returning. This also
|
||||||
// serves a dual-purpose, as it makes sure that the PUT from the postInit
|
// serves a dual-purpose, as it makes sure that the PUT from the postInit
|
||||||
// above has propagated from the local garage instance, if there is one.
|
// above has propagated from the local garage instance, if there is one.
|
||||||
n.logger.Info(ctx, "Reloading bootstrap from network")
|
n.logger.Info(ctx, "Reloading hosts from network storage")
|
||||||
if err = n.reload(ctx); err != nil {
|
if err = n.reloadHosts(ctx); err != nil {
|
||||||
return fmt.Errorf("Reloading network bootstrap: %w", err)
|
return fmt.Errorf("Reloading network bootstrap: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -523,20 +523,24 @@ func (n *network) postInit(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
n.logger.Info(ctx, "Updating host info in garage")
|
n.logger.Info(ctx, "Updating host info in garage")
|
||||||
if err = n.putGarageBoostrapHost(ctx, n.currBootstrap); err != nil {
|
err = putGarageBoostrapHost(ctx, n.secretsStore, n.currBootstrap)
|
||||||
|
if err != nil {
|
||||||
return fmt.Errorf("updating host info in garage: %w", err)
|
return fmt.Errorf("updating host info in garage: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *network) reload(ctx context.Context) error {
|
func (n *network) reloadHosts(ctx context.Context) error {
|
||||||
n.l.RLock()
|
n.l.RLock()
|
||||||
|
networkConfig := n.networkConfig
|
||||||
currBootstrap := n.currBootstrap
|
currBootstrap := n.currBootstrap
|
||||||
n.l.RUnlock()
|
n.l.RUnlock()
|
||||||
|
|
||||||
n.logger.Info(ctx, "Checking for bootstrap changes")
|
n.logger.Info(ctx, "Checking for bootstrap changes")
|
||||||
newHosts, err := n.getGarageBootstrapHosts(ctx, currBootstrap)
|
newHosts, err := getGarageBootstrapHosts(
|
||||||
|
ctx, n.logger, n.secretsStore, currBootstrap,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("getting hosts from garage: %w", err)
|
return fmt.Errorf("getting hosts from garage: %w", err)
|
||||||
}
|
}
|
||||||
@ -546,7 +550,11 @@ func (n *network) reload(ctx context.Context) error {
|
|||||||
// garage and the bootstrap, but then this reload call removes the
|
// garage and the bootstrap, but then this reload call removes the
|
||||||
// host from this bootstrap/children until the next reload.
|
// host from this bootstrap/children until the next reload.
|
||||||
|
|
||||||
if err := n.reloadWithHosts(ctx, currBootstrap, newHosts); err != nil {
|
newBootstrap := currBootstrap
|
||||||
|
newBootstrap.Hosts = newHosts
|
||||||
|
|
||||||
|
err = n.reload(ctx, networkConfig, newBootstrap)
|
||||||
|
if err != nil {
|
||||||
return fmt.Errorf("reloading with new host data: %w", err)
|
return fmt.Errorf("reloading with new host data: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -554,7 +562,8 @@ func (n *network) reload(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n *network) reloadLoop(ctx context.Context) {
|
func (n *network) reloadLoop(ctx context.Context) {
|
||||||
ticker := time.NewTicker(3 * time.Minute)
|
const period = 3 * time.Minute
|
||||||
|
ticker := time.NewTicker(period)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@ -563,7 +572,7 @@ func (n *network) reloadLoop(ctx context.Context) {
|
|||||||
return
|
return
|
||||||
|
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
if err := n.reload(ctx); err != nil {
|
if err := n.reloadHosts(ctx); err != nil {
|
||||||
n.logger.Error(ctx, "Attempting to reload", err)
|
n.logger.Error(ctx, "Attempting to reload", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -571,27 +580,31 @@ func (n *network) reloadLoop(ctx context.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// reloadWithHosts will check the existing hosts data from currBootstrap against
|
// reload will check the existing hosts data from currBootstrap against
|
||||||
// a potentially updated set of hosts data, and if there are any differences
|
// a potentially updated set of hosts data, and if there are any differences
|
||||||
// will perform whatever changes are necessary.
|
// will perform whatever changes are necessary.
|
||||||
func (n *network) reloadWithHosts(
|
func (n *network) reload(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
currBootstrap bootstrap.Bootstrap,
|
newNetworkConfig daecommon.NetworkConfig,
|
||||||
newHosts map[nebula.HostName]bootstrap.Host,
|
newBootstrap bootstrap.Bootstrap,
|
||||||
) error {
|
) error {
|
||||||
var (
|
n.l.Lock()
|
||||||
newBootstrap = currBootstrap
|
defer n.l.Unlock()
|
||||||
thisHost = currBootstrap.ThisHost()
|
|
||||||
)
|
|
||||||
|
|
||||||
newBootstrap.Hosts = newHosts
|
|
||||||
|
|
||||||
// the daemon's view of this host's bootstrap info takes precedence over
|
// the daemon's view of this host's bootstrap info takes precedence over
|
||||||
// whatever is in garage
|
// whatever is in garage. The garage version lacks the private credentials
|
||||||
|
// which must be stored locally.
|
||||||
|
thisHost := n.currBootstrap.ThisHost()
|
||||||
newBootstrap.Hosts[thisHost.Name] = thisHost
|
newBootstrap.Hosts[thisHost.Name] = thisHost
|
||||||
|
|
||||||
|
n.logger.Info(ctx, "Writing updated bootstrap to state dir")
|
||||||
|
err := writeBootstrapToStateDir(n.stateDir.Path, newBootstrap)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("writing bootstrap to state dir: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
diff, err := children.CalculateReloadDiff(
|
diff, err := children.CalculateReloadDiff(
|
||||||
n.networkConfig, currBootstrap, newBootstrap,
|
n.networkConfig, n.currBootstrap, newBootstrap,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("calculating diff between bootstraps: %w", err)
|
return fmt.Errorf("calculating diff between bootstraps: %w", err)
|
||||||
@ -600,13 +613,11 @@ func (n *network) reloadWithHosts(
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
n.logger.Info(ctx, "Bootstrap has changed, storing new bootstrap")
|
n.networkConfig = newNetworkConfig
|
||||||
n.l.Lock()
|
|
||||||
networkConfig := n.networkConfig
|
|
||||||
n.currBootstrap = newBootstrap
|
n.currBootstrap = newBootstrap
|
||||||
n.l.Unlock()
|
|
||||||
|
|
||||||
err = n.children.Reload(ctx, networkConfig, newBootstrap, diff)
|
n.logger.Info(ctx, "Reloading child processes")
|
||||||
|
err = n.children.Reload(ctx, newNetworkConfig, newBootstrap, diff)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("reloading child processes (diff:%+v): %w", diff, err)
|
return fmt.Errorf("reloading child processes (diff:%+v): %w", diff, err)
|
||||||
}
|
}
|
||||||
@ -637,18 +648,17 @@ func (n *network) getBootstrap() (
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n *network) GetHosts(ctx context.Context) ([]bootstrap.Host, error) {
|
func (n *network) GetHosts(ctx context.Context) ([]bootstrap.Host, error) {
|
||||||
// TODO use withCurrBootstrap in here
|
return withCurrBootstrap(n, func(
|
||||||
b, err := n.getBootstrap()
|
currBootstrap bootstrap.Bootstrap,
|
||||||
if err != nil {
|
) (
|
||||||
return nil, fmt.Errorf("retrieving bootstrap: %w", err)
|
[]bootstrap.Host, error,
|
||||||
}
|
) {
|
||||||
|
hosts := maps.Values(currBootstrap.Hosts)
|
||||||
hosts := maps.Values(b.Hosts)
|
slices.SortFunc(hosts, func(a, b bootstrap.Host) int {
|
||||||
slices.SortFunc(hosts, func(a, b bootstrap.Host) int {
|
return cmp.Compare(a.Name, b.Name)
|
||||||
return cmp.Compare(a.Name, b.Name)
|
})
|
||||||
|
return hosts, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
return hosts, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *network) GetGarageClientParams(
|
func (n *network) GetGarageClientParams(
|
||||||
@ -661,7 +671,7 @@ func (n *network) GetGarageClientParams(
|
|||||||
) (
|
) (
|
||||||
GarageClientParams, error,
|
GarageClientParams, error,
|
||||||
) {
|
) {
|
||||||
return n.getGarageClientParams(ctx, currBootstrap)
|
return getGarageClientParams(ctx, n.secretsStore, currBootstrap)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -688,7 +698,9 @@ func (n *network) RemoveHost(ctx context.Context, hostName nebula.HostName) erro
|
|||||||
) (
|
) (
|
||||||
struct{}, error,
|
struct{}, error,
|
||||||
) {
|
) {
|
||||||
garageClientParams, err := n.getGarageClientParams(ctx, currBootstrap)
|
garageClientParams, err := getGarageClientParams(
|
||||||
|
ctx, n.secretsStore, currBootstrap,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return struct{}{}, fmt.Errorf("get garage client params: %w", err)
|
return struct{}{}, fmt.Errorf("get garage client params: %w", err)
|
||||||
}
|
}
|
||||||
@ -798,6 +810,7 @@ func (n *network) CreateHost(
|
|||||||
JoiningBootstrap, error,
|
JoiningBootstrap, error,
|
||||||
) {
|
) {
|
||||||
n.l.RLock()
|
n.l.RLock()
|
||||||
|
networkConfig := n.networkConfig
|
||||||
currBootstrap := n.currBootstrap
|
currBootstrap := n.currBootstrap
|
||||||
n.l.RUnlock()
|
n.l.RUnlock()
|
||||||
|
|
||||||
@ -851,17 +864,19 @@ func (n *network) CreateHost(
|
|||||||
}
|
}
|
||||||
|
|
||||||
n.logger.Info(ctx, "Putting new host in garage")
|
n.logger.Info(ctx, "Putting new host in garage")
|
||||||
err = n.putGarageBoostrapHost(ctx, joiningBootstrap.Bootstrap)
|
err = putGarageBoostrapHost(ctx, n.secretsStore, joiningBootstrap.Bootstrap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return JoiningBootstrap{}, fmt.Errorf("putting new host in garage: %w", err)
|
return JoiningBootstrap{}, fmt.Errorf("putting new host in garage: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// the new bootstrap will have been initialized with both all existing hosts
|
// the new bootstrap will have been initialized with both all existing hosts
|
||||||
// (based on currBootstrap) and the host being created.
|
// (based on currBootstrap) and the host being created.
|
||||||
newHosts := joiningBootstrap.Bootstrap.Hosts
|
newBootstrap := currBootstrap
|
||||||
|
newBootstrap.Hosts = joiningBootstrap.Bootstrap.Hosts
|
||||||
|
|
||||||
n.logger.Info(ctx, "Reloading local state with new host")
|
n.logger.Info(ctx, "Reloading local state with new host")
|
||||||
if err := n.reloadWithHosts(ctx, currBootstrap, newHosts); err != nil {
|
err = n.reload(ctx, networkConfig, newBootstrap)
|
||||||
|
if err != nil {
|
||||||
return JoiningBootstrap{}, fmt.Errorf("reloading child processes: %w", err)
|
return JoiningBootstrap{}, fmt.Errorf("reloading child processes: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -900,6 +915,8 @@ func (n *network) CreateNebulaCertificate(
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n *network) GetConfig(context.Context) (daecommon.NetworkConfig, error) {
|
func (n *network) GetConfig(context.Context) (daecommon.NetworkConfig, error) {
|
||||||
|
n.l.RLock()
|
||||||
|
defer n.l.RUnlock()
|
||||||
return n.networkConfig, nil
|
return n.networkConfig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -957,7 +974,6 @@ func (n *network) GetNetworkCreationParams(
|
|||||||
) (
|
) (
|
||||||
bootstrap.CreationParams, error,
|
bootstrap.CreationParams, error,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
return withCurrBootstrap(n, func(
|
return withCurrBootstrap(n, func(
|
||||||
currBootstrap bootstrap.Bootstrap,
|
currBootstrap bootstrap.Bootstrap,
|
||||||
) (
|
) (
|
||||||
|
Loading…
Reference in New Issue
Block a user