From 160bdf95fab12f73d43750d41b664d3ba5544574 Mon Sep 17 00:00:00 2001 From: Kelly Gao Date: Wed, 13 Aug 2025 00:32:38 -0400 Subject: [PATCH 1/3] Added import statement for v1 rc --- utils/reconciler.go | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/reconciler.go b/utils/reconciler.go index 6cc11fdf..a11d9686 100644 --- a/utils/reconciler.go +++ b/utils/reconciler.go @@ -12,6 +12,7 @@ import ( networkingv1 "k8s.io/api/networking/v1" "github.com/application-stacks/runtime-component-operator/common" + v1 "github.com/application-stacks/runtime-component-operator/api/v1" certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" certmanagermetav1 "github.com/cert-manager/cert-manager/pkg/apis/meta/v1" routev1 "github.com/openshift/api/route/v1" From a36f7a00e4f314f222e7d8ef48bc3c0bc6d96d25 Mon Sep 17 00:00:00 2001 From: Kelly Gao Date: Wed, 13 Aug 2025 00:34:58 -0400 Subject: [PATCH 2/3] Added helper and sanitiser to ensure ready condition always exists and appears first in status conditions --- utils/reconciler.go | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/utils/reconciler.go b/utils/reconciler.go index a11d9686..f838a5ee 100644 --- a/utils/reconciler.go +++ b/utils/reconciler.go @@ -280,6 +280,51 @@ func updateReconcileInterval(maxSeconds int, s common.BaseComponentStatus, ba co return time.Duration(newInterval) * time.Second } +func (r *ReconcilerBase) ensureReadyExists(ba common.BaseComponent) { + status := ba.GetStatus() + + readyExists := false + for _, condition := range status.GetConditions() { + if condition.GetType() == common.StatusConditionTypeReady { + readyExists = true + break + } + } + + if !readyExists { + readyCondition := status.NewCondition(common.StatusConditionTypeReady) + readyCondition.SetStatus(corev1.ConditionFalse) + readyCondition.SetReason("Reconciling") + readyCondition.SetMessage("Application is being reconciled") + readyCondition.SetLastTransitionTime(&metav1.Time{Time: time.Now()}) + status.SetCondition(readyCondition) + } +} + +func (r *ReconcilerBase) sanitizeReadyFirst(ba common.BaseComponent) { + status := ba.GetStatus() + rcs, ok := status.(*v1.RuntimeComponentStatus) + if !ok || len(rcs.Conditions) <= 1 { + return + } + + var ready v1.StatusCondition + var others []v1.StatusCondition + for _, c := range rcs.Conditions { + if c.GetType() == common.StatusConditionTypeReady { + ready = c + } else { + others = append(others, c) + } + } + + if ready.GetType() == "" || rcs.Conditions[0].GetType() == common.StatusConditionTypeReady { + return + } + + rcs.Conditions = append([]v1.StatusCondition{ready}, others...) +} + // ManageError ... func (r *ReconcilerBase) ManageError(issue error, conditionType common.StatusConditionType, ba common.BaseComponent) (reconcile.Result, error) { s := ba.GetStatus() From 5236f2a17c4403d3065003ce471d03128aec14fe Mon Sep 17 00:00:00 2001 From: Kelly Gao Date: Wed, 13 Aug 2025 00:36:32 -0400 Subject: [PATCH 3/3] Updated ManageError and ManageSuccess --- utils/reconciler.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/utils/reconciler.go b/utils/reconciler.go index f838a5ee..8cc65fc0 100644 --- a/utils/reconciler.go +++ b/utils/reconciler.go @@ -371,6 +371,10 @@ func (r *ReconcilerBase) ManageError(issue error, conditionType common.StatusCon maxSeconds := getMaxReconcileInterval(false) retryInterval = updateReconcileInterval(maxSeconds, s, ba) } + + // Ensure Ready condition exists before updating status + r.ensureReadyExists(ba) + r.sanitizeReadyFirst(ba) err := r.UpdateStatus(obj) if err != nil { @@ -429,6 +433,10 @@ func (r *ReconcilerBase) ManageSuccess(conditionType common.StatusConditionType, retryInterval = updateReconcileInterval(maxSeconds, s, ba) } } + + // Ensure Ready condition exists before updating status + r.ensureReadyExists(ba) + r.sanitizeReadyFirst(ba) err := r.UpdateStatus(ba.(client.Object)) if err != nil {