diff --git a/controllers/apps/cluster_controller.go b/controllers/apps/cluster_controller.go
index 8e32b581465..96288c4cdaa 100644
--- a/controllers/apps/cluster_controller.go
+++ b/controllers/apps/cluster_controller.go
@@ -179,7 +179,7 @@ func (r *ClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
// SetupWithManager sets up the controller with the Manager.
func (r *ClusterReconciler) SetupWithManager(mgr ctrl.Manager) error {
- return intctrlutil.NewControllerManagedBy(mgr, &appsv1alpha1.Cluster{}, &appsv1alpha1.Component{}).
+ return intctrlutil.NewControllerManagedBy(mgr).
For(&appsv1alpha1.Cluster{}).
WithOptions(controller.Options{
MaxConcurrentReconciles: int(math.Ceil(viper.GetFloat64(constant.CfgKBReconcileWorkers) / 4)),
diff --git a/controllers/apps/clusterdefinition_controller.go b/controllers/apps/clusterdefinition_controller.go
index 86e2a4e150c..a492cdb00ae 100644
--- a/controllers/apps/clusterdefinition_controller.go
+++ b/controllers/apps/clusterdefinition_controller.go
@@ -71,6 +71,10 @@ func (r *ClusterDefinitionReconciler) Reconcile(ctx context.Context, req ctrl.Re
return intctrlutil.CheckedRequeueWithError(err, reqCtx.Log, "")
}
+ if !intctrlutil.ObjectAPIVersionSupported(clusterDef) {
+ return intctrlutil.Reconciled()
+ }
+
if res, err := intctrlutil.HandleCRDeletion(reqCtx, r, clusterDef,
clusterDefinitionFinalizerName, r.deletionHandler(reqCtx, clusterDef)); res != nil {
return *res, err
@@ -99,7 +103,7 @@ func (r *ClusterDefinitionReconciler) Reconcile(ctx context.Context, req ctrl.Re
// SetupWithManager sets up the controller with the Manager.
func (r *ClusterDefinitionReconciler) SetupWithManager(mgr ctrl.Manager) error {
- return intctrlutil.NewControllerManagedBy(mgr, &appsv1alpha1.ClusterDefinition{}).
+ return intctrlutil.NewControllerManagedBy(mgr).
For(&appsv1alpha1.ClusterDefinition{}).
Complete(r)
}
diff --git a/controllers/apps/component_controller.go b/controllers/apps/component_controller.go
index 6d5428d02a2..7689e5b8b66 100644
--- a/controllers/apps/component_controller.go
+++ b/controllers/apps/component_controller.go
@@ -212,7 +212,7 @@ func (r *ComponentReconciler) SetupWithManager(mgr ctrl.Manager, multiClusterMgr
}
func (r *ComponentReconciler) setupWithManager(mgr ctrl.Manager) error {
- b := intctrlutil.NewControllerManagedBy(mgr, &appsv1alpha1.Component{}, &workloads.InstanceSet{}).
+ b := intctrlutil.NewControllerManagedBy(mgr).
For(&appsv1alpha1.Component{}).
WithOptions(controller.Options{
MaxConcurrentReconciles: viper.GetInt(constant.CfgKBReconcileWorkers),
@@ -241,7 +241,7 @@ func (r *ComponentReconciler) setupWithManager(mgr ctrl.Manager) error {
}
func (r *ComponentReconciler) setupWithMultiClusterManager(mgr ctrl.Manager, multiClusterMgr multicluster.Manager) error {
- b := intctrlutil.NewControllerManagedBy(mgr, &appsv1alpha1.Component{}, &workloads.InstanceSet{}).
+ b := intctrlutil.NewControllerManagedBy(mgr).
For(&appsv1alpha1.Component{}).
WithOptions(controller.Options{
MaxConcurrentReconciles: viper.GetInt(constant.CfgKBReconcileWorkers),
diff --git a/controllers/apps/componentdefinition_controller.go b/controllers/apps/componentdefinition_controller.go
index 83a54a42419..fb749d5996e 100644
--- a/controllers/apps/componentdefinition_controller.go
+++ b/controllers/apps/componentdefinition_controller.go
@@ -85,7 +85,7 @@ func (r *ComponentDefinitionReconciler) Reconcile(ctx context.Context, req ctrl.
// SetupWithManager sets up the controller with the Manager.
func (r *ComponentDefinitionReconciler) SetupWithManager(mgr ctrl.Manager) error {
- return intctrlutil.NewControllerManagedBy(mgr, &appsv1alpha1.ComponentDefinition{}).
+ return intctrlutil.NewControllerManagedBy(mgr).
For(&appsv1alpha1.ComponentDefinition{}).
Complete(r)
}
diff --git a/controllers/apps/componentversion_controller.go b/controllers/apps/componentversion_controller.go
index a1cc1967e21..581aca306db 100644
--- a/controllers/apps/componentversion_controller.go
+++ b/controllers/apps/componentversion_controller.go
@@ -85,13 +85,16 @@ func (r *ComponentVersionReconciler) Reconcile(ctx context.Context, req ctrl.Req
if err := r.Client.Get(rctx.Ctx, rctx.Req.NamespacedName, compVersion); err != nil {
return intctrlutil.CheckedRequeueWithError(err, rctx.Log, "")
}
+ if !intctrlutil.ObjectAPIVersionSupported(compVersion) {
+ return intctrlutil.Reconciled()
+ }
return r.reconcile(rctx, compVersion)
}
// SetupWithManager sets up the controller with the Manager.
func (r *ComponentVersionReconciler) SetupWithManager(mgr ctrl.Manager) error {
- return intctrlutil.NewControllerManagedBy(mgr, &appsv1alpha1.ComponentVersion{}, &appsv1alpha1.ComponentDefinition{}).
+ return intctrlutil.NewControllerManagedBy(mgr).
For(&appsv1alpha1.ComponentVersion{}).
Watches(&appsv1alpha1.ComponentDefinition{}, handler.EnqueueRequestsFromMapFunc(r.compatibleCompVersion)).
Complete(r)
diff --git a/controllers/apps/transformer_cluster_init.go b/controllers/apps/transformer_cluster_init.go
index d869ab8b22e..0a0b697fffb 100644
--- a/controllers/apps/transformer_cluster_init.go
+++ b/controllers/apps/transformer_cluster_init.go
@@ -23,6 +23,7 @@ import (
appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1"
"github.com/apecloud/kubeblocks/pkg/controller/graph"
"github.com/apecloud/kubeblocks/pkg/controller/model"
+ intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil"
)
type clusterInitTransformer struct {
@@ -38,5 +39,8 @@ func (t *clusterInitTransformer) Transform(ctx graph.TransformContext, dag *grap
// init dag
graphCli.Root(dag, transCtx.OrigCluster, transCtx.Cluster, model.ActionStatusPtr())
+ if !intctrlutil.ObjectAPIVersionSupported(transCtx.Cluster) {
+ return graph.ErrPrematureStop
+ }
return nil
}
diff --git a/controllers/apps/transformer_component_init.go b/controllers/apps/transformer_component_init.go
index 82f73960214..0564c45b9b1 100644
--- a/controllers/apps/transformer_component_init.go
+++ b/controllers/apps/transformer_component_init.go
@@ -22,6 +22,7 @@ package apps
import (
"github.com/apecloud/kubeblocks/pkg/controller/graph"
"github.com/apecloud/kubeblocks/pkg/controller/model"
+ intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil"
)
type componentInitTransformer struct{}
@@ -38,5 +39,8 @@ func (t *componentInitTransformer) Transform(ctx graph.TransformContext, dag *gr
// init placement
transCtx.Context = intoContext(transCtx.Context, placement(transCtx.Component))
+ if !intctrlutil.ObjectAPIVersionSupported(transCtx.Component) {
+ return graph.ErrPrematureStop
+ }
return nil
}
diff --git a/controllers/workloads/instanceset_controller.go b/controllers/workloads/instanceset_controller.go
index ee6cfe2843f..d10cbb57900 100644
--- a/controllers/workloads/instanceset_controller.go
+++ b/controllers/workloads/instanceset_controller.go
@@ -81,6 +81,7 @@ func (r *InstanceSetReconciler) Reconcile(ctx context.Context, req ctrl.Request)
res, err := kubebuilderx.NewController(ctx, r.Client, req, r.Recorder, logger).
Prepare(instanceset.NewTreeLoader()).
+ Do(instanceset.NewAPIVersionReconciler()).
Do(instanceset.NewFixMetaReconciler()).
Do(instanceset.NewDeletionReconciler()).
Do(instanceset.NewStatusReconciler()).
@@ -112,7 +113,7 @@ func (r *InstanceSetReconciler) SetupWithManager(mgr ctrl.Manager, multiClusterM
func (r *InstanceSetReconciler) setupWithManager(mgr ctrl.Manager, ctx *handler.FinderContext) error {
itsFinder := handler.NewLabelFinder(&workloads.InstanceSet{}, instanceset.WorkloadsManagedByLabelKey, workloads.Kind, instanceset.WorkloadsInstanceLabelKey)
podHandler := handler.NewBuilder(ctx).AddFinder(itsFinder).Build()
- return intctrlutil.NewControllerManagedBy(mgr, &workloads.InstanceSet{}).
+ return intctrlutil.NewControllerManagedBy(mgr).
For(&workloads.InstanceSet{}).
WithOptions(controller.Options{
MaxConcurrentReconciles: viper.GetInt(constant.CfgKBReconcileWorkers),
@@ -132,7 +133,7 @@ func (r *InstanceSetReconciler) setupWithMultiClusterManager(mgr ctrl.Manager,
// TODO: modify handler.getObjectFromKey to support running Job in data clusters
jobHandler := handler.NewBuilder(ctx).AddFinder(delegatorFinder).Build()
- b := intctrlutil.NewControllerManagedBy(mgr, &workloads.InstanceSet{}).
+ b := intctrlutil.NewControllerManagedBy(mgr).
For(&workloads.InstanceSet{}).
WithOptions(controller.Options{
MaxConcurrentReconciles: viper.GetInt(constant.CfgKBReconcileWorkers),
diff --git a/pkg/controller/instanceset/reconciler_api_version.go b/pkg/controller/instanceset/reconciler_api_version.go
new file mode 100644
index 00000000000..bab86795a80
--- /dev/null
+++ b/pkg/controller/instanceset/reconciler_api_version.go
@@ -0,0 +1,43 @@
+/*
+Copyright (C) 2022-2024 ApeCloud Co., Ltd
+This file is part of KubeBlocks project
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+This program is distributed in the hope that it will be useful
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+
+package instanceset
+
+import (
+ "github.com/apecloud/kubeblocks/pkg/controller/kubebuilderx"
+ intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil"
+)
+
+type apiVersionReconciler struct{}
+
+func (r *apiVersionReconciler) PreCondition(tree *kubebuilderx.ObjectTree) *kubebuilderx.CheckResult {
+ if tree.GetRoot() == nil {
+ return kubebuilderx.ConditionUnsatisfied
+ }
+ return kubebuilderx.ConditionSatisfied
+}
+
+func (r *apiVersionReconciler) Reconcile(tree *kubebuilderx.ObjectTree) (kubebuilderx.Result, error) {
+ if intctrlutil.ObjectAPIVersionSupported(tree.GetRoot()) {
+ return kubebuilderx.Continue, nil
+ }
+ return kubebuilderx.Commit, nil
+}
+
+func NewAPIVersionReconciler() kubebuilderx.Reconciler {
+ return &apiVersionReconciler{}
+}
+
+var _ kubebuilderx.Reconciler = &apiVersionReconciler{}
diff --git a/pkg/controller/instanceset/reconciler_api_version_test.go b/pkg/controller/instanceset/reconciler_api_version_test.go
new file mode 100644
index 00000000000..6014bd40eb3
--- /dev/null
+++ b/pkg/controller/instanceset/reconciler_api_version_test.go
@@ -0,0 +1,65 @@
+/*
+Copyright (C) 2022-2024 ApeCloud Co., Ltd
+This file is part of KubeBlocks project
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+This program is distributed in the hope that it will be useful
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+
+package instanceset
+
+import (
+ . "github.com/onsi/ginkgo/v2"
+ . "github.com/onsi/gomega"
+
+ workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1"
+ viper "github.com/apecloud/kubeblocks/pkg/viperx"
+
+ "github.com/apecloud/kubeblocks/pkg/constant"
+ "github.com/apecloud/kubeblocks/pkg/controller/builder"
+ "github.com/apecloud/kubeblocks/pkg/controller/kubebuilderx"
+)
+
+var _ = Describe("api version reconciler test", func() {
+ Context("PreCondition & Reconcile", func() {
+ It("should work well", func() {
+ By("PreCondition")
+ its := builder.NewInstanceSetBuilder(namespace, name).GetObject()
+ tree := kubebuilderx.NewObjectTree()
+ tree.SetRoot(its)
+ reconciler := NewAPIVersionReconciler()
+ Expect(reconciler.PreCondition(tree)).Should(Equal(kubebuilderx.ConditionSatisfied))
+
+ By("Reconcile without dual mode operator")
+ tree.SetRoot(its)
+ res, err := reconciler.Reconcile(tree)
+ Expect(err).Should(BeNil())
+ Expect(res).Should(Equal(kubebuilderx.Continue))
+
+ By("Reconcile with supported api version and using dual mode operator")
+ viper.Set(constant.DualOperatorsMode, true)
+ if its.Annotations == nil {
+ its.Annotations = make(map[string]string)
+ }
+ its.Annotations[constant.CRDAPIVersionAnnotationKey] = workloads.GroupVersion.String()
+ tree.SetRoot(its)
+ res, err = reconciler.Reconcile(tree)
+ Expect(err).Should(BeNil())
+ Expect(res).Should(Equal(kubebuilderx.Continue))
+
+ By("Reconcile without dual mode operator")
+ delete(its.Annotations, constant.CRDAPIVersionAnnotationKey)
+ tree.SetRoot(its)
+ res, err = reconciler.Reconcile(tree)
+ Expect(err).Should(BeNil())
+ Expect(res).Should(Equal(kubebuilderx.Continue))
+ })
+ })
+})
diff --git a/pkg/controllerutil/predicate.go b/pkg/controllerutil/predicate.go
index edf5676e1fc..2508ff0949f 100644
--- a/pkg/controllerutil/predicate.go
+++ b/pkg/controllerutil/predicate.go
@@ -101,13 +101,9 @@ var (
)
)
-func NewControllerManagedBy(mgr manager.Manager, objs ...client.Object) *builder.Builder {
- b := ctrl.NewControllerManagedBy(mgr).
+func NewControllerManagedBy(mgr manager.Manager) *builder.Builder {
+ return ctrl.NewControllerManagedBy(mgr).
WithEventFilter(predicate.NewPredicateFuncs(namespacePredicateFilter))
- if len(objs) > 0 {
- b.WithEventFilter(predicate.NewPredicateFuncs(newAPIVersionPredicateFilter(objs)))
- }
- return b
}
func namespacePredicateFilter(object client.Object) bool {
@@ -125,20 +121,18 @@ func namespacePredicateFilter(object client.Object) bool {
return managedNamespaces.Has(object.GetNamespace())
}
-func newAPIVersionPredicateFilter(objs []client.Object) func(client.Object) bool {
- return func(obj client.Object) bool {
- if !viper.GetBool(constant.DualOperatorsMode) {
- return true
- }
- _, clusterObj := obj.(*appsv1alpha1.Cluster)
- annotations := obj.GetAnnotations()
- if annotations == nil {
- return !clusterObj // for newly created clusters, let the new operator handle them first
- }
- apiVersion, ok := annotations[constant.CRDAPIVersionAnnotationKey]
- if !ok {
- return !clusterObj // for newly created clusters, let the new operator handle them first
- }
- return supportedCRDAPIVersions.Has(apiVersion)
+func ObjectAPIVersionSupported(obj client.Object) bool {
+ if !viper.GetBool(constant.DualOperatorsMode) {
+ return true
+ }
+ _, clusterObj := obj.(*appsv1alpha1.Cluster)
+ annotations := obj.GetAnnotations()
+ if annotations == nil {
+ return !clusterObj // for newly created clusters, let the new operator handle them first
+ }
+ apiVersion, ok := annotations[constant.CRDAPIVersionAnnotationKey]
+ if !ok {
+ return !clusterObj // for newly created clusters, let the new operator handle them first
}
+ return supportedCRDAPIVersions.Has(apiVersion)
}