From d4729886b0ba729e75659343320ae36fe0e74a5e Mon Sep 17 00:00:00 2001 From: Mathias Gibbens Date: Tue, 2 Dec 2025 07:50:48 -0700 Subject: [PATCH] incus-osd/systemd: Add option to delay provider refresh when bringing up the network Signed-off-by: Mathias Gibbens --- incus-osd/cmd/incus-osd/main.go | 20 +++++++++---------- incus-osd/internal/rest/api_system_network.go | 2 +- incus-osd/internal/systemd/networkd.go | 19 ++++++++++++------ 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/incus-osd/cmd/incus-osd/main.go b/incus-osd/cmd/incus-osd/main.go index a6c9dd61..2b09a8f8 100644 --- a/incus-osd/cmd/incus-osd/main.go +++ b/incus-osd/cmd/incus-osd/main.go @@ -349,10 +349,19 @@ func startup(ctx context.Context, s *state.State, t *tui.TUI) error { //nolint:r return err } + // Sometimes the system may not be able to immediately check the provider for any updates. + // One such example is when Operations Center is installed and the underlying IncusOS system + // is registered to it as the provider. We need to wait until the Operations Center + // application has started, otherwise any update check will fail. + delayInitialUpdateCheck, err := checkDelayInitialUpdate(ctx, s) + if err != nil { + return err + } + // Perform network configuration. slog.InfoContext(ctx, "Bringing up the network") - err = systemd.ApplyNetworkConfiguration(ctx, s, s.System.Network.Config, 30*time.Second, s.OS.SuccessfulBoot, providers.Refresh) + err = systemd.ApplyNetworkConfiguration(ctx, s, s.System.Network.Config, 30*time.Second, s.OS.SuccessfulBoot, providers.Refresh, delayInitialUpdateCheck) if err != nil { return err } @@ -397,15 +406,6 @@ func startup(ctx context.Context, s *state.State, t *tui.TUI) error { //nolint:r return err } - // Sometimes the system may not be able to immediately check the provider for any updates. - // One such example is when Operations Center is installed and the underlying IncusOS system - // is registered to it as the provider. We need to wait until the Operations Center - // application has started, otherwise any update check will fail. - delayInitialUpdateCheck, err := checkDelayInitialUpdate(ctx, s) - if err != nil { - return err - } - if !delayInitialUpdateCheck { // Perform an initial blocking check for updates before proceeding. updateChecker(ctx, s, t, p, true, false) diff --git a/incus-osd/internal/rest/api_system_network.go b/incus-osd/internal/rest/api_system_network.go index 9f327bd4..84a0664b 100644 --- a/incus-osd/internal/rest/api_system_network.go +++ b/incus-osd/internal/rest/api_system_network.go @@ -124,7 +124,7 @@ func (s *Server) apiSystemNetwork(w http.ResponseWriter, r *http.Request) { slog.InfoContext(r.Context(), "Applying new network configuration") - err = systemd.ApplyNetworkConfiguration(r.Context(), s.state, newConfig.Config, 30*time.Second, false, providers.Refresh) + err = systemd.ApplyNetworkConfiguration(r.Context(), s.state, newConfig.Config, 30*time.Second, false, providers.Refresh, false) if err != nil { slog.ErrorContext(r.Context(), "Failed to update network configuration: "+err.Error()) _ = response.InternalError(err).Render(w) diff --git a/incus-osd/internal/systemd/networkd.go b/incus-osd/internal/systemd/networkd.go index 908323aa..c1a25299 100644 --- a/incus-osd/internal/systemd/networkd.go +++ b/incus-osd/internal/systemd/networkd.go @@ -30,7 +30,7 @@ type networkdConfigFile struct { } // ApplyNetworkConfiguration instructs systemd-networkd to apply the supplied network configuration. -func ApplyNetworkConfiguration(ctx context.Context, s *state.State, networkCfg *api.SystemNetworkConfig, timeout time.Duration, allowPartialConfig bool, refresh func(context.Context, *state.State) error) error { +func ApplyNetworkConfiguration(ctx context.Context, s *state.State, networkCfg *api.SystemNetworkConfig, timeout time.Duration, allowPartialConfig bool, refresh func(context.Context, *state.State) error, delayRefreshCheck bool) error { // If a timezone is specified, apply it before doing any network configuration. if networkCfg.Time != nil && networkCfg.Time.Timezone != "" { _, err := subprocess.RunCommandContext(ctx, "timedatectl", "set-timezone", networkCfg.Time.Timezone) @@ -136,12 +136,19 @@ func ApplyNetworkConfiguration(ctx context.Context, s *state.State, networkCfg * return err } - // Refresh registration. + // Refresh registration, delaying by 30 seconds if needed to allow the provider to become available, + // such as when IncusOS is self-hosting Operations Center. if refresh != nil { - err := refresh(ctx, s) - if err != nil { - slog.WarnContext(ctx, "Failed to refresh provider registration", "err", err) - } + go func() { + if delayRefreshCheck { + time.Sleep(30 * time.Second) + } + + err := refresh(ctx, s) + if err != nil { + slog.WarnContext(ctx, "Failed to refresh provider registration", "err", err) + } + }() } return nil