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(
|
@mcp_tool(
|
||||||
name="create_vm",
|
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),
|
annotations=ToolAnnotations(destructiveHint=False, idempotentHint=False),
|
||||||
)
|
)
|
||||||
def create_vm(
|
def create_vm(
|
||||||
@ -111,8 +111,28 @@ class VMLifecycleMixin(MCPMixin):
|
|||||||
datastore: str | None = None,
|
datastore: str | None = None,
|
||||||
network: str | None = None,
|
network: str | None = None,
|
||||||
guest_id: str = "otherGuest64",
|
guest_id: str = "otherGuest64",
|
||||||
|
iso_path: str | None = None,
|
||||||
|
iso_datastore: str | None = None,
|
||||||
|
boot_from_iso: bool = True,
|
||||||
) -> str:
|
) -> 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
|
# Resolve datastore
|
||||||
datastore_obj = self.conn.datastore
|
datastore_obj = self.conn.datastore
|
||||||
if datastore:
|
if datastore:
|
||||||
@ -195,6 +215,40 @@ class VMLifecycleMixin(MCPMixin):
|
|||||||
)
|
)
|
||||||
device_specs.append(nic_spec)
|
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
|
vm_spec.deviceChange = device_specs
|
||||||
|
|
||||||
# Create VM
|
# Create VM
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user