@@ -25,6 +25,7 @@ import (
2525 "fmt"
2626 "reflect"
2727 "slices"
28+ "strconv"
2829
2930 "github.com/imdario/mergo"
3031 "github.com/pkg/errors"
@@ -38,6 +39,8 @@ import (
3839
3940 appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1"
4041 parametersv1alpha1 "github.com/apecloud/kubeblocks/apis/parameters/v1alpha1"
42+ workloads "github.com/apecloud/kubeblocks/apis/workloads/v1"
43+ reconfigurectrl "github.com/apecloud/kubeblocks/controllers/parameters/reconfigure"
4144 "github.com/apecloud/kubeblocks/pkg/constant"
4245 "github.com/apecloud/kubeblocks/pkg/controller/builder"
4346 "github.com/apecloud/kubeblocks/pkg/controller/component"
@@ -104,8 +107,18 @@ func (r *ComponentDrivenParameterReconciler) reconcile(reqCtx intctrlutil.Reques
104107 return intctrlutil .CheckedRequeueWithError (err , reqCtx .Log , "" )
105108 }
106109 if model .IsObjectDeleting (component ) {
110+ if err = r .syncLegacyConfigManagerRequirement (reqCtx , component , false ); err != nil {
111+ return intctrlutil .RequeueWithError (err , reqCtx .Log , errors .Wrap (err , "failed to clear legacy config-manager compatibility annotation" ).Error ())
112+ }
107113 return r .delete (reqCtx , existingObject )
108114 }
115+ required , err := resolveLegacyConfigManagerRequirement (reqCtx .Ctx , r .Client , component )
116+ if err != nil {
117+ return intctrlutil .RequeueWithError (err , reqCtx .Log , "" )
118+ }
119+ if err = r .syncLegacyConfigManagerRequirement (reqCtx , component , required ); err != nil {
120+ return intctrlutil .RequeueWithError (err , reqCtx .Log , errors .Wrap (err , "failed to sync legacy config-manager compatibility annotation" ).Error ())
121+ }
109122 if expectedObject , err = buildComponentParameter (reqCtx , r .Client , component ); err != nil {
110123 return intctrlutil .RequeueWithError (err , reqCtx .Log , "" )
111124 }
@@ -151,6 +164,66 @@ func (r *ComponentDrivenParameterReconciler) update(reqCtx intctrlutil.RequestCt
151164 return intctrlutil .Reconciled ()
152165}
153166
167+ func (r * ComponentDrivenParameterReconciler ) syncLegacyConfigManagerRequirement (reqCtx intctrlutil.RequestCtx , comp * appsv1.Component , required bool ) error {
168+ clusterName , _ := component .GetClusterName (comp )
169+ clusterKey := types.NamespacedName {Namespace : comp .Namespace , Name : clusterName }
170+ cluster := & appsv1.Cluster {}
171+ if err := r .Client .Get (reqCtx .Ctx , clusterKey , cluster ); err != nil {
172+ return client .IgnoreNotFound (err )
173+ }
174+ aggregated , err := r .resolveClusterLegacyConfigManagerRequirement (reqCtx .Ctx , cluster , comp , required )
175+ if err != nil {
176+ return err
177+ }
178+ current , err := parameters .LegacyConfigManagerRequiredForCluster (cluster )
179+ if err != nil {
180+ return err
181+ }
182+ if current == aggregated {
183+ return nil
184+ }
185+ patch := client .MergeFrom (cluster .DeepCopy ())
186+ if cluster .Annotations == nil {
187+ cluster .Annotations = map [string ]string {}
188+ }
189+ if ! aggregated {
190+ delete (cluster .Annotations , constant .LegacyConfigManagerRequiredAnnotationKey )
191+ } else {
192+ cluster .Annotations [constant .LegacyConfigManagerRequiredAnnotationKey ] = strconv .FormatBool (true )
193+ }
194+ return r .Client .Patch (reqCtx .Ctx , cluster , patch )
195+ }
196+
197+ func (r * ComponentDrivenParameterReconciler ) resolveClusterLegacyConfigManagerRequirement (ctx context.Context , cluster * appsv1.Cluster , currentComp * appsv1.Component , currentRequired bool ) (bool , error ) {
198+ if cluster == nil {
199+ return false , nil
200+ }
201+ compList := & appsv1.ComponentList {}
202+ if err := r .Client .List (ctx , compList , client .InNamespace (cluster .Namespace ), client.MatchingLabels {constant .AppInstanceLabelKey : cluster .Name }); err != nil {
203+ return false , err
204+ }
205+ for i := range compList .Items {
206+ comp := & compList .Items [i ]
207+ if currentComp != nil && comp .Name == currentComp .Name {
208+ if currentRequired && ! model .IsObjectDeleting (comp ) {
209+ return true , nil
210+ }
211+ continue
212+ }
213+ if model .IsObjectDeleting (comp ) {
214+ continue
215+ }
216+ required , err := resolveLegacyConfigManagerRequirement (ctx , r .Client , comp )
217+ if err != nil {
218+ return false , err
219+ }
220+ if required {
221+ return true , nil
222+ }
223+ }
224+ return false , nil
225+ }
226+
154227func runningComponentParameter (reqCtx intctrlutil.RequestCtx , reader client.Reader , comp * appsv1.Component ) (* parametersv1alpha1.ComponentParameter , error ) {
155228 var componentParameter = & parametersv1alpha1.ComponentParameter {}
156229
@@ -237,6 +310,49 @@ func buildComponentParameter(reqCtx intctrlutil.RequestCtx, reader client.Reader
237310 return parameterObj , err
238311}
239312
313+ // resolveLegacyConfigManagerRequirement reports whether this component still depends on the
314+ // legacy config-manager compatibility path. The requirement exists only when the parameters
315+ // definition still uses legacy actions and the running workload still carries the injected
316+ // config-manager sidecar from older releases.
317+ func resolveLegacyConfigManagerRequirement (ctx context.Context , reader client.Reader , comp * appsv1.Component ) (bool , error ) {
318+ cmpd , err := getCompDefinition (ctx , reader , comp .Spec .CompDef )
319+ if err != nil {
320+ return false , err
321+ }
322+ _ , paramsDefs , err := parameters .ResolveCmpdParametersDefs (ctx , reader , cmpd )
323+ if err != nil {
324+ return false , err
325+ }
326+ if ! parameters .LegacyConfigManagerRequiredForParamsDefs (paramsDefs ) {
327+ return false , nil
328+ }
329+ its , err := resolveLegacyConfigManagerWorkload (ctx , reader , comp )
330+ if client .IgnoreNotFound (err ) != nil {
331+ return false , err
332+ }
333+ return reconfigurectrl .HasLegacyConfigManagerRuntime (its ), nil
334+ }
335+
336+ func resolveLegacyConfigManagerWorkload (ctx context.Context , reader client.Reader , comp * appsv1.Component ) (* workloads.InstanceSet , error ) {
337+ clusterName , err := component .GetClusterName (comp )
338+ if err != nil {
339+ return nil , err
340+ }
341+ componentName , err := component .ShortName (clusterName , comp .Name )
342+ if err != nil {
343+ return nil , err
344+ }
345+ its := & workloads.InstanceSet {}
346+ key := types.NamespacedName {
347+ Namespace : comp .Namespace ,
348+ Name : constant .GenerateWorkloadNamePattern (clusterName , componentName ),
349+ }
350+ if err := reader .Get (ctx , key , its ); err != nil {
351+ return nil , err
352+ }
353+ return its , nil
354+ }
355+
240356func handleCustomParameterTemplate (ctx context.Context , reader client.Reader , annotations map [string ]string , specs []parametersv1alpha1.ConfigTemplateItemDetail ) error {
241357 if len (annotations ) == 0 {
242358 return nil
0 commit comments