Fix detach_iso: eject the ISO-bearing drive(s), not the first CD/DVD

detach_iso used _find_cdrom (first drive), so on VMs with multiple CD/DVD
drives (e.g. Cisco CUCM's two) it 'ejected' an already-empty drive and
reported previous_iso=null while the mounted ISO stayed put. Now it finds
every drive with an IsoBackingInfo and ejects them all, reporting each.
This commit is contained in:
Ryan Malloy 2026-06-08 06:15:13 -06:00
parent 3e435e3d5f
commit e71610292a

View File

@ -511,42 +511,56 @@ class DiskManagementMixin(VSphereMixin):
if not vm:
raise ValueError(f"VM '{vm_name}' not found")
cdrom = self._find_cdrom(vm)
if not cdrom:
cdroms = [
d
for d in vm.config.hardware.device
if isinstance(d, vim.vm.device.VirtualCdrom)
]
if not cdroms:
raise ValueError(f"No CD/DVD drive found on VM '{vm_name}'")
# Get current ISO path for reporting
old_iso = None
if hasattr(cdrom.backing, "fileName"):
old_iso = cdrom.backing.fileName
# Eject every drive that actually has an ISO mounted (a VM may have
# several CD/DVD drives; the ISO is rarely on the first one).
iso_cdroms = [
c
for c in cdroms
if isinstance(c.backing, vim.vm.device.VirtualCdrom.IsoBackingInfo)
]
if not iso_cdroms:
return {
"vm": vm_name,
"action": "no_iso_mounted",
"previous_iso": None,
"ejected": [],
}
# Create empty client device backing (ejects the ISO)
backing = vim.vm.device.VirtualCdrom.RemotePassthroughBackingInfo()
backing.deviceName = ""
device_changes = []
ejected = []
for cdrom in iso_cdroms:
ejected.append(
{"cdrom": cdrom.deviceInfo.label, "previous_iso": cdrom.backing.fileName}
)
backing = vim.vm.device.VirtualCdrom.RemotePassthroughBackingInfo()
backing.deviceName = ""
backing.exclusive = False
cdrom.backing = backing
cdrom.connectable = vim.vm.device.VirtualDevice.ConnectInfo()
cdrom.connectable.connected = False
cdrom.connectable.startConnected = False
cdrom.connectable.allowGuestControl = True
# Configure CD-ROM
cdrom.backing = backing
cdrom.connectable = vim.vm.device.VirtualDevice.ConnectInfo()
cdrom.connectable.connected = False
cdrom.connectable.startConnected = False
cdrom.connectable.allowGuestControl = True
spec = vim.vm.device.VirtualDeviceSpec()
spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.edit
spec.device = cdrom
device_changes.append(spec)
# Create device edit spec
cdrom_spec = vim.vm.device.VirtualDeviceSpec()
cdrom_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.edit
cdrom_spec.device = cdrom
# Create VM config spec
config_spec = vim.vm.ConfigSpec()
config_spec.deviceChange = [cdrom_spec]
# Reconfigure VM
config_spec = vim.vm.ConfigSpec(deviceChange=device_changes)
task = vm.ReconfigVM_Task(spec=config_spec)
conn.wait_for_task(task)
return {
"vm": vm_name,
"action": "iso_detached",
"previous_iso": old_iso,
"cdrom": cdrom.deviceInfo.label,
"previous_iso": ejected[0]["previous_iso"],
"ejected": ejected,
}