Skip to content

Commit 74f4a29

Browse files
[v1.22.x] (bugfix): approve InstallPlan only if it is a new InstallPlan (#5924)
* fix installplan approval bug Signed-off-by: Bryce Palmer <[email protected]> * add changelog Signed-off-by: Bryce Palmer <[email protected]> * fix sanity issues Signed-off-by: Bryce Palmer <[email protected]> Co-authored-by: Bryce Palmer <[email protected]>
1 parent b88af21 commit 74f4a29

File tree

3 files changed

+93
-22
lines changed

3 files changed

+93
-22
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# entries is a list of entries to include in
2+
# release notes and/or the migration guide
3+
entries:
4+
- description: >
5+
For `operator-sdk run bundle-upgrade`: fix a bug that caused `InstallPlan`s occasionally not being approved when attempting to upgrade a bundle.
6+
7+
# kind is one of:
8+
# - addition
9+
# - change
10+
# - deprecation
11+
# - removal
12+
# - bugfix
13+
kind: "bugfix"
14+
15+
# Is this a breaking change?
16+
breaking: false
17+

internal/olm/operator/registry/operator_installer.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ import (
3131

3232
olmclient "github.com/operator-framework/operator-sdk/internal/olm/client"
3333
"github.com/operator-framework/operator-sdk/internal/olm/operator"
34+
35+
corev1 "k8s.io/api/core/v1"
3436
)
3537

3638
type OperatorInstaller struct {
@@ -345,11 +347,17 @@ func (o OperatorInstaller) waitForInstallPlan(ctx context.Context, sub *v1alpha1
345347
Name: sub.GetName(),
346348
}
347349

350+
// Get the previous InstallPlanRef
351+
prevIPRef := corev1.ObjectReference{}
352+
if sub.Status.InstallPlanRef != nil {
353+
prevIPRef = *sub.Status.InstallPlanRef
354+
}
355+
348356
ipCheck := wait.ConditionFunc(func() (done bool, err error) {
349357
if err := o.cfg.Client.Get(ctx, subKey, sub); err != nil {
350358
return false, err
351359
}
352-
if sub.Status.InstallPlanRef != nil {
360+
if sub.Status.InstallPlanRef != nil && sub.Status.InstallPlanRef.Name != prevIPRef.Name {
353361
return true, nil
354362
}
355363
return false, nil

internal/olm/operator/registry/operator_installer_test.go

Lines changed: 67 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ import (
3232
"github.com/operator-framework/operator-sdk/internal/olm/operator"
3333
)
3434

35+
const name = "fakeName"
36+
const namespace = "fakeNS"
37+
3538
var _ = Describe("OperatorInstaller", func() {
3639
Describe("NewOperatorInstaller", func() {
3740
It("should create an OperatorInstaller", func() {
@@ -161,47 +164,47 @@ var _ = Describe("OperatorInstaller", func() {
161164
oi.cfg.Client = fake.NewClientBuilder().WithScheme(sch).WithObjects(
162165
&v1alpha1.InstallPlan{
163166
ObjectMeta: metav1.ObjectMeta{
164-
Name: "fakeName",
165-
Namespace: "fakeNS",
167+
Name: name,
168+
Namespace: namespace,
166169
},
167170
},
168171
).Build()
169172

170173
ip := &v1alpha1.InstallPlan{}
171174
ipKey := types.NamespacedName{
172-
Namespace: "fakeNS",
173-
Name: "fakeName",
175+
Namespace: namespace,
176+
Name: name,
174177
}
175178

176179
err := oi.cfg.Client.Get(context.TODO(), ipKey, ip)
177180
Expect(err).ToNot(HaveOccurred())
178-
Expect(ip.Name).To(Equal("fakeName"))
179-
Expect(ip.Namespace).To(Equal("fakeNS"))
181+
Expect(ip.Name).To(Equal(name))
182+
Expect(ip.Namespace).To(Equal(namespace))
180183

181184
// Test
182185
sub := &v1alpha1.Subscription{
183186
Status: v1alpha1.SubscriptionStatus{
184187
InstallPlanRef: &corev1.ObjectReference{
185-
Name: "fakeName",
186-
Namespace: "fakeNS",
188+
Name: name,
189+
Namespace: namespace,
187190
},
188191
},
189192
}
190193
err = oi.approveInstallPlan(context.TODO(), sub)
191194
Expect(err).ToNot(HaveOccurred())
192195
err = oi.cfg.Client.Get(context.TODO(), ipKey, ip)
193196
Expect(err).ToNot(HaveOccurred())
194-
Expect(ip.Name).To(Equal("fakeName"))
195-
Expect(ip.Namespace).To(Equal("fakeNS"))
197+
Expect(ip.Name).To(Equal(name))
198+
Expect(ip.Namespace).To(Equal(namespace))
196199
Expect(ip.Spec.Approved).To(Equal(true))
197200
})
198201
It("should return an error if the install plan does not exist.", func() {
199202
oi.cfg.Client = fake.NewClientBuilder().WithScheme(sch).Build()
200203
sub := &v1alpha1.Subscription{
201204
Status: v1alpha1.SubscriptionStatus{
202205
InstallPlanRef: &corev1.ObjectReference{
203-
Name: "fakeName",
204-
Namespace: "fakeNS",
206+
Name: name,
207+
Namespace: namespace,
205208
},
206209
},
207210
}
@@ -224,8 +227,8 @@ var _ = Describe("OperatorInstaller", func() {
224227
cfg.Client = fake.NewClientBuilder().WithScheme(sch).Build()
225228

226229
oi = NewOperatorInstaller(cfg)
227-
oi.StartingCSV = "fakeName"
228-
oi.cfg.Namespace = "fakeNS"
230+
oi.StartingCSV = name
231+
oi.cfg.Namespace = namespace
229232
})
230233
It("should return an error if the subscription does not exist.", func() {
231234
sub := newSubscription(oi.StartingCSV, oi.cfg.Namespace, withCatalogSource("duplicate", oi.cfg.Namespace))
@@ -235,23 +238,66 @@ var _ = Describe("OperatorInstaller", func() {
235238
Expect(err.Error()).Should(ContainSubstring("install plan is not available for the subscription"))
236239

237240
})
238-
It("should return if subscription has an install plan.", func() {
241+
It("should return if subscription has an install plan and previous install plan is nil", func() {
242+
name := name
243+
namespace := namespace
244+
prevSub := &v1alpha1.Subscription{
245+
ObjectMeta: metav1.ObjectMeta{
246+
Name: name,
247+
Namespace: namespace,
248+
},
249+
}
250+
251+
sub := &v1alpha1.Subscription{
252+
ObjectMeta: metav1.ObjectMeta{
253+
Name: name,
254+
Namespace: namespace,
255+
},
256+
Status: v1alpha1.SubscriptionStatus{
257+
InstallPlanRef: &corev1.ObjectReference{
258+
Name: name,
259+
Namespace: namespace,
260+
},
261+
},
262+
}
263+
err := oi.cfg.Client.Create(context.TODO(), sub)
264+
Expect(err).ToNot(HaveOccurred())
265+
266+
err = oi.waitForInstallPlan(context.TODO(), prevSub)
267+
Expect(err).ToNot(HaveOccurred())
268+
})
269+
It("should return if subscription has an install plan and is different than previous install plan", func() {
270+
name := name
271+
namespace := namespace
272+
prevSub := &v1alpha1.Subscription{
273+
ObjectMeta: metav1.ObjectMeta{
274+
Name: name,
275+
Namespace: namespace,
276+
},
277+
Status: v1alpha1.SubscriptionStatus{
278+
InstallPlanRef: &corev1.ObjectReference{
279+
Name: name + "diff",
280+
Namespace: namespace + "diff",
281+
},
282+
},
283+
}
284+
239285
sub := &v1alpha1.Subscription{
240286
ObjectMeta: metav1.ObjectMeta{
241-
Name: "fakeName",
242-
Namespace: "fakeNS",
287+
Name: name,
288+
Namespace: namespace,
243289
},
244290
Status: v1alpha1.SubscriptionStatus{
245291
InstallPlanRef: &corev1.ObjectReference{
246-
Name: "fakeName",
247-
Namespace: "fakeNS",
292+
Name: name,
293+
Namespace: namespace,
248294
},
249295
},
250296
}
251297
err := oi.cfg.Client.Create(context.TODO(), sub)
252298
Expect(err).ToNot(HaveOccurred())
253299

254-
err = oi.waitForInstallPlan(context.TODO(), sub)
300+
err = oi.waitForInstallPlan(context.TODO(), prevSub)
255301
Expect(err).ToNot(HaveOccurred())
256302
})
257303
})
@@ -550,7 +596,7 @@ var _ = Describe("OperatorInstaller", func() {
550596
Expect(err).To(HaveOccurred())
551597
})
552598
It("should return nothing if namespace does not match", func() {
553-
oi.cfg.Namespace = "fakens"
599+
oi.cfg.Namespace = namespace
554600
_ = createOperatorGroupHelper(context.TODO(), client, "og1", "atestns")
555601
grp, found, err := oi.getOperatorGroup(context.TODO())
556602
Expect(grp).To(BeNil())

0 commit comments

Comments
 (0)