Skip to content

Commit 8dcb5c6

Browse files
committed
single stage operandconfig creation
Signed-off-by: Allen Li <liyuchen223@gmail.com>
1 parent d793c76 commit 8dcb5c6

File tree

6 files changed

+634
-41
lines changed

6 files changed

+634
-41
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//
2+
// Copyright 2022 IBM Corporation
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
//
16+
17+
package bootstrap
18+
19+
import (
20+
apiv3 "github.com/IBM/ibm-common-service-operator/v4/api/v3"
21+
)
22+
23+
// ConfigMergerFunc is a function type that merges base config with CommonService configs
24+
// This allows bootstrap to use controller merge logic without import cycles
25+
type ConfigMergerFunc func(baseConfig string, cs *apiv3.CommonService, servicesNs string) (string, error)
26+
27+
// configMerger holds the merger function set by the reconciler
28+
var configMerger ConfigMergerFunc
29+
30+
// SetConfigMerger sets the configuration merger function
31+
// Called during reconciler initialization to inject the merge logic
32+
func SetConfigMerger(merger ConfigMergerFunc) {
33+
configMerger = merger
34+
}
35+
36+
// mergeConfigs calls the injected merger function if available
37+
func (b *Bootstrap) mergeConfigs(baseConfig string, cs *apiv3.CommonService) (string, error) {
38+
if configMerger != nil {
39+
return configMerger(baseConfig, cs, b.CSData.ServicesNs)
40+
}
41+
// If no merger is set, return base config unchanged
42+
return baseConfig, nil
43+
}

internal/controller/bootstrap/init.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ func (b *Bootstrap) InitResources(instance *apiv3.CommonService, forceUpdateODLM
319319
}
320320

321321
klog.Info("Installing/Updating OperandConfig")
322-
if err := b.InstallOrUpdateOpcon(forceUpdateODLMCRs); err != nil {
322+
if err := b.InstallOrUpdateOpcon(forceUpdateODLMCRs, instance); err != nil {
323323
return err
324324
}
325325
}
@@ -369,7 +369,7 @@ func (b *Bootstrap) InitResources(instance *apiv3.CommonService, forceUpdateODLM
369369
}
370370

371371
klog.Info("Installing/Updating OperandConfig")
372-
if err := b.InstallOrUpdateOpcon(forceUpdateODLMCRs); err != nil {
372+
if err := b.InstallOrUpdateOpcon(forceUpdateODLMCRs, instance); err != nil {
373373
return err
374374
}
375375
}
@@ -960,7 +960,8 @@ func (b *Bootstrap) InstallOrUpdateOpreg(ctx context.Context, installPlanApprova
960960
}
961961

962962
// InstallOrUpdateOpcon will install or update OperandConfig when Opcon CRD is existent
963-
func (b *Bootstrap) InstallOrUpdateOpcon(forceUpdateODLMCRs bool) error {
963+
// Now accepts CommonService instance with merged configurations
964+
func (b *Bootstrap) InstallOrUpdateOpcon(forceUpdateODLMCRs bool, csInstance *apiv3.CommonService) error {
964965

965966
var baseCon string
966967
configs := []string{
@@ -983,7 +984,21 @@ func (b *Bootstrap) InstallOrUpdateOpcon(forceUpdateODLMCRs bool) error {
983984
return err
984985
}
985986

986-
if err := b.renderTemplate(concatenatedCon, b.CSData, forceUpdateODLMCRs); err != nil {
987+
// Merge CommonService configurations with base templates
988+
// before rendering to create complete OperandConfig in one step
989+
finalConfig := concatenatedCon
990+
if csInstance != nil {
991+
klog.Info("Merging CommonService configurations with base OperandConfig")
992+
mergedConfig, err := b.mergeConfigs(concatenatedCon, csInstance)
993+
if err != nil {
994+
klog.Errorf("Failed to merge configurations: %v", err)
995+
return err
996+
}
997+
finalConfig = mergedConfig
998+
klog.Info("Successfully merged configurations for single-stage OperandConfig creation")
999+
}
1000+
1001+
if err := b.renderTemplate(finalConfig, b.CSData, forceUpdateODLMCRs); err != nil {
9871002
return err
9881003
}
9891004
return nil

internal/controller/commonservice_controller.go

Lines changed: 10 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -248,38 +248,11 @@ func (r *CommonServiceReconciler) ReconcileMasterCR(ctx context.Context, instanc
248248
return ctrl.Result{}, statusErr
249249
}
250250

251-
// Apply new configs to CommonService CR
252-
cs := util.NewUnstructured("operator.ibm.com", "CommonService", "v3")
253-
if statusErr = r.Bootstrap.Client.Get(ctx, types.NamespacedName{Name: instance.Name, Namespace: instance.Namespace}, cs); statusErr != nil {
254-
klog.Errorf("Fail to reconcile %s/%s: %v", instance.Namespace, instance.Name, statusErr)
255-
return ctrl.Result{}, statusErr
256-
}
257-
// Set "Pending" condition and "Updating" for phase when config CS CR
258-
instance.SetPendingCondition(constant.MasterCR, apiv3.ConditionTypeReconciling, corev1.ConditionTrue, apiv3.ConditionReasonConfig, apiv3.ConditionMessageConfig)
259-
instance.Status.Phase = apiv3.CRUpdating
260-
newConfigs, serviceControllerMapping, statusErr := r.getNewConfigs(cs)
261-
if statusErr != nil {
262-
klog.Errorf("Fail to reconcile %s/%s: %v", instance.Namespace, instance.Name, statusErr)
263-
instance.SetErrorCondition(constant.MasterCR, apiv3.ConditionTypeError, corev1.ConditionTrue, apiv3.ConditionReasonError, statusErr.Error())
264-
instance.Status.Phase = apiv3.CRFailed
265-
}
266-
267-
if statusErr = r.Client.Status().Update(ctx, instance); statusErr != nil {
268-
klog.Errorf("Fail to update %s/%s: %v", instance.Namespace, instance.Name, statusErr)
269-
return ctrl.Result{}, statusErr
270-
}
251+
// OperandConfig already created with complete configuration
252+
// in InitResources, no need for second updateOperandConfig call
253+
klog.Info("OperandConfig created with complete configuration")
271254

272255
var isEqual bool
273-
if isEqual, statusErr = r.updateOperandConfig(ctx, newConfigs, serviceControllerMapping); statusErr != nil {
274-
if statusErr := r.updatePhase(ctx, instance, apiv3.CRFailed); statusErr != nil {
275-
klog.Error(statusErr)
276-
}
277-
klog.Errorf("Fail to reconcile %s/%s: %v", instance.Namespace, instance.Name, statusErr)
278-
return ctrl.Result{}, statusErr
279-
} else if isEqual {
280-
r.Recorder.Event(instance, corev1.EventTypeNormal, "Noeffect", fmt.Sprintf("No update, resource sizings in the OperandConfig %s/%s are larger than the profile from CommonService CR %s/%s", r.Bootstrap.CSData.OperatorNs, "common-service", instance.Namespace, instance.Name))
281-
}
282-
283256
if isEqual, statusErr = r.updateOperatorConfig(ctx, instance.Spec.OperatorConfigs); statusErr != nil {
284257
if statusErr := r.updatePhase(ctx, instance, apiv3.CRFailed); statusErr != nil {
285258
klog.Error(statusErr)
@@ -371,11 +344,6 @@ func (r *CommonServiceReconciler) ReconcileGeneralCR(ctx context.Context, instan
371344
return ctrl.Result{}, err
372345
}
373346

374-
cs := util.NewUnstructured("operator.ibm.com", "CommonService", "v3")
375-
if err := r.Bootstrap.Client.Get(ctx, types.NamespacedName{Name: instance.Name, Namespace: instance.Namespace}, cs); err != nil {
376-
klog.Errorf("Fail to reconcile %s/%s: %v", instance.Namespace, instance.Name, err)
377-
return ctrl.Result{}, err
378-
}
379347
// Generate Issuer and Certificate CR
380348
if err := r.Bootstrap.DeployCertManagerCR(); err != nil {
381349
klog.Errorf("Failed to deploy cert manager CRs: %v", err)
@@ -386,7 +354,8 @@ func (r *CommonServiceReconciler) ReconcileGeneralCR(ctx context.Context, instan
386354
return ctrl.Result{}, err
387355
}
388356

389-
newConfigs, serviceControllerMapping, err := r.getNewConfigs(cs)
357+
// Extract configurations using new extractor for subsequent updates
358+
newConfigs, serviceControllerMapping, err := ExtractCommonServiceConfigs(instance, r.Bootstrap.CSData.ServicesNs)
390359
if err != nil {
391360
if err := r.updatePhase(ctx, instance, apiv3.CRFailed); err != nil {
392361
klog.Error(err)
@@ -395,6 +364,7 @@ func (r *CommonServiceReconciler) ReconcileGeneralCR(ctx context.Context, instan
395364
return ctrl.Result{}, err
396365
}
397366

367+
// Update OperandConfig (single update for subsequent reconciliations)
398368
isEqual, err := r.updateOperandConfig(ctx, newConfigs, serviceControllerMapping)
399369
if err != nil {
400370
if err := r.updatePhase(ctx, instance, apiv3.CRFailed); err != nil {
@@ -557,6 +527,10 @@ func isNonNoopOperandReconcile(operandRegistry *odlm.OperandRegistry) bool {
557527
}
558528

559529
func (r *CommonServiceReconciler) SetupWithManager(mgr ctrl.Manager) error {
530+
// Set up configuration merger for single-stage OperandConfig creation
531+
// This injects the merge logic into bootstrap without creating import cycles
532+
bootstrap.SetConfigMerger(CreateMergerFunc(r))
533+
klog.Info("Configuration merger initialized for single-stage OperandConfig creation")
560534

561535
controller := ctrl.NewControllerManagedBy(mgr).
562536
// AnnotationChangedPredicate is intended to be used in conjunction with the GenerationChangedPredicate

0 commit comments

Comments
 (0)