Skip to content

Commit e45ea95

Browse files
shwstpprPearl1594
authored andcommitted
engine-schema: upgrade path for 24.0.0
Adds a 4.23.0 to 24.0.0 upgrade path (squashed from sb/upgradepath-424: engine-schema: upgrade path for 24.0.0, fix CS version, fix upgrade unit tests for cutover, fix imports).
1 parent d87c804 commit e45ea95

8 files changed

Lines changed: 205 additions & 52 deletions

File tree

‎engine/schema/src/main/java/com/cloud/upgrade/DatabaseUpgradeChecker.java‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,12 @@
9191
import com.cloud.upgrade.dao.Upgrade42020to42030;
9292
import com.cloud.upgrade.dao.Upgrade42030to42040;
9393
import com.cloud.upgrade.dao.Upgrade42040to42100;
94-
import com.cloud.upgrade.dao.Upgrade42100to42200;
95-
import com.cloud.upgrade.dao.Upgrade42200to42210;
9694
import com.cloud.upgrade.dao.Upgrade420to421;
95+
import com.cloud.upgrade.dao.Upgrade42100to42200;
9796
import com.cloud.upgrade.dao.Upgrade421to430;
97+
import com.cloud.upgrade.dao.Upgrade42200to42210;
9898
import com.cloud.upgrade.dao.Upgrade42210to42300;
99+
import com.cloud.upgrade.dao.Upgrade42300to2400;
99100
import com.cloud.upgrade.dao.Upgrade430to440;
100101
import com.cloud.upgrade.dao.Upgrade431to440;
101102
import com.cloud.upgrade.dao.Upgrade432to440;
@@ -248,6 +249,7 @@ public DatabaseUpgradeChecker() {
248249
.next("4.21.0.0", new Upgrade42100to42200())
249250
.next("4.22.0.0", new Upgrade42200to42210())
250251
.next("4.22.1.0", new Upgrade42210to42300())
252+
.next("4.23.0.0", new Upgrade42300to2400())
251253
.build();
252254
}
253255

@@ -513,8 +515,13 @@ protected void doUpgrades(GlobalLock lock) {
513515
String csVersion = parseSystemVmMetadata();
514516
final CloudStackVersion sysVmVersion = CloudStackVersion.parse(csVersion);
515517
final CloudStackVersion currentVersion = CloudStackVersion.parse(currentVersionValue);
516-
SystemVmTemplateRegistration.CS_MAJOR_VERSION = sysVmVersion.getMajorRelease() + "." + sysVmVersion.getMinorRelease();
517-
SystemVmTemplateRegistration.CS_TINY_VERSION = String.valueOf(sysVmVersion.getPatchRelease());
518+
if (sysVmVersion.usesNewVersioning()) {
519+
SystemVmTemplateRegistration.CS_MAJOR_VERSION = String.valueOf(sysVmVersion.getMajorRelease());
520+
SystemVmTemplateRegistration.CS_TINY_VERSION = String.valueOf(sysVmVersion.getMajorRelease());
521+
} else {
522+
SystemVmTemplateRegistration.CS_MAJOR_VERSION = String.format("%d.%d", sysVmVersion.getMajorRelease(), sysVmVersion.getMinorRelease());
523+
SystemVmTemplateRegistration.CS_TINY_VERSION = String.valueOf(sysVmVersion.getPatchRelease());
524+
}
518525

519526
LOGGER.info("DB version = {} Code Version = {}", dbVersion, currentVersion);
520527

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
package com.cloud.upgrade.dao;
18+
19+
public class Upgrade42300to2400 extends DbUpgradeAbstractImpl implements DbUpgrade, DbUpgradeSystemVmTemplate {
20+
21+
@Override
22+
public String[] getUpgradableVersionRange() {
23+
return new String[]{"4.23.0.0", "24.0.0"};
24+
}
25+
26+
@Override
27+
public String getUpgradedVersion() {
28+
return "24.0.0";
29+
}
30+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
-- Licensed to the Apache Software Foundation (ASF) under one
2+
-- or more contributor license agreements. See the NOTICE file
3+
-- distributed with this work for additional information
4+
-- regarding copyright ownership. The ASF licenses this file
5+
-- to you under the Apache License, Version 2.0 (the
6+
-- "License"); you may not use this file except in compliance
7+
-- with the License. You may obtain a copy of the License at
8+
--
9+
-- http://www.apache.org/licenses/LICENSE-2.0
10+
--
11+
-- Unless required by applicable law or agreed to in writing,
12+
-- software distributed under the License is distributed on an
13+
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
-- KIND, either express or implied. See the License for the
15+
-- specific language governing permissions and limitations
16+
-- under the License.
17+
18+
--;
19+
-- Schema upgrade cleanup from 4.23.0.0 to 24.0.0
20+
--;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
-- Licensed to the Apache Software Foundation (ASF) under one
2+
-- or more contributor license agreements. See the NOTICE file
3+
-- distributed with this work for additional information
4+
-- regarding copyright ownership. The ASF licenses this file
5+
-- to you under the Apache License, Version 2.0 (the
6+
-- "License"); you may not use this file except in compliance
7+
-- with the License. You may obtain a copy of the License at
8+
--
9+
-- http://www.apache.org/licenses/LICENSE-2.0
10+
--
11+
-- Unless required by applicable law or agreed to in writing,
12+
-- software distributed under the License is distributed on an
13+
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
-- KIND, either express or implied. See the License for the
15+
-- specific language governing permissions and limitations
16+
-- under the License.
17+
18+
--;
19+
-- Schema upgrade from 4.23.0.0 to 24.0.0
20+
--;

‎engine/schema/src/test/java/com/cloud/upgrade/DatabaseUpgradeCheckerTest.java‎

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,25 @@
1616
// under the License.
1717
package com.cloud.upgrade;
1818

19-
import java.sql.SQLException;
19+
import static org.junit.Assert.assertArrayEquals;
20+
import static org.junit.Assert.assertEquals;
21+
import static org.junit.Assert.assertFalse;
22+
import static org.junit.Assert.assertNotNull;
23+
import static org.junit.Assert.assertTrue;
24+
2025
import java.lang.reflect.Field;
2126
import java.sql.Connection;
2227
import java.sql.PreparedStatement;
2328
import java.sql.ResultSet;
29+
import java.sql.SQLException;
2430

2531
import javax.sql.DataSource;
2632

2733
import org.apache.cloudstack.utils.CloudStackVersion;
28-
import org.junit.Test;
29-
import org.junit.Before;
3034
import org.junit.After;
35+
import org.junit.Before;
36+
import org.junit.Test;
3137
import org.junit.runner.RunWith;
32-
3338
import org.mockito.ArgumentMatchers;
3439
import org.mockito.Mock;
3540
import org.mockito.Mockito;
@@ -55,15 +60,8 @@
5560
import com.cloud.upgrade.dao.Upgrade471to480;
5661
import com.cloud.upgrade.dao.Upgrade480to481;
5762
import com.cloud.upgrade.dao.Upgrade490to4910;
58-
5963
import com.cloud.utils.db.TransactionLegacy;
6064

61-
import static org.junit.Assert.assertTrue;
62-
import static org.junit.Assert.assertFalse;
63-
import static org.junit.Assert.assertNotNull;
64-
import static org.junit.Assert.assertEquals;
65-
import static org.junit.Assert.assertArrayEquals;
66-
6765

6866
@RunWith(MockitoJUnitRunner.class)
6967
public class DatabaseUpgradeCheckerTest {
@@ -214,10 +212,10 @@ public void testFindUpgradePath452to490() {
214212
@Test
215213
public void testCalculateUpgradePathUnknownDbVersion() {
216214

217-
final CloudStackVersion dbVersion = CloudStackVersion.parse("4.99.0.0");
215+
final CloudStackVersion dbVersion = CloudStackVersion.parse("99.0.0");
218216
assertNotNull(dbVersion);
219217

220-
final CloudStackVersion currentVersion = CloudStackVersion.parse("4.99.1.0");
218+
final CloudStackVersion currentVersion = CloudStackVersion.parse("99.1.0");
221219
assertNotNull(currentVersion);
222220

223221
final DatabaseUpgradeChecker checker = new DatabaseUpgradeChecker();
@@ -234,7 +232,7 @@ public void testCalculateUpgradePathFromKnownDbVersion() {
234232
final CloudStackVersion dbVersion = CloudStackVersion.parse("4.17.0.0");
235233
assertNotNull(dbVersion);
236234

237-
final CloudStackVersion currentVersion = CloudStackVersion.parse("4.99.1.0");
235+
final CloudStackVersion currentVersion = CloudStackVersion.parse("99.1.0");
238236
assertNotNull(currentVersion);
239237

240238
final DatabaseUpgradeChecker checker = new DatabaseUpgradeChecker();
@@ -268,10 +266,7 @@ public void testCalculateUpgradePathFromLatestDbVersion() {
268266
final CloudStackVersion dbVersion = checker.getLatestVersion();
269267
assertNotNull(dbVersion);
270268

271-
final CloudStackVersion currentVersion = CloudStackVersion.parse(dbVersion.getMajorRelease() + "."
272-
+ dbVersion.getMinorRelease() + "."
273-
+ dbVersion.getPatchRelease() + "."
274-
+ (dbVersion.getSecurityRelease() + 1));
269+
final CloudStackVersion currentVersion = getNextSecurityRelease(dbVersion);
275270
assertNotNull(currentVersion);
276271

277272
final DbUpgrade[] upgrades = checker.calculateUpgradePath(dbVersion, currentVersion);
@@ -293,10 +288,7 @@ public void testCalculateUpgradePathFrom41800toNextSecurityRelease() {
293288
final DbUpgrade[] upgrades = checker.calculateUpgradePath(dbVersion, currentVersion);
294289
assertNotNull(upgrades);
295290

296-
final CloudStackVersion nextSecurityRelease = CloudStackVersion.parse(currentVersion.getMajorRelease() + "."
297-
+ currentVersion.getMinorRelease() + "."
298-
+ currentVersion.getPatchRelease() + "."
299-
+ (currentVersion.getSecurityRelease() + 1));
291+
final CloudStackVersion nextSecurityRelease = getNextSecurityRelease(currentVersion);
300292
assertNotNull(nextSecurityRelease);
301293

302294
final DbUpgrade[] upgradesToNext = checker.calculateUpgradePath(dbVersion, nextSecurityRelease);
@@ -306,16 +298,26 @@ public void testCalculateUpgradePathFrom41800toNextSecurityRelease() {
306298
assertTrue(upgradesToNext[upgradesToNext.length - 1] instanceof NoopDbUpgrade);
307299
}
308300

301+
private static CloudStackVersion getNextSecurityRelease(CloudStackVersion version, int increment) {
302+
String nextSecurityReleaseVersionStr = version.getMajorRelease() + "."
303+
+ version.getMinorRelease() + "."
304+
+ (version.usesNewVersioning() ? "" : version.getPatchRelease() + ".")
305+
+ (version.getSecurityRelease() + increment);
306+
307+
return CloudStackVersion.parse(nextSecurityReleaseVersionStr);
308+
}
309+
310+
private static CloudStackVersion getNextSecurityRelease(CloudStackVersion version) {
311+
return getNextSecurityRelease(version, 1);
312+
}
313+
309314
@Test
310315
public void testCalculateUpgradePathFromSecurityReleaseToLatest() {
311316

312317
final CloudStackVersion dbVersion = CloudStackVersion.parse("4.17.2.0"); // a EOL version
313318
assertNotNull(dbVersion);
314319

315-
final CloudStackVersion oldSecurityRelease = CloudStackVersion.parse(dbVersion.getMajorRelease() + "."
316-
+ dbVersion.getMinorRelease() + "."
317-
+ dbVersion.getPatchRelease() + "."
318-
+ (dbVersion.getSecurityRelease() + 100));
320+
final CloudStackVersion oldSecurityRelease = getNextSecurityRelease(dbVersion, 100);
319321
assertNotNull(oldSecurityRelease); // fake security release 4.17.2.100
320322

321323
final DatabaseUpgradeChecker checker = new DatabaseUpgradeChecker();
@@ -347,10 +349,7 @@ public void testCalculateUpgradePathFromSecurityReleaseToNextSecurityRelease() {
347349
final CloudStackVersion currentVersion = checker.getLatestVersion();
348350
assertNotNull(currentVersion);
349351

350-
final CloudStackVersion nextSecurityRelease = CloudStackVersion.parse(currentVersion.getMajorRelease() + "."
351-
+ currentVersion.getMinorRelease() + "."
352-
+ currentVersion.getPatchRelease() + "."
353-
+ (currentVersion.getSecurityRelease() + 1));
352+
final CloudStackVersion nextSecurityRelease = getNextSecurityRelease(currentVersion);
354353
assertNotNull(nextSecurityRelease); // fake security release
355354

356355
final DbUpgrade[] upgrades = checker.calculateUpgradePath(dbVersion, currentVersion);

‎plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/api/dto/Version.java‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,12 @@ public static Version fromPackageAndCSVersion(boolean complete) {
8787
}
8888
version.setMajor(String.valueOf(csVersion.getMajorRelease()));
8989
version.setMinor(String.valueOf(csVersion.getMinorRelease()));
90-
version.setBuild(String.valueOf(csVersion.getPatchRelease()));
91-
version.setRevision(String.valueOf(csVersion.getSecurityRelease()));
90+
if (csVersion.usesNewVersioning()) {
91+
version.setBuild(String.valueOf(csVersion.getSecurityRelease()));
92+
} else {
93+
version.setBuild(String.valueOf(csVersion.getPatchRelease()));
94+
version.setRevision(String.valueOf(csVersion.getSecurityRelease()));
95+
}
9296
return version;
9397
}
9498
}

‎utils/src/main/java/org/apache/cloudstack/utils/CloudStackVersion.java‎

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,22 +39,23 @@
3939
*/
4040
public final class CloudStackVersion implements Comparable<CloudStackVersion> {
4141

42-
private final static Pattern NUMBER_VERSION_FORMAT = Pattern.compile("(\\d+\\.){2}(\\d+\\.)?\\d+");
43-
private final static Pattern FULL_VERSION_FORMAT = Pattern.compile("(\\d+\\.){2}(\\d+\\.)?\\d+(-[a-zA-Z]+)?(-\\d+)?(-SNAPSHOT)?");
42+
private final static Pattern NUMBER_VERSION_FORMAT = Pattern.compile("\\d+\\.\\d+\\.\\d+(?:\\.\\d+)?");
43+
private final static Pattern FULL_VERSION_FORMAT = Pattern.compile("\\d+\\.\\d+\\.\\d+(?:\\.\\d+)?(?:-[a-zA-Z]+)?(?:-\\d+)?(?:-SNAPSHOT)?");
44+
private final static int NEW_VERSIONING_CUTOVER_MAJOR_VERSION = 24;
4445

4546
private final int majorRelease;
4647
private final int minorRelease;
47-
private final int patchRelease;
48+
private final Integer patchRelease;
4849
private final Integer securityRelease;
4950

50-
private CloudStackVersion(final int majorRelease, final int minorRelease, final int patchRelease, final Integer securityRelease) {
51+
private CloudStackVersion(final int majorRelease, final int minorRelease, final Integer patchRelease, final Integer securityRelease) {
5152

5253
super();
5354

5455
checkArgument(majorRelease >= 0, CloudStackVersion.class.getName() + "(int, int, int, Integer) requires a majorRelease greater than 0.");
5556
checkArgument(minorRelease >= 0, CloudStackVersion.class.getName() + "(int, int, int, Integer) requires a minorRelease greater than 0.");
56-
checkArgument(patchRelease >= 0, CloudStackVersion.class.getName() + "(int, int, int, Integer) requires a patchRelease greater than 0.");
57-
checkArgument((securityRelease != null && securityRelease >= 0) || (securityRelease == null),
57+
checkArgument(patchRelease == null || patchRelease >= 0, CloudStackVersion.class.getName() + "(int, int, int, Integer) requires a patchRelease greater than 0.");
58+
checkArgument(securityRelease == null || securityRelease >= 0,
5859
CloudStackVersion.class.getName() + "(int, int, int, Integer) requires a null securityRelease or a non-null value greater than 0.");
5960

6061
this.majorRelease = majorRelease;
@@ -69,11 +70,13 @@ private CloudStackVersion(final int majorRelease, final int minorRelease, final
6970
* Parses a <code>String</code> representation of a version that conforms one of the following
7071
* formats into a <code>CloudStackVersion</code> instance:
7172
* <ul>
72-
* <li><code>&lt;major&gt;.&lt;minor&gt;.&lt;patch&gt;.&lt;security&gt;</code></li>
73-
* <li><code>&lt;major&gt;.&lt;minor&gt;.&lt;patch&gt;.&lt;security&gt;.&lt;security&gt;</code></li>
74-
* <li><code>&lt;major&gt;.&lt;minor&gt;.&lt;patch&gt;.&lt;security&gt;.&lt;security&gt;-&lt;any string&gt;</code></li>
73+
* <li><code>&lt;major&gt;.&lt;minor&gt;.&lt;patch&gt;</code> (legacy, deprecated since 24.0.0, allowed only below major version 24)</li>
74+
* <li><code>&lt;major&gt;.&lt;minor&gt;.&lt;patch&gt;.&lt;security&gt;</code> (legacy, deprecated since 24.0.0, allowed only below major version 24)</li>
75+
* <li><code>&lt;major&gt;.&lt;minor&gt;.&lt;security release&gt;</code> (for versions &gt;= 24.0.0)</li>
7576
* </ul>
7677
*
78+
* Legacy patch-based formats remain supported for backward compatibility.
79+
*
7780
* If the string contains a suffix that begins with a "-" character, then the "-" and all characters following it
7881
* will be dropped.
7982
*
@@ -91,7 +94,7 @@ public static CloudStackVersion parse(final String value) {
9194

9295
checkArgument(StringUtils.isNotBlank(trimmedValue), CloudStackVersion.class.getName() + ".parse(String) requires a non-blank value");
9396
checkArgument(NUMBER_VERSION_FORMAT.matcher(trimmedValue).matches(), CloudStackVersion.class.getName() + ".parse(String) passed " +
94-
value + ", but requires a value in the format of int.int.int(.int)(-<legacy patch>)");
97+
value + ", but requires a value in the format of int.int.int(.int)(-<suffix>)");
9598

9699
final String[] components = trimmedValue.split("\\.");
97100

@@ -100,8 +103,26 @@ public static CloudStackVersion parse(final String value) {
100103

101104
final int majorRelease = Integer.valueOf(components[0]);
102105
final int minorRelease = Integer.valueOf(components[1]);
103-
final int patchRelease = Integer.valueOf(components[2]);
104-
final Integer securityRelease = components.length == 3 ? null : Integer.valueOf(components[3]);
106+
final int thirdComponent = Integer.valueOf(components[2]);
107+
108+
final int patchRelease;
109+
final Integer securityRelease;
110+
111+
if (components.length == 4) {
112+
checkArgument(isLegacyVersioning(majorRelease), CloudStackVersion.class.getName() + ".parse(String) passed " + value +
113+
", but major versions at or above 24 do not support legacy int.int.int.int format");
114+
// Deprecated legacy format: major.minor.patch.security
115+
patchRelease = thirdComponent;
116+
securityRelease = Integer.valueOf(components[3]);
117+
} else if (isNewVersioning(majorRelease)) {
118+
// New format: major.minor.securityRelease (patch dropped)
119+
patchRelease = 0;
120+
securityRelease = thirdComponent;
121+
} else {
122+
// Deprecated legacy format: major.minor.patch
123+
patchRelease = thirdComponent;
124+
securityRelease = null;
125+
}
105126

106127
return new CloudStackVersion(majorRelease, minorRelease, patchRelease, securityRelease);
107128

@@ -207,6 +228,14 @@ private static ImmutableList<Integer> normalizeVersionValues(final ImmutableList
207228

208229
}
209230

231+
private static boolean isLegacyVersioning(final int majorRelease) {
232+
return majorRelease < NEW_VERSIONING_CUTOVER_MAJOR_VERSION;
233+
}
234+
235+
private static boolean isNewVersioning(final int majorRelease) {
236+
return majorRelease >= NEW_VERSIONING_CUTOVER_MAJOR_VERSION;
237+
}
238+
210239
/**
211240
*
212241
* @return The components of this version as an {@link ImmutableList} in order of major release, minor release,
@@ -244,6 +273,10 @@ public Integer getSecurityRelease() {
244273
return securityRelease;
245274
}
246275

276+
public boolean usesNewVersioning() {
277+
return isNewVersioning(majorRelease);
278+
}
279+
247280
@Override
248281
public boolean equals(final Object thatObject) {
249282

@@ -270,6 +303,11 @@ public int hashCode() {
270303

271304
@Override
272305
public String toString() {
306+
// Canonicalize cutover-and-later versions to major.minor.securityRelease.
307+
if (securityRelease != null && patchRelease == 0 && isNewVersioning(majorRelease)) {
308+
return Joiner.on(".").join(ImmutableList.of(majorRelease, minorRelease, securityRelease));
309+
}
310+
273311
return Joiner.on(".").join(asList());
274312
}
275313

0 commit comments

Comments
 (0)