From e0e92d00995e68a3844ce9e1c71f37f0e7f3b656 Mon Sep 17 00:00:00 2001 From: Claudiu Belu Date: Tue, 14 Feb 2017 23:27:42 +0200 Subject: [PATCH] vmutils: Adds remove_all_pci_devices method When resizing an imported VM, nova does not specify which PCI devices needs to be attached and which needs to be detached. Thus, all the VM's PCI devices needs to be detached, and reattached according to the new PCI request. Change-Id: Ia7fbb2a9bc8f5d21bf5ec4a865fc7b1368ecf136 Partial-Bug: #1663238 (cherry picked from commit a1bc0e3aec4c11fe72804c1b718928cf6a65ef34) --- os_win/tests/unit/utils/compute/test_vmutils.py | 3 +++ .../tests/unit/utils/compute/test_vmutils10.py | 17 +++++++++++++++++ os_win/utils/compute/vmutils.py | 8 ++++++++ os_win/utils/compute/vmutils10.py | 15 +++++++++++++++ os_win/utils/jobutils.py | 7 +++++-- 5 files changed, 48 insertions(+), 2 deletions(-) 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):