Skip to content

Commit 60b5a2a

Browse files
committed
improvements and add tests
Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
1 parent 027172a commit 60b5a2a

8 files changed

Lines changed: 245 additions & 29 deletions

File tree

‎engine/schema/pom.xml‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,20 @@
153153
<artifactId>exec-maven-plugin</artifactId>
154154
<version>${cs.exec-maven-plugin.version}</version>
155155
<executions>
156+
<execution>
157+
<id>test-templateConfig</id>
158+
<phase>test</phase>
159+
<goals>
160+
<goal>exec</goal>
161+
</goals>
162+
<configuration>
163+
<workingDirectory>${basedir}/</workingDirectory>
164+
<executable>bash</executable>
165+
<arguments>
166+
<argument>test_templateConfig.sh</argument>
167+
</arguments>
168+
</configuration>
169+
</execution>
156170
<execution>
157171
<id>systemvm-template-metadata</id>
158172
<phase>package</phase>

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -515,8 +515,7 @@ protected void doUpgrades(GlobalLock lock) {
515515
String csVersion = parseSystemVmMetadata();
516516
final CloudStackVersion sysVmVersion = CloudStackVersion.parse(csVersion);
517517
final CloudStackVersion currentVersion = CloudStackVersion.parse(currentVersionValue);
518-
SystemVmTemplateRegistration.CS_MAJOR_VERSION = String.format("%d.%d", sysVmVersion.getMajorRelease(), sysVmVersion.getMinorRelease());
519-
SystemVmTemplateRegistration.CS_TINY_VERSION = String.valueOf(sysVmVersion.usesNewVersioning() ? sysVmVersion.getSecurityRelease() : sysVmVersion.getPatchRelease());
518+
updateSystemVmTemplateVersion(sysVmVersion);
520519

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

@@ -542,6 +541,18 @@ protected void doUpgrades(GlobalLock lock) {
542541
}
543542
}
544543

544+
/**
545+
* Sets the system VM template major/tiny version used to look up the matching system VM template,
546+
* from the version parsed out of the system VM template metadata file. Below the versioning cutover
547+
* (major &lt; 24) the tiny version is the legacy patch release; from the cutover onwards it is the
548+
* security release, since the patch position is dropped in that scheme.
549+
*/
550+
@VisibleForTesting
551+
protected static void updateSystemVmTemplateVersion(CloudStackVersion sysVmVersion) {
552+
SystemVmTemplateRegistration.CS_MAJOR_VERSION = String.format("%d.%d", sysVmVersion.getMajorRelease(), sysVmVersion.getMinorRelease());
553+
SystemVmTemplateRegistration.CS_TINY_VERSION = String.valueOf(sysVmVersion.usesNewVersioning() ? sysVmVersion.getSecurityRelease() : sysVmVersion.getPatchRelease());
554+
}
555+
545556
/**
546557
* Hook that is called when an upgrade is required but the management server is clustered.
547558
* Default behavior is to exit the JVM, tests can override to throw instead.

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,4 +421,28 @@ public void testCalculateUpgradePath42010to42100() {
421421
assertTrue(upgrades[2] instanceof Upgrade42040to42100);
422422
assertEquals(currentVersion.toString(), upgrades[2].getUpgradedVersion());
423423
}
424+
425+
@Test
426+
public void testUpdateSystemVmTemplateVersionBelowCutover() {
427+
DatabaseUpgradeChecker.updateSystemVmTemplateVersion(CloudStackVersion.parse("4.22.1.0"));
428+
429+
assertEquals("4.22", SystemVmTemplateRegistration.CS_MAJOR_VERSION);
430+
assertEquals("1", SystemVmTemplateRegistration.CS_TINY_VERSION);
431+
}
432+
433+
@Test
434+
public void testUpdateSystemVmTemplateVersionAtCutover() {
435+
DatabaseUpgradeChecker.updateSystemVmTemplateVersion(CloudStackVersion.parse("24.0.1"));
436+
437+
assertEquals("24.0", SystemVmTemplateRegistration.CS_MAJOR_VERSION);
438+
assertEquals("1", SystemVmTemplateRegistration.CS_TINY_VERSION);
439+
}
440+
441+
@Test
442+
public void testUpdateSystemVmTemplateVersionAfterCutover() {
443+
DatabaseUpgradeChecker.updateSystemVmTemplateVersion(CloudStackVersion.parse("25.3.2"));
444+
445+
assertEquals("25.3", SystemVmTemplateRegistration.CS_MAJOR_VERSION);
446+
assertEquals("2", SystemVmTemplateRegistration.CS_TINY_VERSION);
447+
}
424448
}

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

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1638,4 +1638,41 @@ public void updateTemplateUrlChecksumAndGuestOsId_ThrowsExceptionWhenUpdateFails
16381638
assertTrue(exception.getMessage().contains("Exception while updating 'url' and 'checksum' for hypervisor type"));
16391639
verify(vmTemplateDao).update(templateVO.getId(), templateVO);
16401640
}
1641+
1642+
@Test
1643+
public void getSystemVmTemplateVersion_UsesExplicitVersionWhenSet() {
1644+
SystemVmTemplateRegistration registration = new SystemVmTemplateRegistration("4.22.0.0");
1645+
1646+
assertEquals("4.22.0.0", registration.getSystemVmTemplateVersion());
1647+
}
1648+
1649+
@Test
1650+
public void getSystemVmTemplateVersion_BuildsFromMajorAndTinyVersionBelowCutover() {
1651+
String previousMajor = SystemVmTemplateRegistration.CS_MAJOR_VERSION;
1652+
String previousTiny = SystemVmTemplateRegistration.CS_TINY_VERSION;
1653+
try {
1654+
SystemVmTemplateRegistration.CS_MAJOR_VERSION = "4.22";
1655+
SystemVmTemplateRegistration.CS_TINY_VERSION = "1";
1656+
1657+
assertEquals("4.22.1", systemVmTemplateRegistration.getSystemVmTemplateVersion());
1658+
} finally {
1659+
SystemVmTemplateRegistration.CS_MAJOR_VERSION = previousMajor;
1660+
SystemVmTemplateRegistration.CS_TINY_VERSION = previousTiny;
1661+
}
1662+
}
1663+
1664+
@Test
1665+
public void getSystemVmTemplateVersion_BuildsFromMajorAndTinyVersionAfterCutover() {
1666+
String previousMajor = SystemVmTemplateRegistration.CS_MAJOR_VERSION;
1667+
String previousTiny = SystemVmTemplateRegistration.CS_TINY_VERSION;
1668+
try {
1669+
SystemVmTemplateRegistration.CS_MAJOR_VERSION = "24.0";
1670+
SystemVmTemplateRegistration.CS_TINY_VERSION = "1";
1671+
1672+
assertEquals("24.0.1", systemVmTemplateRegistration.getSystemVmTemplateVersion());
1673+
} finally {
1674+
SystemVmTemplateRegistration.CS_MAJOR_VERSION = previousMajor;
1675+
SystemVmTemplateRegistration.CS_TINY_VERSION = previousTiny;
1676+
}
1677+
}
16411678
}

‎engine/schema/templateConfig.sh‎

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,26 @@
1717
# specific language governing permissions and limitations
1818
# under the License.
1919

20+
NEW_VERSIONING_CUTOVER_MAJOR_VERSION=24
21+
2022
function getTemplateVersion() {
2123
projVersion=$1
2224
version="$(cut -d'-' -f1 <<<"$projVersion")"
2325
subversion1="$(cut -d'.' -f1 <<<"$version")"
2426
subversion2="$(cut -d'.' -f2 <<<"$version")"
2527
minorversion="$(cut -d'.' -f3 <<<"$version")"
26-
securityversion="$(cut -d'.' -f4 <<<"$version")"
2728
export CS_VERSION="${subversion1}"."${subversion2}"
2829
export CS_MINOR_VERSION="${minorversion}"
2930
export VERSION="${CS_VERSION}.${CS_MINOR_VERSION}"
31+
if [[ "$subversion1" -ge "$NEW_VERSIONING_CUTOVER_MAJOR_VERSION" ]]; then
32+
# New versioning (major.minor.security): the third component is the
33+
# security release itself, there is no separate patch component.
34+
export FULL_VERSION="${VERSION}"
35+
else
36+
# Legacy versioning (major.minor.patch.security)
37+
securityversion="$(cut -d'.' -f4 <<<"$version")"
38+
export FULL_VERSION="${VERSION}.${securityversion}"
39+
fi
3040
export CS_SYSTEMTEMPLATE_REPO="https://download.cloudstack.org/systemvm/"
3141
}
3242

@@ -64,7 +74,7 @@ function getChecksum() {
6474

6575
function createMetadataFile() {
6676
local fileData=$(cat "$SOURCEFILE")
67-
echo -e "["default"]\nversion = $VERSION.${securityversion}\ndownloadrepository = $CS_SYSTEMTEMPLATE_REPO\n" >> "$METADATAFILE"
77+
echo -e "["default"]\nversion = $FULL_VERSION\ndownloadrepository = $CS_SYSTEMTEMPLATE_REPO\n" >> "$METADATAFILE"
6878
for template in "${templates[@]}"
6979
do
7080
section="${template%%:*}"
@@ -81,27 +91,30 @@ function createMetadataFile() {
8191
done
8292
}
8393

84-
declare -a templates
85-
getTemplateVersion $1
86-
declare -A template_specs=(
87-
[kvm-x86_64]="x86_64-kvm.qcow2.bz2"
88-
[kvm-aarch64]="aarch64-kvm.qcow2.bz2"
89-
[vmware]="x86_64-vmware.ova"
90-
[xenserver]="x86_64-xen.vhd.bz2"
91-
[hyperv]="x86_64-hyperv.vhd.zip"
92-
[lxc]="x86_64-kvm.qcow2.bz2"
93-
[ovm3]="x86_64-ovm.raw.bz2"
94-
)
94+
# Guard so the file can be sourced (e.g. by tests) without running the steps below.
95+
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
96+
declare -a templates
97+
getTemplateVersion $1
98+
declare -A template_specs=(
99+
[kvm-x86_64]="x86_64-kvm.qcow2.bz2"
100+
[kvm-aarch64]="aarch64-kvm.qcow2.bz2"
101+
[vmware]="x86_64-vmware.ova"
102+
[xenserver]="x86_64-xen.vhd.bz2"
103+
[hyperv]="x86_64-hyperv.vhd.zip"
104+
[lxc]="x86_64-kvm.qcow2.bz2"
105+
[ovm3]="x86_64-ovm.raw.bz2"
106+
)
95107

96-
templates=()
97-
for key in "${!template_specs[@]}"; do
98-
url="${CS_SYSTEMTEMPLATE_REPO}/${CS_VERSION}/systemvmtemplate-$VERSION-${template_specs[$key]}"
99-
templates+=("$key:$url")
100-
done
108+
templates=()
109+
for key in "${!template_specs[@]}"; do
110+
url="${CS_SYSTEMTEMPLATE_REPO}/${CS_VERSION}/systemvmtemplate-$VERSION-${template_specs[$key]}"
111+
templates+=("$key:$url")
112+
done
101113

102-
PARENTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )/dist/systemvm-templates/"
103-
mkdir -p "$PARENTPATH"
104-
METADATAFILE="${PARENTPATH}metadata.ini"
105-
echo > "$METADATAFILE"
106-
SOURCEFILE="${PARENTPATH}sha512sum.txt"
107-
createMetadataFile
114+
PARENTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )/dist/systemvm-templates/"
115+
mkdir -p "$PARENTPATH"
116+
METADATAFILE="${PARENTPATH}metadata.ini"
117+
echo > "$METADATAFILE"
118+
SOURCEFILE="${PARENTPATH}sha512sum.txt"
119+
createMetadataFile
120+
fi
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#!/bin/bash
2+
3+
# Licensed to the Apache Software Foundation (ASF) under one
4+
# or more contributor license agreements. See the NOTICE file
5+
# distributed with this work for additional information
6+
# regarding copyright ownership. The ASF licenses this file
7+
# to you under the Apache License, Version 2.0 (the
8+
# "License"); you may not use this file except in compliance
9+
# with the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing,
14+
# software distributed under the License is distributed on an
15+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
# KIND, either express or implied. See the License for the
17+
# specific language governing permissions and limitations
18+
# under the License.
19+
#
20+
# Standalone smoke test for templateConfig.sh's version handling across the
21+
# 4.x (legacy) to 24.x (cutover) versioning schemes. Run directly:
22+
# bash engine/schema/test_templateConfig.sh
23+
24+
set -u
25+
26+
SCRIPT_DIR="$( cd -- "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 ; pwd -P )"
27+
# shellcheck source=templateConfig.sh
28+
source "${SCRIPT_DIR}/templateConfig.sh"
29+
30+
pass=0
31+
fail=0
32+
33+
assert_eq() {
34+
local description="$1"
35+
local expected="$2"
36+
local actual="$3"
37+
if [[ "$expected" == "$actual" ]]; then
38+
pass=$((pass + 1))
39+
echo "PASS: $description"
40+
else
41+
fail=$((fail + 1))
42+
echo "FAIL: $description (expected '$expected', got '$actual')"
43+
fi
44+
}
45+
46+
# --- getTemplateVersion: legacy versioning (major < 24) ---
47+
48+
getTemplateVersion "4.22.0.0"
49+
assert_eq "legacy: CS_VERSION" "4.22" "$CS_VERSION"
50+
assert_eq "legacy: VERSION" "4.22.0" "$VERSION"
51+
assert_eq "legacy: FULL_VERSION keeps the 4th (security) component" "4.22.0.0" "$FULL_VERSION"
52+
53+
getTemplateVersion "4.23.0.1-SNAPSHOT"
54+
assert_eq "legacy with -SNAPSHOT suffix: VERSION" "4.23.0" "$VERSION"
55+
assert_eq "legacy with -SNAPSHOT suffix: FULL_VERSION" "4.23.0.1" "$FULL_VERSION"
56+
57+
# --- getTemplateVersion: new versioning (major >= 24, post-cutover) ---
58+
59+
getTemplateVersion "24.0.0"
60+
assert_eq "cutover: CS_VERSION" "24.0" "$CS_VERSION"
61+
assert_eq "cutover: VERSION" "24.0.0" "$VERSION"
62+
assert_eq "cutover: FULL_VERSION has no trailing dot (patch dropped)" "24.0.0" "$FULL_VERSION"
63+
64+
getTemplateVersion "24.1.2-SNAPSHOT"
65+
assert_eq "cutover with -SNAPSHOT suffix: VERSION" "24.1.2" "$VERSION"
66+
assert_eq "cutover with -SNAPSHOT suffix: FULL_VERSION" "24.1.2" "$FULL_VERSION"
67+
68+
getTemplateVersion "99.9.9"
69+
assert_eq "future major: VERSION" "99.9.9" "$VERSION"
70+
assert_eq "future major: FULL_VERSION" "99.9.9" "$FULL_VERSION"
71+
72+
# --- createMetadataFile: end-to-end metadata.ini "version" line ---
73+
74+
run_create_metadata_file() {
75+
local projVersion="$1"
76+
local workdir
77+
workdir="$(mktemp -d)"
78+
79+
getTemplateVersion "$projVersion"
80+
METADATAFILE="${workdir}/metadata.ini"
81+
SOURCEFILE="${workdir}/sha512sum.txt"
82+
printf "abc123 systemvmtemplate-%s-x86_64-kvm.qcow2.bz2\n" "$VERSION" > "$SOURCEFILE"
83+
templates=("kvm-x86_64:${CS_SYSTEMTEMPLATE_REPO}/${CS_VERSION}/systemvmtemplate-${VERSION}-x86_64-kvm.qcow2.bz2")
84+
: > "$METADATAFILE"
85+
86+
createMetadataFile
87+
grep '^version = ' "$METADATAFILE" | head -1 | cut -d' ' -f3
88+
89+
rm -rf "$workdir"
90+
}
91+
92+
actual="$(run_create_metadata_file "4.22.0.0")"
93+
assert_eq "metadata.ini legacy 'version' line" "4.22.0.0" "$actual"
94+
95+
actual="$(run_create_metadata_file "24.0.0")"
96+
assert_eq "metadata.ini cutover 'version' line has no trailing dot" "24.0.0" "$actual"
97+
98+
echo ""
99+
echo "${pass} passed, ${fail} failed"
100+
[[ $fail -eq 0 ]]

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

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ private CloudStackVersion(final int majorRelease, final int minorRelease, final
7575
* <li><code>&lt;major&gt;.&lt;minor&gt;.&lt;security release&gt;</code> (for versions &gt;= 24.0.0)</li>
7676
* </ul>
7777
*
78-
* Legacy patch-based formats remain supported for backward compatibility.
78+
* Legacy patch-based formats remain supported for backward compatibility, e.g. <code>4.23.0.1-SNAPSHOT</code>,
79+
* but only below major version 24: a 4-position value whose major release is at or above 24, e.g.
80+
* <code>24.0.0.1</code>, is rejected.
7981
*
8082
* If the string contains a suffix that begins with a "-" character, then the "-" and all characters following it
8183
* will be dropped.
@@ -208,13 +210,26 @@ public int compareTo(final CloudStackVersion thatVersion) {
208210
public static String trimRouterVersion(String version) {
209211
final String[] tokens = version.split(" ");
210212

211-
if (tokens.length >= 3 && FULL_VERSION_FORMAT.matcher(tokens[2]).matches()) {
213+
if (tokens.length >= 3 && FULL_VERSION_FORMAT.matcher(tokens[2]).matches() && isParseableVersion(tokens[2])) {
212214
return tokens[2];
213215
}
214216

215217
return "0";
216218
}
217219

220+
/**
221+
* Whether {@link #parse(String)} would accept the given value, following the same cutover rule that
222+
* rejects a 4-position <code>major.minor.patch.security</code> value once the major release reaches 24.
223+
*/
224+
private static boolean isParseableVersion(final String value) {
225+
try {
226+
parse(value);
227+
return true;
228+
} catch (RuntimeException e) {
229+
return false;
230+
}
231+
}
232+
218233
private static ImmutableList<Integer> normalizeVersionValues(final ImmutableList<Integer> values) {
219234

220235
checkArgument(values != null);

‎utils/src/test/java/org/apache/cloudstack/utils/CloudStackVersionTest.java‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,9 @@ public void testGreaterThanAndLessThanCompareDirect(final String value, final St
231231
"Cloudstack Release 1.2.3.4-brnading-1519453362 Mon Jan 1 10:10:10 UTC 2018, 1.2.3.4-brnading-1519453362",
232232
"Cloudstack Release 1.2 Mon Jan 1 10:10:10 UTC 2018, 0",
233233
"Cloudstack Release 1.2-SNAPSHOT Mon Jan 1 10:10:10 UTC 2018, 0",
234-
"Cloud stack Release 1.2.3.4 Mon Jan 1 10:10:10 UTC 2018, 0"
234+
"Cloud stack Release 1.2.3.4 Mon Jan 1 10:10:10 UTC 2018, 0",
235+
"Cloudstack Release 24.0.0 Mon Jan 1 10:10:10 UTC 2018, 24.0.0",
236+
"Cloudstack Release 24.0.0.1 Mon Jan 1 10:10:10 UTC 2018, 0"
235237
})
236238
public void testTrimRouterVersion(final String value, final String expected) {
237239

0 commit comments

Comments
 (0)