Skip to content

Commit 79063fe

Browse files
committed
NE-2097: Update Progressing status logic to add OSSM operator installation
1 parent 31eeb0d commit 79063fe

File tree

3 files changed

+254
-19
lines changed

3 files changed

+254
-19
lines changed

pkg/operator/controller/gatewayclass/subscription.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,6 @@ func (r *reconciler) currentInstallPlan(ctx context.Context) (bool, *operatorsv1
263263
// but the next one in the upgrade graph exists.
264264
// Return the next InstallPlan to continue the upgrade.
265265
if currentInstallPlan == nil && nextInstallPlan != nil {
266-
log.Info("next install plan time")
267266
// The condition below prevents approving an InstallPlan
268267
// that targets a version beyond the expected operator version.
269268
// This can happen when:

pkg/operator/controller/status/controller.go

Lines changed: 102 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ func New(mgr manager.Manager, config Config) (controller.Controller, error) {
100100
isIngressClusterOperator := func(o client.Object) bool {
101101
return o.GetName() == operatorcontroller.IngressClusterOperatorName().Name
102102
}
103+
isOpenshiftOperatorNamespace := func(o client.Object) bool {
104+
return o.GetNamespace() == operatorcontroller.OpenshiftOperatorNamespace
105+
}
103106
toDefaultIngressController := func(ctx context.Context, _ client.Object) []reconcile.Request {
104107
return []reconcile.Request{{
105108
NamespacedName: types.NamespacedName{
@@ -129,13 +132,13 @@ func New(mgr manager.Manager, config Config) (controller.Controller, error) {
129132
return e.Object.GetNamespace() == operatorcontroller.OpenshiftOperatorNamespace
130133
},
131134
UpdateFunc: func(e event.UpdateEvent) bool {
132-
return false
135+
return e.ObjectNew.GetNamespace() == operatorcontroller.OpenshiftOperatorNamespace
133136
},
134137
DeleteFunc: func(e event.DeleteEvent) bool {
135138
return e.Object.GetNamespace() == operatorcontroller.OpenshiftOperatorNamespace
136139
},
137140
GenericFunc: func(e event.GenericEvent) bool {
138-
return false
141+
return e.Object.GetNamespace() == operatorcontroller.OpenshiftOperatorNamespace
139142
},
140143
})); err != nil {
141144
return nil, err
@@ -156,6 +159,9 @@ func New(mgr manager.Manager, config Config) (controller.Controller, error) {
156159
})); err != nil {
157160
return nil, err
158161
}
162+
if err := c.Watch(source.Kind[client.Object](operatorCache, &operatorsv1alpha1.ClusterServiceVersion{}, handler.EnqueueRequestsFromMapFunc(toDefaultIngressController), predicate.NewPredicateFuncs(isOpenshiftOperatorNamespace))); err != nil {
163+
return nil, err
164+
}
159165
}
160166

161167
return c, nil
@@ -295,13 +301,11 @@ func (r *reconciler) Reconcile(ctx context.Context, request reconcile.Request) (
295301
co.Status.Conditions = mergeConditions(co.Status.Conditions,
296302
computeOperatorAvailableCondition(state.IngressControllers),
297303
computeOperatorProgressingCondition(
298-
state.IngressControllers,
304+
state,
305+
r.config,
299306
allIngressesAvailable,
300307
oldStatus.Versions,
301308
co.Status.Versions,
302-
r.config.OperatorReleaseVersion,
303-
r.config.IngressControllerImage,
304-
r.config.CanaryImage,
305309
),
306310
computeOperatorDegradedCondition(state),
307311
computeOperatorUpgradeableCondition(state.IngressControllers),
@@ -366,6 +370,18 @@ type operatorState struct {
366370
// haveGatewayclassesResource means that the
367371
// "gatewayclasses.gateway.networking.k8s.io" CRD exists.
368372
haveGatewayclassesResource bool
373+
// desiredOSSMVersion contains the desired OSSM operator
374+
// as recorded in the subscription.
375+
desiredOSSMVersion string
376+
// installedOSSMVersion contains the currently installed
377+
// version of the OSSM operator.
378+
installedOSSMVersion string
379+
// currentOSSMVersion contains the OSSM operator version
380+
// which is currently being installed or the next in the upgrade graph.
381+
currentOSSMVersion string
382+
// installedOSSMVersionSucceeded means that the installed OSSM operator
383+
// version succeeded.
384+
installedOSSMVersionSucceeded bool
369385
}
370386

371387
// getOperatorState gets and returns the resources necessary to compute the
@@ -417,6 +433,27 @@ func (r *reconciler) getOperatorState(ctx context.Context, ingressNamespace, can
417433
} else {
418434
state.haveOSSMSubscription = true
419435

436+
// To compute the OSSM operator's progressing status,
437+
// we need to inspect the CSV level to determine whether
438+
// the installedCSV of the subscription succeeded.
439+
var installedCSV operatorsv1alpha1.ClusterServiceVersion
440+
installedCSVName := types.NamespacedName{
441+
Name: subscription.Status.InstalledCSV,
442+
Namespace: operatorcontroller.OpenshiftOperatorNamespace,
443+
}
444+
if err := r.cache.Get(ctx, installedCSVName, &installedCSV); err != nil {
445+
if !errors.IsNotFound(err) {
446+
return state, fmt.Errorf("failed to get installed CSV %q: %v", installedCSVName.Name, err)
447+
}
448+
} else {
449+
state.installedOSSMVersionSucceeded = (installedCSV.Status.Phase == operatorsv1alpha1.CSVPhaseSucceeded)
450+
}
451+
// StartingCSV is set by the gatewayclass controller to record
452+
// the desired operator version, even if this field is noop for OLM
453+
// after the operator was installed.
454+
state.desiredOSSMVersion = subscription.Spec.StartingCSV
455+
state.installedOSSMVersion = subscription.Status.InstalledCSV
456+
state.currentOSSMVersion = subscription.Status.CurrentCSV
420457
}
421458

422459
var (
@@ -648,7 +685,19 @@ func computeOperatorEvaluationConditionsDetectedCondition(ingresses []operatorv1
648685
}
649686

650687
// computeOperatorProgressingCondition computes the operator's current Progressing status state.
651-
func computeOperatorProgressingCondition(ingresscontrollers []operatorv1.IngressController, allIngressesAvailable bool, oldVersions, curVersions []configv1.OperandVersion, operatorReleaseVersion, ingressControllerImage string, canaryImage string) configv1.ClusterOperatorStatusCondition {
688+
func computeOperatorProgressingCondition(state operatorState, config Config, allIngressesAvailable bool, oldVersions, curVersions []configv1.OperandVersion) configv1.ClusterOperatorStatusCondition {
689+
progressingCondition := configv1.ClusterOperatorStatusCondition{
690+
Type: configv1.OperatorProgressing,
691+
}
692+
693+
icCondition := computeIngressControllersProgressingCondition(state.IngressControllers, allIngressesAvailable, oldVersions, curVersions, config.OperatorReleaseVersion, config.IngressControllerImage, config.CanaryImage)
694+
ossmCondition := computeOSSMOperatorProgressingCondition(state)
695+
696+
return joinConditions(joinConditions(progressingCondition, icCondition), ossmCondition)
697+
}
698+
699+
// computeIngressControllersProgressingCondition computes the IngressControllers' current Progressing status state.
700+
func computeIngressControllersProgressingCondition(ingresscontrollers []operatorv1.IngressController, allIngressesAvailable bool, oldVersions, curVersions []configv1.OperandVersion, operatorReleaseVersion, ingressControllerImage string, canaryImage string) configv1.ClusterOperatorStatusCondition {
652701
progressingCondition := configv1.ClusterOperatorStatusCondition{
653702
Type: configv1.OperatorProgressing,
654703
}
@@ -715,6 +764,51 @@ func computeOperatorProgressingCondition(ingresscontrollers []operatorv1.Ingress
715764
return progressingCondition
716765
}
717766

767+
// computeOSSMOperatorProgressingCondition computes the OSSM operator's current Progressing status state.
768+
func computeOSSMOperatorProgressingCondition(state operatorState) configv1.ClusterOperatorStatusCondition {
769+
progressingCondition := configv1.ClusterOperatorStatusCondition{}
770+
771+
// Skip updating the progressing status if OSSM operator subscription doesn't exist.
772+
if !state.haveOSSMSubscription {
773+
return progressingCondition
774+
}
775+
776+
progressing := false
777+
778+
// Set the progressing to true if the desired version is different
779+
// from the currently installed.
780+
if state.desiredOSSMVersion != state.installedOSSMVersion {
781+
// Note that the progressing state remains "true" if the desired version is
782+
// beyond the latest available in the upgrade graph.
783+
// There is no reliable way of knowing that the end of the upgrade graph
784+
// is reached and no next version is available. None of OLM resources
785+
// can provide such information.
786+
progressing = true
787+
} else {
788+
// The desired version was reached. However the CSV may still be
789+
// in "Replacing" or "Installing" state, stop setting progressing
790+
// when the installed CSV succeeded.
791+
if !state.installedOSSMVersionSucceeded {
792+
progressing = true
793+
}
794+
}
795+
796+
if progressing {
797+
progressingCondition.Status = configv1.ConditionTrue
798+
progressingCondition.Reason = "OSSMOperatorUpgrading"
799+
progressingCondition.Message = fmt.Sprintf("OSSM operator is upgrading to version %q", state.desiredOSSMVersion)
800+
if len(state.installedOSSMVersion) > 0 && len(state.currentOSSMVersion) > 0 {
801+
progressingCondition.Message += fmt.Sprintf(" (installed(-ing):%q,next:%q)", state.installedOSSMVersion, state.currentOSSMVersion)
802+
}
803+
} else {
804+
progressingCondition.Status = configv1.ConditionFalse
805+
progressingCondition.Reason = "OSSMOperatorUpToDate"
806+
progressingCondition.Message = fmt.Sprintf("OSSM operator is running the expected version %q", state.desiredOSSMVersion)
807+
}
808+
809+
return progressingCondition
810+
}
811+
718812
// computeOperatorAvailableCondition computes the operator's current Available status state.
719813
func computeOperatorAvailableCondition(ingresses []operatorv1.IngressController) configv1.ClusterOperatorStatusCondition {
720814
availableCondition := configv1.ClusterOperatorStatusCondition{
@@ -825,7 +919,7 @@ func operatorStatusesEqual(a, b configv1.ClusterOperatorStatus) bool {
825919

826920
// joinConditions merges two cluster operator conditions into one.
827921
// If both conditions have the same status:
828-
// - Reason becomes: "MultipleComponents[Not]" + condType.
922+
// - Reasons are concatenated using "And" as a delimiter.
829923
// - Messages are concatenated.
830924
// If the new condition has a higher-priority status, it overrides the current one.
831925
// Status priority (highest to lowest): True, Unknown, False, empty.

0 commit comments

Comments
 (0)