Jelajahi Sumber

Fix Windows OSMount when migrating read-only disks.

This patch makes sure that the read-only and nodefaultdriveletter flags get
disabled before bringing the disks online, thus making sure that disks are
always initialized before looking for the root partition.
Daniel Vincze 8 bulan lalu
induk
melakukan
0cde5ab356

+ 10 - 7
coriolis/osmorphing/osmount/windows.py

@@ -195,7 +195,6 @@ class WindowsMountTools(base.BaseOSMountTools):
         self._bring_disks_online(disk_nums=disk_nums)
 
     def _set_volumes_drive_letter(self):
-        disk_nums = []
         partitions = self._conn.exec_ps_command(
             'Get-Partition | Where-Object { $_.Type -eq "Basic" -and '
             '$_.NoDefaultDriveLetter -eq $True } | Select-Object -Property '
@@ -211,16 +210,20 @@ class WindowsMountTools(base.BaseOSMountTools):
                 if not disk_num.isnumeric() or not part_num.isnumeric():
                     LOG.debug(f"Skipping partition line: {part_line}")
                     continue
-                self._conn.exec_ps_command(
-                    f'Set-Partition -NoDefaultDriveLetter $False -DiskNumber '
-                    f'{disk_num} -PartitionNumber {part_num}')
-                disk_nums.append(disk_num)
-            self._rebring_disks_online(disk_nums=disk_nums)
+                try:
+                    self._conn.exec_ps_command(
+                        f'Set-Partition -NoDefaultDriveLetter $False '
+                        f'-DiskNumber {disk_num} -PartitionNumber {part_num}')
+                except exception.CoriolisException:
+                    LOG.warning(
+                        f"Failed setting default drive letter on partition "
+                        f"number '{part_num}' of disk number '{disk_num}'. "
+                        f"Error was: {utils.get_exception_details()}")
 
     def mount_os(self):
-        self._bring_disks_online()
         self._set_basic_disks_rw_mode()
         self._set_volumes_drive_letter()
+        self._bring_disks_online()
         fs_roots = utils.retry_on_error(sleep_seconds=5)(self._get_fs_roots)(
             fail_if_empty=True)
         system_drive = self._get_system_drive()

+ 9 - 3
coriolis/tests/osmorphing/osmount/test_windows.py

@@ -4,6 +4,7 @@
 import logging
 from unittest import mock
 
+from coriolis import exception
 from coriolis.osmorphing.osmount import windows
 from coriolis.tests import test_base
 
@@ -271,8 +272,7 @@ class WindowsMountToolsTestCase(test_base.CoriolisBaseTestCase):
         bring_disks_offline_mock.assert_called()
         bring_disks_online_mock.assert_called()
 
-    @mock.patch.object(windows.WindowsMountTools, '_rebring_disks_online')
-    def test__set_volumes_drive_letter(self, rebring_disks_mock):
+    def test__set_volumes_drive_letter(self):
         self.tools._conn.exec_ps_command.return_value = GET_PARTITION_OUTPUT
         result = self.tools._set_volumes_drive_letter()
         self.assertIsNone(result)
@@ -289,7 +289,13 @@ class WindowsMountToolsTestCase(test_base.CoriolisBaseTestCase):
                 'Set-Partition -NoDefaultDriveLetter $False -DiskNumber 3 '
                 '-PartitionNumber 4'),
         ])
-        rebring_disks_mock.assert_called_once_with(disk_nums=['2', '3'])
+
+    def test__set_volumes_drive_letter_exception(self):
+        self.tools._conn.exec_ps_command.side_effect = [
+            GET_PARTITION_OUTPUT, None, exception.CoriolisException]
+        with self.assertLogs(
+                'coriolis.osmorphing.osmount.windows', logging.WARNING):
+            self.tools._set_volumes_drive_letter()
 
     @mock.patch.object(windows.WindowsMountTools, '_get_system_drive')
     @mock.patch.object(windows.WindowsMountTools, '_get_fs_roots')