DUE TO SPAM, SIGN-UP IS DISABLED. Goto Selfserve wiki signup and request an account.

DUE TO SPAM, SIGN-UP IS DISABLED. Goto Selfserve wiki signup and request an account.
CloudStack currently supports at most one ISO per VM. This forces users into a manual "ISO swap" workflow for common tasks such as installing Windows on KVM — which requires both a Windows installer ISO and a VirtIO drivers ISO simultaneously — and pushes template creation to external tools like Proxmox or virt-manager. This feature adds native support for attaching multiple ISOs per VM, each surfaced as a discrete CD-ROM drive inside the guest. The Windows + VirtIO use case is a natural consequence of the generic multi-ISO capability.
Note: KVM only for 4.23.
vm.iso.max.count to cap the number of CD-ROMs per VM. Per-cluster overrides are supported.No new parameters. Behavior changes:
user_vm.iso_id (the bootable/primary slot); subsequent attaches create a new vm_iso_map row.New optional parameter:
id (UUID, optional; annotated since=4.23.0) — the ISO to detach.Rules:
id may be omitted (back-compat).id is required; the call is rejected without it.id is supplied and the specified ISO is not attached, the call is rejected.Response gains a new isos[] array. Each entry contains:
id, name, displaytextdeviceseq — the CD-ROM slot index (3 = hdc, 4 = hdd, …)The legacy isoid / isoname / isodisplaytext fields are unchanged and continue to reflect the slot-3 (bootable/primary) ISO. Existing API consumers require no modification.
UserVmResponse now also exposes cdrommaxcount (since 4.23.0) — the server-computed effective cap for the VM. The UI reads this field directly from the response instead of making a separate listConfigurations call.
| Parameter | Scope | Type | Default | Description |
|---|---|---|---|---|
vm.iso.max.count | Cluster | Integer | 1 | Maximum number of CD-ROM drives (ISOs) that may be attached to a single VM. Enforced at attach and deploy time. Per-cluster overrides are supported. |
The effective max for a given VM is: min(vm.iso.max.count.valueIn(clusterId), host-advertised hypervisor cap). The hardcoded "2 for KVM, 1 for others" logic has been removed from the management server; the hypervisor cap is now discovered at runtime (see Hypervisor Cap Discovery below).
cmk attach iso id=<windows-iso-uuid> virtualmachineid=<vm-uuid>
cmk attach iso id=<virtio-iso-uuid> virtualmachineid=<vm-uuid>
cmk detach iso virtualmachineid=<vm-uuid>
cmk detach iso id=<virtio-iso-uuid> virtualmachineid=<vm-uuid>
{
"id": "a1b2c3d4-...",
"name": "my-vm",
"isoid": "<windows-iso-uuid>",
"isoname": "Windows Server 2022",
"isos": [
{
"id": "<windows-iso-uuid>",
"name": "Windows Server 2022",
"displaytext": "Windows Server 2022",
"deviceseq": 3
},
{
"id": "<virtio-iso-uuid>",
"name": "virtio-win-0.9.x",
"displaytext": "VirtIO Drivers",
"deviceseq": 4
}
],
...
}
Each hypervisor agent advertises its own CD-ROM cap as a host detail named host.cdrom.max.count (Host.HOST_CDROM_MAX_COUNT) on StartupRoutingCommand. The management server reads this via HostDetailsDao and falls back to TemplateManager.DEFAULT_CDROM_MAX_PER_VM (= 1) if the detail is absent (older agents, never-deployed VMs).
LibvirtVMDef.MAX_CDROMS_PER_VM), co-located with the slot-allocation logic in getDevLabel that places CD-ROMs at hdc (TemplateManager.CDROM_PRIMARY_DEVICE_SEQ = 3) and hdd.domcapabilities lists supported buses but not slot counts. The number is a function of CloudStack's own slot-allocation choices, not a hypervisor-discoverable fact.min(vm.iso.max.count.valueIn(clusterId), host-advertised cap).If vm.iso.max.count is set above the host-advertised cap, attach and deploy operations now log an error and throw InvalidParameterValueException with the recommended maximum in the message. The old behavior of silently clamping to the hypervisor cap has been removed.
The listVirtualMachines endpoint silently clamps the displayed cdrommaxcount value for robustness; the loud failure is reserved for action paths (attach, deploy).
The first attached ISO always occupies user_vm.iso_id (slot 3, hdc). This field is never reassigned by a subsequent attach or detach of a non-primary ISO. Detaching the primary ISO when additional ISOs remain attached is rejected; the primary slot must be the last one cleared.
All attached ISOs and their slot assignments are re-applied on VM start using data from vm_iso_map. No guest-side state is required.
"ISO <uuid> is already attached to VM <uuid>""The maximum number of CD-ROMs (<n>) for this VM has been reached"id omitted with multiple ISOs attached: Error "Multiple ISOs are attached; the 'id' parameter is required to detach"id supplied but ISO not attached: Error "ISO <uuid> is not attached to VM <uuid>"templateIsDeleteable now also consults the vm_iso_map table (via VmIsoMapDao.listByIsoId), filtering out VMs in Error or Expunging states. Previously only user_vm.iso_id was checked, which meant an ISO attached to a non-primary slot (i.e. in vm_iso_map only) could be wrongly considered deletable even while still in use.
| Constant | Location | Value / Role |
|---|---|---|
Host.HOST_CDROM_MAX_COUNT | Management server | Key for the host detail ("host.cdrom.max.count") that agents write on startup. |
LibvirtVMDef.MAX_CDROMS_PER_VM | KVM agent | Value advertised by the KVM agent (= 2). Co-located with the getDevLabel slot-allocation logic. |
TemplateManager.CDROM_PRIMARY_DEVICE_SEQ | Management server | Device sequence index of the primary (bootable) CD-ROM slot (= 3, i.e. hdc). |
TemplateManager.DEFAULT_CDROM_MAX_PER_VM | Management server | Fallback cap (= 1) used when the host has not advertised host.cdrom.max.count (older agents, never-deployed VMs). |
A new mapping table tracks secondary ISO attachments:
CREATE TABLE vm_iso_map (
id bigint unsigned NOT NULL AUTO_INCREMENT,
vm_id bigint unsigned NOT NULL COMMENT 'virtual machine id',
iso_id bigint unsigned NOT NULL COMMENT 'iso (volume) id',
device_seq int unsigned NOT NULL COMMENT 'cdrom slot index (3=hdc, 4=hdd, ...)',
PRIMARY KEY (id),
CONSTRAINT fk_vm_iso_map__vm_id
FOREIGN KEY (vm_id) REFERENCES vm_instance(id) ON DELETE CASCADE,
CONSTRAINT fk_vm_iso_map__iso_id
FOREIGN KEY (iso_id) REFERENCES volumes(id) ON DELETE CASCADE,
UNIQUE KEY uk_vm_iso_map__vm_device (vm_id, device_seq),
INDEX i_vm_iso_map__vm_id (vm_id),
INDEX i_vm_iso_map__iso_id (iso_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
user_vm.iso_id continues to own slot 3 (primary/bootable); vm_iso_map owns slots 4+.UNIQUE KEY on (vm_id, device_seq) prevents slot collisions at the DB layer.hdc, hdd).