Skip to content

engine-schema: upgrade path for 24.0.0 - #14033

Open
shwstppr wants to merge 15 commits into
apache:mainfrom
shapeblue:upgradepath-424
Open

shwstppr wants to merge 15 commits into
apache:mainfrom
shapeblue:upgradepath-424

Conversation

@shwstppr

@shwstppr shwstppr commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Description

Adds the 4.23.0.0 to 24.0.0 database upgrade path for CloudStack's versioning cutover (management server versions drop the leading 4. and move to a 3-component major.minor.security scheme from 24.0.0 onwards; legacy 4-component major.minor.patch.security versions remain supported below major 24 - Reference PR: #14041).

Includes:

  • Upgrade42300to2400 DB upgrade step (4.23.0.0 → 24.0.0) and its (currently no-op) schema/cleanup scripts, registered in DatabaseUpgradeChecker's upgrade hierarchy.
  • CloudStackVersion (utils): parses and compares both the legacy 4-part scheme and the new 3-part cutover scheme, rejecting a legacy-shaped 4-part value once major reaches 24. Adds parse(value, external) / compare(v1, v2, external) overloads so version strings from unrelated schemes (VMware/ESXi hypervisor versions, NSX/Nicira NVP controller API versions) aren't misinterpreted under CloudStack's own cutover rule. Fixes a trimRouterVersion() invalid-input fallback that wasn't itself parseable, which could crash router version checks instead of failing gracefully.
  • templateConfig.sh / export-templates.sh: generate and consume system VM template metadata correctly across the cutover (3-part version for major ≥ 24, no dangling separators for either scheme), and reject malformed input instead of silently normalizing it.
  • DatabaseUpgradeChecker / SystemVmTemplateRegistration: derive the system VM template's major/tiny version correctly for both versioning schemes.
  • Veeam integration (Version.java) and NSX/Nicira NVP (NiciraNvpApiVersion): updated to use the new cutover-aware/external-aware APIs so their own version reporting and comparisons aren't affected by CloudStack's cutover rule.

Types of changes

  • Breaking change (fix or feature that would cause existing functionality to change)
  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Enhancement (improves an existing feature and functionality)
  • Cleanup (Code refactoring and cleanup, that may add test cases)
  • Build/CI
  • Test (unit or integration test code)

Feature/Enhancement Scale or Bug Severity

Feature/Enhancement Scale

  • Major
  • Minor

Bug Severity

  • BLOCKER
  • Critical
  • Major
  • Minor
  • Trivial

Screenshots (if appropriate):

How Has This Been Tested?

How did you try to break this feature and the system with this change?

@shwstppr

shwstppr commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

@blueorangutan package

@blueorangutan

Copy link
Copy Markdown

@shwstppr a [SL] Jenkins job has been kicked to build packages. It will be bundled with no SystemVM templates. I'll keep you posted as I make progress.

@codecov

codecov Bot commented Sep 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.30769% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 19.91%. Comparing base (a723d44) to head (569417c).
⚠️ Report is 60 commits behind head on main.

Files with missing lines Patch % Lines
...org/apache/cloudstack/utils/CloudStackVersion.java 91.66% 2 Missing and 2 partials ⚠️
...d/utils/nicira/nvp/plugin/NiciraNvpApiVersion.java 0.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main   #14033      +/-   ##
============================================
+ Coverage     19.78%   19.91%   +0.13%     
- Complexity    19992    20201     +209     
============================================
  Files          6371     6373       +2     
  Lines        575903   577230    +1327     
  Branches      70496    70696     +200     
============================================
+ Hits         113945   114980    +1035     
- Misses       449530   449683     +153     
- Partials      12428    12567     +139     
Flag Coverage Δ
uitests 3.71% <ø> (+0.17%) ⬆️
unittests 21.19% <92.30%> (+0.13%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@weizhouapache weizhouapache left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

code lgtm

@shwstppr
shwstppr requested a lite review from Copilot September 2, 2026 07:27
@blueorangutan

Copy link
Copy Markdown

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 19055

Copilot AI left a comment

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.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Pull request overview

Adds the database upgrade plumbing for a 4.23.0.0 → 4.24.0.0 engine schema upgrade.

Changes:

  • Adds new (currently comment-only) schema upgrade and cleanup SQL scripts for 4.23.0.0 → 4.24.0.0.
  • Introduces Upgrade42300to42400 Java upgrade class to define the version range and target version.
  • Registers the new upgrade step in DatabaseUpgradeChecker’s upgrade path chain.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
engine/schema/src/main/resources/META-INF/db/schema-42300to42400.sql Adds the 4.23.0.0 → 4.24.0.0 schema upgrade script file (currently header/comments only).
engine/schema/src/main/resources/META-INF/db/schema-42300to42400-cleanup.sql Adds the corresponding cleanup script file (currently header/comments only).
engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade42300to42400.java Adds the Java upgrade step declaring version range and upgraded version.
engine/schema/src/main/java/com/cloud/upgrade/DatabaseUpgradeChecker.java Wires the new upgrade step into the upgrader chain.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread engine/schema/src/main/resources/META-INF/db/schema-42300to2400.sql

@DaanHoogland DaanHoogland left a comment

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.

let’s do #14033 instead

@DaanHoogland

Copy link
Copy Markdown
Contributor

maybe this can go on top of that one

Adds a 4.23.0 to 24.0.0 upgrade path.

Signed-off-by: Abhishek Kumar <[email protected]>
@shwstppr shwstppr changed the title engine-schema: upgrade path for 4.24.0 engine-schema: upgrade path for 24.0.0 Sep 7, 2026
@DaanHoogland
DaanHoogland dismissed their stale review September 7, 2026 13:08

not relevant

.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.

@DaanHoogland DaanHoogland left a comment

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.

clgtm

@nvazquez nvazquez left a comment

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.

Code LGTM

Signed-off-by: Abhishek Kumar <[email protected]>
@nvazquez

nvazquez commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

@blueorangutan package

@nvazquez
nvazquez requested a review from RosiKyu September 9, 2026 21:10
@shwstppr shwstppr closed this Sep 10, 2026
@shwstppr shwstppr reopened this Sep 10, 2026
Signed-off-by: Abhishek Kumar <[email protected]>
@DaanHoogland

Copy link
Copy Markdown
Contributor

@blueorangutan package

@blueorangutan

Copy link
Copy Markdown

[SF] Trillian Build Failed (tid-16998)

@blueorangutan

Copy link
Copy Markdown

[SF] Trillian Build Failed (tid-17000)

@blueorangutan

Copy link
Copy Markdown

[SF] Trillian Build Failed (tid-35)

@blueorangutan

Copy link
Copy Markdown

[SF] Trillian Build Failed (tid-17001)

@blueorangutan

Copy link
Copy Markdown

[SF] Trillian Build Failed (tid-17002)

@blueorangutan

Copy link
Copy Markdown

[SF] Trillian Build Failed (tid-17003)

@blueorangutan

Copy link
Copy Markdown

[SF] Trillian Build Failed (tid-17006)

@blueorangutan

Copy link
Copy Markdown

[SF] Trillian Build Failed (tid-17005)

@nvazquez

Copy link
Copy Markdown
Contributor

@blueorangutan test

@blueorangutan

Copy link
Copy Markdown

@nvazquez a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests

@apache apache deleted a comment from blueorangutan Sep 16, 2026
@blueorangutan

Copy link
Copy Markdown

[SF] Trillian test result (tid-36)
Environment: kvm-ol8 (x2), zone: Advanced Networking with Mgmt server ol8
Total time taken: 53959 seconds
Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr14033-n36-kvm-ol8.zip
Smoke tests completed. 155 look OK, 1 have errors, 0 did not run
Only failed and skipped tests results shown below:

Test Result Time (s) Test File
test_02_list_cpvm_vm Failure 0.06 test_ssvm.py
test_04_cpvm_internals Failure 0.06 test_ssvm.py

@weizhouapache

Copy link
Copy Markdown
Member

@shwstppr @nvazquez
smoke tests look good. can we merge ?
is there anything else to check ?

@shwstppr

Copy link
Copy Markdown
Contributor Author

@weizhouapache maybe @nvazquez or @RosiKyu can advise about that.
I checked the failing tests manually and they were not giving any errors so the 2 failures could be intermittent

@nvazquez

Copy link
Copy Markdown
Contributor

Hi @weizhouapache - @RosiKyu is performing additional manual tests and if no further issues it should be good to merge, smoke test failures seem intermittent - no issues observed with system VMs on created envs

@RosiKyu RosiKyu self-assigned this Sep 17, 2026
@weizhouapache

Copy link
Copy Markdown
Member

cool, thanks @shwstppr @nvazquez
let's wait @RosiKyu to finish the testing

@RosiKyu

RosiKyu commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

Tested this on a 24.0.0 build: OL9 Management server, 2 KVM hosts, Advanced Networking, single MS. The database was seeded at 4.0.0 and ran the full upgrade chain, so the new Upgrade42300to2400 step was exercised end to end. Two issues found, the first one I would treat as a blocker.

What I checked

Area How Result
Upgrade42300to2400 executes and completes in the chain live env, empty schema PASS, see caveat above
Upgrade of a populated 4.23.0.0 deployment not done NOT TESTED
System VM template registration inside that upgrade step live env NOT YET EXERCISED
Multi MS clustered upgrade guard not done NOT YET TESTED
Non KVM hypervisors (VMware in particular) not done NOT YET TESTED
Upgrade is idempotent on restart (DB version = 24.0.0 Code Version = 24.0.0, no upgrade needed) live env, restarted the MS PASS
Stored DB version re-parses to 24.0.0 and matches the code version live env, startup log, did not read the table directly PASS
schema-42300to2400.sql and its cleanup script resolve and run live env log PASS
NoopDbUpgrade tail handling for a future 25.x SNAPSHOT code review only OK by inspection
4 part value rejected at major >= 24 live env PASS
Legacy 4 part below 24 still parses live env, the chain parses 4.x throughout PASS
24.0.0 > 4.23.0.0 ordering live env, via the chain PASS
24.0.2 > 24.0.1, 24.1.0 > 24.0.9 PR's own unit tests covered by the PR's tests
toString() gives 24.0.0 not 24.0.0.0, branding suffix stripped live env, softwareversion on a -shapeblue21768 build PASS
trimRouterVersion fallback is parseable, nothing keys on the old "0" code review and grep OK by inspection
templateConfig.sh legacy and cutover paths ran the PR's own suite locally PASS, 16/16
export-templates.sh bash -n locally, plus the packaged script on the MS and both KVM hosts FAIL, issue 1
listCapabilities, listManagementServers, listHosts, listSystemVms live env PASS, all report 24.0.0-SNAPSHOT
listRouters: template version 4.22.0 vs software version 24.0.0, requiresupgrade live env PASS
listRouters version= filter live env PASS
VR programming end to end (create and delete an egress rule) live env PASS
minreq.sysvmtemplate.version with a valid 3 part value live env PASS
minreq.sysvmtemplate.version with a 4 part value live env FAIL, issue 2
UI footer version and Virtual Routers page live env, browser PASS
UI "new version available" logic across legacy and new tags ran it locally under real semver PASS for all realistic inputs
RPM and DEB upgrade ordering, and debian/changelog order dpkg --compare-versions locally, rpm.labelCompare on the env PASS
All poms, marvin setup.py, Dockerfiles, checkstyle pom, simulator CI version extraction code review and grep PASS
VR health check scripts (router_version_check.py, get_template_version.sh) code review not affected, they compare the release string literally
Any leftover since = "4.24" annotations grep none
Installed filesystem scan for stale 4.2x version strings live env PASS
Usage server and KVM agent package and jar versions live env PASS

Issue 1: export-templates.sh has a syntax error and does not run at all

The new cutover if/else in scripts/installer/export-templates.sh is missing its closing fi, so the script does not parse.

Expected result: the script runs and derives the template filename prefix from metadata.ini.

Actual result: it aborts immediately with a syntax error, for any input.

[root@ref-trl-12372-k-Mol9-nicolas-vazquez-mgmt1 ~]# bash -n /usr/share/cloudstack-common/scripts/installer/export-templates.sh
/usr/share/cloudstack-common/scripts/installer/export-templates.sh: line 207: syntax error: unexpected end of file
[root@ref-trl-12372-k-Mol9-nicolas-vazquez-mgmt1 ~]# 

This is not only in the diff, it is in the packaged RPM, and since it ships in cloudstack-common it is on the KVM hosts as well as the management server. Same result on all three nodes. The same check passes on main.

Issue 2: a 4 part minreq.sysvmtemplate.version breaks listRouters and all VR operations

minreq.sysvmtemplate.version accepts any string, and with the new rules a value such as 24.0.0.0 is rejected by CloudStackVersion.parse with nothing catching the exception.

Steps: set minreq.sysvmtemplate.version to 24.0.0.0 with updateConfiguration, then call listRouters, or make any change that reprograms the VR.

Expected result: either the value is rejected when it is set, or the version check treats it as "router needs upgrading".

Actual result: the value is accepted with no error, then listRouters fails and every VR operation fails.

listRouters:

"errorcode": 431,
"errortext": "org.apache.cloudstack.utils.CloudStackVersion.parse(String) passed 24.0.0.0, but major versions at or above 24 do not support legacy int.int.int.int format"

createEgressFirewallRule, job fails with resultCode 530:

java.lang.IllegalArgumentException: org.apache.cloudstack.utils.CloudStackVersion.parse(String) passed 24.0.0.0, but major versions at or above 24 do not support legacy int.int.int.int format
	at org.apache.cloudstack.utils.CloudStackVersion.parse(CloudStackVersion.java:145)
	at org.apache.cloudstack.utils.CloudStackVersion.compare(CloudStackVersion.java:196)
	at org.apache.cloudstack.utils.CloudStackVersion.compare(CloudStackVersion.java:177)

Still to verify

I am building a second environment for the upgrade side: a populated 4.23.0.0 database, mixed hypervisors including VMware, and two management servers. That will cover the things this environment could not: upgrade of a database with real data in it, the clustered upgrade guard with both MS up, the VMware path, and what minreq.sysvmtemplate.version ends up as after a real upgrade rather than a fresh install. Will report back.

Copilot AI review requested due to automatic review settings September 17, 2026 14:07

Copilot AI left a comment

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.

🟡 Changes recommended

Template-version validation gaps remain unresolved.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

engine/schema/templateConfig.sh:38

  • This branch only checks whether a fourth component exists; it never validates the complete stripped version. For example, getTemplateVersion "24.0" succeeds and exports FULL_VERSION=24.0., while a legacy value such as 4.23.0.1.2 silently drops the fifth component, even though CloudStackVersion.parse rejects both forms. Validate the input as exactly three or four numeric components before extracting fields so the build cannot emit unparseable metadata.

utils/src/main/java/org/apache/cloudstack/utils/CloudStackVersion.java:263

  • The updated parseability check rejects four-component versions at major 24 and above, but the trimRouterVersion Javadoc immediately above still documents every four-component value as valid. Please qualify those formats by the legacy-major rule and document the post-cutover major.minor.security form so callers are not given an incorrect contract.
        if (tokens.length >= 3 && FULL_VERSION_FORMAT.matcher(tokens[2]).matches() && isParseableVersion(tokens[2])) {
  • Files reviewed: 15/15 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment on lines +27 to +39
TEMPLATE_MAJOR_VERSION="$(cut -d'.' -f1 <<<"$TEMPLATE_VERSION")"
if [[ "$TEMPLATE_MAJOR_VERSION" -ge "$NEW_VERSIONING_CUTOVER_MAJOR_VERSION" ]]; then
# New versioning (major.minor.security): the generated template files use the full version as-is.
VERSION="${TEMPLATE_VERSION}"
else
# Legacy versioning drops the trailing security component only for four-component metadata;
# a valid three-component major.minor.patch value is already the filename version.
if [[ "$TEMPLATE_VERSION" == *.*.*.* ]]; then
VERSION="${TEMPLATE_VERSION%.*}"
else
VERSION="${TEMPLATE_VERSION}"
fi
fi
@blueorangutan

Copy link
Copy Markdown

[SF] Trillian test result (tid-17008)
Environment: kvm-ol8 (x2), zone: Advanced Networking with Mgmt server ol8
Total time taken: 58680 seconds
Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr14033-t17008-kvm-ol8.zip
Smoke tests completed. 152 look OK, 4 have errors, 0 did not run
Only failed and skipped tests results shown below:

Test Result Time (s) Test File
ContextSuite context=TestClusterDRS>:setup Error 0.00 test_cluster_drs.py
test_list_system_vms_metrics_history Failure 0.66 test_metrics_api.py
test_02_list_cpvm_vm Failure 0.05 test_ssvm.py
test_04_cpvm_internals Failure 0.04 test_ssvm.py
test_1_userdata_on_ssvm Failure 140.28 test_systemvm_userdata.py
test_3_userdata_on_vr Failure 58.66 test_systemvm_userdata.py

@RosiKyu

RosiKyu commented Sep 18, 2026

Copy link
Copy Markdown
Collaborator

Upgrade testing is done. Built a second environment for it: populated 4.23.0.0, Ubuntu 24.04, 2 management servers, three hypervisors with 2 hosts each (VMware ESXi 8.0.3, XenServer 8.3, KVM). Populated before upgrading with 3 isolated networks each with a running VM on its own hypervisor, a standard VPC, a redundant VPC (so a redundant VR pair), 6 routers Running, 5 VMs and a snapshot. Upgraded to 24.0.0. Everything on the upgrade path passed.

Upgrade results

Check Result
Upgrade refused while a second MS is still running PASS, refused cleanly and left the database untouched at 4.23.0.0
Upgrade42300to2400 on a populated 4.23.0.0 database PASS, single step, version gains exactly one row 24.0.0
Second MS started against the already upgraded database PASS, DB version = 24.0.0 Code Version = 24.0.0 ... no upgrade needed
minreq.sysvmtemplate.version after upgrade PASS, rewritten 4.10.0 to 4.22.0, three parts
System VM template registration during the upgrade step PASS, resolved 4.22.0 templates for all six hypervisor types
Data survival PASS, 6 routers, 5 VMs, 5 networks, 2 VPCs and the snapshot all intact and Running
Routers across VMware, XenServer and KVM PASS, all Running after the upgrade

CloudStack refuses to upgrade the database while another management server is still up, so I tested that first: mgmt2 left running on 4.23, mgmt1 started on 24.0.0. It refused and the database stayed at 4.23.0.0.

root@ref-trl-12374-v-Mu24-rositsa-kyuchukova-mgmt1:~# grep -a "clustered environment" /var/log/cloudstack/management/management-server.err
2026-09-17 18:13:59,823 ERROR [c.c.u.DatabaseUpgradeChecker] (main:[]) (logid:) Database upgrade is required but the management server is running in a clustered environment. Please perform the database upgrade when the management server is not running in a clustered environment.

One note: that message only goes to management-server.err and .out.

The two issues

Issue 1, export-templates.sh: fixed by 569417c and verified. I patched the file by hand on the management server and both KVM hosts. bash -n passes and the filename derivation is right for both schemes, including 4.22.0.0 giving systemvmtemplate-4.22.0 which matches the template actually on disk. Good from my side.

Issue 2, minreq.sysvmtemplate.version: still open. It reproduces the same way on the upgraded environment, so it is not environment specific. However, the overall error message in case of a badly formatted input is quite descriptive

Separate problem, not caused by this PR

Flagging here because it will stop anyone upgrading to 24.0.0 on Ubuntu. After the upgrade the management server starts and listens on 8080 but serves HTTP 503 permanently. Reproduced on both management servers.

root@ref-trl-12374-v-Mu24-rositsa-kyuchukova-mgmt1:~# grep -a "Failed to load module" /var/log/cloudstack/management/management-server.err | tail -1
2026-09-17 18:35:13,833 ERROR [o.a.c.s.m.m.i.DefaultModuleDefinitionSet] (main:[]) (logid:) Failed to load module [root-ca] due to: org.springframework.context.ApplicationContextException: Failed to start bean 'cloudStackLifeCycle'; nested exception is java.lang.NoSuchFieldError: xmss_SHAKE128_512ph

The management server ends up with two copies of the same BouncyCastle class on its classpath, one complete and one old and incomplete, and Java loads whichever it finds first. The order is not defined, so which one wins is luck. On both Ubuntu management servers it picked the incomplete one and the server never finished starting. My el9 environment has both copies too but picks the good one, so this is not Ubuntu specific. Forcing the good copy first on the classpath makes it start normally in about 75 seconds. Raising this as a separate issue with the details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants