diff --git a/os_win/tests/unit/utils/compute/test_vmutils.py b/os_win/tests/unit/utils/compute/test_vmutils.py index 4cd8e10a..1dcebaae 100644 --- a/os_win/tests/unit/utils/compute/test_vmutils.py +++ b/os_win/tests/unit/utils/compute/test_vmutils.py @@ -865,20 +865,26 @@ class VMUtilsTestCase(test_base.OsWinBaseTestCase): mock_disk = self._prepare_mock_disk() self._vmutils.detach_vm_disk(self._FAKE_VM_NAME, - self._FAKE_HOST_RESOURCE) + self._FAKE_HOST_RESOURCE, + serial=mock.sentinel.serial) self._vmutils._jobutils.remove_virt_resource.assert_called_once_with( mock_disk) - def test_get_mounted_disk_resource_from_path(self): - mock_disk_1 = mock.MagicMock() - mock_disk_2 = mock.MagicMock() - mock_disk_2.HostResource = [self._FAKE_MOUNTED_DISK_PATH] - self._vmutils._conn.query.return_value = [mock_disk_1, mock_disk_2] + @ddt.data(None, mock.sentinel.serial) + def test_get_mounted_disk_resource_from_path(self, serial): + mock_disk = mock.MagicMock() + + if serial: + self._vmutils._conn.query.return_value = [mock_disk] + else: + mock_disk.HostResource = [self._FAKE_MOUNTED_DISK_PATH] + self._vmutils._conn.query.return_value = [ + mock.MagicMock(), mock_disk] physical_disk = self._vmutils._get_mounted_disk_resource_from_path( - self._FAKE_MOUNTED_DISK_PATH, True) + self._FAKE_MOUNTED_DISK_PATH, True, serial=serial) - self.assertEqual(mock_disk_2, physical_disk) + self.assertEqual(mock_disk, physical_disk) def test_get_controller_volume_paths(self): self._prepare_mock_disk() diff --git a/os_win/utils/compute/vmutils.py b/os_win/utils/compute/vmutils.py index 9935f1f9..fb09e2aa 100644 --- a/os_win/utils/compute/vmutils.py +++ b/os_win/utils/compute/vmutils.py @@ -784,10 +784,11 @@ class VMUtils(baseutils.BaseUtilsVirt): is_physical) return disk_resource is not None - def detach_vm_disk(self, vm_name, disk_path, is_physical=True): + def detach_vm_disk(self, vm_name, disk_path=None, is_physical=True, + serial=None): # TODO(claudiub): remove vm_name argument, no longer used. - disk_resource = self._get_mounted_disk_resource_from_path(disk_path, - is_physical) + disk_resource = self._get_mounted_disk_resource_from_path( + disk_path, is_physical, serial=serial) if disk_resource: parent = self._conn.query("SELECT * FROM " @@ -799,7 +800,8 @@ class VMUtils(baseutils.BaseUtilsVirt): if not is_physical: self._jobutils.remove_virt_resource(parent) - def _get_mounted_disk_resource_from_path(self, disk_path, is_physical): + def _get_mounted_disk_resource_from_path(self, disk_path, is_physical, + serial=None): if is_physical: class_name = self._RESOURCE_ALLOC_SETTING_DATA_CLASS else: @@ -814,9 +816,15 @@ class VMUtils(baseutils.BaseUtilsVirt): 'res_sub_type_virt': self._HARD_DISK_RES_SUB_TYPE, 'res_sub_type_dvd': self._DVD_DISK_RES_SUB_TYPE}) + if serial: + query += " AND ElementName='%s'" % serial + disk_resources = self._compat_conn.query(query) for disk_resource in disk_resources: + if serial: + return disk_resource + if disk_resource.HostResource: if disk_resource.HostResource[0].lower() == disk_path.lower(): return disk_resource diff --git a/releasenotes/notes/detach_disk_by_tag-9d8d5b04f91fedd2.yaml b/releasenotes/notes/detach_disk_by_tag-9d8d5b04f91fedd2.yaml new file mode 100644 index 00000000..a37c2980 --- /dev/null +++ b/releasenotes/notes/detach_disk_by_tag-9d8d5b04f91fedd2.yaml @@ -0,0 +1,7 @@ +--- +features: + - | + os-win now allows detaching VM disks by their unique tag. This considerably + reduces the time needed for this operation in case of passthrough disks + as the disk paths no longer have to be retrieved (which can be really time + consuming, especially under high load).