@@ -230,44 +230,61 @@ func supportedOperatorVersion(version string) bool {
230230// upgradeTagValid compares and validates the PostgreSQL version values stored
231231// in the image tag of the existing pgcluster CR against the values set in the
232232// Postgres Operator's configuration
233+ // A typical example tag is `ubi8-12.9-4.7.4`, so we want to extract and
234+ // compare that `12.9` to make sure that we are only allowing minor upgrades.
235+ // For major upgrades, see PGOv5.1.
233236func upgradeTagValid (upgradeFrom , upgradeTo string ) bool {
234237 log .Debugf ("Validating upgrade from %s to %s" , upgradeFrom , upgradeTo )
235238
236- versionRegex := regexp .MustCompile (`-(\d+)\.(\d+)(\. \d+)?-` )
239+ versionRegex := regexp .MustCompile (`-(\d+)\.(\d+)\.?( \d+)?-` )
237240
238241 // get the PostgreSQL version values
239242 upgradeFromValue := versionRegex .FindStringSubmatch (upgradeFrom )
240243 upgradeToValue := versionRegex .FindStringSubmatch (upgradeTo )
241244
242245 // if this regex passes, the returned array should always contain
243- // 4 values. At 0, the full match, then 1-3 are the three defined groups
244- // If this is not true, the upgrade cannot continue (and we won't want to
245- // reference potentially missing array items).
246+ // 4 values:
247+ // -At 0, the full match;
248+ // -At 1, the major version of PG;
249+ // -At 2, the minor version of PG, which needs to be compared as ints;
250+ // -At 3, the patch version, which can be null, but if not, should be compared as ints;
251+ // (Note the `?` in the regex after the last capture group.)
246252 if len (upgradeFromValue ) != 4 || len (upgradeToValue ) != 4 {
247253 return false
248254 }
249255
250- // if the first group does not match (PG version 9, 10, 11, 12 etc ), or if a value is
256+ // if the first group does not match (i.e., the PG major version ), or if a value is
251257 // missing, then the upgrade cannot continue
252258 if upgradeFromValue [1 ] != upgradeToValue [1 ] && upgradeToValue [1 ] != "" {
253259 return false
254260 }
255261
256- // if the above check passed, and there is no fourth value, then the PG
257- // version has only two digits (e.g. PG 10, 11 or 12 ), meaning this is a minor upgrade.
262+ // if the above check passed, and there is no patch version value, then the PG
263+ // version has only two digits (e.g. PG 12.6, 12.10 ), meaning this is a minor upgrade.
258264 // After validating the second value is at least equal (this is to allow for multiple executions of the
259265 // upgrade in case an error occurs), the upgrade can continue
260- if upgradeFromValue [3 ] == "" && upgradeToValue [3 ] == "" && upgradeFromValue [2 ] <= upgradeToValue [2 ] {
266+ // In order to compare correctly, these values have to be ints.
267+ // Note: thanks to the regex capture, we know these second values consist of digits,
268+ // so we can skip testing the error.
269+
270+ upgradeFromInt , _ := strconv .Atoi (upgradeFromValue [2 ])
271+ upgradeToInt , _ := strconv .Atoi (upgradeToValue [2 ])
272+ if upgradeFromValue [3 ] == "" && upgradeToValue [3 ] == "" && upgradeFromInt <= upgradeToInt {
261273 return true
262274 }
263275
264276 // finally, if the second group matches and is not empty, then, based on the
265277 // possibilities remaining for Operator container image tags, this is either PG 9.5 or 9.6.
266- // if the second group value matches, and the third group was already validated as not
267- // empty, check that the third value is at least equal (this is to allow for multiple executions of the
278+ // if the second group value matches, check that the third value is not empty and
279+ // at least equal (this is to allow for multiple executions of the
268280 // upgrade in case an error occurs). If so, the upgrade can continue.
269- if upgradeFromValue [2 ] == upgradeToValue [2 ] && upgradeToValue [2 ] != "" && upgradeFromValue [3 ] <= upgradeToValue [3 ] {
270- return true
281+ if upgradeFromValue [2 ] == upgradeToValue [2 ] && upgradeToValue [2 ] != "" &&
282+ upgradeFromValue [3 ] != "" && upgradeToValue [3 ] != "" {
283+ upgradeFromInt , _ = strconv .Atoi (upgradeFromValue [3 ])
284+ upgradeToInt , _ = strconv .Atoi (upgradeToValue [3 ])
285+ if upgradeFromInt <= upgradeToInt {
286+ return true
287+ }
271288 }
272289
273290 // if none of the above conditions are met, a two digit Major version upgrade is likely being
0 commit comments