Skip to content

Commit

Permalink
Fixes #37653 - Always load local disk's GRUB2 configuration
Browse files Browse the repository at this point in the history
Load the local disk's GRUB2 configuration regardless of weather
SecureBoot is enabled or not. This standardizes the boot process
under UEFI.

To support SecureBoot for arbitrary operating systems, support for
distribution vendor specific boot files is added separately.

The following existing approaches for local boot don't work (anymore).

Using `chainloader` command:
    - Not supported according to GRUB2 manual [1] if SecureBoot is
      enabled (even if supported by some distribution vendors).
    - Chainloading with disabled SecureBoot requires patched
      `connectefi` command on some platforms which is currently only
      supported by EL GRUB2 binaries.

Using `exit 1` to boot from next boot device by firmware:
    - Tests showed that this behavior is not deterministic across
      different distribution vendor specific boot files.
    - Additional effort would be required to ensure the correct boot
      order.
    - This was introduced with commit b6b3204 for enabled SecureBoot
      only and was already fixed with commit aca4023.

For Windows we still use chainloading as there is no local `grub.cfg`.
The default EL GRUB2 which is used in this case supports the
`connectefi` command. SecureBoot verification is done by the Microsoft
certificate in the db.

[1]: https://www.gnu.org/software/grub/manual/grub/html_node/UEFI-secure-boot-and-shim.html#UEFI-secure-boot-and-shim
  • Loading branch information
goarsna committed Aug 28, 2024
1 parent 175b5f2 commit 022574b
Show file tree
Hide file tree
Showing 4 changed files with 5 additions and 485 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,12 @@ name: pxegrub2_chainload
model: ProvisioningTemplate
snippet: true
description: |
In Foreman's typical PXE workflow, managed hosts are configured to always boot from network and inventory build flag dictates if they should boot into installer (build is on) or boot from local drive (build is off). This template is used to chainload from EFI ESP for systems which booted from network. It is not as straightforward as in BIOS and EFI boot file must be found on an ESP partition.
In Foreman's typical PXE workflow, managed hosts are configured to always boot from network and inventory build flag dictates if they should boot into installer (build is on) or boot from local drive (build is off). This template first tries to load different GRUB2 configuration files from local ESP, then to chainload EFI binaries from ESP.
This will only be needed when provisioned hosts are set to boot from network, typically EFI firmware implementations overrides boot order after new OS installation. This behavior can be set in EFI, or "efi_bootentry" host parameter can be set to "previous" to override boot order back to previous (network) setting. See efibootmgr_netboot snippet for more info.
-%>
<%
paths = [
'/EFI/fedora/shim.efi',
'/EFI/fedora/grubx64.efi',
'/EFI/redhat/shim.efi',
'/EFI/redhat/grubx64.efi',
'/EFI/centos/shim.efi',
'/EFI/centos/grubx64.efi',
'/EFI/rocky/shim.efi',
'/EFI/rocky/grubx64.efi',
'/EFI/almalinux/shim.efi',
'/EFI/almalinux/grubx64.efi',
'/EFI/debian/grubx64.efi',
'/EFI/ubuntu/grubx64.efi',
'/EFI/sles/grubx64.efi',
'/EFI/opensuse/grubx64.efi',
'/EFI/Microsoft/boot/bootmgfw.efi'
]
config_paths = [
Expand Down Expand Up @@ -67,12 +53,7 @@ echo
"connectefi #{connectefi_option}" if connectefi_option
%>

if [ "${lockdown}" == "y" ]; then
if [ "${default}" == "local" ]; then
set default="grub_config"
fi

menuentry 'Loading GRUB2 config from ESP' --id grub_config {
menuentry 'Loading system from ESP' --id local {
<%
config_paths.each do |config_path|
-%>
Expand All @@ -85,14 +66,6 @@ if [ "${lockdown}" == "y" ]; then
fi
<%
end
-%>
}
fi

menuentry 'Chainload Grub2 EFI from ESP' --id local_chain_hd0 {
echo "Chainloading Grub2 EFI from ESP, enabled devices for booting:"
ls
<%
paths.each do |path|
-%>
echo "Trying <%= path %> "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,7 @@ echo "(*) grub2-efi-x64-2.02-122.el8 (upstream doesn't have the patches yet)"
echo
connectefi scsi

if [ "${lockdown}" == "y" ]; then
if [ "${default}" == "local" ]; then
set default="grub_config"
fi

menuentry 'Loading GRUB2 config from ESP' --id grub_config {
menuentry 'Loading system from ESP' --id local {
echo "Trying /EFI/fedora/grub.cfg"
unset chroot
# add --efidisk-only when using Software RAID
Expand Down Expand Up @@ -95,152 +90,6 @@ if [ "${lockdown}" == "y" ]; then
if [ -f ($chroot)/EFI/opensuse/grub.cfg ]; then
configfile ($chroot)/EFI/opensuse/grub.cfg
fi
}
fi

menuentry 'Chainload Grub2 EFI from ESP' --id local_chain_hd0 {
echo "Chainloading Grub2 EFI from ESP, enabled devices for booting:"
ls
echo "Trying /EFI/fedora/shim.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/fedora/shim.efi
if [ -f ($chroot)/EFI/fedora/shim.efi ]; then
chainloader ($chroot)/EFI/fedora/shim.efi
echo "Found /EFI/fedora/shim.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/fedora/grubx64.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/fedora/grubx64.efi
if [ -f ($chroot)/EFI/fedora/grubx64.efi ]; then
chainloader ($chroot)/EFI/fedora/grubx64.efi
echo "Found /EFI/fedora/grubx64.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/redhat/shim.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/redhat/shim.efi
if [ -f ($chroot)/EFI/redhat/shim.efi ]; then
chainloader ($chroot)/EFI/redhat/shim.efi
echo "Found /EFI/redhat/shim.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/redhat/grubx64.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/redhat/grubx64.efi
if [ -f ($chroot)/EFI/redhat/grubx64.efi ]; then
chainloader ($chroot)/EFI/redhat/grubx64.efi
echo "Found /EFI/redhat/grubx64.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/centos/shim.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/centos/shim.efi
if [ -f ($chroot)/EFI/centos/shim.efi ]; then
chainloader ($chroot)/EFI/centos/shim.efi
echo "Found /EFI/centos/shim.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/centos/grubx64.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/centos/grubx64.efi
if [ -f ($chroot)/EFI/centos/grubx64.efi ]; then
chainloader ($chroot)/EFI/centos/grubx64.efi
echo "Found /EFI/centos/grubx64.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/rocky/shim.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/rocky/shim.efi
if [ -f ($chroot)/EFI/rocky/shim.efi ]; then
chainloader ($chroot)/EFI/rocky/shim.efi
echo "Found /EFI/rocky/shim.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/rocky/grubx64.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/rocky/grubx64.efi
if [ -f ($chroot)/EFI/rocky/grubx64.efi ]; then
chainloader ($chroot)/EFI/rocky/grubx64.efi
echo "Found /EFI/rocky/grubx64.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/almalinux/shim.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/almalinux/shim.efi
if [ -f ($chroot)/EFI/almalinux/shim.efi ]; then
chainloader ($chroot)/EFI/almalinux/shim.efi
echo "Found /EFI/almalinux/shim.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/almalinux/grubx64.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/almalinux/grubx64.efi
if [ -f ($chroot)/EFI/almalinux/grubx64.efi ]; then
chainloader ($chroot)/EFI/almalinux/grubx64.efi
echo "Found /EFI/almalinux/grubx64.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/debian/grubx64.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/debian/grubx64.efi
if [ -f ($chroot)/EFI/debian/grubx64.efi ]; then
chainloader ($chroot)/EFI/debian/grubx64.efi
echo "Found /EFI/debian/grubx64.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/ubuntu/grubx64.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/ubuntu/grubx64.efi
if [ -f ($chroot)/EFI/ubuntu/grubx64.efi ]; then
chainloader ($chroot)/EFI/ubuntu/grubx64.efi
echo "Found /EFI/ubuntu/grubx64.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/sles/grubx64.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/sles/grubx64.efi
if [ -f ($chroot)/EFI/sles/grubx64.efi ]; then
chainloader ($chroot)/EFI/sles/grubx64.efi
echo "Found /EFI/sles/grubx64.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/opensuse/grubx64.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/opensuse/grubx64.efi
if [ -f ($chroot)/EFI/opensuse/grubx64.efi ]; then
chainloader ($chroot)/EFI/opensuse/grubx64.efi
echo "Found /EFI/opensuse/grubx64.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/Microsoft/boot/bootmgfw.efi "
unset chroot
# add --efidisk-only when using Software RAID
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,7 @@ echo "(*) grub2-efi-x64-2.02-122.el8 (upstream doesn't have the patches yet)"
echo
connectefi scsi

if [ "${lockdown}" == "y" ]; then
if [ "${default}" == "local" ]; then
set default="grub_config"
fi

menuentry 'Loading GRUB2 config from ESP' --id grub_config {
menuentry 'Loading system from ESP' --id local {
echo "Trying /EFI/fedora/grub.cfg"
unset chroot
# add --efidisk-only when using Software RAID
Expand Down Expand Up @@ -111,152 +106,6 @@ if [ "${lockdown}" == "y" ]; then
if [ -f ($chroot)/EFI/opensuse/grub.cfg ]; then
configfile ($chroot)/EFI/opensuse/grub.cfg
fi
}
fi

menuentry 'Chainload Grub2 EFI from ESP' --id local_chain_hd0 {
echo "Chainloading Grub2 EFI from ESP, enabled devices for booting:"
ls
echo "Trying /EFI/fedora/shim.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/fedora/shim.efi
if [ -f ($chroot)/EFI/fedora/shim.efi ]; then
chainloader ($chroot)/EFI/fedora/shim.efi
echo "Found /EFI/fedora/shim.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/fedora/grubx64.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/fedora/grubx64.efi
if [ -f ($chroot)/EFI/fedora/grubx64.efi ]; then
chainloader ($chroot)/EFI/fedora/grubx64.efi
echo "Found /EFI/fedora/grubx64.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/redhat/shim.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/redhat/shim.efi
if [ -f ($chroot)/EFI/redhat/shim.efi ]; then
chainloader ($chroot)/EFI/redhat/shim.efi
echo "Found /EFI/redhat/shim.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/redhat/grubx64.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/redhat/grubx64.efi
if [ -f ($chroot)/EFI/redhat/grubx64.efi ]; then
chainloader ($chroot)/EFI/redhat/grubx64.efi
echo "Found /EFI/redhat/grubx64.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/centos/shim.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/centos/shim.efi
if [ -f ($chroot)/EFI/centos/shim.efi ]; then
chainloader ($chroot)/EFI/centos/shim.efi
echo "Found /EFI/centos/shim.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/centos/grubx64.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/centos/grubx64.efi
if [ -f ($chroot)/EFI/centos/grubx64.efi ]; then
chainloader ($chroot)/EFI/centos/grubx64.efi
echo "Found /EFI/centos/grubx64.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/rocky/shim.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/rocky/shim.efi
if [ -f ($chroot)/EFI/rocky/shim.efi ]; then
chainloader ($chroot)/EFI/rocky/shim.efi
echo "Found /EFI/rocky/shim.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/rocky/grubx64.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/rocky/grubx64.efi
if [ -f ($chroot)/EFI/rocky/grubx64.efi ]; then
chainloader ($chroot)/EFI/rocky/grubx64.efi
echo "Found /EFI/rocky/grubx64.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/almalinux/shim.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/almalinux/shim.efi
if [ -f ($chroot)/EFI/almalinux/shim.efi ]; then
chainloader ($chroot)/EFI/almalinux/shim.efi
echo "Found /EFI/almalinux/shim.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/almalinux/grubx64.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/almalinux/grubx64.efi
if [ -f ($chroot)/EFI/almalinux/grubx64.efi ]; then
chainloader ($chroot)/EFI/almalinux/grubx64.efi
echo "Found /EFI/almalinux/grubx64.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/debian/grubx64.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/debian/grubx64.efi
if [ -f ($chroot)/EFI/debian/grubx64.efi ]; then
chainloader ($chroot)/EFI/debian/grubx64.efi
echo "Found /EFI/debian/grubx64.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/ubuntu/grubx64.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/ubuntu/grubx64.efi
if [ -f ($chroot)/EFI/ubuntu/grubx64.efi ]; then
chainloader ($chroot)/EFI/ubuntu/grubx64.efi
echo "Found /EFI/ubuntu/grubx64.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/sles/grubx64.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/sles/grubx64.efi
if [ -f ($chroot)/EFI/sles/grubx64.efi ]; then
chainloader ($chroot)/EFI/sles/grubx64.efi
echo "Found /EFI/sles/grubx64.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/opensuse/grubx64.efi "
unset chroot
# add --efidisk-only when using Software RAID
search --file --no-floppy --set=chroot /EFI/opensuse/grubx64.efi
if [ -f ($chroot)/EFI/opensuse/grubx64.efi ]; then
chainloader ($chroot)/EFI/opensuse/grubx64.efi
echo "Found /EFI/opensuse/grubx64.efi at $chroot, attempting to chainboot it..."
sleep 2
boot
fi
echo "Trying /EFI/Microsoft/boot/bootmgfw.efi "
unset chroot
# add --efidisk-only when using Software RAID
Expand Down
Loading

0 comments on commit 022574b

Please sign in to comment.