Make _get_efi_bootloaders return relative paths
To make this function useful for purposes other than efibootmgr
entries, this change moves the path manipulation to _run_efibootmgr.
This change also adds boot*.efi entries to BOOTLOADERS_EFI so that it
includes every entry in the UEFI Spec 2.9[1] Table 3-2 UEFI Image
Types.
[1] https://uefi.org/sites/default/files/resources/UEFI_Spec_2_9_2021_03_18.pdf
Story: 2008923
Task: 42521
Change-Id: Ibe02786609aa0de65115897d8f4a9b4f36c8aed2
(cherry picked from commit 10d18c4113
)
This commit is contained in:
parent
dc78c5074a
commit
d61b7bd843
|
@ -38,8 +38,18 @@ CONF = cfg.CONF
|
||||||
|
|
||||||
BIND_MOUNTS = ('/dev', '/proc', '/run')
|
BIND_MOUNTS = ('/dev', '/proc', '/run')
|
||||||
|
|
||||||
BOOTLOADERS_EFI = ['bootaa64.efi', 'bootx64.efi', 'grubaa64.efi',
|
BOOTLOADERS_EFI = [
|
||||||
'winload.efi']
|
'bootia32.efi',
|
||||||
|
'bootx64.efi',
|
||||||
|
'bootia64.efi',
|
||||||
|
'bootarm.efi',
|
||||||
|
'bootaa64.efi',
|
||||||
|
'bootriscv32.efi',
|
||||||
|
'bootriscv64.efi',
|
||||||
|
'bootriscv128.efi',
|
||||||
|
'grubaa64.efi',
|
||||||
|
'winload.efi'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def _rescan_device(device):
|
def _rescan_device(device):
|
||||||
|
@ -216,9 +226,8 @@ def _get_efi_bootloaders(location):
|
||||||
|
|
||||||
:param location: the location where it should start looking for the
|
:param location: the location where it should start looking for the
|
||||||
efi files.
|
efi files.
|
||||||
:return: a list of valid efi bootloaders
|
:return: a list of relative paths to valid efi bootloaders
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Let's find all files with .efi or .EFI extension
|
# Let's find all files with .efi or .EFI extension
|
||||||
LOG.debug('Looking for all efi files on %s', location)
|
LOG.debug('Looking for all efi files on %s', location)
|
||||||
valid_bootloaders = []
|
valid_bootloaders = []
|
||||||
|
@ -230,7 +239,7 @@ def _get_efi_bootloaders(location):
|
||||||
efi_f = os.path.join(root, name)
|
efi_f = os.path.join(root, name)
|
||||||
LOG.debug('Checking if %s is executable', efi_f)
|
LOG.debug('Checking if %s is executable', efi_f)
|
||||||
if os.access(efi_f, os.X_OK):
|
if os.access(efi_f, os.X_OK):
|
||||||
v_bl = efi_f.split('/boot/efi')[-1].replace('/', '\\')
|
v_bl = efi_f.split(location)[-1][1:]
|
||||||
LOG.debug('%s is a valid bootloader', v_bl)
|
LOG.debug('%s is a valid bootloader', v_bl)
|
||||||
valid_bootloaders.append(v_bl)
|
valid_bootloaders.append(v_bl)
|
||||||
return valid_bootloaders
|
return valid_bootloaders
|
||||||
|
@ -253,7 +262,8 @@ def _run_efibootmgr(valid_efi_bootloaders, device, efi_partition):
|
||||||
duplicated_label = re.compile(r'^.*:\s\*\*.*\*\*\s:\s.*'
|
duplicated_label = re.compile(r'^.*:\s\*\*.*\*\*\s:\s.*'
|
||||||
r'Boot([0-9a-f-A-F]+)\s.*$')
|
r'Boot([0-9a-f-A-F]+)\s.*$')
|
||||||
label_id = 1
|
label_id = 1
|
||||||
for v_efi_bl_path in valid_efi_bootloaders:
|
for v_bl in valid_efi_bootloaders:
|
||||||
|
v_efi_bl_path = '\\' + v_bl.replace('/', '\\')
|
||||||
# Update the nvram using efibootmgr
|
# Update the nvram using efibootmgr
|
||||||
# https://linux.die.net/man/8/efibootmgr
|
# https://linux.die.net/man/8/efibootmgr
|
||||||
label = 'ironic' + str(label_id)
|
label = 'ironic' + str(label_id)
|
||||||
|
|
|
@ -245,7 +245,7 @@ class TestImageExtension(base.IronicAgentTest):
|
||||||
self.fake_dev, hardware.BootInfo(current_boot_mode='uefi')
|
self.fake_dev, hardware.BootInfo(current_boot_mode='uefi')
|
||||||
]
|
]
|
||||||
mock_partition.side_effect = [self.fake_dev, self.fake_efi_system_part]
|
mock_partition.side_effect = [self.fake_dev, self.fake_efi_system_part]
|
||||||
mock_efi_bl.return_value = ['\\EFI\\BOOT\\BOOTX64.EFI']
|
mock_efi_bl.return_value = ['EFI/BOOT/BOOTX64.EFI']
|
||||||
mock_utils_efi_part.return_value = '1'
|
mock_utils_efi_part.return_value = '1'
|
||||||
|
|
||||||
mock_execute.side_effect = iter([('', ''), ('', ''),
|
mock_execute.side_effect = iter([('', ''), ('', ''),
|
||||||
|
@ -295,7 +295,7 @@ class TestImageExtension(base.IronicAgentTest):
|
||||||
]
|
]
|
||||||
mock_partition.return_value = self.fake_dev
|
mock_partition.return_value = self.fake_dev
|
||||||
mock_utils_efi_part.return_value = '1'
|
mock_utils_efi_part.return_value = '1'
|
||||||
mock_efi_bl.return_value = ['\\EFI\\BOOT\\BOOTX64.EFI']
|
mock_efi_bl.return_value = ['EFI/BOOT/BOOTX64.EFI']
|
||||||
mock_execute.side_effect = iter([('', ''), ('', ''),
|
mock_execute.side_effect = iter([('', ''), ('', ''),
|
||||||
('', ''), ('', ''),
|
('', ''), ('', ''),
|
||||||
('', ''), ('', ''),
|
('', ''), ('', ''),
|
||||||
|
@ -343,7 +343,7 @@ class TestImageExtension(base.IronicAgentTest):
|
||||||
]
|
]
|
||||||
mock_partition.return_value = self.fake_dev
|
mock_partition.return_value = self.fake_dev
|
||||||
mock_utils_efi_part.return_value = '1'
|
mock_utils_efi_part.return_value = '1'
|
||||||
mock_efi_bl.return_value = ['\\EFI\\BOOT\\BOOTX64.EFI']
|
mock_efi_bl.return_value = ['EFI/BOOT/BOOTX64.EFI']
|
||||||
stdeer_msg = """
|
stdeer_msg = """
|
||||||
efibootmgr: ** Warning ** : Boot0004 has same label ironic1\n
|
efibootmgr: ** Warning ** : Boot0004 has same label ironic1\n
|
||||||
efibootmgr: ** Warning ** : Boot0005 has same label ironic1\n
|
efibootmgr: ** Warning ** : Boot0005 has same label ironic1\n
|
||||||
|
@ -398,8 +398,8 @@ efibootmgr: ** Warning ** : Boot0005 has same label ironic1\n
|
||||||
]
|
]
|
||||||
mock_partition.return_value = self.fake_dev
|
mock_partition.return_value = self.fake_dev
|
||||||
mock_utils_efi_part.return_value = '1'
|
mock_utils_efi_part.return_value = '1'
|
||||||
mock_efi_bl.return_value = ['\\EFI\\BOOT\\BOOTX64.EFI',
|
mock_efi_bl.return_value = ['EFI/BOOT/BOOTX64.EFI',
|
||||||
'\\WINDOWS\\system32\\winload.efi']
|
'WINDOWS/system32/winload.efi']
|
||||||
|
|
||||||
mock_execute.side_effect = iter([('', ''), ('', ''),
|
mock_execute.side_effect = iter([('', ''), ('', ''),
|
||||||
('', ''), ('', ''),
|
('', ''), ('', ''),
|
||||||
|
@ -2126,7 +2126,7 @@ efibootmgr: ** Warning ** : Boot0005 has same label ironic1\n
|
||||||
mock_utils_efi_part.return_value = '1'
|
mock_utils_efi_part.return_value = '1'
|
||||||
mock_get_part_uuid.return_value = self.fake_dev
|
mock_get_part_uuid.return_value = self.fake_dev
|
||||||
|
|
||||||
mock_efi_bl.return_value = ['\\EFI\\BOOT\\BOOTX64.EFI']
|
mock_efi_bl.return_value = ['EFI/BOOT/BOOTX64.EFI']
|
||||||
|
|
||||||
mock_execute.side_effect = iter([('', ''), ('', ''),
|
mock_execute.side_effect = iter([('', ''), ('', ''),
|
||||||
('', ''), ('', ''),
|
('', ''), ('', ''),
|
||||||
|
@ -2165,7 +2165,7 @@ efibootmgr: ** Warning ** : Boot0005 has same label ironic1\n
|
||||||
mock_utils_efi_part.return_value = '1'
|
mock_utils_efi_part.return_value = '1'
|
||||||
mock_get_part_uuid.return_value = '/dev/fakenvme0p1'
|
mock_get_part_uuid.return_value = '/dev/fakenvme0p1'
|
||||||
|
|
||||||
mock_efi_bl.return_value = ['\\EFI\\BOOT\\BOOTX64.EFI']
|
mock_efi_bl.return_value = ['EFI/BOOT/BOOTX64.EFI']
|
||||||
|
|
||||||
mock_execute.side_effect = iter([('', ''), ('', ''),
|
mock_execute.side_effect = iter([('', ''), ('', ''),
|
||||||
('', ''), ('', ''),
|
('', ''), ('', ''),
|
||||||
|
@ -2205,7 +2205,7 @@ efibootmgr: ** Warning ** : Boot0005 has same label ironic1\n
|
||||||
mock_utils_efi_part.return_value = '1'
|
mock_utils_efi_part.return_value = '1'
|
||||||
mock_get_part_uuid.side_effect = Exception
|
mock_get_part_uuid.side_effect = Exception
|
||||||
|
|
||||||
mock_efi_bl.return_value = ['\\EFI\\BOOT\\BOOTX64.EFI']
|
mock_efi_bl.return_value = ['EFI/BOOT/BOOTX64.EFI']
|
||||||
|
|
||||||
mock_execute.side_effect = iter([('', ''), ('', ''),
|
mock_execute.side_effect = iter([('', ''), ('', ''),
|
||||||
('', ''), ('', ''),
|
('', ''), ('', ''),
|
||||||
|
@ -2274,7 +2274,7 @@ efibootmgr: ** Warning ** : Boot0005 has same label ironic1\n
|
||||||
]
|
]
|
||||||
mock_access.return_value = True
|
mock_access.return_value = True
|
||||||
result = image._get_efi_bootloaders("/boot/efi")
|
result = image._get_efi_bootloaders("/boot/efi")
|
||||||
self.assertEqual(result[0], '\\EFI\\BOOT\\BOOTX64.EFI')
|
self.assertEqual(result[0], 'EFI/BOOT/BOOTX64.EFI')
|
||||||
|
|
||||||
@mock.patch.object(os, 'walk', autospec=True)
|
@mock.patch.object(os, 'walk', autospec=True)
|
||||||
@mock.patch.object(os, 'access', autospec=True)
|
@mock.patch.object(os, 'access', autospec=True)
|
||||||
|
@ -2288,7 +2288,7 @@ efibootmgr: ** Warning ** : Boot0005 has same label ironic1\n
|
||||||
]
|
]
|
||||||
mock_access.return_value = True
|
mock_access.return_value = True
|
||||||
result = image._get_efi_bootloaders("/boot/efi")
|
result = image._get_efi_bootloaders("/boot/efi")
|
||||||
self.assertEqual(result[0], '\\WINDOWS\\system32\\winload.efi')
|
self.assertEqual(result[0], 'WINDOWS/system32/winload.efi')
|
||||||
|
|
||||||
def test__run_efibootmgr_no_bootloaders(self, mock_execute, mock_dispatch):
|
def test__run_efibootmgr_no_bootloaders(self, mock_execute, mock_dispatch):
|
||||||
result = image._run_efibootmgr([], self.fake_dev,
|
result = image._run_efibootmgr([], self.fake_dev,
|
||||||
|
@ -2298,7 +2298,7 @@ efibootmgr: ** Warning ** : Boot0005 has same label ironic1\n
|
||||||
mock_execute.assert_has_calls(expected)
|
mock_execute.assert_has_calls(expected)
|
||||||
|
|
||||||
def test__run_efibootmgr(self, mock_execute, mock_dispatch):
|
def test__run_efibootmgr(self, mock_execute, mock_dispatch):
|
||||||
result = image._run_efibootmgr(['\\EFI\\BOOT\\BOOTX64.EFI'],
|
result = image._run_efibootmgr(['EFI/BOOT/BOOTX64.EFI'],
|
||||||
self.fake_dev,
|
self.fake_dev,
|
||||||
self.fake_efi_system_part)
|
self.fake_efi_system_part)
|
||||||
expected = [mock.call('efibootmgr'),
|
expected = [mock.call('efibootmgr'),
|
||||||
|
|
Loading…
Reference in New Issue