From 5862e8e0c0c3966e69e5edd7e70e26c13e807074 Mon Sep 17 00:00:00 2001 From: Maciej Zimnoch Date: Tue, 9 Feb 2021 12:39:20 +0100 Subject: [PATCH] replace: use Patch() to clear PVC finalizers (#350) Operator updates PVC which is subject for removal, so this is expected that update may conflict. To avoid conflicts instead updating whole resource, patch is used. Fixes #350 --- pkg/controllers/cluster/actions/replace.go | 9 +++++---- pkg/controllers/cluster/util/patch.go | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/pkg/controllers/cluster/actions/replace.go b/pkg/controllers/cluster/actions/replace.go index 165049c78f4..90062fda1a5 100644 --- a/pkg/controllers/cluster/actions/replace.go +++ b/pkg/controllers/cluster/actions/replace.go @@ -14,6 +14,7 @@ import ( "github.com/scylladb/scylla-operator/pkg/naming" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/wait" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -186,10 +187,10 @@ func (a *RackReplaceNode) replaceNode(ctx context.Context, state *State, member // Remove finalizer, which will wait until pod is deleted. // We want to delete pod anyway, so it's better to delete pvc immediately. - pvcCopy := p.DeepCopy() - pvcCopy.SetFinalizers([]string{}) - if err := cc.Update(ctx, pvcCopy); err != nil { - return false, errors.Wrap(err, "failed to update pvc") + if err := cc.Patch(ctx, pvc, util.StrategicMergePatchFunc(func(_ runtime.Object) ([]byte, error) { + return []byte(fmt.Sprintf(`{"metadata":{"$patch":"replace","finalizers": [], "uid":"%s"}`, pvc.UID)), nil + })); err != nil { + return false, errors.Wrap(err, "clear PVC finalizers") } return false, nil diff --git a/pkg/controllers/cluster/util/patch.go b/pkg/controllers/cluster/util/patch.go index d00ff8b194e..8195b4b1963 100644 --- a/pkg/controllers/cluster/util/patch.go +++ b/pkg/controllers/cluster/util/patch.go @@ -9,6 +9,7 @@ import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/strategicpatch" "k8s.io/client-go/kubernetes" @@ -82,3 +83,16 @@ func PatchService(ctx context.Context, old, new *corev1.Service, kubeClient kube _, err = kubeClient.CoreV1().Services(old.Namespace).Patch(ctx, old.Name, types.StrategicMergePatchType, patchBytes, metav1.PatchOptions{}) return err } + +// The StrategicMergePatchFunc type is an adapter to allow the use of ordinary functions as Strategic Merge Patch. +type StrategicMergePatchFunc func(obj runtime.Object) ([]byte, error) + +// Type returns PatchType of Strategic Merge Patch +func (f StrategicMergePatchFunc) Type() types.PatchType { + return types.StrategicMergePatchType +} + +// Data returns the raw data representing the patch. +func (f StrategicMergePatchFunc) Data(obj runtime.Object) ([]byte, error) { + return f(obj) +}