diff --git a/os_win/tests/unit/utils/compute/test_vmutils.py b/os_win/tests/unit/utils/compute/test_vmutils.py index 0538cd08..c7fecdb1 100644 --- a/os_win/tests/unit/utils/compute/test_vmutils.py +++ b/os_win/tests/unit/utils/compute/test_vmutils.py @@ -1298,3 +1298,6 @@ class VMUtilsTestCase(test_base.OsWinBaseTestCase): self._vmutils.remove_pci_device, mock.sentinel.vm_name, mock.sentinel.vendor_id, mock.sentinel.product_id) + + def test_remove_all_pci_devices(self): + self._vmutils.remove_all_pci_devices(mock.sentinel.vm_name) diff --git a/os_win/tests/unit/utils/compute/test_vmutils10.py b/os_win/tests/unit/utils/compute/test_vmutils10.py index 20c8005d..a6096d14 100644 --- a/os_win/tests/unit/utils/compute/test_vmutils10.py +++ b/os_win/tests/unit/utils/compute/test_vmutils10.py @@ -319,3 +319,20 @@ class VMUtils10TestCase(test_base.OsWinBaseTestCase): vmsettings.InstanceID) self._vmutils._jobutils.remove_virt_resource.assert_called_once_with( pci_setting_data) + + @mock.patch.object(_wqlutils, 'get_element_associated_class') + @mock.patch.object(vmutils10.VMUtils10, '_lookup_vm_check') + def test_remove_all_pci_devices(self, mock_lookup_vm_check, + mock_get_element_associated_class): + vmsettings = mock_lookup_vm_check.return_value + + self._vmutils.remove_all_pci_devices(mock.sentinel.vm_name) + + mock_lookup_vm_check.assert_called_once_with(mock.sentinel.vm_name) + mock_get_element_associated_class.assert_called_once_with( + self._vmutils._conn, self._vmutils._PCI_EXPRESS_SETTING_DATA, + vmsettings.InstanceID) + mock_remove_multiple_virt_resource = ( + self._vmutils._jobutils.remove_multiple_virt_resources) + mock_remove_multiple_virt_resource.assert_called_once_with( + mock_get_element_associated_class.return_value) diff --git a/os_win/utils/compute/vmutils.py b/os_win/utils/compute/vmutils.py index 262fbfac..7608ea0d 100644 --- a/os_win/utils/compute/vmutils.py +++ b/os_win/utils/compute/vmutils.py @@ -1136,3 +1136,11 @@ class VMUtils(baseutils.BaseUtilsVirt): """ raise NotImplementedError(_('PCI passthrough is supported on ' 'Windows / Hyper-V Server 2016 or newer.')) + + def remove_all_pci_devices(self, vm_name): + """Removes all the PCI devices from the given VM. + + There are no PCI devices attached to Windows / Hyper-V Server 2012 R2 + or older VMs. + """ + pass diff --git a/os_win/utils/compute/vmutils10.py b/os_win/utils/compute/vmutils10.py index 51e11023..05f199cc 100644 --- a/os_win/utils/compute/vmutils10.py +++ b/os_win/utils/compute/vmutils10.py @@ -282,3 +282,18 @@ class VMUtils10(vmutils.VMUtils): "%(product_id)s is not attached to %(vm_name)s", {'vendor_id': vendor_id, 'product_id': product_id, 'vm_name': vm_name}) + + def remove_all_pci_devices(self, vm_name): + """Removes all the PCI devices from the given VM. + + :param vm_name: the name of the VM from which all the PCI devices will + be detached from. + """ + vmsettings = self._lookup_vm_check(vm_name) + + pci_sds = _wqlutils.get_element_associated_class( + self._conn, self._PCI_EXPRESS_SETTING_DATA, + vmsettings.InstanceID) + + if pci_sds: + self._jobutils.remove_multiple_virt_resources(pci_sds) diff --git a/os_win/utils/jobutils.py b/os_win/utils/jobutils.py index deb520a5..e0d3de3b 100644 --- a/os_win/utils/jobutils.py +++ b/os_win/utils/jobutils.py @@ -200,10 +200,13 @@ class JobUtils(baseutils.BaseUtilsVirt): ResourceSettings=[virt_resource.GetText_(1)]) self.check_ret_val(ret_val, job_path) - @_utils.retry_decorator(exceptions=exceptions.HyperVException) def remove_virt_resource(self, virt_resource): + self.remove_multiple_virt_resources([virt_resource]) + + @_utils.retry_decorator(exceptions=exceptions.HyperVException) + def remove_multiple_virt_resources(self, virt_resources): (job, ret_val) = self._vs_man_svc.RemoveResourceSettings( - ResourceSettings=[virt_resource.path_()]) + ResourceSettings=[r.path_() for r in virt_resources]) self.check_ret_val(ret_val, job) def add_virt_feature(self, virt_feature, parent):