diff options
-rw-r--r-- | ironic_python_agent/efi_utils.py | 10 | ||||
-rw-r--r-- | ironic_python_agent/partition_utils.py | 3 | ||||
-rw-r--r-- | ironic_python_agent/tests/unit/extensions/test_image.py | 12 | ||||
-rw-r--r-- | ironic_python_agent/tests/unit/test_hardware.py | 84 | ||||
-rw-r--r-- | ironic_python_agent/tests/unit/test_partition_utils.py | 29 | ||||
-rw-r--r-- | ironic_python_agent/tests/unit/test_utils.py | 12 | ||||
-rw-r--r-- | ironic_python_agent/utils.py | 4 | ||||
-rw-r--r-- | releasenotes/notes/detect-endianness-f53a6c4571aba3fe.yaml | 6 | ||||
-rw-r--r-- | releasenotes/notes/rescan-device-after-mkfs-3f9d52a2e3b6fff3.yaml | 5 |
9 files changed, 100 insertions, 65 deletions
diff --git a/ironic_python_agent/efi_utils.py b/ironic_python_agent/efi_utils.py index ea7a9474..c4e9dcc7 100644 --- a/ironic_python_agent/efi_utils.py +++ b/ironic_python_agent/efi_utils.py @@ -297,8 +297,14 @@ def _run_efibootmgr(valid_efi_bootloaders, device, efi_partition, 'File: %s', v_bl) # These files are always UTF-16 encoded, sometimes have a header. # Positive bonus is python silently drops the FEFF header. - with open(mount_point + '/' + v_bl, 'r', encoding='utf-16') as csv: - contents = str(csv.read()) + try: + with open(mount_point + '/' + v_bl, 'r', + encoding='utf-16') as csv: + contents = str(csv.read()) + except UnicodeError: + with open(mount_point + '/' + v_bl, 'r', + encoding='utf-16-le') as csv: + contents = str(csv.read()) csv_contents = contents.split(',', maxsplit=3) csv_filename = v_bl.split('/')[-1] v_efi_bl_path = v_bl.replace(csv_filename, str(csv_contents[0])) diff --git a/ironic_python_agent/partition_utils.py b/ironic_python_agent/partition_utils.py index 18b4cfdb..42b90445 100644 --- a/ironic_python_agent/partition_utils.py +++ b/ironic_python_agent/partition_utils.py @@ -316,6 +316,9 @@ def work_on_disk(dev, root_mb, swap_mb, ephemeral_mb, ephemeral_format, "formatted for node %(node)s", {'ephemeral': ephemeral_part, 'node': node_uuid}) + # Rescan device to get current status (e.g. reflect modification of mkfs) + disk_utils.trigger_device_rescan(dev) + uuids_to_return = { 'root uuid': root_part, 'efi system partition uuid': part_dict.get('efi system partition'), diff --git a/ironic_python_agent/tests/unit/extensions/test_image.py b/ironic_python_agent/tests/unit/extensions/test_image.py index fe24a79f..00aaf706 100644 --- a/ironic_python_agent/tests/unit/extensions/test_image.py +++ b/ironic_python_agent/tests/unit/extensions/test_image.py @@ -234,7 +234,7 @@ class TestImageExtension(base.IronicAgentTest): ('', ''), ('', '')]) expected = [mock.call('efibootmgr', '--version'), - mock.call('partx', '-a', '/dev/fake', attempts=3, + mock.call('partx', '-av', '/dev/fake', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('mount', self.fake_efi_system_part, @@ -281,7 +281,7 @@ class TestImageExtension(base.IronicAgentTest): ('', ''), ('', '')]) expected = [mock.call('efibootmgr', '--version'), - mock.call('partx', '-a', '/dev/fake', attempts=3, + mock.call('partx', '-av', '/dev/fake', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('mount', self.fake_efi_system_part, @@ -337,7 +337,7 @@ Boot0002 VENDMAGIC FvFile(9f3c6294-bf9b-4208-9808-be45dfc34b51) ('', ''), ('', '')]) expected = [mock.call('efibootmgr', '--version'), - mock.call('partx', '-a', '/dev/fake', attempts=3, + mock.call('partx', '-av', '/dev/fake', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('mount', self.fake_efi_system_part, @@ -398,7 +398,7 @@ Boot0004* ironic1 HD(1,GPT,55db8d03-c8f6-4a5b-9155-790dddc348fa,0x800,0x640 ('', ''), ('', ''), ('', ''), ('', '')]) expected = [mock.call('efibootmgr', '--version'), - mock.call('partx', '-a', '/dev/fake', attempts=3, + mock.call('partx', '-av', '/dev/fake', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('mount', self.fake_efi_system_part, @@ -450,7 +450,7 @@ Boot0004* ironic1 HD(1,GPT,55db8d03-c8f6-4a5b-9155-790dddc348fa,0x800,0x640 ('', '')]) expected = [mock.call('efibootmgr', '--version'), - mock.call('partx', '-a', '/dev/fake', attempts=3, + mock.call('partx', '-av', '/dev/fake', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('mount', self.fake_efi_system_part, @@ -1741,7 +1741,7 @@ Boot0004* ironic1 HD(1,GPT,55db8d03-c8f6-4a5b-9155-790dddc348fa,0x800,0x640 efi_system_part_uuid=self.fake_efi_system_part_uuid, target_boot_mode='uefi') - expected = [mock.call('partx', '-a', '/dev/fake', attempts=3, + expected = [mock.call('partx', '-av', '/dev/fake', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('mount', '/dev/fake2', self.fake_dir), diff --git a/ironic_python_agent/tests/unit/test_hardware.py b/ironic_python_agent/tests/unit/test_hardware.py index 8a05f35b..60820727 100644 --- a/ironic_python_agent/tests/unit/test_hardware.py +++ b/ironic_python_agent/tests/unit/test_hardware.py @@ -2570,22 +2570,22 @@ class TestGenericHardwareManager(base.IronicAgentTest): mock.call('sgdisk', '-F', '/dev/sdb'), mock.call('parted', '/dev/sda', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '42s', '10GiB'), - mock.call('partx', '-a', '/dev/sda', attempts=3, + mock.call('partx', '-av', '/dev/sda', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sdb', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '42s', '10GiB'), - mock.call('partx', '-a', '/dev/sdb', attempts=3, + mock.call('partx', '-av', '/dev/sdb', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sda', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '10GiB', '-1'), - mock.call('partx', '-a', '/dev/sda', attempts=3, + mock.call('partx', '-av', '/dev/sda', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sdb', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '10GiB', '-1'), - mock.call('partx', '-a', '/dev/sdb', attempts=3, + mock.call('partx', '-av', '/dev/sdb', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('mdadm', '--create', '/dev/md0', '--force', '--run', @@ -2665,32 +2665,32 @@ class TestGenericHardwareManager(base.IronicAgentTest): mock.call('sgdisk', '-F', '/dev/sdc'), mock.call('parted', '/dev/sda', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '42s', '10GiB'), - mock.call('partx', '-a', '/dev/sda', attempts=3, + mock.call('partx', '-av', '/dev/sda', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sdb', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '42s', '10GiB'), - mock.call('partx', '-a', '/dev/sdb', attempts=3, + mock.call('partx', '-av', '/dev/sdb', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sdc', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '42s', '10GiB'), - mock.call('partx', '-a', '/dev/sdc', attempts=3, + mock.call('partx', '-av', '/dev/sdc', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sda', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '10GiB', '-1'), - mock.call('partx', '-a', '/dev/sda', attempts=3, + mock.call('partx', '-av', '/dev/sda', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sdb', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '10GiB', '-1'), - mock.call('partx', '-a', '/dev/sdb', attempts=3, + mock.call('partx', '-av', '/dev/sdb', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sdc', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '10GiB', '-1'), - mock.call('partx', '-a', '/dev/sdc', attempts=3, + mock.call('partx', '-av', '/dev/sdc', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('mdadm', '--create', '/dev/md0', '--force', '--run', @@ -2771,42 +2771,42 @@ class TestGenericHardwareManager(base.IronicAgentTest): mock.call('sgdisk', '-F', '/dev/sdd'), mock.call('parted', '/dev/sda', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '42s', '10GiB'), - mock.call('partx', '-a', '/dev/sda', attempts=3, + mock.call('partx', '-av', '/dev/sda', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sdb', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '42s', '10GiB'), - mock.call('partx', '-a', '/dev/sdb', attempts=3, + mock.call('partx', '-av', '/dev/sdb', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sdc', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '42s', '10GiB'), - mock.call('partx', '-a', '/dev/sdc', attempts=3, + mock.call('partx', '-av', '/dev/sdc', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sdd', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '42s', '10GiB'), - mock.call('partx', '-a', '/dev/sdd', attempts=3, + mock.call('partx', '-av', '/dev/sdd', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sda', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '10GiB', '-1'), - mock.call('partx', '-a', '/dev/sda', attempts=3, + mock.call('partx', '-av', '/dev/sda', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sdb', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '10GiB', '-1'), - mock.call('partx', '-a', '/dev/sdb', attempts=3, + mock.call('partx', '-av', '/dev/sdb', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sdc', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '10GiB', '-1'), - mock.call('partx', '-a', '/dev/sdc', attempts=3, + mock.call('partx', '-av', '/dev/sdc', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sdd', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '10GiB', '-1'), - mock.call('partx', '-a', '/dev/sdd', attempts=3, + mock.call('partx', '-av', '/dev/sdd', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('mdadm', '--create', '/dev/md0', '--force', '--run', @@ -2872,22 +2872,22 @@ class TestGenericHardwareManager(base.IronicAgentTest): mock.call('parted', '/dev/sdb', '-s', '--', 'mklabel', 'gpt'), mock.call('parted', '/dev/sda', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '551MiB', '10GiB'), - mock.call('partx', '-a', '/dev/sda', attempts=3, + mock.call('partx', '-av', '/dev/sda', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sdb', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '551MiB', '10GiB'), - mock.call('partx', '-a', '/dev/sdb', attempts=3, + mock.call('partx', '-av', '/dev/sdb', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sda', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '10GiB', '-1'), - mock.call('partx', '-a', '/dev/sda', attempts=3, + mock.call('partx', '-av', '/dev/sda', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sdb', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '10GiB', '-1'), - mock.call('partx', '-a', '/dev/sdb', attempts=3, + mock.call('partx', '-av', '/dev/sdb', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('mdadm', '--create', '/dev/md0', '--force', '--run', @@ -2959,22 +2959,22 @@ class TestGenericHardwareManager(base.IronicAgentTest): mock.call('parted', '/dev/sdb', '-s', '--', 'mklabel', 'gpt'), mock.call('parted', '/dev/sda', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '8MiB', '10GiB'), - mock.call('partx', '-a', '/dev/sda', attempts=3, + mock.call('partx', '-av', '/dev/sda', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sdb', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '8MiB', '10GiB'), - mock.call('partx', '-a', '/dev/sdb', attempts=3, + mock.call('partx', '-av', '/dev/sdb', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sda', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '10GiB', '-1'), - mock.call('partx', '-a', '/dev/sda', attempts=3, + mock.call('partx', '-av', '/dev/sda', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sdb', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '10GiB', '-1'), - mock.call('partx', '-a', '/dev/sdb', attempts=3, + mock.call('partx', '-av', '/dev/sdb', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('mdadm', '--create', '/dev/md0', '--force', '--run', @@ -3041,22 +3041,22 @@ class TestGenericHardwareManager(base.IronicAgentTest): mock.call('sgdisk', '-F', '/dev/sdb'), mock.call('parted', '/dev/sda', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '42s', '10GiB'), - mock.call('partx', '-a', '/dev/sda', attempts=3, + mock.call('partx', '-av', '/dev/sda', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sdb', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '42s', '10GiB'), - mock.call('partx', '-a', '/dev/sdb', attempts=3, + mock.call('partx', '-av', '/dev/sdb', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sda', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '10GiB', '30GiB'), - mock.call('partx', '-a', '/dev/sda', attempts=3, + mock.call('partx', '-av', '/dev/sda', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sdb', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '10GiB', '30GiB'), - mock.call('partx', '-a', '/dev/sdb', attempts=3, + mock.call('partx', '-av', '/dev/sdb', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('mdadm', '--create', '/dev/md0', '--force', '--run', @@ -3125,22 +3125,22 @@ class TestGenericHardwareManager(base.IronicAgentTest): mock.call('sgdisk', '-F', '/dev/sdb'), mock.call('parted', '/dev/sda', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '42s', '20GiB'), - mock.call('partx', '-a', '/dev/sda', attempts=3, + mock.call('partx', '-av', '/dev/sda', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sdb', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '42s', '20GiB'), - mock.call('partx', '-a', '/dev/sdb', attempts=3, + mock.call('partx', '-av', '/dev/sdb', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sda', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '20GiB', '-1'), - mock.call('partx', '-a', '/dev/sda', attempts=3, + mock.call('partx', '-av', '/dev/sda', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sdb', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '20GiB', '-1'), - mock.call('partx', '-a', '/dev/sdb', attempts=3, + mock.call('partx', '-av', '/dev/sdb', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('mdadm', '--create', '/dev/md0', '--force', '--run', @@ -3218,22 +3218,22 @@ class TestGenericHardwareManager(base.IronicAgentTest): mock.call('sgdisk', '-F', '/dev/sdb'), mock.call('parted', '/dev/sda', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '42s', '10GiB'), - mock.call('partx', '-a', '/dev/sda', attempts=3, + mock.call('partx', '-av', '/dev/sda', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sdb', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '42s', '10GiB'), - mock.call('partx', '-a', '/dev/sdb', attempts=3, + mock.call('partx', '-av', '/dev/sdb', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sda', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '10GiB', '-1'), - mock.call('partx', '-a', '/dev/sda', attempts=3, + mock.call('partx', '-av', '/dev/sda', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/sdb', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '10GiB', '-1'), - mock.call('partx', '-a', '/dev/sdb', attempts=3, + mock.call('partx', '-av', '/dev/sdb', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('mdadm', '--create', '/dev/md0', '--force', '--run', @@ -3565,22 +3565,22 @@ class TestGenericHardwareManager(base.IronicAgentTest): 'gpt'), mock.call('parted', '/dev/nvme0n1', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '551MiB', '10GiB'), - mock.call('partx', '-a', '/dev/nvme0n1', attempts=3, + mock.call('partx', '-av', '/dev/nvme0n1', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/nvme1n1', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '551MiB', '10GiB'), - mock.call('partx', '-a', '/dev/nvme1n1', attempts=3, + mock.call('partx', '-av', '/dev/nvme1n1', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/nvme0n1', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '10GiB', '-1'), - mock.call('partx', '-a', '/dev/nvme0n1', attempts=3, + mock.call('partx', '-av', '/dev/nvme0n1', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('parted', '/dev/nvme1n1', '-s', '-a', 'optimal', '--', 'mkpart', 'primary', '10GiB', '-1'), - mock.call('partx', '-a', '/dev/nvme1n1', attempts=3, + mock.call('partx', '-av', '/dev/nvme1n1', attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('mdadm', '--create', '/dev/md0', '--force', '--run', diff --git a/ironic_python_agent/tests/unit/test_partition_utils.py b/ironic_python_agent/tests/unit/test_partition_utils.py index f6f56695..b4017c2b 100644 --- a/ironic_python_agent/tests/unit/test_partition_utils.py +++ b/ironic_python_agent/tests/unit/test_partition_utils.py @@ -408,6 +408,8 @@ class WorkOnDiskTestCase(base.IronicAgentTest): cpu_arch="") mock_unlink.assert_called_once_with('fake-path') + @mock.patch.object(disk_utils, 'trigger_device_rescan', + lambda d: None) @mock.patch.object(utils, 'mkfs', lambda fs, path, label=None: None) @mock.patch.object(disk_utils, 'block_uuid', lambda p: 'uuid') @mock.patch.object(disk_utils, 'populate_image', autospec=True) @@ -442,6 +444,8 @@ class WorkOnDiskTestCase(base.IronicAgentTest): self.assertEqual('uuid', res['root uuid']) self.assertFalse(mock_populate.called) + @mock.patch.object(disk_utils, 'trigger_device_rescan', + lambda d: None) @mock.patch.object(utils, 'mkfs', lambda fs, path, label=None: None) @mock.patch.object(disk_utils, 'block_uuid', lambda p: 'uuid') @mock.patch.object(disk_utils, 'populate_image', lambda image_path, @@ -475,11 +479,12 @@ class WorkOnDiskTestCase(base.IronicAgentTest): disk_label='gpt', cpu_arch="") + @mock.patch.object(disk_utils, 'trigger_device_rescan', autospec=True) @mock.patch.object(disk_utils, 'block_uuid', autospec=True) @mock.patch.object(disk_utils, 'populate_image', autospec=True) @mock.patch.object(utils, 'mkfs', autospec=True) def test_uefi_localboot(self, mock_mkfs, mock_populate_image, - mock_block_uuid): + mock_block_uuid, mock_trigger_device_rescan): """Test that we create a fat filesystem with UEFI localboot.""" root_part = '/dev/fake-part1' efi_part = '/dev/fake-part2' @@ -510,12 +515,14 @@ class WorkOnDiskTestCase(base.IronicAgentTest): root_part, conv_flags=None) mock_block_uuid.assert_any_call(root_part) mock_block_uuid.assert_any_call(efi_part) + mock_trigger_device_rescan.assert_called_once_with(self.dev) + @mock.patch.object(disk_utils, 'trigger_device_rescan', autospec=True) @mock.patch.object(disk_utils, 'block_uuid', autospec=True) @mock.patch.object(disk_utils, 'populate_image', autospec=True) @mock.patch.object(utils, 'mkfs', autospec=True) def test_preserve_ephemeral(self, mock_mkfs, mock_populate_image, - mock_block_uuid): + mock_block_uuid, mock_trigger_device_rescan): """Test that ephemeral partition doesn't get overwritten.""" ephemeral_part = '/dev/fake-part1' root_part = '/dev/fake-part2' @@ -543,11 +550,12 @@ class WorkOnDiskTestCase(base.IronicAgentTest): cpu_arch="") self.assertFalse(mock_mkfs.called) + @mock.patch.object(disk_utils, 'trigger_device_rescan', autospec=True) @mock.patch.object(disk_utils, 'block_uuid', autospec=True) @mock.patch.object(disk_utils, 'populate_image', autospec=True) @mock.patch.object(utils, 'mkfs', autospec=True) def test_ppc64le_prep_part(self, mock_mkfs, mock_populate_image, - mock_block_uuid): + mock_block_uuid, mock_trigger_device_rescan): """Test that PReP partition uuid is returned.""" prep_part = '/dev/fake-part1' root_part = '/dev/fake-part2' @@ -573,11 +581,12 @@ class WorkOnDiskTestCase(base.IronicAgentTest): cpu_arch="ppc64le") self.assertFalse(mock_mkfs.called) + @mock.patch.object(disk_utils, 'trigger_device_rescan', autospec=True) @mock.patch.object(disk_utils, 'block_uuid', autospec=True) @mock.patch.object(disk_utils, 'populate_image', autospec=True) @mock.patch.object(utils, 'mkfs', autospec=True) def test_convert_to_sparse(self, mock_mkfs, mock_populate_image, - mock_block_uuid): + mock_block_uuid, mock_trigger_device_rescan): ephemeral_part = '/dev/fake-part1' swap_part = '/dev/fake-part2' root_part = '/dev/fake-part3' @@ -1199,7 +1208,7 @@ class TestGetPartition(base.IronicAgentTest): root_part = partition_utils.get_partition( self.fake_dev, self.fake_root_uuid) self.assertEqual('/dev/test2', root_part) - expected = [mock.call('partx', '-a', self.fake_dev, attempts=3, + expected = [mock.call('partx', '-av', self.fake_dev, attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('lsblk', '-PbioKNAME,UUID,PARTUUID,TYPE,LABEL', @@ -1219,7 +1228,7 @@ class TestGetPartition(base.IronicAgentTest): self.assertRaises(errors.DeviceNotFound, partition_utils.get_partition, self.fake_dev, self.fake_root_uuid) - expected = [mock.call('partx', '-a', self.fake_dev, attempts=3, + expected = [mock.call('partx', '-av', self.fake_dev, attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('lsblk', '-PbioKNAME,UUID,PARTUUID,TYPE,LABEL', @@ -1240,7 +1249,7 @@ class TestGetPartition(base.IronicAgentTest): result = partition_utils.get_partition( self.fake_dev, self.fake_root_uuid) self.assertEqual('/dev/loop0', result) - expected = [mock.call('partx', '-a', self.fake_dev, attempts=3, + expected = [mock.call('partx', '-av', self.fake_dev, attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('lsblk', '-PbioKNAME,UUID,PARTUUID,TYPE,LABEL', @@ -1257,7 +1266,7 @@ class TestGetPartition(base.IronicAgentTest): partition_utils.get_partition, self.fake_dev, self.fake_root_uuid) - expected = [mock.call('partx', '-a', self.fake_dev, attempts=3, + expected = [mock.call('partx', '-av', self.fake_dev, attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('lsblk', '-PbioKNAME,UUID,PARTUUID,TYPE,LABEL', @@ -1275,7 +1284,7 @@ class TestGetPartition(base.IronicAgentTest): root_part = partition_utils.get_partition( self.fake_dev, self.fake_root_uuid) self.assertEqual('/dev/test2', root_part) - expected = [mock.call('partx', '-a', self.fake_dev, attempts=3, + expected = [mock.call('partx', '-av', self.fake_dev, attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('lsblk', '-PbioKNAME,UUID,PARTUUID,TYPE,LABEL', @@ -1292,7 +1301,7 @@ class TestGetPartition(base.IronicAgentTest): root_part = partition_utils.get_partition( self.fake_dev, self.fake_root_uuid) self.assertEqual('/dev/test2', root_part) - expected = [mock.call('partx', '-a', self.fake_dev, attempts=3, + expected = [mock.call('partx', '-av', self.fake_dev, attempts=3, delay_on_retry=True), mock.call('udevadm', 'settle'), mock.call('lsblk', '-PbioKNAME,UUID,PARTUUID,TYPE,LABEL', diff --git a/ironic_python_agent/tests/unit/test_utils.py b/ironic_python_agent/tests/unit/test_utils.py index 96d31688..1bb7c1fe 100644 --- a/ironic_python_agent/tests/unit/test_utils.py +++ b/ironic_python_agent/tests/unit/test_utils.py @@ -431,7 +431,8 @@ class TestUtils(ironic_agent_base.IronicAgentTest): file_list=[], io_dict={'journal': mock.ANY, 'ip_addr': mock.ANY, 'ps': mock.ANY, 'df': mock.ANY, 'iptables': mock.ANY, 'lshw': mock.ANY, - 'lsblk': mock.ANY, 'mdstat': mock.ANY}) + 'lsblk': mock.ANY, 'mdstat': mock.ANY, + 'mount': mock.ANY, 'parted': mock.ANY}) @mock.patch.object(utils, 'gzip_and_b64encode', autospec=True) @mock.patch.object(utils, 'is_journalctl_present', autospec=True) @@ -458,7 +459,8 @@ class TestUtils(ironic_agent_base.IronicAgentTest): file_list=[tmp.name], io_dict={'journal': mock.ANY, 'ip_addr': mock.ANY, 'ps': mock.ANY, 'df': mock.ANY, 'iptables': mock.ANY, 'lshw': mock.ANY, - 'lsblk': mock.ANY, 'mdstat': mock.ANY}) + 'lsblk': mock.ANY, 'mdstat': mock.ANY, + 'mount': mock.ANY, 'parted': mock.ANY}) @mock.patch.object(utils, 'gzip_and_b64encode', autospec=True) @mock.patch.object(utils, 'is_journalctl_present', autospec=True) @@ -480,7 +482,8 @@ class TestUtils(ironic_agent_base.IronicAgentTest): file_list=['/var/log'], io_dict={'iptables': mock.ANY, 'ip_addr': mock.ANY, 'ps': mock.ANY, 'dmesg': mock.ANY, 'df': mock.ANY, 'lshw': mock.ANY, - 'lsblk': mock.ANY, 'mdstat': mock.ANY}) + 'lsblk': mock.ANY, 'mdstat': mock.ANY, + 'mount': mock.ANY, 'parted': mock.ANY}) @mock.patch.object(utils, 'gzip_and_b64encode', autospec=True) @mock.patch.object(utils, 'is_journalctl_present', autospec=True) @@ -506,7 +509,8 @@ class TestUtils(ironic_agent_base.IronicAgentTest): file_list=['/var/log', tmp.name], io_dict={'iptables': mock.ANY, 'ip_addr': mock.ANY, 'ps': mock.ANY, 'dmesg': mock.ANY, 'df': mock.ANY, 'lshw': mock.ANY, - 'lsblk': mock.ANY, 'mdstat': mock.ANY}) + 'lsblk': mock.ANY, 'mdstat': mock.ANY, + 'mount': mock.ANY, 'parted': mock.ANY}) def test_get_ssl_client_options(self): # defaults diff --git a/ironic_python_agent/utils.py b/ironic_python_agent/utils.py index 71e29d16..ff0f8926 100644 --- a/ironic_python_agent/utils.py +++ b/ironic_python_agent/utils.py @@ -69,6 +69,8 @@ COLLECT_LOGS_COMMANDS = { 'lshw': ['lshw', '-quiet', '-json'], 'lsblk': ['lsblk', '--all', '-o%s' % ','.join(LSBLK_COLUMNS)], 'mdstat': ['cat', '/proc/mdstat'], + 'mount': ['mount'], + 'parted': ['parted', '-l'], } @@ -888,7 +890,7 @@ def rescan_device(device): kernel partition records. """ try: - execute('partx', '-a', device, attempts=3, delay_on_retry=True) + execute('partx', '-av', device, attempts=3, delay_on_retry=True) except processutils.ProcessExecutionError: LOG.warning("Couldn't re-read the partition table " "on device %s", device) diff --git a/releasenotes/notes/detect-endianness-f53a6c4571aba3fe.yaml b/releasenotes/notes/detect-endianness-f53a6c4571aba3fe.yaml new file mode 100644 index 00000000..82d90886 --- /dev/null +++ b/releasenotes/notes/detect-endianness-f53a6c4571aba3fe.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + In case the CSV file used for the bootloader hint does not have BOM + we fail reading its content as utf-16 codec is too generic. + Fail over to utf-16-le as Little Endian is mostly used. diff --git a/releasenotes/notes/rescan-device-after-mkfs-3f9d52a2e3b6fff3.yaml b/releasenotes/notes/rescan-device-after-mkfs-3f9d52a2e3b6fff3.yaml new file mode 100644 index 00000000..3a8d9e08 --- /dev/null +++ b/releasenotes/notes/rescan-device-after-mkfs-3f9d52a2e3b6fff3.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Adds device rescan operation after partitioning the root device to ensure + that updated UUIDs are reflected correctly |