Skip to content

Commit cafa6e9

Browse files
juliakregersteveb
authored andcommitted
Fix UEFI record regex
I accidently put colons on the test data and remembered taking the colon character out of the regex I was working on, but apparently left it in, and accounted for the active entry indicator flag which appears to have inconsistent support across vendors. The regex has been fixed, and a test added from a Lenovo SR650 which has some additional string entry data in the UEFI output which may separate entries. Change-Id: I1f67b0fb1f645fa82e98bd7c7bba3ffc7755cc74 (cherry picked from commit e10f052)
1 parent f3eb5ea commit cafa6e9

File tree

3 files changed

+76
-6
lines changed

3 files changed

+76
-6
lines changed

ironic_python_agent/extensions/image.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ def _run_efibootmgr(valid_efi_bootloaders, device, efi_partition,
278278
original_efi_output = utils.execute('efibootmgr', '-v')
279279
# NOTE(TheJulia): regex used to identify entries in the efibootmgr
280280
# output on stdout.
281-
entry_label = re.compile(r'Boot([0-9a-f-A-F]+):\s(.*).*$')
281+
entry_label = re.compile(r'Boot([0-9a-f-A-F]+)\*?\s(.*).*$')
282282
label_id = 1
283283
for v_bl in valid_efi_bootloaders:
284284
if 'csv' in v_bl.lower():

ironic_python_agent/tests/unit/extensions/test_image.py

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -348,9 +348,9 @@ def test__uefi_bootloader_with_entry_removal(
348348
BootCurrent: 0001
349349
Timeout: 0 seconds
350350
BootOrder: 0000,00001
351-
Boot0000: ironic1 HD(1, GPT,4f3c6294-bf9b-4208-9808-be45dfc34b5c)File(\EFI\Boot\BOOTX64.EFI)
352-
Boot0001: ironic2 HD(1, GPT,4f3c6294-bf9b-4208-9808-111111111112)File(\EFI\Boot\BOOTX64.EFI)
353-
Boot0002: VENDMAGIC FvFile(9f3c6294-bf9b-4208-9808-be45dfc34b51)
351+
Boot0000 ironic1 HD(1,GPT,4f3c6294-bf9b-4208-9808-be45dfc34b5c)File(\EFI\Boot\BOOTX64.EFI)
352+
Boot0001 ironic2 HD(1,GPT,4f3c6294-bf9b-4208-9808-111111111112)File(\EFI\Boot\BOOTX64.EFI)
353+
Boot0002 VENDMAGIC FvFile(9f3c6294-bf9b-4208-9808-be45dfc34b51)
354354
""" # noqa This is a giant literal string for testing.
355355
mock_execute.side_effect = iter([('', ''), ('', ''),
356356
('', ''), ('', ''),
@@ -386,6 +386,69 @@ def test__uefi_bootloader_with_entry_removal(
386386
mock_utils_efi_part.assert_called_once_with(self.fake_dev)
387387
self.assertEqual(9, mock_execute.call_count)
388388

389+
@mock.patch.object(hardware, 'is_md_device', lambda *_: False)
390+
@mock.patch.object(os.path, 'exists', lambda *_: False)
391+
@mock.patch.object(iscsi, 'clean_up', autospec=True)
392+
@mock.patch.object(image, '_get_efi_bootloaders', autospec=True)
393+
@mock.patch.object(image, '_get_partition', autospec=True)
394+
@mock.patch.object(utils, 'get_efi_part_on_device', autospec=True)
395+
@mock.patch.object(os, 'makedirs', autospec=True)
396+
def test__uefi_bootloader_with_entry_removal_lenovo(
397+
self, mkdir_mock, mock_utils_efi_part, mock_partition,
398+
mock_efi_bl, mock_iscsi_clean, mock_execute, mock_dispatch):
399+
mock_dispatch.side_effect = [
400+
self.fake_dev, hardware.BootInfo(current_boot_mode='uefi')
401+
]
402+
mock_partition.return_value = self.fake_dev
403+
mock_utils_efi_part.return_value = '1'
404+
mock_efi_bl.return_value = ['EFI/BOOT/BOOTX64.EFI']
405+
# NOTE(TheJulia): This test string was derived from a lenovo SR650
406+
# which does do some weird things with additional entries.
407+
# most notabley
408+
stdout_msg = """
409+
BootCurrent: 0000
410+
Timeout: 1 seconds
411+
BootOrder: 0000,0003,0002,0001
412+
Boot0000* ironic1 HD(1,GPT,55db8d03-c8f6-4a5b-9155-790dddc348fa,0x800,0x64000)/File(\EFI\boot\shimx64.efi)
413+
Boot0001* CD/DVD Rom VenHw(1fad3248-0000-7950-2166-a1e506fdb83a,02000000)..GO
414+
Boot0002* Hard Disk VenHw(1fad3248-0000-7950-2166-a1e506fdb83a,01000000)..GO..NO..........V.U.E.F.I.:. . . .S.C.S.I. .H.a.r.d. .D.r.i.v.e........A....................................*[email protected]..[J.Uy...H.......BO
415+
Boot0003* Network VenHw(1fad3248-0000-7950-2166-a1e506fdb83a,05000000)..GO..NO............U.E.F.I.:. . . .S.L.O.T.2. .(.2.F./.0./.0.). .P.X.E. .I.P.4. . .Q.L.o.g.i.c. .Q.L.4.1.2.6.2. .P.C.I.e. .2.5.G.b. .2.-.P.o.r.t. .S.F.P.2.8. .E.t.h.e.r.n.e.t. .A.d.a.p.t.e.r. .-. .P.X.E........A....................%.4..Z...............................................................Gd-.;.A..MQ..L.P.X.E. .I.P.4. .Q.L.o.g.i.c. .Q.L.4.1.2.6.2. .P.C.I.e. .2.5.G.b. .2.-.P.o.r.t. .S.F.P.2.8. .E.t.h.e.r.n.e.t. .A.d.a.p.t.e.r. .-. .P.X.E.......BO..NO............U.E.F.I.:. . . .S.L.O.T.1. .(.3.0./.0./.0.). .P.X.E. .I.P.4. . .Q.L.o.g.i.c. .Q.L.4.1.2.6.2. .P.C.I.e. .2.5.G.b. .2.-.P.o.r.t. .S.F.P.2.8. .E.t.h.e.r.n.e.t. .A.d.a.p.t.e.r. .-.
416+
Boot0004* ironic1 HD(1,GPT,55db8d03-c8f6-4a5b-9155-790dddc348fa,0x800,0x64000)/File(\EFI\boot\shimx64.efi)
417+
""" # noqa This is a giant literal string for testing.
418+
mock_execute.side_effect = iter([('', ''), ('', ''),
419+
('', ''), ('', ''),
420+
(stdout_msg, ''), ('', ''),
421+
('', ''), ('', ''),
422+
('', ''), ('', '')])
423+
expected = [mock.call('efibootmgr', '--version'),
424+
mock.call('partx', '-a', '/dev/fake', attempts=3,
425+
delay_on_retry=True),
426+
mock.call('udevadm', 'settle'),
427+
mock.call('mount', self.fake_efi_system_part,
428+
self.fake_dir + '/boot/efi'),
429+
mock.call('efibootmgr', '-v'),
430+
mock.call('efibootmgr', '-b', '0000', '-B'),
431+
mock.call('efibootmgr', '-b', '0004', '-B'),
432+
mock.call('efibootmgr', '-v', '-c', '-d', self.fake_dev,
433+
'-p', '1', '-w',
434+
'-L', 'ironic1', '-l',
435+
'\\EFI\\BOOT\\BOOTX64.EFI'),
436+
mock.call('umount', self.fake_dir + '/boot/efi',
437+
attempts=3, delay_on_retry=True),
438+
mock.call('sync')]
439+
440+
self.agent_extension.install_bootloader(
441+
root_uuid=self.fake_root_uuid,
442+
efi_system_part_uuid=None).join()
443+
444+
mock_dispatch.assert_any_call('get_os_install_device')
445+
mock_dispatch.assert_any_call('get_boot_info')
446+
mkdir_mock.assert_called_once_with(self.fake_dir + '/boot/efi')
447+
mock_efi_bl.assert_called_once_with(self.fake_dir + '/boot/efi')
448+
mock_execute.assert_has_calls(expected)
449+
mock_utils_efi_part.assert_called_once_with(self.fake_dev)
450+
self.assertEqual(10, mock_execute.call_count)
451+
389452
@mock.patch.object(hardware, 'is_md_device', lambda *_: False)
390453
@mock.patch.object(os.path, 'exists', lambda *_: False)
391454
@mock.patch.object(iscsi, 'clean_up', autospec=True)
@@ -2184,8 +2247,8 @@ def test__manage_uefi_found_csv(self, mkdir_mock, mock_utils_efi_part,
21842247
BootCurrent: 0001
21852248
Timeout: 0 seconds
21862249
BootOrder: 0000,00001
2187-
Boot0000: Vendor String HD(1, GPT,4f3c6294-bf9b-4208-9808-be45dfc34b5c)File(\EFI\Boot\BOOTX64.EFI)
2188-
Boot0001: Vendor String HD(2, GPT,4f3c6294-bf9b-4208-9808-be45dfc34b5c)File(\EFI\Boot\BOOTX64.EFI)
2250+
Boot0000* Vendor String HD(1,GPT,4f3c6294-bf9b-4208-9808-be45dfc34b5c)File(\EFI\Boot\BOOTX64.EFI)
2251+
Boot0001 Vendor String HD(2,GPT,4f3c6294-bf9b-4208-9808-be45dfc34b5c)File(\EFI\Boot\BOOTX64.EFI)
21892252
Boot0002: VENDMAGIC FvFile(9f3c6294-bf9b-4208-9808-be45dfc34b51)
21902253
""" # noqa This is a giant literal string for testing.
21912254

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
fixes:
3+
- |
4+
Fixes a minor issue with the regular expression used for UEFI duplicate
5+
entry cleanup which was introduced in a prior change to refactor the
6+
cleanup operation to avoid UEFI firmware which treats deletion of
7+
entries after addition as an invalid operation.

0 commit comments

Comments
 (0)