diff --git a/internal/controller/dataprotectionapplication_controller.go b/internal/controller/dataprotectionapplication_controller.go index 13818a9e746..6cee9db817c 100644 --- a/internal/controller/dataprotectionapplication_controller.go +++ b/internal/controller/dataprotectionapplication_controller.go @@ -90,6 +90,12 @@ func (r *DataProtectionApplicationReconciler) Reconcile(ctx context.Context, req logger.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 := r.dpa.DeepCopy() // set client to pkg/client for use in non-reconcile functions oadpclient.SetClient(r.Client) @@ -135,7 +141,7 @@ func (r *DataProtectionApplicationReconciler) Reconcile(ctx context.Context, req }, ) } - statusErr := r.Client.Status().Update(ctx, r.dpa) + statusErr := r.Client.Status().Patch(ctx, r.dpa, client.MergeFrom(origDpa)) if err == nil { // Don't mask previous error err = statusErr }