summaryrefslogtreecommitdiff
path: root/ironic_python_agent/tests
diff options
context:
space:
mode:
authorArne Wiebalck <Arne.Wiebalck@cern.ch>2021-04-14 08:50:16 +0200
committerArne Wiebalck <Arne.Wiebalck@cern.ch>2021-04-16 14:40:28 +0200
commitc2d04dc1566bb947d0e6afd040b82be55c925b11 (patch)
treeaa96fb5ee83aa38ce840bfdf02c973e8659373a8 /ironic_python_agent/tests
parentc72997d8d0c80f29fcaf452092f1e66e7270a427 (diff)
downloadironic-python-agent-c2d04dc1566bb947d0e6afd040b82be55c925b11.tar.gz
Software RAID: RAID the ESPs
For software RAID in UEFI mode, we create ESPs on all holder disks and copy the bootloader there. Since there is no mechanism to keep the ESPs in sync, e.g. on kernel upgrades or when kernel parameters are updated, the ESPs will get out of sync eventually. This may lead to a situation where a node boots with outdated parameters or does not have any of the installed kernels in the boot menu anymore. This change proposes to RAID the ESPs. While the UEFI firmware will find an ESP partition (one leg of the mirror), the node will see an md device and all subsequent updates will go to all member disks. Also, remove the source ESP after copying in order to avoid mount confusion (same UUID!). Story: #2008745 Task: #42103 Change-Id: I9078ef37f1e94382c645ae98ce724ac9ed87c287
Diffstat (limited to 'ironic_python_agent/tests')
-rw-r--r--ironic_python_agent/tests/unit/extensions/test_image.py66
1 files changed, 30 insertions, 36 deletions
diff --git a/ironic_python_agent/tests/unit/extensions/test_image.py b/ironic_python_agent/tests/unit/extensions/test_image.py
index d7093b6b..4c4ce03a 100644
--- a/ironic_python_agent/tests/unit/extensions/test_image.py
+++ b/ironic_python_agent/tests/unit/extensions/test_image.py
@@ -1200,7 +1200,7 @@ efibootmgr: ** Warning ** : Boot0005 has same label ironic1\n
mock_preserve_efi_assets.assert_called_with(
self.fake_dir,
self.fake_dir + '/boot/efi/EFI',
- ['/dev/fake1'],
+ '/dev/fake1',
self.fake_dir + '/boot/efi')
mock_append_to_fstab.assert_called_with(self.fake_dir,
self.fake_efi_system_part_uuid)
@@ -1526,16 +1526,17 @@ efibootmgr: ** Warning ** : Boot0005 has same label ironic1\n
(None, None), # partprobe
(None, None), # blkid
('/dev/sda12: dsfkgsdjfg', None), # blkid
- (None, None), # cp
('452', None), # sgdisk -F
(None, None), # sgdisk create part
(None, None), # partprobe
(None, None), # blkid
('/dev/sdb14: whatever', None), # blkid
+ (None, None), # mdadm
(None, None), # cp
+ (None, None), # wipefs
]
- efi_parts = image._prepare_boot_partitions_for_softraid(
+ efi_part = image._prepare_boot_partitions_for_softraid(
'/dev/md0', ['/dev/sda', '/dev/sdb'], None,
target_boot_mode='uefi')
@@ -1548,7 +1549,6 @@ efibootmgr: ** Warning ** : Boot0005 has same label ironic1\n
mock.call('blkid'),
mock.call('blkid', '-l', '-t', 'PARTLABEL=uefi-holder-0',
'/dev/sda'),
- mock.call('cp', '/dev/md0p12', '/dev/sda12'),
mock.call('sgdisk', '-F', '/dev/sdb'),
mock.call('sgdisk', '-n', '0:452s:+550MiB', '-t', '0:ef00', '-c',
'0:uefi-holder-1', '/dev/sdb'),
@@ -1556,10 +1556,14 @@ efibootmgr: ** Warning ** : Boot0005 has same label ironic1\n
mock.call('blkid'),
mock.call('blkid', '-l', '-t', 'PARTLABEL=uefi-holder-1',
'/dev/sdb'),
- mock.call('cp', '/dev/md0p12', '/dev/sdb14')
+ mock.call('mdadm', '--create', '/dev/md/esp', '--force', '--run',
+ '--metadata=1.0', '--level', '1', '--raid-devices', 2,
+ '/dev/sda12', '/dev/sdb14'),
+ mock.call('cp', '/dev/md0p12', '/dev/md/esp'),
+ mock.call('wipefs', '-a', '/dev/md0p12')
]
mock_execute.assert_has_calls(expected, any_order=False)
- self.assertEqual(efi_parts, ['/dev/sda12', '/dev/sdb14'])
+ self.assertEqual(efi_part, '/dev/md/esp')
@mock.patch.object(utils, 'get_efi_part_on_device', autospec=True)
@mock.patch.object(ilib_utils, 'mkfs', autospec=True)
@@ -1577,9 +1581,10 @@ efibootmgr: ** Warning ** : Boot0005 has same label ironic1\n
(None, None), # partprobe
(None, None), # blkid
('/dev/sdb14: whatever', None), # blkid
+ (None, None), # mdadm
]
- efi_parts = image._prepare_boot_partitions_for_softraid(
+ efi_part = image._prepare_boot_partitions_for_softraid(
'/dev/md0', ['/dev/sda', '/dev/sdb'], None,
target_boot_mode='uefi')
@@ -1602,10 +1607,9 @@ efibootmgr: ** Warning ** : Boot0005 has same label ironic1\n
]
mock_execute.assert_has_calls(expected, any_order=False)
mock_mkfs.assert_has_calls([
- mock.call(path='/dev/sda12', label='efi-part', fs='vfat'),
- mock.call(path='/dev/sdb14', label='efi-part-b', fs='vfat'),
+ mock.call(path='/dev/md/esp', label='efi-part', fs='vfat'),
], any_order=False)
- self.assertEqual(efi_parts, ['/dev/sda12', '/dev/sdb14'])
+ self.assertEqual(efi_part, '/dev/md/esp')
def test__prepare_boot_partitions_for_softraid_uefi_gpt_efi_provided(
self, mock_execute, mock_dispatch):
@@ -1615,16 +1619,17 @@ efibootmgr: ** Warning ** : Boot0005 has same label ironic1\n
(None, None), # partprobe
(None, None), # blkid
('/dev/sda12: dsfkgsdjfg', None), # blkid
- (None, None), # cp
('452', None), # sgdisk -F
(None, None), # sgdisk create part
(None, None), # partprobe
(None, None), # blkid
('/dev/sdb14: whatever', None), # blkid
+ (None, None), # mdadm create
(None, None), # cp
+ (None, None), # wipefs
]
- efi_parts = image._prepare_boot_partitions_for_softraid(
+ efi_part = image._prepare_boot_partitions_for_softraid(
'/dev/md0', ['/dev/sda', '/dev/sdb'], '/dev/md0p15',
target_boot_mode='uefi')
@@ -1636,7 +1641,6 @@ efibootmgr: ** Warning ** : Boot0005 has same label ironic1\n
mock.call('blkid'),
mock.call('blkid', '-l', '-t', 'PARTLABEL=uefi-holder-0',
'/dev/sda'),
- mock.call('cp', '/dev/md0p15', '/dev/sda12'),
mock.call('sgdisk', '-F', '/dev/sdb'),
mock.call('sgdisk', '-n', '0:452s:+550MiB', '-t', '0:ef00', '-c',
'0:uefi-holder-1', '/dev/sdb'),
@@ -1644,17 +1648,21 @@ efibootmgr: ** Warning ** : Boot0005 has same label ironic1\n
mock.call('blkid'),
mock.call('blkid', '-l', '-t', 'PARTLABEL=uefi-holder-1',
'/dev/sdb'),
- mock.call('cp', '/dev/md0p15', '/dev/sdb14')
+ mock.call('mdadm', '--create', '/dev/md/esp', '--force', '--run',
+ '--metadata=1.0', '--level', '1', '--raid-devices', 2,
+ '/dev/sda12', '/dev/sdb14'),
+ mock.call('cp', '/dev/md0p15', '/dev/md/esp'),
+ mock.call('wipefs', '-a', '/dev/md0p15')
]
mock_execute.assert_has_calls(expected, any_order=False)
- self.assertEqual(efi_parts, ['/dev/sda12', '/dev/sdb14'])
+ self.assertEqual(efi_part, '/dev/md/esp')
@mock.patch.object(utils, 'scan_partition_table_type', autospec=True,
return_value='msdos')
def test__prepare_boot_partitions_for_softraid_bios_msdos(
self, mock_label_scan, mock_execute, mock_dispatch):
- efi_parts = image._prepare_boot_partitions_for_softraid(
+ efi_part = image._prepare_boot_partitions_for_softraid(
'/dev/md0', ['/dev/sda', '/dev/sdb'], 'notusedanyway',
target_boot_mode='bios')
@@ -1663,7 +1671,7 @@ efibootmgr: ** Warning ** : Boot0005 has same label ironic1\n
mock.call('/dev/sdb'),
]
mock_label_scan.assert_has_calls(expected, any_order=False)
- self.assertEqual(efi_parts, [])
+ self.assertIsNone(efi_part)
@mock.patch.object(utils, 'scan_partition_table_type', autospec=True,
return_value='gpt')
@@ -1677,7 +1685,7 @@ efibootmgr: ** Warning ** : Boot0005 has same label ironic1\n
(None, None), # bios boot grub
]
- efi_parts = image._prepare_boot_partitions_for_softraid(
+ efi_part = image._prepare_boot_partitions_for_softraid(
'/dev/md0', ['/dev/sda', '/dev/sdb'], 'notusedanyway',
target_boot_mode='bios')
@@ -1698,7 +1706,7 @@ efibootmgr: ** Warning ** : Boot0005 has same label ironic1\n
]
mock_execute.assert_has_calls(expected_exec, any_order=False)
- self.assertEqual(efi_parts, [])
+ self.assertIsNone(efi_part)
@mock.patch.object(image, '_is_bootloader_loaded', lambda *_: True)
@mock.patch.object(hardware, 'is_md_device', autospec=True)
@@ -1711,7 +1719,7 @@ efibootmgr: ** Warning ** : Boot0005 has same label ironic1\n
@mock.patch.object(image, '_get_partition', autospec=True)
@mock.patch.object(image, '_prepare_boot_partitions_for_softraid',
autospec=True,
- return_value=['/dev/sda1', '/dev/sdb2'])
+ return_value='/dev/md/esp')
@mock.patch.object(image, '_has_dracut',
autospec=True,
return_value=False)
@@ -1746,21 +1754,7 @@ efibootmgr: ** Warning ** : Boot0005 has same label ironic1\n
(self.fake_dir)), shell=True,
env_variables={
'PATH': '/sbin:/bin:/usr/sbin:/sbin'}),
- mock.call('mount', '/dev/sda1',
- self.fake_dir + '/boot/efi'),
- mock.call(('chroot %s /bin/sh -c "grub-install"' %
- self.fake_dir), shell=True,
- env_variables={
- 'PATH': '/sbin:/bin:/usr/sbin:/sbin'}),
- mock.call(('chroot %s /bin/sh -c '
- '"grub-install --removable"' %
- self.fake_dir), shell=True,
- env_variables={
- 'PATH': '/sbin:/bin:/usr/sbin:/sbin'}),
- mock.call(
- 'umount', self.fake_dir + '/boot/efi',
- attempts=3, delay_on_retry=True),
- mock.call('mount', '/dev/sdb2',
+ mock.call('mount', '/dev/md/esp',
self.fake_dir + '/boot/efi'),
mock.call(('chroot %s /bin/sh -c "grub-install"' %
self.fake_dir), shell=True,
@@ -1774,7 +1768,7 @@ efibootmgr: ** Warning ** : Boot0005 has same label ironic1\n
mock.call(
'umount', self.fake_dir + '/boot/efi',
attempts=3, delay_on_retry=True),
- mock.call('mount', '/dev/sda1',
+ mock.call('mount', '/dev/md/esp',
'/tmp/fake-dir/boot/efi'),
mock.call(('chroot %s /bin/sh -c '
'"grub-mkconfig -o '