Skip to content

Conversation

@sudo87
Copy link
Collaborator

@sudo87 sudo87 commented Jan 15, 2026

Description

This PR proposes 251 char limit on iso filename to prevent this issue #11731

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?

@codecov
Copy link

codecov bot commented Jan 15, 2026

Codecov Report

❌ Patch coverage is 20.00000% with 20 lines in your changes missing coverage. Please review.
✅ Project coverage is 16.24%. Comparing base (8627c60) to head (a467a2b).
⚠️ Report is 17 commits behind head on 4.20.

Files with missing lines Patch % Lines
...ava/com/cloud/upgrade/dao/Upgrade42020to42030.java 16.66% 20 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##               4.20   #12430    +/-   ##
==========================================
  Coverage     16.24%   16.24%            
- Complexity    13378    13395    +17     
==========================================
  Files          5657     5658     +1     
  Lines        498971   499153   +182     
  Branches      60561    60578    +17     
==========================================
+ Hits          81033    81097    +64     
- Misses       408904   409015   +111     
- Partials       9034     9041     +7     
Flag Coverage Δ
uitests 4.03% <ø> (-0.01%) ⬇️
unittests 17.10% <20.00%> (+<0.01%) ⬆️

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

☔ View full report in Codecov by Sentry.
📢 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.

@sudo87
Copy link
Collaborator Author

sudo87 commented Jan 15, 2026

@blueorangutan package

@blueorangutan
Copy link

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

@blueorangutan
Copy link

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

Copy link
Contributor

@DaanHoogland DaanHoogland left a comment

Choose a reason for hiding this comment

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

clgtm

Copy link
Member

@vishesh92 vishesh92 left a comment

Choose a reason for hiding this comment

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

clgtm. IMO, it will be good to have this restriction in the UI as well.

@DaanHoogland
Copy link
Contributor

@sudo87 , can you rebase on the 4.20 branch?

@sudo87 sudo87 changed the base branch from main to 4.20 January 16, 2026 09:45
@sudo87
Copy link
Collaborator Author

sudo87 commented Jan 16, 2026

my bad, it is meant for 4.20, corrected the base.

@DaanHoogland DaanHoogland added this to the 4.20.3 milestone Jan 16, 2026
@DaanHoogland
Copy link
Contributor

@blueorangutan package

@blueorangutan
Copy link

@DaanHoogland a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.

@blueorangutan
Copy link

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

Copy link
Collaborator

@RosiKyu RosiKyu left a comment

Choose a reason for hiding this comment

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

PR #12430 Test Results

Test Results Summary

Test Description Expected Actual Status
TC1 Register ISO with 251 chars PASS Registration succeeded PASS
TC2 Register ISO with 252 chars FAIL with validation error Rejected correctly PASS
TC3 Register ISO with 255 chars FAIL with validation error Rejected correctly PASS
TC4 Update ISO to 251 chars PASS Update succeeded PASS
TC5 Update ISO to 252 chars FAIL with validation error Rejected correctly PASS
TC6 Update Template to 251 chars PASS Update succeeded PASS
TC7 Update Template to 252 chars FAIL with validation error Rejected correctly PASS
TC8 Extract 251-char ISO PASS Data too long error FAIL
TC9 Register ISO with short name PASS Registration succeeded PASS
TC10 Special characters in name PASS Registration succeeded PASS
TC11 Register ISO with 250 chars PASS Registration succeeded PASS

Additional Boundary Tests

Test Description Expected Actual Status
TC12 Extract short-name ISO PASS Extraction succeeded PASS
186-char Extract 186-char ISO PASS Extraction succeeded PASS
187-char Extract 187-char ISO FAIL Data too long error FAIL

Problem Identified: 251-char limit is insufficient

The PR correctly implements API-level validation to reject ISO/template names longer than 251 characters. However, 251 characters is still too long and does not actually fix issue #11731.

Root Cause Analysis

The extraction failure occurs because the download_url column in template_store_ref table is VARCHAR(255). When extracting an ISO, CloudStack constructs a URL in this format: http://<SSVM_IP>/userdata/<UUID>/<ISO_NAME>.iso

URL component breakdown:

Component Example Length
Protocol + IP http://10.0.57.141 ~19 chars
Path prefix /userdata/ 10 chars
UUID b23a3895-b99d-458c-9b5c-4c8ad486cc74 36 chars
Slash / 1 char
Total prefix ~65-70 chars
ISO name (variable) ? chars
Extension .iso 4 chars

Test Evidence

ISO Name Length Total URL Length Extraction Result
32 chars ~101 chars Success
186 chars 255 chars Success (exactly at limit)
187 chars 256 chars FAILED - Data too long for column download_url
251 chars ~320 chars FAILED - Data too long for column download_url

Calculation

Max URL length: 255 (VARCHAR limit)
URL prefix: ~65 chars (varies by SSVM IP length)
File extension: 4 chars (.iso)
Max safe name: 255 - 65 - 4 = 186 chars

Recommendation

Change the limit from 251 to 186 characters (or lower, e.g., 180, to provide safety margin for longer IP addresses or hostnames).

Alternative Solution

If preserving longer names is important, consider expanding the download_url column in the database schema to VARCHAR(512) or TEXT. This would require a database migration but would allow the original 251-char limit (or even 255) to work correctly.

Detailed Test Report:

TC1: Register ISO with 251 chars (PASS)

[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# NAME_251=$(python3 -c "print('A' * 251)")
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# echo "Name length: ${#NAME_251}"
Name length: 251
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# echo "Name: $NAME_251"
Name: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# cmk register iso name="$NAME_251" displaytext="TC1-251chars" url="$ISO_URL" zoneid="$ZONE_ID" ostypeid="$OS_TYPE_ID"
{
  "count": 1,
  "iso": [
    {
      "account": "admin",
      "arch": "x86_64",
      "bits": 64,
      "bootable": true,
      "created": "2026-01-22T08:41:48+0000",
      "crossZones": false,
      "directdownload": false,
      "displaytext": "TC1-251chars",
      "domain": "ROOT",
      "domainid": "fa7a2f34-f60f-11f0-beda-1e005c0001cd",
      "domainpath": "/",
      "downloaddetails": [
        {
          "datastore": "NFS://10.0.32.4/acs/secondary/ref-trl-10673-k-Mol9-rositsa-kyuchukova/ref-trl-10673-k-Mol9-rositsa-kyuchukova-sec1",
          "downloadPercent": "0",
          "downloadState": "NOT_DOWNLOADED"
        }
      ],
      "format": "ISO",
      "hasannotations": false,
      "id": "950f92a5-ab2b-475a-97df-6b7bf31a8726",
      "isdynamicallyscalable": false,
      "isextractable": false,
      "isfeatured": false,
      "ispublic": false,
      "isready": false,
      "name": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
      "ostypeid": "260aaea4-f610-11f0-beda-1e005c0001cd",
      "ostypename": "Debian GNU/Linux 11 (64-bit)",
      "passwordenabled": false,
      "status": "",
      "tags": [],
      "url": "http://10.0.3.122/vladitemplates/iso/debian-live-11.0.0-amd64-standard.iso",
      "zoneid": "fd205674-8809-4ae5-b555-c1267d6ed4c1",
      "zonename": "ref-trl-10673-k-Mol9-rositsa-kyuchukova"
    }
  ]
}
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# 

TC2: Register ISO with 252 chars (should FAIL)

[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# echo "Name: $NAME_252"
Name: BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# cmk register iso name="$NAME_252" displaytext="TC2-252chars" url="$ISO_URL" zoneid="$ZONE_ID" ostypeid="$OS_TYPE_ID"
🙈 Error: (HTTP 431, error code 9999) Unable to execute API command registeriso due to invalid value. Value greater than max allowed length 251 for param: isoName
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# 

TC3 is: Register ISO with 255 chars

*Test Result: PASS - Correctly rejected 255-char name with: "Value greater than max allowed length 251 for param: isoName"

[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# NAME_255=$(python3 -c "print('C' * 255)")
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# echo "Name length: ${#NAME_255}"
Name length: 255
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# echo "Name: $NAME_255"
Name: CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# cmk register iso name="$NAME_255" displaytext="TC3-255chars" url="$ISO_URL" zoneid="$ZONE_ID" ostypeid="$OS_TYPE_ID"
🙈 Error: (HTTP 431, error code 9999) Unable to execute API command registeriso due to invalid value. Value greater than max allowed length 251 for param: isoName
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# 

TC9 (Regression Test - Short Name)

Test Result: PASS - Short name (32 chars) registered successfully

[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# SHORT_NAME="debian11-pr12430-test-$(date +%s)"
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# echo "Name length: ${#SHORT_NAME}"
Name length: 32
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# echo "Name: $SHORT_NAME"
Name: debian11-pr12430-test-1769071703
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# cmk register iso name="$SHORT_NAME" displaytext="TC9-shortname" url="$ISO_URL" zoneid="$ZONE_ID" ostypeid="$OS_TYPE_ID"
{
  "count": 1,
  "iso": [
    {
      "account": "admin",
      "arch": "x86_64",
      "bits": 64,
      "bootable": true,
      "created": "2026-01-22T08:48:34+0000",
      "crossZones": false,
      "directdownload": false,
      "displaytext": "TC9-shortname",
      "domain": "ROOT",
      "domainid": "fa7a2f34-f60f-11f0-beda-1e005c0001cd",
      "domainpath": "/",
      "downloaddetails": [
        {
          "datastore": "NFS://10.0.32.4/acs/secondary/ref-trl-10673-k-Mol9-rositsa-kyuchukova/ref-trl-10673-k-Mol9-rositsa-kyuchukova-sec1",
          "downloadPercent": "0",
          "downloadState": "NOT_DOWNLOADED"
        }
      ],
      "format": "ISO",
      "hasannotations": false,
      "id": "d1dd679c-9efa-43cf-9b01-e00e860d43a3",
      "isdynamicallyscalable": false,
      "isextractable": false,
      "isfeatured": false,
      "ispublic": false,
      "isready": false,
      "name": "debian11-pr12430-test-1769071703",
      "ostypeid": "260aaea4-f610-11f0-beda-1e005c0001cd",
      "ostypename": "Debian GNU/Linux 11 (64-bit)",
      "passwordenabled": false,
      "status": "",
      "tags": [],
      "url": "http://10.0.3.122/vladitemplates/iso/debian-live-11.0.0-amd64-standard.iso",
      "zoneid": "fd205674-8809-4ae5-b555-c1267d6ed4c1",
      "zonename": "ref-trl-10673-k-Mol9-rositsa-kyuchukova"
    }
  ]
}
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# 

TC12: Extract short-name ISO (Regression Test)

Test Result: PASS - Short-name ISO extraction succeeded immediately with state DOWNLOAD_URL_CREATED and URL generated.

[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# cmk extract iso id="d1dd679c-9efa-43cf-9b01-e00e860d43a3" zoneid="$ZONE_ID" mode=HTTP_DOWNLOAD
{
  "iso": {
    "accountid": "3bfcb663-f610-11f0-beda-1e005c0001cd",
    "extractMode": "HTTP_DOWNLOAD",
    "id": "d1dd679c-9efa-43cf-9b01-e00e860d43a3",
    "name": "debian11-pr12430-test-1769071703",
    "state": "DOWNLOAD_URL_CREATED",
    "url": "http://10.0.57.141/userdata/531b1144-3505-4e9f-a4dc-098bcc908098/debian11-pr12430-test-1769071703.iso",
    "zoneid": "fd205674-8809-4ae5-b555-c1267d6ed4c1",
    "zonename": "ref-trl-10673-k-Mol9-rositsa-kyuchukova"
  }
}

TC8 - Critical Extraction Test (251-char ISO)

Test Result - FAIL (expected) - The extraction failed with: "Data too long for column 'download_url' at row 1"

[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# cmk extract iso id="950f92a5-ab2b-475a-97df-6b7bf31a8726" zoneid="$ZONE_ID" mode=HTTP_DOWNLOAD
{
  "account": "admin",
  "accountid": "3bfcb663-f610-11f0-beda-1e005c0001cd",
  "cmd": "org.apache.cloudstack.api.command.user.iso.ExtractIsoCmd",
  "completed": "2026-01-22T08:51:03+0000",
  "created": "2026-01-22T08:51:03+0000",
  "domainid": "fa7a2f34-f60f-11f0-beda-1e005c0001cd",
  "domainpath": "ROOT",
  "jobid": "2a3c641a-1c35-4f4c-ab33-5f0dde9f52d3",
  "jobinstanceid": "950f92a5-ab2b-475a-97df-6b7bf31a8726",
  "jobinstancetype": "Iso",
  "jobprocstatus": 0,
  "jobresult": {
    "errorcode": 530,
    "errortext": "Unable to update on DB, due to: Data truncation: Data too long for column 'download_url' at row 1"
  },
  "jobresultcode": 530,
  "jobresulttype": "object",
  "jobstatus": 2,
  "userid": "3bfd7a69-f610-11f0-beda-1e005c0001cd"
}
🙈 Error: async API failed for job 2a3c641a-1c35-4f4c-ab33-5f0dde9f52d3
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# 

This proves that 251 characters is not a safe limit. The PR's fix might be insufficient, because:

  • The ISO name is 251 chars
  • But the download_url includes: http://10.0.57.141/userdata// + <ISO_NAME> + .iso
  • The URL prefix alone is ~50+ characters
  • Total URL length = ~50 + 251 + 4 = ~305 characters
  • But download_url column is only VARCHAR(255)

The URL structure is:

[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# echo "http://10.0.57.141/userdata/531b1144-3505-4e9f-a4dc-098bcc908098/debian11-pr12430-test-1769071703.iso" | wc -c
102
  • Prefix: http://10.0.57.141/userdata/531b1144-3505-4e9f-a4dc-098bcc908098/ = 65 characters
  • Filename: debian11-pr12430-test-1769071703.iso = 36 characters (32 name + 4 for .iso)
  • Total: 101 characters (+ 1 for newline = 102 from wc -c)

The prefix length is 65 chars:

[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# echo -n "http://10.0.57.141/userdata/531b1144-3505-4e9f-a4dc-098bcc908098/" | wc -c
65

So the theoretical max name length = 255 - 65 - 4 = 186 characters

Extraction with 186 characters works:

[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# NAME_186=$(python3 -c "print('M' * 186)")
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# echo "Name length: ${#NAME_186}"
Name length: 186
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# cmk register iso name="$NAME_186" displaytext="Test-186" url="$ISO_URL" zoneid="$ZONE_ID" ostypeid="$OS_TYPE_ID"
{
  "count": 1,
  "iso": [
    {
      "account": "admin",
      "arch": "x86_64",
      "bits": 64,
      "bootable": true,
      "created": "2026-01-22T08:56:18+0000",
      "crossZones": false,
      "directdownload": false,
      "displaytext": "Test-186",
      "domain": "ROOT",
      "domainid": "fa7a2f34-f60f-11f0-beda-1e005c0001cd",
      "domainpath": "/",
      "downloaddetails": [
        {
          "datastore": "NFS://10.0.32.4/acs/secondary/ref-trl-10673-k-Mol9-rositsa-kyuchukova/ref-trl-10673-k-Mol9-rositsa-kyuchukova-sec1",
          "downloadPercent": "0",
          "downloadState": "NOT_DOWNLOADED"
        }
      ],
      "format": "ISO",
      "hasannotations": false,
      "id": "704b4067-ac92-4879-86f8-d006576752de",
      "isdynamicallyscalable": false,
      "isextractable": false,
      "isfeatured": false,
      "ispublic": false,
      "isready": false,
      "name": "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM",
      "ostypeid": "260aaea4-f610-11f0-beda-1e005c0001cd",
      "ostypename": "Debian GNU/Linux 11 (64-bit)",
      "passwordenabled": false,
      "status": "",
      "tags": [],
      "url": "http://10.0.3.122/vladitemplates/iso/debian-live-11.0.0-amd64-standard.iso",
      "zoneid": "fd205674-8809-4ae5-b555-c1267d6ed4c1",
      "zonename": "ref-trl-10673-k-Mol9-rositsa-kyuchukova"
    }
  ]
}

And iso is in Ready state:

root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# cmk list isos listall=true filter=id,name,isready id="704b4067-ac92-4879-86f8-d006576752de"
{
  "count": 1,
  "iso": [
    {
      "id": "704b4067-ac92-4879-86f8-d006576752de",
      "isready": true,
      "name": "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM"
    }
  ]
}

Extraction succeeds:

[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# cmk extract iso id="704b4067-ac92-4879-86f8-d006576752de" zoneid="$ZONE_ID" mode=HTTP_DOWNLOAD
{
  "iso": {
    "accountid": "3bfcb663-f610-11f0-beda-1e005c0001cd",
    "extractMode": "HTTP_DOWNLOAD",
    "id": "704b4067-ac92-4879-86f8-d006576752de",
    "name": "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM",
    "state": "DOWNLOAD_URL_CREATED",
    "url": "http://10.0.57.141/userdata/b23a3895-b99d-458c-9b5c-4c8ad486cc74/MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM.iso",
    "zoneid": "fd205674-8809-4ae5-b555-c1267d6ed4c1",
    "zonename": "ref-trl-10673-k-Mol9-rositsa-kyuchukova"
  }
}
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# 
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# 
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# echo -n "http://10.0.57.141/userdata/b23a3895-b99d-458c-9b5c-4c8ad486cc74/MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM.iso" | wc -c
255
  • Test with 187 chars - registration succeeds :
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# NAME_187=$(python3 -c "print('N' * 187)")
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# echo "Name length: ${#NAME_187}"
Name length: 187
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# cmk register iso name="$NAME_187" displaytext="Test-187" url="$ISO_URL" zoneid="$ZONE_ID" ostypeid="$OS_TYPE_ID"
{
  "count": 1,
  "iso": [
    {
      "account": "admin",
      "arch": "x86_64",
      "bits": 64,
      "bootable": true,
      "created": "2026-01-22T08:59:06+0000",
      "crossZones": false,
      "directdownload": false,
      "displaytext": "Test-187",
      "domain": "ROOT",
      "domainid": "fa7a2f34-f60f-11f0-beda-1e005c0001cd",
      "domainpath": "/",
      "downloaddetails": [
        {
          "datastore": "NFS://10.0.32.4/acs/secondary/ref-trl-10673-k-Mol9-rositsa-kyuchukova/ref-trl-10673-k-Mol9-rositsa-kyuchukova-sec1",
          "downloadPercent": "0",
          "downloadState": "NOT_DOWNLOADED"
        }
      ],
      "format": "ISO",
      "hasannotations": false,
      "id": "f4867475-1ccc-4411-a772-87946bc2af6f",
      "isdynamicallyscalable": false,
      "isextractable": false,
      "isfeatured": false,
      "ispublic": false,
      "isready": false,
      "name": "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN",
      "ostypeid": "260aaea4-f610-11f0-beda-1e005c0001cd",
      "ostypename": "Debian GNU/Linux 11 (64-bit)",
      "passwordenabled": false,
      "status": "",
      "tags": [],
      "url": "http://10.0.3.122/vladitemplates/iso/debian-live-11.0.0-amd64-standard.iso",
      "zoneid": "fd205674-8809-4ae5-b555-c1267d6ed4c1",
      "zonename": "ref-trl-10673-k-Mol9-rositsa-kyuchukova"
    }
  ]
}
  • ISO in Ready state, but extraction fails due to the l
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# cmk list isos listall=true filter=id,isready id="f4867475-1ccc-4411-a772-87946bc2af6f"
{
  "count": 1,
  "iso": [
    {
      "id": "f4867475-1ccc-4411-a772-87946bc2af6f",
      "isready": true
    }
  ]
}
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# 

[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# cmk extract iso id="f4867475-1ccc-4411-a772-87946bc2af6f" zoneid="$ZONE_ID" mode=HTTP_DOWNLOAD
{
  "account": "admin",
  "accountid": "3bfcb663-f610-11f0-beda-1e005c0001cd",
  "cmd": "org.apache.cloudstack.api.command.user.iso.ExtractIsoCmd",
  "completed": "2026-01-22T09:00:25+0000",
  "created": "2026-01-22T09:00:24+0000",
  "domainid": "fa7a2f34-f60f-11f0-beda-1e005c0001cd",
  "domainpath": "ROOT",
  "jobid": "ae0218ea-037c-421d-a43b-0b199d7c59cf",
  "jobinstanceid": "f4867475-1ccc-4411-a772-87946bc2af6f",
  "jobinstancetype": "Iso",
  "jobprocstatus": 0,
  "jobresult": {
    "errorcode": 530,
    "errortext": "Unable to update on DB, due to: Data truncation: Data too long for column 'download_url' at row 1"
  },
  "jobresultcode": 530,
  "jobresulttype": "object",
  "jobstatus": 2,
  "userid": "3bfd7a69-f610-11f0-beda-1e005c0001cd"
}
🙈 Error: async API failed for job ae0218ea-037c-421d-a43b-0b199d7c59cf

TC4: Update ISO to 251 chars

Test Result: Update ISO to 251 chars succeeded.

[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# cmk register iso name="update-test-iso" displaytext="TC4-update-test" url="$ISO_URL" zoneid="$ZONE_ID" ostypeid="$OS_TYPE_ID"
{
  "count": 1,
  "iso": [
    {
      "account": "admin",
      "arch": "x86_64",
      "bits": 64,
      "bootable": true,
      "created": "2026-01-22T09:02:14+0000",
      "crossZones": false,
      "directdownload": false,
      "displaytext": "TC4-update-test",
      "domain": "ROOT",
      "domainid": "fa7a2f34-f60f-11f0-beda-1e005c0001cd",
      "domainpath": "/",
      "downloaddetails": [
        {
          "datastore": "NFS://10.0.32.4/acs/secondary/ref-trl-10673-k-Mol9-rositsa-kyuchukova/ref-trl-10673-k-Mol9-rositsa-kyuchukova-sec1",
          "downloadPercent": "0",
          "downloadState": "NOT_DOWNLOADED"
        }
      ],
      "format": "ISO",
      "hasannotations": false,
      "id": "a70e82cd-c66b-4cb4-b83f-57ef063856ac",
      "isdynamicallyscalable": false,
      "isextractable": false,
      "isfeatured": false,
      "ispublic": false,
      "isready": false,
      "name": "update-test-iso",
      "ostypeid": "260aaea4-f610-11f0-beda-1e005c0001cd",
      "ostypename": "Debian GNU/Linux 11 (64-bit)",
      "passwordenabled": false,
      "status": "",
      "tags": [],
      "url": "http://10.0.3.122/vladitemplates/iso/debian-live-11.0.0-amd64-standard.iso",
      "zoneid": "fd205674-8809-4ae5-b555-c1267d6ed4c1",
      "zonename": "ref-trl-10673-k-Mol9-rositsa-kyuchukova"
    }
  ]
}
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# 
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# 
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# ISO_ID="a70e82cd-c66b-4cb4-b83f-57ef063856ac"
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# NAME_251=$(python3 -c "print('D' * 251)")
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# echo "Name length: ${#NAME_251}"
Name length: 251
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# cmk update iso id="$ISO_ID" name="$NAME_251"
{
  "iso": {
    "account": "admin",
    "bits": 0,
    "bootable": true,
    "created": "2026-01-22T09:02:14+0000",
    "crossZones": false,
    "displaytext": "TC4-update-test",
    "domain": "ROOT",
    "domainid": "fa7a2f34-f60f-11f0-beda-1e005c0001cd",
    "domainpath": "/",
    "format": "ISO",
    "hypervisor": "None",
    "id": "a70e82cd-c66b-4cb4-b83f-57ef063856ac",
    "isdynamicallyscalable": false,
    "isfeatured": false,
    "ispublic": false,
    "isready": false,
    "name": "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD",
    "ostypeid": "260aaea4-f610-11f0-beda-1e005c0001cd",
    "ostypename": "Debian GNU/Linux 11 (64-bit)",
    "tags": []
  }
}

TC5: Update ISO to 252 chars

[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# NAME_252=$(python3 -c "print('E' * 252)")
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# echo "Name length: ${#NAME_252}"
Name length: 252
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# cmk update iso id="$ISO_ID" name="$NAME_252"
🙈 Error: (HTTP 431, error code 9999) Unable to execute API command updateiso due to invalid value. Value greater than max allowed length 251 for param: templateName

TC6: Update Template to 251 chars

Test Result: Update template to 251 chars succeeded.


[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# cmk list templates templatefilter=all listall=true filter=id,name
{
  "count": 2,
  "template": [
    {
      "id": "fa8b2cbc-f60f-11f0-beda-1e005c0001cd",
      "name": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
    },
    {
      "id": "fa8c121b-f60f-11f0-beda-1e005c0001cd",
      "name": "CentOS 5.5(64-bit) no GUI (KVM)"
    }
  ]
}

[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# TEMPLATE_ID="fa8c121b-f60f-11f0-beda-1e005c0001cd"
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# NAME_251=$(python3 -c "print('F' * 251)")
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# echo "Name length: ${#NAME_251}"
Name length: 251
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# cmk update template id="$TEMPLATE_ID" name="$NAME_251"
{
  "template": {
    "account": "system",
    "bits": 0,
    "bootable": true,
    "created": "2026-01-20T14:54:53+0000",
    "crossZones": false,
    "displaytext": "CentOS 5.5(64-bit) no GUI (KVM)",
    "domain": "ROOT",
    "domainid": "fa7a2f34-f60f-11f0-beda-1e005c0001cd",
    "domainpath": "/",
    "format": "QCOW2",
    "hypervisor": "KVM",
    "id": "fa8c121b-f60f-11f0-beda-1e005c0001cd",
    "isdynamicallyscalable": false,
    "isfeatured": false,
    "ispublic": true,
    "isready": false,
    "name": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
    "ostypeid": "faadd111-f60f-11f0-beda-1e005c0001cd",
    "ostypename": "CentOS 5.5 (64-bit)",
    "tags": [],
    "templatetype": "BUILTIN"
  }
}

TC7: Update Template to 252 chars

Test Result: 250-char name registered successfully

[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# NAME_252=$(python3 -c "print('G' * 252)")
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# echo "Name length: ${#NAME_252}"
Name length: 252
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# cmk update template id="$TEMPLATE_ID" name="$NAME_252"
🙈 Error: (HTTP 431, error code 9999) Unable to execute API command updatetemplate due to invalid value. Value greater than max allowed length 251 for param: templateName

TC10: Special characters test

Test Result: Special characters in name (39 chars) registered successfully

[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# SPECIAL_NAME="Test-ISO_with.special(chars)_$(date +%s)"
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# echo "Name: $SPECIAL_NAME"
Name: Test-ISO_with.special(chars)_1769073373
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# echo "Name length: ${#SPECIAL_NAME}"
Name length: 39
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# cmk register iso name="$SPECIAL_NAME" displaytext="TC10-special-chars" url="$ISO_URL" zoneid="$ZONE_ID" ostypeid="$OS_TYPE_ID"
{
  "count": 1,
  "iso": [
    {
      "account": "admin",
      "arch": "x86_64",
      "bits": 64,
      "bootable": true,
      "created": "2026-01-22T09:16:20+0000",
      "crossZones": false,
      "directdownload": false,
      "displaytext": "TC10-special-chars",
      "domain": "ROOT",
      "domainid": "fa7a2f34-f60f-11f0-beda-1e005c0001cd",
      "domainpath": "/",
      "downloaddetails": [
        {
          "datastore": "NFS://10.0.32.4/acs/secondary/ref-trl-10673-k-Mol9-rositsa-kyuchukova/ref-trl-10673-k-Mol9-rositsa-kyuchukova-sec1",
          "downloadPercent": "0",
          "downloadState": "NOT_DOWNLOADED"
        }
      ],
      "format": "ISO",
      "hasannotations": false,
      "id": "598299ad-c0a3-415c-8176-9bc2054a3c89",
      "isdynamicallyscalable": false,
      "isextractable": false,
      "isfeatured": false,
      "ispublic": false,
      "isready": false,
      "name": "Test-ISO_with.special(chars)_1769073373",
      "ostypeid": "260aaea4-f610-11f0-beda-1e005c0001cd",
      "ostypename": "Debian GNU/Linux 11 (64-bit)",
      "passwordenabled": false,
      "status": "",
      "tags": [],
      "url": "http://10.0.3.122/vladitemplates/iso/debian-live-11.0.0-amd64-standard.iso",
      "zoneid": "fd205674-8809-4ae5-b555-c1267d6ed4c1",
      "zonename": "ref-trl-10673-k-Mol9-rositsa-kyuchukova"
    }
  ]
}

TC11: 250 chars boundary test

[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# NAME_250=$(python3 -c "print('Z' * 250)")
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# echo "Name length: ${#NAME_250}"
Name length: 250
[root@ref-trl-10673-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# cmk register iso name="$NAME_250" displaytext="TC11-250chars" url="$ISO_URL" zoneid="$ZONE_ID" ostypeid="$OS_TYPE_ID"
{
  "count": 1,
  "iso": [
    {
      "account": "admin",
      "arch": "x86_64",
      "bits": 64,
      "bootable": true,
      "created": "2026-01-22T09:18:02+0000",
      "crossZones": false,
      "directdownload": false,
      "displaytext": "TC11-250chars",
      "domain": "ROOT",
      "domainid": "fa7a2f34-f60f-11f0-beda-1e005c0001cd",
      "domainpath": "/",
      "downloaddetails": [
        {
          "datastore": "NFS://10.0.32.4/acs/secondary/ref-trl-10673-k-Mol9-rositsa-kyuchukova/ref-trl-10673-k-Mol9-rositsa-kyuchukova-sec1",
          "downloadPercent": "0",
          "downloadState": "NOT_DOWNLOADED"
        }
      ],
      "format": "ISO",
      "hasannotations": false,
      "id": "b0d52e79-d0b0-4ad7-b363-e706efb4d4ad",
      "isdynamicallyscalable": false,
      "isextractable": false,
      "isfeatured": false,
      "ispublic": false,
      "isready": false,
      "name": "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ",
      "ostypeid": "260aaea4-f610-11f0-beda-1e005c0001cd",
      "ostypename": "Debian GNU/Linux 11 (64-bit)",
      "passwordenabled": false,
      "status": "",
      "tags": [],
      "url": "http://10.0.3.122/vladitemplates/iso/debian-live-11.0.0-amd64-standard.iso",
      "zoneid": "fd205674-8809-4ae5-b555-c1267d6ed4c1",
      "zonename": "ref-trl-10673-k-Mol9-rositsa-kyuchukova"
    }
  ]
}

@sudo87
Copy link
Collaborator Author

sudo87 commented Jan 22, 2026

Thank you @RosiKyu for testing the changes and for rightly identifying the issue with char limit on download_url column. We would need to increase current limit which is 255 to 204, similar to other columns dealing with urls.

I will make the required changes.

@sudo87 sudo87 force-pushed the templDownload255Char branch from 7314b1e to a467a2b Compare January 22, 2026 12:30
@sudo87
Copy link
Collaborator Author

sudo87 commented Jan 22, 2026

@blueorangutan package

@blueorangutan
Copy link

@sudo87 a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.

@blueorangutan
Copy link

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

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.

6 participants