Skip to content

Commit 27ced56

Browse files
authored
fix: buggy nextY logic for maxOCPVersion (#3416)
The handling logic of versions that are pre-releases by the nextY() func (that determines the next Y release) was erroneous. Eg: nextY("4.16.0") returns "4.17" correctly, but nextY("4.16.0-rc1") returns "4.16" (the correct value is still "4.17"). This PR fixes the nextY function. Also has improvement for the "not-upgradeable to next OCP" version message.
1 parent efe9779 commit 27ced56

File tree

2 files changed

+44
-25
lines changed

2 files changed

+44
-25
lines changed

pkg/controller/operators/openshift/helpers.go

+11-22
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,12 @@ func (s skews) String() string {
9191
j--
9292
}
9393

94-
return "ClusterServiceVersions blocking cluster upgrade: " + strings.Join(msg, ",")
94+
// it is safe to ignore the error here, with the assumption
95+
// that we build each skew object only after verifying that the
96+
// version string is parseable safely.
97+
maxOCPVersion, _ := semver.ParseTolerant(s[0].maxOpenShiftVersion)
98+
nextY := nextY(maxOCPVersion).String()
99+
return fmt.Sprintf("ClusterServiceVersions blocking minor version upgrades to %s or higher:\n%s", nextY, strings.Join(msg, "\n"))
95100
}
96101

97102
type skew struct {
@@ -103,10 +108,9 @@ type skew struct {
103108

104109
func (s skew) String() string {
105110
if s.err != nil {
106-
return fmt.Sprintf("%s/%s has invalid %s properties: %s", s.namespace, s.name, MaxOpenShiftVersionProperty, s.err)
111+
return fmt.Sprintf("- %s/%s has invalid %s properties: %s", s.namespace, s.name, MaxOpenShiftVersionProperty, s.err)
107112
}
108-
109-
return fmt.Sprintf("%s/%s is incompatible with OpenShift minor versions greater than %s", s.namespace, s.name, s.maxOpenShiftVersion)
113+
return fmt.Sprintf("- maximum supported OCP version for %s/%s is %s", s.namespace, s.name, s.maxOpenShiftVersion)
110114
}
111115

112116
type transientError struct {
@@ -131,11 +135,6 @@ func incompatibleOperators(ctx context.Context, cli client.Client) (skews, error
131135
return nil, fmt.Errorf("failed to determine current OpenShift Y-stream release")
132136
}
133137

134-
next, err := nextY(*current)
135-
if err != nil {
136-
return nil, err
137-
}
138-
139138
csvList := &operatorsv1alpha1.ClusterServiceVersionList{}
140139
if err := cli.List(ctx, csvList); err != nil {
141140
return nil, &transientError{fmt.Errorf("failed to list ClusterServiceVersions: %w", err)}
@@ -158,7 +157,7 @@ func incompatibleOperators(ctx context.Context, cli client.Client) (skews, error
158157
continue
159158
}
160159

161-
if max == nil || max.GTE(next) {
160+
if max == nil || max.GTE(nextY(*current)) {
162161
continue
163162
}
164163

@@ -224,18 +223,8 @@ func getCurrentRelease() (*semver.Version, error) {
224223
return currentRelease.version, nil
225224
}
226225

227-
func nextY(v semver.Version) (semver.Version, error) {
228-
v.Build = nil // Builds are irrelevant
229-
230-
if len(v.Pre) > 0 {
231-
// Dropping pre-releases is equivalent to incrementing Y
232-
v.Pre = nil
233-
v.Patch = 0
234-
235-
return v, nil
236-
}
237-
238-
return v, v.IncrementMinor() // Sets Y=Y+1 and Z=0
226+
func nextY(v semver.Version) semver.Version {
227+
return semver.Version{Major: v.Major, Minor: v.Minor + 1} // Sets Y=Y+1
239228
}
240229

241230
const (

pkg/controller/operators/openshift/helpers_test.go

+33-3
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ func TestIncompatibleOperators(t *testing.T) {
423423
},
424424
{
425425
description: "ClusterPre",
426-
version: "1.1.0-pre", // Next Y-stream is 1.1.0, NOT 1.2.0
426+
version: "1.1.0-pre", // Next Y-stream is 1.2.0
427427
in: skews{
428428
{
429429
name: "almond",
@@ -432,8 +432,14 @@ func TestIncompatibleOperators(t *testing.T) {
432432
},
433433
},
434434
expect: expect{
435-
err: false,
436-
incompatible: nil,
435+
err: false,
436+
incompatible: skews{
437+
{
438+
name: "almond",
439+
namespace: "default",
440+
maxOpenShiftVersion: "1.1",
441+
},
442+
},
437443
},
438444
},
439445
} {
@@ -597,3 +603,27 @@ func TestNotCopiedSelector(t *testing.T) {
597603
})
598604
}
599605
}
606+
607+
func TestOCPVersionNextY(t *testing.T) {
608+
for _, tc := range []struct {
609+
description string
610+
inVersion semver.Version
611+
expectedVersion semver.Version
612+
}{
613+
{
614+
description: "Version: 4.16.0. Expected output: 4.17",
615+
inVersion: semver.MustParse("4.16.0"),
616+
expectedVersion: semver.MustParse("4.17.0"),
617+
},
618+
{
619+
description: "Version: 4.16.0-rc1. Expected output: 4.17",
620+
inVersion: semver.MustParse("4.16.0-rc1"),
621+
expectedVersion: semver.MustParse("4.17.0"),
622+
},
623+
} {
624+
t.Run(tc.description, func(t *testing.T) {
625+
outVersion := nextY(tc.inVersion)
626+
require.Equal(t, outVersion, tc.expectedVersion)
627+
})
628+
}
629+
}

0 commit comments

Comments
 (0)