Skip to content

Commit b3bff60

Browse files
Merge pull request #1203 from rfredette/ocpbugs-53424-multiple-installplans
OCPBUGS-53424: Wait for install plans to enter the "Requires Approval" phase before approving them
2 parents 1410fe0 + b9d2420 commit b3bff60

File tree

3 files changed

+326
-11
lines changed

3 files changed

+326
-11
lines changed

pkg/operator/controller/gatewayclass/controller.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,14 @@ func NewUnmanaged(mgr manager.Manager, config Config) (controller.Controller, er
8181
}
8282
return false
8383
})
84-
// Check the approved status of an InstallPlan. The ingress operator only needs to potentially move install plans
85-
// from Approved=false to Approved=true, so we can filter out all approved plans at the Watch() level.
86-
isInstallPlanApproved := predicate.NewPredicateFuncs(func(o client.Object) bool {
84+
// Check if an InstallPlan is ready for approval. This requires that both the spec.approved field is false and that
85+
// the status.phase is "RequiresApproval" to make sure OLM is done modifying the InstallPlan before it can be
86+
// approved.
87+
isInstallPlanReadyForApproval := predicate.NewPredicateFuncs(func(o client.Object) bool {
8788
installPlan := o.(*operatorsv1alpha1.InstallPlan)
88-
return installPlan.Spec.Approved
89+
return !installPlan.Spec.Approved && installPlan.Status.Phase == operatorsv1alpha1.InstallPlanPhaseRequiresApproval
8990
})
90-
if err := c.Watch(source.Kind[client.Object](operatorCache, &operatorsv1alpha1.InstallPlan{}, reconciler.enqueueRequestForSomeGatewayClass(), isOurInstallPlan, predicate.Not(isInstallPlanApproved))); err != nil {
91+
if err := c.Watch(source.Kind[client.Object](operatorCache, &operatorsv1alpha1.InstallPlan{}, reconciler.enqueueRequestForSomeGatewayClass(), isOurInstallPlan, isInstallPlanReadyForApproval)); err != nil {
9192
return nil, err
9293
}
9394

pkg/operator/controller/gatewayclass/subscription.go

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -158,22 +158,45 @@ func (r *reconciler) currentInstallPlan(ctx context.Context) (bool, *operatorsv1
158158
if installPlans == nil || len(installPlans.Items) == 0 {
159159
return false, nil, nil
160160
}
161+
var currentInstallPlan *operatorsv1alpha1.InstallPlan
162+
multipleInstallPlans := false
161163
for _, installPlan := range installPlans.Items {
162164
if len(installPlan.OwnerReferences) == 0 || len(installPlan.Spec.ClusterServiceVersionNames) == 0 {
163165
continue
164166
}
167+
ownerRefMatches := false
165168
for _, ownerRef := range installPlan.OwnerReferences {
166169
if ownerRef.UID == subscription.UID {
167-
for _, csvName := range installPlan.Spec.ClusterServiceVersionNames {
168-
if csvName == r.config.GatewayAPIOperatorVersion {
169-
return true, &installPlan, nil
170-
}
170+
ownerRefMatches = true
171+
break
172+
}
173+
}
174+
if !ownerRefMatches {
175+
continue
176+
}
177+
// Ignore InstallPlans not in the "RequiresApproval" state. OLM may not be done setting them up.
178+
if installPlan.Status.Phase != operatorsv1alpha1.InstallPlanPhaseRequiresApproval {
179+
continue
180+
}
181+
for _, csvName := range installPlan.Spec.ClusterServiceVersionNames {
182+
if csvName == r.config.GatewayAPIOperatorVersion {
183+
// Keep the newest InstallPlan to return at the end of the loop.
184+
if currentInstallPlan == nil {
185+
currentInstallPlan = &installPlan
186+
break
187+
}
188+
multipleInstallPlans = true
189+
if currentInstallPlan.ObjectMeta.CreationTimestamp.Before(&installPlan.ObjectMeta.CreationTimestamp) {
190+
currentInstallPlan = &installPlan
191+
break
171192
}
172193
}
173194
}
174195
}
175-
// No valid InstallPlan found.
176-
return false, nil, nil
196+
if multipleInstallPlans {
197+
log.Info(fmt.Sprintf("found multiple valid InstallPlans. using %s because it's the newest", currentInstallPlan.Name))
198+
}
199+
return (currentInstallPlan != nil), currentInstallPlan, nil
177200
}
178201

179202
// desiredInstallPlan returns a version of the expected InstallPlan that is approved.

0 commit comments

Comments
 (0)