Skip to content

Commit a21d201

Browse files
committed
Bug 1822513: Determine current version by checking for status completed
Preconditions such as ClusterVersion overrides should block all upgrades including z-level upgrades. However other preconditions should not be block z-level upgrades. Currently, when upgrades are performed using `oc adm upgrade` CVO will check if it is a z-level upgrade by comaparing the minor level version of the desired update with the minor level version of the currently installed version. The currently installed version is determined by simply using the first entry in version history however this is incorrect since that entry will be the version being upgraded to, i.e. the desired version. A side-effect of this is that when the `--to-image option` is used, this first entry will have an empty version string and therefore the z-level upgrade check will always return false and preconditions are always checked. Instead, this change iterates through the version history until it finds the first version with update State of Completed which will be the currently installed version. If no Completed version is found the originally installed version is returned.
1 parent 62ff8e3 commit a21d201

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

pkg/payload/precondition/clusterversion/upgradable_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ func TestUpgradeableRun(t *testing.T) {
116116
},
117117
}
118118
if len(tc.currVersion) > 0 {
119-
clusterVersion.Status.History = append(clusterVersion.Status.History, configv1.UpdateHistory{Version: tc.currVersion})
119+
clusterVersion.Status.History = append(clusterVersion.Status.History, configv1.UpdateHistory{Version: tc.currVersion, State: configv1.CompletedUpdate})
120120
}
121121
if tc.upgradeable != nil {
122122
clusterVersion.Status.Conditions = append(clusterVersion.Status.Conditions, configv1.ClusterOperatorStatusCondition{

pkg/payload/precondition/clusterversion/upgradeable.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,10 @@ func (pf *Upgradeable) Run(ctx context.Context, releaseContext precondition.Rele
6262
return nil
6363
}
6464

65-
currentMinor := getEffectiveMinor(cv.Status.History[0].Version)
65+
currentVersion := getCurrentVersion(cv.Status.History)
66+
currentMinor := getEffectiveMinor(currentVersion)
6667
desiredMinor := getEffectiveMinor(releaseContext.DesiredVersion)
68+
klog.V(5).Infof("currentMinor %s releaseContext.DesiredVersion %s desiredMinor %s", currentMinor, releaseContext.DesiredVersion, desiredMinor)
6769

6870
// if there is no difference in the minor version (4.y.z where 4.y is the same for current and desired), then we can still upgrade
6971
if currentMinor == desiredMinor {
@@ -82,6 +84,20 @@ func (pf *Upgradeable) Run(ctx context.Context, releaseContext precondition.Rele
8284
// Name returns Name for the precondition.
8385
func (pf *Upgradeable) Name() string { return "ClusterVersionUpgradeable" }
8486

87+
// getCurrentVersion determines and returns the cluster's current version by iterating through the
88+
// provided update history until it finds the first version with update State of Completed. If a
89+
// Completed version is not found the version of the oldest history entry, which is the originally
90+
// installed version, is returned.
91+
func getCurrentVersion(history []configv1.UpdateHistory) string {
92+
for _, h := range history {
93+
if h.State == configv1.CompletedUpdate {
94+
klog.V(5).Infof("Cluster current version=%s", h.Version)
95+
return h.Version
96+
}
97+
}
98+
return history[len(history)-1].Version
99+
}
100+
85101
// getEffectiveMinor attempts to do a simple parse of the version provided. If it does not parse, the value is considered
86102
// empty string, which works for the comparison done here for equivalence.
87103
func getEffectiveMinor(version string) string {

0 commit comments

Comments
 (0)