def add_pci_device(self, vm, pci_device): """ Attaches PCI device to VM Args: vm (vim.VirtualMachine): VM instance pci_device (vim.vm.PciPassthroughInfo): PCI device to add """ host = vm.runtime.host.name logger.info( f"Adding PCI device with ID:{pci_device.pciDevice.id} on host {host} to {vm.name}" ) deviceId = hex(pci_device.pciDevice.deviceId % 2**16).lstrip("0x") backing = vim.VirtualPCIPassthroughDeviceBackingInfo( deviceId=deviceId, id=pci_device.pciDevice.id, systemId=pci_device.systemId, vendorId=pci_device.pciDevice.vendorId, deviceName=pci_device.pciDevice.deviceName, ) hba_object = vim.VirtualPCIPassthrough(key=-100, backing=backing) new_device_config = vim.VirtualDeviceConfigSpec(device=hba_object) new_device_config.operation = "add" vmConfigSpec = vim.vm.ConfigSpec() vmConfigSpec.memoryReservationLockedToMax = True vmConfigSpec.deviceChange = [new_device_config] WaitForTask(vm.ReconfigVM_Task(spec=vmConfigSpec))
def _add_pci_device_to_vm(self, vm_obj, pci_Passthrough_device_obj, pci_id): changed = False failed = False vm_current_pci_devices = self._get_the_pci_devices_in_the_vm(vm_obj) if self.params['force'] or pci_id not in vm_current_pci_devices: deviceid = hex(pci_Passthrough_device_obj.pciDevice.deviceId % 2**16).lstrip('0x') systemid = pci_Passthrough_device_obj.systemId backing = vim.VirtualPCIPassthroughDeviceBackingInfo(deviceId=deviceid, id=pci_id, systemId=systemid, vendorId=pci_Passthrough_device_obj.pciDevice.vendorId, deviceName=pci_Passthrough_device_obj.pciDevice.deviceName) hba_object = vim.VirtualPCIPassthrough(key=-100, backing=backing) new_device_config = vim.VirtualDeviceConfigSpec(device=hba_object) new_device_config.operation = "add" vmConfigSpec = vim.vm.ConfigSpec() vmConfigSpec.deviceChange = [new_device_config] vmConfigSpec.memoryReservationLockedToMax = True try: task = vm_obj.ReconfigVM_Task(spec=vmConfigSpec) wait_for_task(task) changed = True except Exception as exc: failed = True self.module.fail_json(msg="Failed to add Pci device" " '{}' to vm {}.".format(pci_id, vm_obj.name), detail=exc.msg) else: return changed, failed return changed, failed
def add_pci(self, pci, host_obj, vm_update, vm_status, mmio_size): """ Add a PCI device for a VM. If a PCI device has large BARs, it requires 64bit MMIO support and large enough MMIO mapping space. This method will add these two configurations by default and check uEFI installation. But haven't evaluated the impacts of adding these configurations for a PCI device which doesn't have large BARs. For more details, check the reference KB article. Args: pci (str): pci ID of the PCI device host_obj (vim.HostSystem): Host obj to locate the PCI device vm_update (ConfigVM): VM update obj vm_status (GetVM): VM status obj mmio_size (int): 64-bit MMIO space in GB Returns: list: a list of Task objects References: https://kb.vmware.com/s/article/2142307 """ self.logger.info("Adding PCI device {0} for {1}".format( pci, self.vm_obj.name)) extra_config_key1 = "pciPassthru.64bitMMIOSizeGB" extra_config_key2 = "pciPassthru.use64bitMMIO" if mmio_size is None: mmio_size = 256 tasks = [] pci_obj = GetHost(host_obj).pci_obj(pci) # Convert decimal to hex for the device ID of PCI device device_id = hex(pci_obj.deviceId % 2**16).lstrip("0x") if not vm_status.uefi(): self.logger.warning("VM {0} is not installed with UEFI. " "If PCI device has large BARs, " "UEFI installation is required.".format( self.vm_obj.name)) else: self.logger.info("Good. VM {0} has UEFI " "installation.".format(self.vm_obj.name)) sys_id = vm_status.pci_id_sys_id_passthru() backing = vim.VirtualPCIPassthroughDeviceBackingInfo( deviceId=device_id, id=pci_obj.id, systemId=sys_id[pci_obj.id], vendorId=pci_obj.vendorId, deviceName=pci_obj.deviceName, ) backing_obj = vim.VirtualPCIPassthrough(backing=backing) dev_config_spec = vim.VirtualDeviceConfigSpec(device=backing_obj) dev_config_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add config_spec = vim.vm.ConfigSpec() config_spec.deviceChange = [dev_config_spec] tasks.append(self.vm_obj.ReconfigVM_Task(spec=config_spec)) tasks.append(vm_update.add_extra(extra_config_key1, str(mmio_size))) tasks.append(vm_update.add_extra(extra_config_key2, "TRUE")) return tasks
def add_pci_nics(args, vm): pci_id_list = args.pci_nics.rstrip(',') pci_id_list = pci_id_list.split(',') pci_id_list.sort() if vm.runtime.powerState == vim.VirtualMachinePowerState.poweredOn: print "VM:%s is powered ON. Cannot do hot pci add now. Shutting it down" % ( args.vm_name) poweroffvm(vm) for pci_id in pci_id_list: device_config_list = [] found = False for device_list in vm.config.hardware.device: if (isinstance(device_list, vim.vm.device.VirtualPCIPassthrough)) == True \ and device_list.backing.id == pci_id: print "pci_device already present! Not adding the pci device." found = True break if found == True: continue pci_passthroughs = vm.environmentBrowser.QueryConfigTarget( host=None).pciPassthrough for pci_entry in pci_passthroughs: if pci_entry.pciDevice.id == pci_id: found = True print "Found the pci device %s in the host" % (pci_id) break if found == False: print "Did not find the pci passthrough device %s on the host" % ( pci_id) exit(1) print "Adding PCI device to Contrail VM: %s" % (args.vm_name) deviceId = hex(pci_entry.pciDevice.deviceId % 2**16).lstrip('0x') backing = vim.VirtualPCIPassthroughDeviceBackingInfo( deviceId=deviceId, id=pci_entry.pciDevice.id, systemId=pci_entry.systemId, vendorId=pci_entry.pciDevice.vendorId, deviceName=pci_entry.pciDevice.deviceName) hba_object = vim.VirtualPCIPassthrough(key=-100, backing=backing) new_device_config = vim.VirtualDeviceConfigSpec(device=hba_object) new_device_config.operation = "add" new_device_config.device.connectable = vim.vm.device.VirtualDevice.ConnectInfo( ) new_device_config.device.connectable.startConnected = True device_config_list.append(new_device_config) vm_spec = vim.vm.ConfigSpec() vm_spec.deviceChange = device_config_list task = vm.ReconfigVM_Task(spec=vm_spec) wait_for_task(task)
def add_sriov_adapter(self, network_obj, pf_obj, dvs_obj, allow_guest_os_mtu_change=False): """ Add a network adapter with SR-IOV adapter type for a VM Adding SR-IOV adapter requires a back-up physical adapter. Args: dvs_obj (vim.dvs.VmwareDistributedVirtualSwitch): distributed virtual switch object type network_obj (vim.Network): network object accessible by either hosts or virtual machines pf_obj (vim.host.PciDevice): a PCI object type describes info about of a single PCI device for backing up SR-IOV configuration allow_guest_os_mtu_change (bool): Whether to allow guest OS MTU change Returns: Task References: pyvmomi/docs/vim/Network.rst pyvmomi/docs/vim/vm/device/VirtualDeviceSpec.rst pyvmomi/docs/vim/host/PciDevice.rst """ nic_spec = vim.vm.device.VirtualDeviceSpec() nic_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add nic_spec.device = vim.vm.device.VirtualSriovEthernetCard() nic_spec.device.wakeOnLanEnabled = True nic_spec.device.addressType = "assigned" nic_spec.device.deviceInfo = vim.Description() if dvs_obj: nic_spec.device.backing = (vim.vm.device.VirtualEthernetCard. DistributedVirtualPortBackingInfo()) nic_spec.device.backing.port = vim.dvs.PortConnection( switchUuid=dvs_obj.summary.uuid, portgroupKey=network_obj.config.key) else: nic_spec.device.backing = ( vim.vm.device.VirtualEthernetCard.NetworkBackingInfo()) nic_spec.device.backing.network = network_obj nic_spec.device.backing.deviceName = network_obj.name nic_spec.device.backing.useAutoDetect = False nic_spec.device.connectable = vim.vm.device.VirtualDevice.ConnectInfo() nic_spec.device.connectable.startConnected = True nic_spec.device.connectable.connected = True nic_spec.device.connectable.allowGuestControl = True nic_spec.device.sriovBacking = ( vim.vm.device.VirtualSriovEthernetCard.SriovBackingInfo()) nic_spec.device.allowGuestOSMtuChange = allow_guest_os_mtu_change # convert decimal to hex for the device ID of physical adapter device_id = hex(pf_obj.deviceId % 2**16).lstrip("0x") sys_id = GetVM(self.vm_obj).pci_id_sys_id_sriov() backing = vim.VirtualPCIPassthroughDeviceBackingInfo( deviceId=device_id, id=pf_obj.id, systemId=sys_id[pf_obj.id], vendorId=pf_obj.vendorId, deviceName=pf_obj.deviceName, ) nic_spec.device.sriovBacking.physicalFunctionBacking = backing config_spec = vim.vm.ConfigSpec() config_spec.deviceChange = [nic_spec] return self.vm_obj.ReconfigVM_Task(spec=config_spec)