Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ metadata:
categories: Application Runtime
certified: "true"
containerImage: icr.io/appcafe/runtime-component-operator:daily
createdAt: "2025-06-23T19:46:14Z"
createdAt: "2025-07-15T04:30:14Z"
description: Deploys any runtime component with dynamic and auto-tuning configuration
features.operators.openshift.io/disconnected: "true"
features.operators.openshift.io/fips-compliant: "true"
Expand Down
32 changes: 32 additions & 0 deletions common/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package common
import (
"errors"
"strconv"
"strings"
"sync"

uberzap "go.uber.org/zap"
Expand Down Expand Up @@ -59,6 +60,9 @@ const (

// OpConfigShowReconcileInterval default whether reconcile interval will be visible in the instance's status field
OpConfigShowReconcileInterval = "showReconcileInterval"

// OpConfigDelayReconcile list of instances/namespaces with delayed reconciliation
OpConfigDelayReconcile = "delayReconcile"
)

// Config stores operator configuration
Expand Down Expand Up @@ -108,6 +112,34 @@ func LoadFromConfig(oc *sync.Map, key string) string {
return value.(string)
}

// Checks if the instance / namespace exists in delay reconcile list
func CheckDelayReconcile(oc *sync.Map, key string, name string, namespace string, OperatorName string) (bool, error) {
value := LoadFromConfig(oc, key)
lines := strings.Split(value, "\n")

nsFound := false

for _, line := range lines {
if strings.Contains(line, ":") {
ns := strings.TrimRight(line, ":")
if namespace == ns {
nsFound = true
} else {
nsFound = false
}
} else if nsFound && strings.Contains(line, "- ") {
instance := strings.TrimLeft(line, "- ")
if instance == "*" || instance == name {
return true, nil
}
} else if !strings.Contains(line, ":") && !strings.Contains(line, "- ") {
return false, errors.New("delayReconcile syntax error in ConfigMap: " + OperatorName + ".")
}
}

return false, nil
}

func CheckValidValue(oc *sync.Map, key string, OperatorName string) error {
value := LoadFromConfig(oc, key)

Expand Down
11 changes: 11 additions & 0 deletions internal/controller/runtimecomponent_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,17 @@ func (r *RuntimeComponentReconciler) Reconcile(ctx context.Context, req ctrl.Req
return reconcile.Result{}, err
}

// If the instance was already reconciled and is waiting for operator version upgrade
if instance.Status.Versions.Reconciled != "" && instance.Status.Versions.Reconciled != appstacksutils.RCOOperandVersion {
// If the instance / namespace is listed under delayReconcile in ConfigMap, skip and delay reconciliation
delay, err := common.CheckDelayReconcile(common.Config, common.OpConfigDelayReconcile, req.Name, req.Namespace, OperatorName)
if err != nil {
return r.ManageError(err, common.StatusConditionTypeReconciled, instance)
} else if delay {
return r.ManageSuccess(common.StatusConditionTypeReconciled, instance)
}
}

if err = common.CheckValidValue(common.Config, common.OpConfigReconcileIntervalMinimum, OperatorName); err != nil {
return r.ManageError(err, common.StatusConditionTypeReconciled, instance)
}
Expand Down