Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,12 @@
import com.cloud.upgrade.dao.Upgrade42020to42030;
import com.cloud.upgrade.dao.Upgrade42030to42040;
import com.cloud.upgrade.dao.Upgrade42040to42100;
import com.cloud.upgrade.dao.Upgrade42100to42200;
import com.cloud.upgrade.dao.Upgrade42200to42210;
import com.cloud.upgrade.dao.Upgrade420to421;
import com.cloud.upgrade.dao.Upgrade42100to42200;
import com.cloud.upgrade.dao.Upgrade421to430;
import com.cloud.upgrade.dao.Upgrade42200to42210;
import com.cloud.upgrade.dao.Upgrade42210to42300;
import com.cloud.upgrade.dao.Upgrade42300to2400;
import com.cloud.upgrade.dao.Upgrade430to440;
import com.cloud.upgrade.dao.Upgrade431to440;
import com.cloud.upgrade.dao.Upgrade432to440;
Expand Down Expand Up @@ -248,6 +249,7 @@ public DatabaseUpgradeChecker() {
.next("4.21.0.0", new Upgrade42100to42200())
.next("4.22.0.0", new Upgrade42200to42210())
.next("4.22.1.0", new Upgrade42210to42300())
.next("4.23.0.0", new Upgrade42300to2400())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when we reach 30, we might get some clashes with the old 3.x version. I think we should disgard thos by then.

.build();
}

Expand Down Expand Up @@ -513,8 +515,13 @@ protected void doUpgrades(GlobalLock lock) {
String csVersion = parseSystemVmMetadata();
final CloudStackVersion sysVmVersion = CloudStackVersion.parse(csVersion);
final CloudStackVersion currentVersion = CloudStackVersion.parse(currentVersionValue);
SystemVmTemplateRegistration.CS_MAJOR_VERSION = sysVmVersion.getMajorRelease() + "." + sysVmVersion.getMinorRelease();
SystemVmTemplateRegistration.CS_TINY_VERSION = String.valueOf(sysVmVersion.getPatchRelease());
if (sysVmVersion.usesNewVersioning()) {
SystemVmTemplateRegistration.CS_MAJOR_VERSION = String.valueOf(sysVmVersion.getMajorRelease());
SystemVmTemplateRegistration.CS_TINY_VERSION = String.valueOf(sysVmVersion.getMajorRelease());
} else {
SystemVmTemplateRegistration.CS_MAJOR_VERSION = String.format("%d.%d", sysVmVersion.getMajorRelease(), sysVmVersion.getMinorRelease());
SystemVmTemplateRegistration.CS_TINY_VERSION = String.valueOf(sysVmVersion.getPatchRelease());
}

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

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.upgrade.dao;

public class Upgrade42300to2400 extends DbUpgradeAbstractImpl implements DbUpgrade, DbUpgradeSystemVmTemplate {

@Override
public String[] getUpgradableVersionRange() {
return new String[]{"4.23.0.0", "24.0.0"};
}

@Override
public String getUpgradedVersion() {
return "24.0.0";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.

--;
-- Schema upgrade cleanup from 4.23.0.0 to 24.0.0
--;
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.

--;
-- Schema upgrade from 4.23.0.0 to 24.0.0
--;
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,12 @@ public static Version fromPackageAndCSVersion(boolean complete) {
}
version.setMajor(String.valueOf(csVersion.getMajorRelease()));
version.setMinor(String.valueOf(csVersion.getMinorRelease()));
version.setBuild(String.valueOf(csVersion.getPatchRelease()));
version.setRevision(String.valueOf(csVersion.getSecurityRelease()));
if (csVersion.usesNewVersioning()) {
version.setBuild(String.valueOf(csVersion.getSecurityRelease()));
} else {
version.setBuild(String.valueOf(csVersion.getPatchRelease()));
version.setRevision(String.valueOf(csVersion.getSecurityRelease()));
}
return version;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,23 @@
*/
public final class CloudStackVersion implements Comparable<CloudStackVersion> {

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

private final int majorRelease;
private final int minorRelease;
private final int patchRelease;
private final Integer patchRelease;
private final Integer securityRelease;

private CloudStackVersion(final int majorRelease, final int minorRelease, final int patchRelease, final Integer securityRelease) {
private CloudStackVersion(final int majorRelease, final int minorRelease, final Integer patchRelease, final Integer securityRelease) {

super();

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

this.majorRelease = majorRelease;
Expand All @@ -69,11 +70,13 @@ private CloudStackVersion(final int majorRelease, final int minorRelease, final
* Parses a <code>String</code> representation of a version that conforms one of the following
* formats into a <code>CloudStackVersion</code> instance:
* <ul>
* <li><code>&lt;major&gt;.&lt;minor&gt;.&lt;patch&gt;.&lt;security&gt;</code></li>
* <li><code>&lt;major&gt;.&lt;minor&gt;.&lt;patch&gt;.&lt;security&gt;.&lt;security&gt;</code></li>
* <li><code>&lt;major&gt;.&lt;minor&gt;.&lt;patch&gt;.&lt;security&gt;.&lt;security&gt;-&lt;any string&gt;</code></li>
* <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>
* <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>
* <li><code>&lt;major&gt;.&lt;minor&gt;.&lt;security release&gt;</code> (for versions &gt;= 24.0.0)</li>
* </ul>
*
* Legacy patch-based formats remain supported for backward compatibility.
*
* If the string contains a suffix that begins with a "-" character, then the "-" and all characters following it
* will be dropped.
*
Expand All @@ -91,7 +94,7 @@ public static CloudStackVersion parse(final String value) {

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

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

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

final int majorRelease = Integer.valueOf(components[0]);
final int minorRelease = Integer.valueOf(components[1]);
final int patchRelease = Integer.valueOf(components[2]);
final Integer securityRelease = components.length == 3 ? null : Integer.valueOf(components[3]);
final int thirdComponent = Integer.valueOf(components[2]);

final int patchRelease;
final Integer securityRelease;

if (components.length == 4) {
checkArgument(isLegacyVersioning(majorRelease), CloudStackVersion.class.getName() + ".parse(String) passed " + value +
", but major versions at or above 24 do not support legacy int.int.int.int format");
// Deprecated legacy format: major.minor.patch.security
patchRelease = thirdComponent;
securityRelease = Integer.valueOf(components[3]);
} else if (isNewVersioning(majorRelease)) {
// New format: major.minor.securityRelease (patch dropped)
patchRelease = 0;
securityRelease = thirdComponent;
} else {
// Deprecated legacy format: major.minor.patch
patchRelease = thirdComponent;
securityRelease = null;
}

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

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

}

private static boolean isLegacyVersioning(final int majorRelease) {
return majorRelease < NEW_VERSIONING_CUTOVER_MAJOR_VERSION;
}

private static boolean isNewVersioning(final int majorRelease) {
return majorRelease >= NEW_VERSIONING_CUTOVER_MAJOR_VERSION;
}

/**
*
* @return The components of this version as an {@link ImmutableList} in order of major release, minor release,
Expand Down Expand Up @@ -244,6 +273,10 @@ public Integer getSecurityRelease() {
return securityRelease;
}

public boolean usesNewVersioning() {
return isNewVersioning(majorRelease);
}

@Override
public boolean equals(final Object thatObject) {

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

@Override
public String toString() {
// Canonicalize cutover-and-later versions to major.minor.securityRelease.
if (securityRelease != null && patchRelease == 0 && isNewVersioning(majorRelease)) {
return Joiner.on(".").join(ImmutableList.of(majorRelease, minorRelease, securityRelease));
}

return Joiner.on(".").join(asList());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,40 @@ public final class CloudStackVersionTest {
"1.2.3, 1.2.3",
"1.2.3.4, 1.2.3.4",
"1.2.3-12, 1.2.3",
"1.2.3.4-14, 1.2.3.4"
"1.2.3.4-14, 1.2.3.4",
"23.9.5, 23.9.5",
"24.0.0, 24.0.0",
"24.0.1, 24.0.1",
"25.1.1, 25.1.1"
})
public void testValidParse(final String inputValue, final String expectedVersion) {
final CloudStackVersion version = CloudStackVersion.parse(inputValue);
assertNotNull(version);
assertEquals(expectedVersion, version.toString());
}

@Test
public void testParseComponentMappingForLegacyAndNewVersioning() {
final CloudStackVersion legacyVersion = CloudStackVersion.parse("23.9.5");
assertEquals(23, legacyVersion.getMajorRelease());
assertEquals(9, legacyVersion.getMinorRelease());
assertEquals(5, legacyVersion.getPatchRelease());
Assert.assertNull(legacyVersion.getSecurityRelease());

final CloudStackVersion newVersion = CloudStackVersion.parse("24.0.1");
assertEquals(24, newVersion.getMajorRelease());
assertEquals(0, newVersion.getMinorRelease());
// Patch is retained as 0 to represent "no patch" in the new major.minor.security scheme.
assertEquals(0, newVersion.getPatchRelease());
assertEquals(Integer.valueOf(1), newVersion.getSecurityRelease());

final CloudStackVersion futureNewVersion = CloudStackVersion.parse("25.1.1");
assertEquals(25, futureNewVersion.getMajorRelease());
assertEquals(1, futureNewVersion.getMinorRelease());
assertEquals(0, futureNewVersion.getPatchRelease());
assertEquals(Integer.valueOf(1), futureNewVersion.getSecurityRelease());
}

@Test(expected = IllegalArgumentException.class)
@DataProvider({
"1.2",
Expand All @@ -52,7 +78,10 @@ public void testValidParse(final String inputValue, final String expectedVersion
"aaaa",
"",
" ",
"1.2.3.4.5"
"1.2.3.4.5",
"24.0.0.1",
"25.0.0.1",
"26.2.3.4"
})
public void testInvalidParse(final String invalidValue) {
CloudStackVersion.parse(invalidValue);
Expand Down Expand Up @@ -147,7 +176,9 @@ public void testEqualCompareDirect(final String value, final String thatValue) {
"1.2.3.4-10, 1.0.0.0-5",
"1.2.3-10, 1.0.0-5",
"1.2.3.4, 1.0.0.0-5",
"1.2.3.4-10, 1.0.0"
"1.2.3.4-10, 1.0.0",
"24.0.2, 24.0.1",
"24.1.0, 24.0.9"
})
public void testGreaterThanAndLessThanCompareTo(final String value, final String thatValue) {

Expand Down Expand Up @@ -178,7 +209,9 @@ public void testGreaterThanAndLessThanCompareTo(final String value, final String
"1.2.3.4-10, 1.0.0.0-5",
"1.2.3-10, 1.0.0-5",
"1.2.3.4, 1.0.0.0-5",
"1.2.3.4-10, 1.0.0"
"1.2.3.4-10, 1.0.0",
"24.0.2, 24.0.1",
"24.1.0, 24.0.9"
})
public void testGreaterThanAndLessThanCompareDirect(final String value, final String thatValue) {

Expand Down Expand Up @@ -213,6 +246,7 @@ private void verifyGetVMwareParentVersion(String hypervisorVersion, String expec
Assert.assertEquals(CloudStackVersion.getVMwareParentVersion(hypervisorVersion), expectedParentVersion);
}
}

@Test
public void testGetParentVersion() {
verifyGetVMwareParentVersion(null, null);
Expand All @@ -223,5 +257,6 @@ public void testGetParentVersion() {
verifyGetVMwareParentVersion("8.0.0", "8.0");
verifyGetVMwareParentVersion("8.0.0.2", "8.0");
verifyGetVMwareParentVersion("8.0.1.0", "8.0.1");
verifyGetVMwareParentVersion("24.1.1", "24.1");
}
}
Loading