diff --git a/cmd/incusd/daemon.go b/cmd/incusd/daemon.go index d00017fc759..d43438e0aee 100644 --- a/cmd/incusd/daemon.go +++ b/cmd/incusd/daemon.go @@ -1572,7 +1572,7 @@ func (d *Daemon) init() error { } // Setup the networks. - if !d.db.Cluster.LocalNodeIsEvacuated() { + if !d.serverClustered || !d.db.Cluster.LocalNodeIsEvacuated() { logger.Infof("Initializing networks") err = networkStartup(d.State()) diff --git a/cmd/incusd/events.go b/cmd/incusd/events.go index f70230e2f7f..236dd0bba18 100644 --- a/cmd/incusd/events.go +++ b/cmd/incusd/events.go @@ -109,16 +109,13 @@ func eventsSocket(s *state.State, r *http.Request, w http.ResponseWriter) error l := logger.AddContext(logger.Ctx{"remote": r.RemoteAddr}) var excludeLocations []string - // Get the current local serverName and store it for the events. - // We do that now to avoid issues with changes to the name and to limit - // the number of DB access to just one per connection. - err := s.DB.Cluster.Transaction(context.TODO(), func(ctx context.Context, tx *db.ClusterTx) error { - if isClusterNotification(r) { - ctx := r.Context() - - // Try and match cluster member certificate fingerprint to member name. - fingerprint, found := ctx.Value(request.CtxUsername).(string) - if found { + if isClusterNotification(r) { + ctx := r.Context() + + // Try and match cluster member certificate fingerprint to member name. + fingerprint, found := ctx.Value(request.CtxUsername).(string) + if found { + err := s.DB.Cluster.Transaction(context.TODO(), func(ctx context.Context, tx *db.ClusterTx) error { cert, err := cluster.GetCertificateByFingerprintPrefix(context.Background(), tx.Tx(), fingerprint) if err != nil { return fmt.Errorf("Failed matching client certificate to cluster member: %w", err) @@ -127,14 +124,14 @@ func eventsSocket(s *state.State, r *http.Request, w http.ResponseWriter) error // Add the cluster member client's name to the excluded locations so that we can avoid // looping the event back to them when they send us an event via recvFunc. excludeLocations = append(excludeLocations, cert.Name) + + return nil + }) + if err != nil { + l.Warn("Failed setting up event connection", logger.Ctx{"err": err}) + return nil } } - - return nil - }) - if err != nil { - l.Warn("Failed setting up event connection", logger.Ctx{"err": err}) - return nil } var recvFunc events.EventHandler diff --git a/cmd/incusd/instance_state.go b/cmd/incusd/instance_state.go index 8a8e5370960..8e414d5836b 100644 --- a/cmd/incusd/instance_state.go +++ b/cmd/incusd/instance_state.go @@ -177,7 +177,7 @@ func instanceStatePut(d *Daemon, r *http.Request) response.Response { } // Check if the cluster member is evacuated. - if s.DB.Cluster.LocalNodeIsEvacuated() && req.Action != "stop" { + if s.ServerClustered && req.Action != "stop" && s.DB.Cluster.LocalNodeIsEvacuated() { return response.Forbidden(fmt.Errorf("Cluster member is evacuated")) } diff --git a/cmd/incusd/instances.go b/cmd/incusd/instances.go index bed2763c792..d4fccb1e014 100644 --- a/cmd/incusd/instances.go +++ b/cmd/incusd/instances.go @@ -209,7 +209,7 @@ func instanceShouldAutoStart(inst instance.Instance) bool { func instancesStart(s *state.State, instances []instance.Instance) { // Check if the cluster is currently evacuated. - if s.DB.Cluster.LocalNodeIsEvacuated() { + if s.ServerClustered && s.DB.Cluster.LocalNodeIsEvacuated() { return } diff --git a/cmd/incusd/instances_post.go b/cmd/incusd/instances_post.go index 54a97a23bfa..677258ab66d 100644 --- a/cmd/incusd/instances_post.go +++ b/cmd/incusd/instances_post.go @@ -93,7 +93,7 @@ func ensureDownloadedImageFitWithinBudget(ctx context.Context, s *state.State, r } func createFromImage(s *state.State, r *http.Request, p api.Project, profiles []api.Profile, img *api.Image, imgAlias string, req *api.InstancesPost) response.Response { - if s.DB.Cluster.LocalNodeIsEvacuated() { + if s.ServerClustered && s.DB.Cluster.LocalNodeIsEvacuated() { return response.Forbidden(fmt.Errorf("Cluster member is evacuated")) } @@ -156,7 +156,7 @@ func createFromImage(s *state.State, r *http.Request, p api.Project, profiles [] } func createFromNone(s *state.State, r *http.Request, projectName string, profiles []api.Profile, req *api.InstancesPost) response.Response { - if s.DB.Cluster.LocalNodeIsEvacuated() { + if s.ServerClustered && s.DB.Cluster.LocalNodeIsEvacuated() { return response.Forbidden(fmt.Errorf("Cluster member is evacuated")) } @@ -209,7 +209,7 @@ func createFromNone(s *state.State, r *http.Request, projectName string, profile } func createFromMigration(ctx context.Context, s *state.State, r *http.Request, projectName string, profiles []api.Profile, req *api.InstancesPost) response.Response { - if s.DB.Cluster.LocalNodeIsEvacuated() && r != nil && r.Context().Value(request.CtxProtocol) != "cluster" { + if s.ServerClustered && r != nil && r.Context().Value(request.CtxProtocol) != "cluster" && s.DB.Cluster.LocalNodeIsEvacuated() { return response.Forbidden(fmt.Errorf("Cluster member is evacuated")) } @@ -474,7 +474,7 @@ func createFromMigration(ctx context.Context, s *state.State, r *http.Request, p } func createFromCopy(ctx context.Context, s *state.State, r *http.Request, projectName string, profiles []api.Profile, req *api.InstancesPost) response.Response { - if s.DB.Cluster.LocalNodeIsEvacuated() { + if s.ServerClustered && s.DB.Cluster.LocalNodeIsEvacuated() { return response.Forbidden(fmt.Errorf("Cluster member is evacuated")) } @@ -956,12 +956,12 @@ func instancesPost(d *Daemon, r *http.Request) response.Response { var targetMemberInfo *db.NodeInfo var targetGroupName string - err = s.DB.Cluster.Transaction(r.Context(), func(ctx context.Context, tx *db.ClusterTx) error { - target := request.QueryParam(r, "target") - if !s.ServerClustered && target != "" { - return api.StatusErrorf(http.StatusBadRequest, "Target only allowed when clustered") - } + target := request.QueryParam(r, "target") + if !s.ServerClustered && target != "" { + return response.BadRequest(fmt.Errorf("Target only allowed when clustered")) + } + err = s.DB.Cluster.Transaction(r.Context(), func(ctx context.Context, tx *db.ClusterTx) error { dbProject, err := dbCluster.GetProject(ctx, tx.Tx(), targetProjectName) if err != nil { return fmt.Errorf("Failed loading project: %w", err)