create_vm: add CD/DVD drive with optional ISO boot
Previously created VMs had no CD/DVD drive, so attach_iso failed with 'No CD/DVD drive found' and there was no way to install a guest from an ISO. create_vm now always adds a CD/DVD drive on the default IDE controller. New optional args iso_path/iso_datastore back the drive with an ISO and boot_from_iso puts the CD/DVD first in the boot order, giving MCP clients a complete create-and-install-from-ISO path.
This commit is contained in:
parent
c93c97a0de
commit
7888494efb
@ -99,7 +99,7 @@ class VMLifecycleMixin(MCPMixin):
|
||||
|
||||
@mcp_tool(
|
||||
name="create_vm",
|
||||
description="Create a new virtual machine with specified resources",
|
||||
description="Create a new virtual machine with specified resources and a CD/DVD drive (optionally booting from an ISO)",
|
||||
annotations=ToolAnnotations(destructiveHint=False, idempotentHint=False),
|
||||
)
|
||||
def create_vm(
|
||||
@ -111,8 +111,28 @@ class VMLifecycleMixin(MCPMixin):
|
||||
datastore: str | None = None,
|
||||
network: str | None = None,
|
||||
guest_id: str = "otherGuest64",
|
||||
iso_path: str | None = None,
|
||||
iso_datastore: str | None = None,
|
||||
boot_from_iso: bool = True,
|
||||
) -> str:
|
||||
"""Create a new virtual machine with specified configuration."""
|
||||
"""Create a new virtual machine with specified configuration.
|
||||
|
||||
The VM always gets a CD/DVD drive. If ``iso_path`` is given, the drive
|
||||
is backed by that ISO and connected at power-on; otherwise it is an
|
||||
empty client device (so ``attach_iso`` can mount media later).
|
||||
|
||||
Args:
|
||||
name: VM name
|
||||
cpu: vCPU count
|
||||
memory_mb: Memory in MB
|
||||
disk_gb: Primary disk size in GB
|
||||
datastore: Datastore for the VM (default: largest available)
|
||||
network: Port group for the NIC (default: configured network)
|
||||
guest_id: vSphere guest OS identifier
|
||||
iso_path: ISO path on a datastore (e.g. 'iso/ubuntu.iso') to mount in the CD/DVD drive
|
||||
iso_datastore: Datastore holding the ISO (default: the VM's datastore)
|
||||
boot_from_iso: When an ISO is given, put the CD/DVD first in the boot order
|
||||
"""
|
||||
# Resolve datastore
|
||||
datastore_obj = self.conn.datastore
|
||||
if datastore:
|
||||
@ -195,6 +215,40 @@ class VMLifecycleMixin(MCPMixin):
|
||||
)
|
||||
device_specs.append(nic_spec)
|
||||
|
||||
# Add a CD/DVD drive on the default IDE controller (vSphere auto-creates
|
||||
# IDE controller key 200). Backed by an ISO if one was requested,
|
||||
# otherwise an empty client device so media can be mounted later.
|
||||
cdrom_spec = vim.vm.device.VirtualDeviceSpec()
|
||||
cdrom_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add
|
||||
cdrom_spec.device = vim.vm.device.VirtualCdrom()
|
||||
cdrom_spec.device.controllerKey = 200
|
||||
cdrom_spec.device.unitNumber = 0
|
||||
cdrom_spec.device.key = -2
|
||||
connectable = vim.vm.device.VirtualDevice.ConnectInfo()
|
||||
connectable.allowGuestControl = True
|
||||
connectable.connected = False
|
||||
|
||||
if iso_path:
|
||||
iso_ds = iso_datastore or datastore_obj.name
|
||||
backing = vim.vm.device.VirtualCdrom.IsoBackingInfo()
|
||||
backing.fileName = f"[{iso_ds}] {iso_path}"
|
||||
connectable.startConnected = True
|
||||
else:
|
||||
backing = vim.vm.device.VirtualCdrom.RemotePassthroughBackingInfo()
|
||||
backing.deviceName = ""
|
||||
backing.exclusive = False
|
||||
connectable.startConnected = False
|
||||
|
||||
cdrom_spec.device.backing = backing
|
||||
cdrom_spec.device.connectable = connectable
|
||||
device_specs.append(cdrom_spec)
|
||||
|
||||
# Boot from the CD/DVD first when installing from an ISO
|
||||
if iso_path and boot_from_iso:
|
||||
vm_spec.bootOptions = vim.vm.BootOptions(
|
||||
bootOrder=[vim.vm.BootOptions.BootableCdromDevice()]
|
||||
)
|
||||
|
||||
vm_spec.deviceChange = device_specs
|
||||
|
||||
# Create VM
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user