From f0efe2aaa181f61830bf08f08e3c7676d92db901 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wenkai=20Yin=28=E5=B0=B9=E6=96=87=E5=BC=80=29?= Date: Tue, 21 Jan 2025 13:06:24 +0800 Subject: [PATCH] Handle update conflict when restoring the status MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Handle update conflict when restoring the status Fixes #8184 Signed-off-by: Wenkai Yin(尹文开) --- changelogs/unreleased/8630-ywk253100 | 1 + pkg/restore/restore.go | 24 +++++++++++++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 changelogs/unreleased/8630-ywk253100 diff --git a/changelogs/unreleased/8630-ywk253100 b/changelogs/unreleased/8630-ywk253100 new file mode 100644 index 0000000000..85c06629c3 --- /dev/null +++ b/changelogs/unreleased/8630-ywk253100 @@ -0,0 +1 @@ +Handle update conflict when restoring the status \ No newline at end of file diff --git a/pkg/restore/restore.go b/pkg/restore/restore.go index 619db5b87e..7dc5826999 100644 --- a/pkg/restore/restore.go +++ b/pkg/restore/restore.go @@ -48,6 +48,7 @@ import ( "k8s.io/client-go/dynamic/dynamicinformer" corev1 "k8s.io/client-go/kubernetes/typed/core/v1" "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/retry" crclient "sigs.k8s.io/controller-runtime/pkg/client" "github.com/vmware-tanzu/velero/internal/credentials" @@ -1669,13 +1670,26 @@ func (ctx *restoreContext) restoreItem(obj *unstructured.Unstructured, groupReso errs.Add(namespace, err) return warnings, errs, itemExists } - obj.SetResourceVersion(createdObj.GetResourceVersion()) - updated, err := resourceClient.UpdateStatus(obj, metav1.UpdateOptions{}) - if err != nil { + + resourceVersion := createdObj.GetResourceVersion() + if err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + obj.SetResourceVersion(resourceVersion) + updated, err := resourceClient.UpdateStatus(obj, metav1.UpdateOptions{}) + if err != nil { + if apierrors.IsConflict(err) { + res, err := resourceClient.Get(name, metav1.GetOptions{}) + if err == nil { + resourceVersion = res.GetResourceVersion() + } + } + return err + } + + createdObj = updated + return nil + }); err != nil { ctx.log.Infof("status field update failed %s: %v", kube.NamespaceAndName(obj), err) warnings.Add(namespace, err) - } else { - createdObj = updated } }