diff --git a/internal/controllers/machinedeployment/machinedeployment_controller.go b/internal/controllers/machinedeployment/machinedeployment_controller.go index 64ac90c58d0f..615c4191477c 100644 --- a/internal/controllers/machinedeployment/machinedeployment_controller.go +++ b/internal/controllers/machinedeployment/machinedeployment_controller.go @@ -88,14 +88,14 @@ func (r *Reconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager, opt handler.EnqueueRequestsFromMapFunc(r.MachineSetToDeployments), ). WithOptions(options). - WithEventFilter(predicates.ResourceNotPausedAndHasFilterLabel(ctrl.LoggerFrom(ctx), r.WatchFilterValue)). + WithEventFilter(predicates.ResourceHasFilterLabel(ctrl.LoggerFrom(ctx), r.WatchFilterValue)). Watches( &clusterv1.Cluster{}, handler.EnqueueRequestsFromMapFunc(clusterToMachineDeployments), builder.WithPredicates( // TODO: should this wait for Cluster.Status.InfrastructureReady similar to Infra Machine resources? predicates.All(ctrl.LoggerFrom(ctx), - predicates.ClusterUnpaused(ctrl.LoggerFrom(ctx)), + predicates.ClusterCreateUpdateEvent(ctrl.LoggerFrom(ctx)), ), ), ).Complete(r) @@ -131,12 +131,6 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ctrl.Re return ctrl.Result{}, err } - // Return early if the object or Cluster is paused. - if annotations.IsPaused(cluster, deployment) { - log.Info("Reconciliation is paused for this object") - return ctrl.Result{}, nil - } - // Initialize the patch helper patchHelper, err := patch.NewHelper(deployment, r.Client) if err != nil { @@ -155,6 +149,14 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ctrl.Re } }() + // Return early if the object or Cluster is paused. + if annotations.IsPaused(cluster, deployment) { + log.Info("Reconciliation is paused for this object") + conditions.MarkTrue(deployment, clusterv1.PausedCondition) + return ctrl.Result{}, nil + } + conditions.MarkFalse(deployment, clusterv1.PausedCondition, clusterv1.ResourceNotPausedReason, clusterv1.ConditionSeverityInfo, "Resource is operating as expected") + // Ignore deleted MachineDeployments, this can happen when foregroundDeletion // is enabled if !deployment.DeletionTimestamp.IsZero() { @@ -262,6 +264,10 @@ func (r *Reconciler) reconcile(ctx context.Context, cluster *clusterv1.Cluster, } if md.Spec.Paused { + log.Info("This machine deployment is paused. Sync and status updates will still be reconciled") + // TODO: Make this condition specific, with a different reason to the other + // paused = true conditions + conditions.MarkTrue(md, clusterv1.PausedCondition) return r.sync(ctx, md, msList) } diff --git a/internal/controllers/machinedeployment/machinedeployment_controller_test.go b/internal/controllers/machinedeployment/machinedeployment_controller_test.go index b54f128cb41e..8299daf6999a 100644 --- a/internal/controllers/machinedeployment/machinedeployment_controller_test.go +++ b/internal/controllers/machinedeployment/machinedeployment_controller_test.go @@ -465,6 +465,25 @@ func TestMachineDeploymentReconciler(t *testing.T) { return conditions.IsTrue(deployment, clusterv1.MachineDeploymentAvailableCondition) }, timeout).Should(BeTrue()) + // By default, the machine deployment is not paused + + g.Eventually(func() bool { + key := client.ObjectKey{Name: deployment.Name, Namespace: deployment.Namespace} + g.Expect(env.Get(ctx, key, deployment)).To(Succeed()) + return conditions.IsFalse(deployment, clusterv1.PausedCondition) + }, timeout).Should(BeTrue()) + + // Pause the cluster, expect the paused condition to be set + g.Expect(env.Get(ctx, util.ObjectKey(testCluster), testCluster)).To(Succeed()) + testCluster.Spec.Paused = true + g.Expect(env.Update(ctx, testCluster)).To(Succeed()) + + g.Eventually(func() bool { + key := client.ObjectKey{Name: deployment.Name, Namespace: deployment.Namespace} + g.Expect(env.Get(ctx, key, deployment)).To(Succeed()) + return conditions.IsTrue(deployment, clusterv1.PausedCondition) + }, timeout).Should(BeTrue()) + // Validate that the controller set the cluster name label in selector. g.Expect(deployment.Status.Selector).To(ContainSubstring(testCluster.Name)) })