Creating a Virtual
Machine
This section shows how to create a
VirtualMachine object, which is complicated but necessary so you can restore
data into it. Before creating this object, you must create a
VirtualMachineConfigSpec
describing the virtual machine and all of its supporting virtual devices.
Almost all the required information is available from the virtual machine
property
config.hardware.device
, which is a
table containing the device configuration information. The relationships
between devices are described by the value
key
, which is a unique identifier
for the device. In turn, each device has a
controllerKey
, which is the key
identifier of the controller where the device is connected. Use negative
integers as temporary key values in the
VirtualMachineConfigSpec
to
guarantee that temporary key numbers do not conflict with real key numbers when
they are assigned by the server. When associating virtual devices with default
devices, the
controllerKey
property should be
reset with the key property of the controller. Below are the settings for a
sample
VirtualMachineConfigSpec
used to
create a virtual machine.
// beginning of VirtualMachineConfigSpec, ends several pages later { dynamicType = <unset>, changeVersion = <unset>, //This is the display name of the VM name = “My New VM“, version = "vmx-04", uuid = <unset>, instanceUuid = <unset>, locationId = <unset>, // This is advisory, the disk determines the O/S guestId = "winNetStandardGuest", alternateGuestName = "Microsoft Windows Server 2008, Enterprise Edition", annotation = <unset>, files = (vim.vm.FileInfo) { dynamicType = <unset>, vmPathName = "[plat004-local]", snapshotDirectory = "[plat004-local]", suspendDirectory = <unset>, logDirectory = <unset>, }, tools = (vim.vm.ToolsConfigInfo) { dynamicType = <unset>, toolsVersion = <unset>, afterPowerOn = true, afterResume = true, beforeGuestStandby = true, beforeGuestShutdown = true, beforeGuestReboot = true, toolsUpgradePolicy = <unset>, pendingCustomization = <unset>, syncTimeWithHost = <unset>, }, flags = (vim.vm.FlagInfo) { dynamicType = <unset>, disableAcceleration = <unset>, enableLogging = <unset>, useToe = <unset>, runWithDebugInfo = <unset>, monitorType = <unset>, htSharing = <unset>, snapshotDisabled = <unset>, snapshotLocked = <unset>, diskUuidEnabled = <unset>, virtualMmuUsage = <unset>, snapshotPowerOffBehavior = "powerOff", recordReplayEnabled = <unset>, }, consolePreferences = (vim.vm.ConsolePreferences) null, powerOpInfo = (vim.vm.DefaultPowerOpInfo) { dynamicType = <unset>, powerOffType = "preset", suspendType = "preset", resetType = "preset", defaultPowerOffType = <unset>, defaultSuspendType = <unset>, defaultResetType = <unset>, standbyAction = "powerOnSuspend", }, // the number of CPUs numCPUs = 1, // the number of memory megabytes memoryMB = 256, memoryHotAddEnabled = <unset>, cpuHotAddEnabled = <unset>, cpuHotRemoveEnabled = <unset>, deviceChange = (vim.vm.device.VirtualDeviceSpec) [ (vim.vm.device.VirtualDeviceSpec) { dynamicType = <unset>, operation = "add", fileOperation = <unset>, // CDROM device = (vim.vm.device.VirtualCdrom) { dynamicType = <unset>, // key number of CDROM key = -42, deviceInfo = (vim.Description) null, backing = (vim.vm.device.VirtualCdrom.RemotePassthroughBackingInfo) { dynamicType = <unset>, deviceName = "", useAutoDetect = <unset>, exclusive = false, }, connectable = (vim.vm.device.VirtualDevice.ConnectInfo) { dynamicType = <unset>, startConnected = false, allowGuestControl = true, connected = false, }, // connects to this controller controllerKey = 200, unitNumber = 0, }, }, (vim.vm.device.VirtualDeviceSpec) { dynamicType = <unset>, operation = "add", fileOperation = <unset>, // SCSI controller device = (vim.vm.device.VirtualLsiLogicController) { dynamicType = <unset>, // key number of SCSI controller key = -44, deviceInfo = (vim.Description) null, backing = (vim.vm.device.VirtualDevice.BackingInfo) null, connectable = (vim.vm.device.VirtualDevice.ConnectInfo) null, controllerKey = <unset>, unitNumber = <unset>, busNumber = 0, hotAddRemove = <unset>, sharedBus = "noSharing", scsiCtlrUnitNumber = <unset>, }, }, (vim.vm.device.VirtualDeviceSpec) { dynamicType = <unset>, operation = "add", fileOperation = <unset>, // Network controller device = (vim.vm.device.VirtualPCNet32) { dynamicType = <unset>, // key number of Network controller key = -48, deviceInfo = (vim.Description) null, backing = (vim.vm.device.VirtualEthernetCard.NetworkBackingInfo) { dynamicType = <unset>, deviceName = "Virtual Machine Network", useAutoDetect = <unset>, network = <unset>, inPassthroughMode = <unset>, }, connectable = (vim.vm.device.VirtualDevice.ConnectInfo) { dynamicType = <unset>, startConnected = true, allowGuestControl = true, connected = true, }, controllerKey = <unset>, unitNumber = <unset>, addressType = "generated", macAddress = <unset>, wakeOnLanEnabled = true, }, }, (vim.vm.device.VirtualDeviceSpec) { dynamicType = <unset>, operation = "add", fileOperation = "create", // SCSI disk one device = (vim.vm.device.VirtualDisk) { dynamicType = <unset>, // key number for SCSI disk one key = -1000000, deviceInfo = (vim.Description) null, backing = (vim.vm.device.VirtualDisk.FlatVer2BackingInfo) { dynamicType = <unset>, fileName = "", datastore = <unset>, diskMode = "persistent", split = false, writeThrough = false, thinProvisioned = <unset>, eagerlyScrub = <unset>, uuid = <unset>, contentId = <unset>, changeId = <unset>, parent = (vim.vm.device.VirtualDisk.FlatVer2BackingInfo) null, }, connectable = (vim.vm.device.VirtualDevice.ConnectInfo) { dynamicType = <unset>, startConnected = true, allowGuestControl = false, connected = true, }, // controller for SCSI disk one controllerKey = -44, unitNumber = 0, // size in MB SCSI disk one capacityInKB = 524288, committedSpace = <unset>, shares = (vim.SharesInfo) null, }, }, (vim.vm.device.VirtualDeviceSpec) { dynamicType = <unset>, operation = "add", fileOperation = "create", // SCSI disk two device = (vim.vm.device.VirtualDisk) { dynamicType = <unset>, // key number of SCSI disk two key = -100, deviceInfo = (vim.Description) null, backing = (vim.vm.device.VirtualDisk.FlatVer2BackingInfo) { dynamicType = <unset>, fileName = "", datastore = <unset>, diskMode = "persistent", split = false, writeThrough = false, thinProvisioned = <unset>, eagerlyScrub = <unset>, uuid = <unset>, contentId = <unset>, changeId = <unset>, parent = (vim.vm.device.VirtualDisk.FlatVer2BackingInfo) null, }, connectable = (vim.vm.device.VirtualDevice.ConnectInfo) { dynamicType = <unset>, startConnected = true, allowGuestControl = false, connected = true, }, // controller for SCSI disk two controllerKey = -44, unitNumber = 1, // size in MB SCSI disk two capacityInKB = 131072, committedSpace = <unset>, shares = (vim.SharesInfo) null, }, } }, cpuAllocation = (vim.ResourceAllocationInfo) { dynamicType = <unset>, reservation = 0, expandableReservation = <unset>, limit = <unset>, shares = (vim.SharesInfo) { dynamicType = <unset>, shares = 100, level = "normal", }, overheadLimit = <unset>, }, memoryAllocation = (vim.ResourceAllocationInfo) { dynamicType = <unset>, reservation = 0, expandableReservation = <unset>, limit = <unset>, shares = (vim.SharesInfo) { dynamicType = <unset>, shares = 100, level = "normal", }, overheadLimit = <unset>, }, cpuAffinity = (vim.vm.AffinityInfo) null, memoryAffinity = (vim.vm.AffinityInfo) null, networkShaper = (vim.vm.NetworkShaperInfo) null, swapPlacement = <unset>, swapDirectory = <unset>, preserveSwapOnPowerOff = <unset>, bootOptions = (vim.vm.BootOptions) null, appliance = (vim.vService.ConfigSpec) null, ftInfo = (vim.vm.FaultToleranceConfigInfo) null, applianceConfigRemoved = <unset>, vAssertsEnabled = <unset>, changeTrackingEnabled = <unset>, } // end of VirtualMachineConfigSpec
The information above is quite complex, but much
of the input consists of defaulted values that are assigned by the system. The
remainder of the supplied information can be extracted from the output of the
config.hardware.device
table
returned from
PropertyCollector
. Borrowing
heavily from an SDK code example, the following code sets up the configuration
specification:
// Duplicate virtual machine configuration VirtualMachineConfigSpec configSpec = new VirtualMachineConfigSpec(); // Set the VM values configSpec.setName("My New VM"); configSpec.setVersion("vmx-04"); configSpec.setGuestId("winNetStandardGuest"); configSpec.setNumCPUs(1); configSpec.setMemoryMB(256); // Set up file storage info VirtualMachineFileInfo vmfi = new VirtualMachineFileInfo(); vmfi.setVmPathName("[plat004-local]"); configSpec.setFiles(vmfi); vmfi.setSnapshotDirectory("[plat004-local]"); // Set up tools config info ToolsConfigInfo tools = new ToolsConfigInfo(); configSpec.setTools(tools); tools.setAfterPowerOn(new Boolean(true)); tools.setAfterResume(new Boolean(true)); tools.setBeforeGuestStandby(new Boolean(true)); tools.setBeforeGuestShutdown(new Boolean(true)); tools.setBeforeGuestReboot(new Boolean(true)); // Set flags VirtualMachineFlagInfo flags = new VirtualMachineFlagInfo(); configSpec.setFlags(flags); flags.setSnapshotPowerOffBehavior("powerOff"); // Set power op info VirtualMachineDefaultPowerOpInfo powerInfo = new VirtualMachineDefaultPowerOpInfo(); configSpec.setPowerOpInfo(powerInfo); powerInfo.setPowerOffType("preset"); powerInfo.setSuspendType("preset"); powerInfo.setResetType("preset"); powerInfo.setStandbyAction("powerOnSuspend"); // Now add in the devices VirtualDeviceConfigSpec[] deviceConfigSpec = new VirtualDeviceConfigSpec [5]; configSpec.setDeviceChange(deviceConfigSpec); // Formulate the CDROM deviceConfigSpec[0].setOperation(VirtualDeviceConfigSpecOperation.add); VirtualCdrom cdrom = new VirtualCdrom(); VirtualCdromIsoBackingInfo cdDeviceBacking = new VirtualCdromRemotePassthroughBackingInfo(); cdDeviceBacking.setDatastore(datastoreRef); cdrom.setBacking(cdDeviceBacking); cdrom.setKey(-42); cdrom.setControllerKey(new Integer(-200)); // Older Java required type for optional properties cdrom.setUnitNumber(new Integer(0)); deviceConfigSpec[0].setDevice(cdrom); // Formulate the SCSI controller deviceConfigSpec[1].setOperation(VirtualDeviceConfigSpecOperation.add); VirtualLsiLogicController scsiCtrl = new VirtualLsiLogicController(); scsiCtrl.setBusNumber(0); deviceConfigSpec[1].setDevice(scsiCtrl); scsiCtrl.setKey(-44); scsiCtrl.setSharedBus(VirtualSCSISharing.noSharing); // Formulate SCSI disk one deviceConfigSpec[2].setFileOperation(VirtualDeviceConfigSpecFileOperation.create); deviceConfigSpec[2].setOperation(VirtualDeviceConfigSpecOperation.add); VirtualDisk disk = new VirtualDisk(); VirtualDiskFlatVer2BackingInfo diskfileBacking = new VirtualDiskFlatVer2BackingInfo(); diskfileBacking.setDatastore(datastoreRef); diskfileBacking.setFileName(volumeName); diskfileBacking.setDiskMode("persistent"); diskfileBacking.setSplit(new Boolean(false)); diskfileBacking.setWriteThrough(new Boolean(false)); disk.setKey(-1000000); disk.setControllerKey(new Integer(-44)); disk.setUnitNumber(new Integer(0)); disk.setBacking(diskfileBacking); disk.setCapacityInKB(524288); deviceConfigSpec[2].setDevice(disk); // Formulate SCSI disk two deviceConfigSpec[3].setFileOperation(VirtualDeviceConfigSpecFileOperation.create); deviceConfigSpec[3].setOperation(VirtualDeviceConfigSpecOperation.add); VirtualDisk disk2 = new VirtualDisk(); VirtualDiskFlatVer2BackingInfo diskfileBacking2 = new VirtualDiskFlatVer2BackingInfo(); diskfileBacking2.setDatastore(datastoreRef); diskfileBacking2.setFileName(volumeName); diskfileBacking2.setDiskMode("persistent"); diskfileBacking2.setSplit(new Boolean(false)); diskfileBacking2.setWriteThrough(new Boolean(false)); disk2.setKey(-100); disk2.setControllerKey(new Integer(-44)); disk2.setUnitNumber(new Integer(1)); disk2.setBacking(diskfileBacking2); disk2.setCapacityInKB(131072); deviceConfigSpec[3].setDevice(disk2); // Finally, formulate the NIC deviceConfigSpec[4].setOperation(VirtualDeviceConfigSpecOperation.add); com.VMware.vim.VirtualEthernetCard nic = new VirtualPCNet32(); VirtualEthernetCardNetworkBackingInfo nicBacking = new VirtualEthernetCardNetworkBackingInfo(); nicBacking.setNetwork(networkRef); nicBacking.setDeviceName(networkName); nic.setAddressType("generated"); nic.setBacking(nicBacking); nic.setKey(-48); deviceConfigSpec[4].setDevice(nic); // Now that it is all put together, create the virtual machine. // Note that folderMo, resourcePool, and hostMo, are moRefs to // the Folder, ResourcePool, and Host where the VM is to be created. ManagedObjectReference taskMoRef = serviceConnection.getService().createVM_Task(folderMo, configSpec, resourcePool, hostMo);