diff --git a/controllers/dpa_controller.go b/controllers/dpa_controller.go index 02e6c7c0e91..0b86e55a07c 100644 --- a/controllers/dpa_controller.go +++ b/controllers/dpa_controller.go @@ -87,6 +87,12 @@ func (r *DPAReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.R log.Error(err, "unable to fetch DataProtectionApplication CR") return result, nil } + // origDpa snapshots status before reconciliation mutates it, so the final + // status update is a merge patch (no resourceVersion check) instead of a + // full update, avoiding optimistic-lock conflicts when the informer cache + // still lags behind a status write this controller (or another actor) + // already made to the object. + origDpa := dpa.DeepCopy() // set client to pkg/client for use in non-reconcile functions oadpClient.SetClient(r.Client) @@ -128,7 +134,7 @@ func (r *DPAReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.R }, ) } - statusErr := r.Client.Status().Update(ctx, &dpa) + statusErr := r.Client.Status().Patch(ctx, &dpa, client.MergeFrom(origDpa)) if err == nil { // Don't mask previous error err = statusErr }