Ejemplo n.º 1
0
    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))
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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)
Ejemplo n.º 5
0
    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)