From cbc9ab7c03094561f8c29bfa9756e763d0d90995 Mon Sep 17 00:00:00 2001 From: Kaustubh Pande Date: Wed, 15 Jul 2026 15:48:39 +0530 Subject: [PATCH 1/2] Fix CAPI MachineSet finalizer cleanup when MAPI MachineSet is absent --- .../machineset_sync_controller.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/pkg/controllers/machinesetsync/machineset_sync_controller.go b/pkg/controllers/machinesetsync/machineset_sync_controller.go index 97bc6185e2..0a9b26f936 100644 --- a/pkg/controllers/machinesetsync/machineset_sync_controller.go +++ b/pkg/controllers/machinesetsync/machineset_sync_controller.go @@ -172,6 +172,23 @@ func (r *MachineSetSyncReconciler) Reconcile(ctx context.Context, req reconcile. } if mapiMachineSet == nil { + if capiMachineSet == nil { + logger.Info("Both MAPI and CAPI machine sets not found, nothing to do") + return ctrl.Result{}, nil + } + + // The MAPI MachineSet has already been deleted. + // If the CAPI MachineSet is deleting and still has our sync finalizer, + // reconcile its deletion so the finalizer can be removed. + if shouldRequeue, err := r.reconcileCAPItoMAPIMachineSetDeletion(ctx, nil, capiMachineSet); err != nil { + return ctrl.Result{}, fmt.Errorf( + "failed to reconcile Cluster API machine set deletion: %w", + err, + ) + } else if shouldRequeue { + return ctrl.Result{}, nil + } + logger.Info("Only CAPI machine set found, nothing to do") return ctrl.Result{}, nil } From 7f7f71331634e434254420ec8cda3c04a513211c Mon Sep 17 00:00:00 2001 From: Kaustubh Pande Date: Thu, 16 Jul 2026 14:34:21 +0530 Subject: [PATCH 2/2] OCPBUGS-98492: Add regression test and remove unreachable dead code --- .../machineset_sync_controller.go | 6 +---- .../machineset_sync_controller_test.go | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/pkg/controllers/machinesetsync/machineset_sync_controller.go b/pkg/controllers/machinesetsync/machineset_sync_controller.go index 0a9b26f936..d7f8c96415 100644 --- a/pkg/controllers/machinesetsync/machineset_sync_controller.go +++ b/pkg/controllers/machinesetsync/machineset_sync_controller.go @@ -172,11 +172,6 @@ func (r *MachineSetSyncReconciler) Reconcile(ctx context.Context, req reconcile. } if mapiMachineSet == nil { - if capiMachineSet == nil { - logger.Info("Both MAPI and CAPI machine sets not found, nothing to do") - return ctrl.Result{}, nil - } - // The MAPI MachineSet has already been deleted. // If the CAPI MachineSet is deleting and still has our sync finalizer, // reconcile its deletion so the finalizer can be removed. @@ -190,6 +185,7 @@ func (r *MachineSetSyncReconciler) Reconcile(ctx context.Context, req reconcile. } logger.Info("Only CAPI machine set found, nothing to do") + return ctrl.Result{}, nil } diff --git a/pkg/controllers/machinesetsync/machineset_sync_controller_test.go b/pkg/controllers/machinesetsync/machineset_sync_controller_test.go index 74eafc4bec..e552ba7a84 100644 --- a/pkg/controllers/machinesetsync/machineset_sync_controller_test.go +++ b/pkg/controllers/machinesetsync/machineset_sync_controller_test.go @@ -1168,6 +1168,31 @@ var _ = Describe("With a running MachineSetSync controller", func() { ContainElement(HaveField("ObjectMeta.Name", Equal(capiMachineSet.GetName()))), )) }) + + // Regression test for OCPBUGS-98492: ensure the sync finalizer is removed + // when the MAPI MachineSet is already absent. + Context("when the CAPI machine set has the sync finalizer and is being deleted", func() { + BeforeEach(func() { + By("Adding the sync finalizer to the CAPI machine set") + Eventually(k.Update(capiMachineSet, func() { + capiMachineSet.SetFinalizers([]string{machinesync.SyncFinalizer}) + })).Should(Succeed()) + + By("Waiting for the manager's informer cache to observe the finalizer") + eventuallyManagerInformerCache(capiMachineSet).Should( + HaveField("ObjectMeta.Finalizers", ContainElement(machinesync.SyncFinalizer)), + ) + + By("Deleting the CAPI machine set") + Eventually(kDelete(ctx, capiMachineSet)).Should(Succeed()) + }) + + It("should remove the sync finalizer and allow the CAPI machine set to be deleted", func() { + Eventually(k.Get(capiMachineSet), timeout).Should( + WithTransform(apierrors.IsNotFound, BeTrue()), + ) + }) + }) }) Context("when the CAPI infra machine template resource does not exist", func() {