From d0374fadb6d32e6753f21e503400f838dbb1bfa8 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: Mon, 26 May 2025 17:32:48 +0800 Subject: [PATCH] Mark BackupRepository not ready when BSL changed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mark BackupRepository not ready when BSL changed Fixes #8860 Signed-off-by: Wenkai Yin(尹文开) --- changelogs/unreleased/8975-ywk253100 | 1 + .../backup_repository_controller.go | 17 ++++--- pkg/util/kube/predicate.go | 51 +++++-------------- pkg/util/kube/predicate_test.go | 30 ++++++++--- 4 files changed, 44 insertions(+), 55 deletions(-) create mode 100644 changelogs/unreleased/8975-ywk253100 diff --git a/changelogs/unreleased/8975-ywk253100 b/changelogs/unreleased/8975-ywk253100 new file mode 100644 index 000000000..bd21417b7 --- /dev/null +++ b/changelogs/unreleased/8975-ywk253100 @@ -0,0 +1 @@ +Mark BackupRepository not ready when BSL changed \ No newline at end of file diff --git a/pkg/controller/backup_repository_controller.go b/pkg/controller/backup_repository_controller.go index b52282e21..27002c0df 100644 --- a/pkg/controller/backup_repository_controller.go +++ b/pkg/controller/backup_repository_controller.go @@ -31,6 +31,7 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/types" clocks "k8s.io/utils/clock" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/builder" @@ -104,14 +105,11 @@ func (r *BackupRepoReconciler) SetupWithManager(mgr ctrl.Manager) error { For(&velerov1api.BackupRepository{}, builder.WithPredicates(kube.SpecChangePredicate{})). WatchesRawSource(s). Watches( + // mark BackupRepository as invalid when BSL is created, updated or deleted. + // BSL may be recreated after deleting, so also include the create event &velerov1api.BackupStorageLocation{}, kube.EnqueueRequestsFromMapUpdateFunc(r.invalidateBackupReposForBSL), - builder.WithPredicates( - // When BSL updates, check if the backup repositories need to be invalidated - kube.NewUpdateEventPredicate(r.needInvalidBackupRepo), - // When BSL is created, invalidate any backup repositories that reference it - kube.NewCreateEventPredicate(func(client.Object) bool { return true }), - ), + builder.WithPredicates(kube.NewUpdateEventPredicate(r.needInvalidBackupRepo)), ). Complete(r) } @@ -130,14 +128,17 @@ func (r *BackupRepoReconciler) invalidateBackupReposForBSL(ctx context.Context, return []reconcile.Request{} } + requests := []reconcile.Request{} for i := range list.Items { r.logger.WithField("BSL", bsl.Name).Infof("Invalidating Backup Repository %s", list.Items[i].Name) - if err := r.patchBackupRepository(context.Background(), &list.Items[i], repoNotReady("re-establish on BSL change or create")); err != nil { + if err := r.patchBackupRepository(context.Background(), &list.Items[i], repoNotReady("re-establish on BSL change, create or delete")); err != nil { r.logger.WithField("BSL", bsl.Name).WithError(err).Errorf("fail to patch BackupRepository %s", list.Items[i].Name) + continue } + requests = append(requests, reconcile.Request{NamespacedName: types.NamespacedName{Namespace: list.Items[i].Namespace, Name: list.Items[i].Name}}) } - return []reconcile.Request{} + return requests } // needInvalidBackupRepo returns true if the BSL's storage type, bucket, prefix, CACert, or config has changed diff --git a/pkg/util/kube/predicate.go b/pkg/util/kube/predicate.go index 9ac9d9894..2fe985038 100644 --- a/pkg/util/kube/predicate.go +++ b/pkg/util/kube/predicate.go @@ -47,15 +47,6 @@ func (SpecChangePredicate) Update(e event.UpdateEvent) bool { return !reflect.DeepEqual(oldSpec.Interface(), newSpec.Interface()) } -// NewGenericEventPredicate creates a new Predicate that checks the Generic event with the provided func -func NewGenericEventPredicate(f func(object client.Object) bool) predicate.Predicate { - return predicate.Funcs{ - GenericFunc: func(event event.GenericEvent) bool { - return f(event.Object) - }, - } -} - // NewAllEventPredicate creates a new Predicate that checks all the events with the provided func func NewAllEventPredicate(f func(object client.Object) bool) predicate.Predicate { return predicate.Funcs{ @@ -74,25 +65,6 @@ func NewAllEventPredicate(f func(object client.Object) bool) predicate.Predicate } } -// NewUpdateEventPredicate creates a new Predicate that checks the update events with the provided func -// and ignore others -func NewUpdateEventPredicate(f func(client.Object, client.Object) bool) predicate.Predicate { - return predicate.Funcs{ - UpdateFunc: func(event event.UpdateEvent) bool { - return f(event.ObjectOld, event.ObjectNew) - }, - CreateFunc: func(event event.CreateEvent) bool { - return false - }, - DeleteFunc: func(event event.DeleteEvent) bool { - return false - }, - GenericFunc: func(event event.GenericEvent) bool { - return false - }, - } -} - // FalsePredicate always returns false for all kinds of events type FalsePredicate struct{} @@ -116,19 +88,20 @@ func (f FalsePredicate) Generic(event.GenericEvent) bool { return false } -func NewCreateEventPredicate(f func(client.Object) bool) predicate.Predicate { +// NewGenericEventPredicate creates a new Predicate that checks the Generic event with the provided func +func NewGenericEventPredicate(f func(object client.Object) bool) predicate.Predicate { return predicate.Funcs{ - CreateFunc: func(event event.CreateEvent) bool { - return f(event.Object) - }, - DeleteFunc: func(event event.DeleteEvent) bool { - return false - }, GenericFunc: func(event event.GenericEvent) bool { - return false - }, - UpdateFunc: func(event event.UpdateEvent) bool { - return false + return f(event.Object) + }, + } +} + +// NewUpdateEventPredicate creates a new Predicate that checks the Update event with the provided func +func NewUpdateEventPredicate(f func(objectOld client.Object, objectNew client.Object) bool) predicate.Predicate { + return predicate.Funcs{ + UpdateFunc: func(event event.UpdateEvent) bool { + return f(event.ObjectOld, event.ObjectNew) }, } } diff --git a/pkg/util/kube/predicate_test.go b/pkg/util/kube/predicate_test.go index 40d1b8c9c..c9079d029 100644 --- a/pkg/util/kube/predicate_test.go +++ b/pkg/util/kube/predicate_test.go @@ -179,14 +179,6 @@ func TestSpecChangePredicate(t *testing.T) { } } -func TestNewGenericEventPredicate(t *testing.T) { - predicate := NewGenericEventPredicate(func(object client.Object) bool { - return false - }) - - assert.False(t, predicate.Generic(event.GenericEvent{})) -} - func TestNewAllEventPredicate(t *testing.T) { predicate := NewAllEventPredicate(func(object client.Object) bool { return false @@ -197,3 +189,25 @@ func TestNewAllEventPredicate(t *testing.T) { assert.False(t, predicate.Delete(event.DeleteEvent{})) assert.False(t, predicate.Generic(event.GenericEvent{})) } + +func TestNewGenericEventPredicate(t *testing.T) { + predicate := NewGenericEventPredicate(func(object client.Object) bool { + return false + }) + + assert.False(t, predicate.Generic(event.GenericEvent{})) + assert.True(t, predicate.Update(event.UpdateEvent{})) + assert.True(t, predicate.Create(event.CreateEvent{})) + assert.True(t, predicate.Delete(event.DeleteEvent{})) +} + +func TestNewUpdateEventPredicate(t *testing.T) { + predicate := NewUpdateEventPredicate(func(client.Object, client.Object) bool { + return false + }) + + assert.False(t, predicate.Update(event.UpdateEvent{})) + assert.True(t, predicate.Create(event.CreateEvent{})) + assert.True(t, predicate.Delete(event.DeleteEvent{})) + assert.True(t, predicate.Generic(event.GenericEvent{})) +}