summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ironic_python_agent/extensions/image.py7
-rw-r--r--ironic_python_agent/tests/unit/extensions/test_image.py39
-rw-r--r--releasenotes/notes/fix-nvme-partition-image-handling-b8487133a188fd32.yaml6
3 files changed, 51 insertions, 1 deletions
diff --git a/ironic_python_agent/extensions/image.py b/ironic_python_agent/extensions/image.py
index c482b69c..8aa71e79 100644
--- a/ironic_python_agent/extensions/image.py
+++ b/ironic_python_agent/extensions/image.py
@@ -300,7 +300,12 @@ def _manage_uefi(device, efi_system_part_uuid=None):
# _get_partition returns <device>+<partition> and we only need the
# partition number
partition = _get_partition(device, uuid=efi_system_part_uuid)
- efi_partition = int(partition.replace(device, ""))
+ try:
+ efi_partition = int(partition.replace(device, ""))
+ except ValueError:
+ # NVMe Devices get a partitioning scheme that is different from
+ # traditional block devices like SCSI/SATA
+ efi_partition = int(partition.replace(device + 'p', ""))
if not efi_partition:
# NOTE(dtantsur): we cannot have a valid EFI deployment without an
diff --git a/ironic_python_agent/tests/unit/extensions/test_image.py b/ironic_python_agent/tests/unit/extensions/test_image.py
index d7093b6b..c91de841 100644
--- a/ironic_python_agent/tests/unit/extensions/test_image.py
+++ b/ironic_python_agent/tests/unit/extensions/test_image.py
@@ -2165,6 +2165,45 @@ efibootmgr: ** Warning ** : Boot0005 has same label ironic1\n
@mock.patch.object(image, '_get_partition', autospec=True)
@mock.patch.object(utils, 'get_efi_part_on_device', autospec=True)
@mock.patch.object(os, 'makedirs', autospec=True)
+ def test__manage_uefi_nvme_device(self, mkdir_mock, mock_utils_efi_part,
+ mock_get_part_uuid, mock_efi_bl,
+ mock_execute, mock_dispatch):
+ mock_utils_efi_part.return_value = '1'
+ mock_get_part_uuid.return_value = '/dev/fakenvme0p1'
+
+ mock_efi_bl.return_value = ['\\EFI\\BOOT\\BOOTX64.EFI']
+
+ mock_execute.side_effect = iter([('', ''), ('', ''),
+ ('', ''), ('', ''),
+ ('', ''), ('', ''),
+ ('', '')])
+
+ expected = [mock.call('partx', '-u', '/dev/fakenvme0', attempts=3,
+ delay_on_retry=True),
+ mock.call('udevadm', 'settle'),
+ mock.call('mount', '/dev/fakenvme0p1',
+ self.fake_dir + '/boot/efi'),
+ mock.call('efibootmgr'),
+ mock.call('efibootmgr', '-c', '-d', '/dev/fakenvme0',
+ '-p', '1', '-w',
+ '-L', 'ironic1', '-l',
+ '\\EFI\\BOOT\\BOOTX64.EFI'),
+ mock.call('umount', self.fake_dir + '/boot/efi',
+ attempts=3, delay_on_retry=True),
+ mock.call('sync')]
+
+ result = image._manage_uefi('/dev/fakenvme0', self.fake_root_uuid)
+ self.assertTrue(result)
+ mkdir_mock.assert_called_once_with(self.fake_dir + '/boot/efi')
+ mock_efi_bl.assert_called_once_with(self.fake_dir + '/boot/efi')
+ mock_execute.assert_has_calls(expected)
+ self.assertEqual(7, mock_execute.call_count)
+
+ @mock.patch.object(os.path, 'exists', lambda *_: False)
+ @mock.patch.object(image, '_get_efi_bootloaders', autospec=True)
+ @mock.patch.object(image, '_get_partition', autospec=True)
+ @mock.patch.object(utils, 'get_efi_part_on_device', autospec=True)
+ @mock.patch.object(os, 'makedirs', autospec=True)
def test__manage_uefi_wholedisk(
self, mkdir_mock, mock_utils_efi_part,
mock_get_part_uuid, mock_efi_bl, mock_execute,
diff --git a/releasenotes/notes/fix-nvme-partition-image-handling-b8487133a188fd32.yaml b/releasenotes/notes/fix-nvme-partition-image-handling-b8487133a188fd32.yaml
new file mode 100644
index 00000000..ee1cf085
--- /dev/null
+++ b/releasenotes/notes/fix-nvme-partition-image-handling-b8487133a188fd32.yaml
@@ -0,0 +1,6 @@
+---
+fixes:
+ - |
+ Fixes an error with UEFI based deployments where using a partition image
+ a NVMe device was previously failing due to the different device name
+ pattern.