From 83a6274563ed0d50bd95e77db7dd60db2db9da7f Mon Sep 17 00:00:00 2001 From: Steve Baker Date: Thu, 3 Jun 2021 13:16:55 +1200 Subject: [PATCH] Ignore efi grub2-install failure Recent releases of redhat grub2 will always fail when installing to EFI paths, to encourage a transition to the signed shim bootloader. Partition image deploys avoid calling grub2-install with the preserve-efi-assets functions. Deploying whole disk images doesn't require grub2-install. This leaves whole disk images installed onto softraid devices, which still attempts to call grub2-install. This change will still attempt to run grub2-install in this one remaining case, but will ignore any failure. A future enhancement can avoid calling grub2-install entirely so that non-redhat secure-boot capable images can keep their signed bootloaders. Story: 2008923 Task: 42521 Change-Id: If432ef795d64d76442d739eb4f7d155ff847041e (cherry picked from commit a057be7dadc898ec813b2cac14913cd8523fbbcc) --- ironic_python_agent/extensions/image.py | 60 ++++++++++--------- .../tests/unit/extensions/test_image.py | 20 ++++++- ...ignore-grub-efi-fail-dcf7eb07f61f4388.yaml | 10 ++++ 3 files changed, 61 insertions(+), 29 deletions(-) create mode 100644 releasenotes/notes/ignore-grub-efi-fail-dcf7eb07f61f4388.yaml diff --git a/ironic_python_agent/extensions/image.py b/ironic_python_agent/extensions/image.py index d90edeaa6..5224cb773 100644 --- a/ironic_python_agent/extensions/image.py +++ b/ironic_python_agent/extensions/image.py @@ -706,34 +706,38 @@ def _install_grub2(device, root_uuid, efi_system_part_uuid=None, utils.execute('mount', efi_partition, efi_partition_mount_point) efi_mounted = True - # FIXME(rg): does not work in cross boot mode case (target - # boot mode differs from ramdisk one) - # Probe for the correct target (depends on the arch, example - # --target=x86_64-efi) - utils.execute('chroot %(path)s /bin/sh -c ' - '"%(bin)s-install"' % - {'path': path, 'bin': binary_name}, - shell=True, - env_variables={ - 'PATH': path_variable - }) - # Also run grub-install with --removable, this installs grub to - # the EFI fallback path. Useful if the NVRAM wasn't written - # correctly, was reset or if testing with virt as libvirt - # resets the NVRAM on instance start. - # This operation is essentially a copy operation. Use of the - # --removable flag, per the grub-install source code changes - # the default file to be copied, destination file name, and - # prevents NVRAM from being updated. - # We only run grub2_install for uefi if we can't verify the - # uefi bits - utils.execute('chroot %(path)s /bin/sh -c ' - '"%(bin)s-install --removable"' % - {'path': path, 'bin': binary_name}, - shell=True, - env_variables={ - 'PATH': path_variable - }) + try: + utils.execute('chroot %(path)s /bin/sh -c ' + '"%(bin)s-install"' % + {'path': path, 'bin': binary_name}, + shell=True, + env_variables={ + 'PATH': path_variable + }) + except processutils.ProcessExecutionError as e: + LOG.warning('Ignoring GRUB2 boot loader installation failure: ' + '%s.', e) + try: + # Also run grub-install with --removable, this installs grub to + # the EFI fallback path. Useful if the NVRAM wasn't written + # correctly, was reset or if testing with virt as libvirt + # resets the NVRAM on instance start. + # This operation is essentially a copy operation. Use of the + # --removable flag, per the grub-install source code changes + # the default file to be copied, destination file name, and + # prevents NVRAM from being updated. + # We only run grub2_install for uefi if we can't verify the + # uefi bits + utils.execute('chroot %(path)s /bin/sh -c ' + '"%(bin)s-install --removable"' % + {'path': path, 'bin': binary_name}, + shell=True, + env_variables={ + 'PATH': path_variable + }) + except processutils.ProcessExecutionError as e: + LOG.warning('Ignoring GRUB2 boot loader installation failure: ' + '%s.', e) utils.execute('umount', efi_partition_mount_point, attempts=3, delay_on_retry=True) efi_mounted = False diff --git a/ironic_python_agent/tests/unit/extensions/test_image.py b/ironic_python_agent/tests/unit/extensions/test_image.py index 6778527cf..4a2fbe74f 100644 --- a/ironic_python_agent/tests/unit/extensions/test_image.py +++ b/ironic_python_agent/tests/unit/extensions/test_image.py @@ -1840,6 +1840,21 @@ Boot0004* ironic1 HD(1,GPT,55db8d03-c8f6-4a5b-9155-790dddc348fa,0x800,0x640 mock_is_md_device, mock_execute, mock_dispatch): + # return success for every execute call + mock_execute.side_effect = [('', '')] * 21 + + # make grub2-install calls fail + grub_failure = processutils.ProcessExecutionError( + stdout='', + stderr='grub2-install: error: this utility cannot be used ' + 'for EFI platforms because it does not support ' + 'UEFI Secure Boot.\n', + exit_code=1, + cmd='grub2-install' + ) + mock_execute.side_effect[9] = grub_failure + mock_execute.side_effect[10] = grub_failure + mock_get_part_uuid.side_effect = [self.fake_root_part, self.fake_efi_system_part] environ_mock.get.return_value = '/sbin' @@ -1851,7 +1866,10 @@ 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('mount', '/dev/fake2', self.fake_dir), + expected = [mock.call('partx', '-a', '/dev/fake', attempts=3, + delay_on_retry=True), + mock.call('udevadm', 'settle'), + mock.call('mount', '/dev/fake2', self.fake_dir), mock.call('mount', '-o', 'bind', '/dev', self.fake_dir + '/dev'), mock.call('mount', '-o', 'bind', '/proc', diff --git a/releasenotes/notes/ignore-grub-efi-fail-dcf7eb07f61f4388.yaml b/releasenotes/notes/ignore-grub-efi-fail-dcf7eb07f61f4388.yaml new file mode 100644 index 000000000..87b00b936 --- /dev/null +++ b/releasenotes/notes/ignore-grub-efi-fail-dcf7eb07f61f4388.yaml @@ -0,0 +1,10 @@ +--- +fixes: + - | + Recent releases of redhat grub2 will always fail when installing to EFI + paths, to encourage a transition to the signed shim bootloader. Partition + image deploys avoid calling grub2-install with the preserve-efi-assets + functions. Deploying whole disk images doesn't require grub2-install. This + leaves whole disk images installed onto softraid devices, which still calls + grub2-install. Running grub2-install is still attempted in this one + remaining case, but any failures are now ignored. \ No newline at end of file