From b5426516da72abfea90a31776a5c02008261c20a Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Wed, 25 Jun 2025 10:53:53 +0800 Subject: [PATCH] Make the backup repository controller doesn't invalidate the BSL on restart. Signed-off-by: Xun Jiang --- changelogs/unreleased/9046-blackpiglet | 1 + .../backup_repository_controller.go | 20 +++++++++++++++--- pkg/util/kube/predicate.go | 14 ++++++++++++- pkg/util/kube/predicate_test.go | 21 ++++++++++++++++--- 4 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 changelogs/unreleased/9046-blackpiglet diff --git a/changelogs/unreleased/9046-blackpiglet b/changelogs/unreleased/9046-blackpiglet new file mode 100644 index 000000000..27d39541c --- /dev/null +++ b/changelogs/unreleased/9046-blackpiglet @@ -0,0 +1 @@ +Make the backup repository controller doesn't invalidate the BSL on restart \ No newline at end of file diff --git a/pkg/controller/backup_repository_controller.go b/pkg/controller/backup_repository_controller.go index b6b3cf43c..c288f8059 100644 --- a/pkg/controller/backup_repository_controller.go +++ b/pkg/controller/backup_repository_controller.go @@ -28,6 +28,7 @@ import ( "github.com/petar/GoLLRB/llrb" "github.com/pkg/errors" "github.com/sirupsen/logrus" + corev1api "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" @@ -38,8 +39,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/reconcile" - corev1api "k8s.io/api/core/v1" - velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" "github.com/vmware-tanzu/velero/pkg/constant" "github.com/vmware-tanzu/velero/pkg/label" @@ -119,7 +118,22 @@ func (r *BackupRepoReconciler) SetupWithManager(mgr ctrl.Manager) error { // BSL may be recreated after deleting, so also include the create event &velerov1api.BackupStorageLocation{}, kube.EnqueueRequestsFromMapUpdateFunc(r.invalidateBackupReposForBSL), - builder.WithPredicates(kube.NewUpdateEventPredicate(r.needInvalidBackupRepo)), + builder.WithPredicates( + // Combine three predicates together to guarantee + // only BSL's Delete Event and Update Event can enqueue. + // We don't care about BSL's Generic Event and Create Event, + // because BSL's periodical enqueue triggers Generic Event, + // and the BackupRepository controller restart will triggers BSL create event. + kube.NewUpdateEventPredicate( + r.needInvalidBackupRepo, + ), + kube.NewGenericEventPredicate( + func(client.Object) bool { return false }, + ), + kube.NewCreateEventPredicate( + func(client.Object) bool { return false }, + ), + ), ). Complete(r) } diff --git a/pkg/util/kube/predicate.go b/pkg/util/kube/predicate.go index 2fe985038..ce5bb85f0 100644 --- a/pkg/util/kube/predicate.go +++ b/pkg/util/kube/predicate.go @@ -98,10 +98,22 @@ func NewGenericEventPredicate(f func(object client.Object) bool) predicate.Predi } // 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 { +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) }, } } + +func NewCreateEventPredicate( + f func(object client.Object) bool, +) predicate.Predicate { + return predicate.Funcs{ + CreateFunc: func(event event.CreateEvent) bool { + return f(event.Object) + }, + } +} diff --git a/pkg/util/kube/predicate_test.go b/pkg/util/kube/predicate_test.go index c9079d029..eb00e2fed 100644 --- a/pkg/util/kube/predicate_test.go +++ b/pkg/util/kube/predicate_test.go @@ -202,12 +202,27 @@ func TestNewGenericEventPredicate(t *testing.T) { } func TestNewUpdateEventPredicate(t *testing.T) { - predicate := NewUpdateEventPredicate(func(client.Object, client.Object) bool { - return false - }) + 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{})) } + +func TestNewCreateEventPredicate(t *testing.T) { + predicate := NewCreateEventPredicate( + func(client.Object) bool { + return false + }, + ) + + assert.False(t, predicate.Create(event.CreateEvent{})) + assert.True(t, predicate.Update(event.UpdateEvent{})) + assert.True(t, predicate.Generic(event.GenericEvent{})) + assert.True(t, predicate.Delete(event.DeleteEvent{})) +}