From Fedora Project Wiki

mNo edit summary
mNo edit summary
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
= Unification of boot loader updates, phase 1 =
Moved to [https://fedoraproject.org/wiki/Changes/BootLoaderUpdatesPhase1 Changes/BootLoaderUpdatesPhase1]
 
{{Change_Proposal_Banner}}
 
== Summary ==
 
Begin the process of using single tool (likely bootupd) for most boot loader updates, especially grub and shim. This decouples package installation, e.g., via rpm transaction, from actual update in /boot, /boot/efi. This change does not affect zipl and systemd-boot.
 
Note: The implementation details for this change are not fully fleshed out yet but we believe that there is a general agreement that we should go this way so we are submitting it so that we can start the discussion around how we should implement it. We will update the change based on feedback from those discussions.
 
== Owner ==
 
* Name/Emails:
** [[User:Siosm| Timothée Ravier]] siosm@fedoraproject.org (Atomic Desktops, CoreOS, bootc)
** [[User:Walters| Colin Walters]] walters@verbum.org (bootupd, bootc)
** Bootloader team member / maintainer needed here 🙂
 
== Current status ==
 
[[Category:ChangePageIncomplete]]
<!-- When your change proposal page is completed and ready for review and announcement -->
<!-- remove Category:ChangePageIncomplete and change it to Category:ChangeReadyForWrangler -->
<!-- The Wrangler announces the Change to the devel-announce list and changes the category to Category:ChangeAnnounced (no action required) -->
<!-- After review, the Wrangler will move your page to Category:ChangeReadyForFesco... if it still needs more work it will move back to Category:ChangePageIncomplete-->
 
[[Category:SystemWideChange]]
 
* Targeted release: [https://docs.fedoraproject.org/en-US/releases/f42/ Fedora Linux 42]
* Last updated: <!-- this is an automatic macro — you don't need to change this line -->  {{REVISIONYEAR}}-{{REVISIONMONTH}}-{{REVISIONDAY2}}
<!-- After the change proposal is accepted by FESCo, tracking bug is created in Bugzilla and linked to this page
Bugzilla state meanings:
ASSIGNED -> accepted by FESCo with ongoing development
MODIFIED -> change is substantially done and testable
ON_QA -> change is fully code complete
-->
* [Announced]
* [<will be assigned by the Wrangler> Discussion thread]
* FESCo issue: <will be assigned by the Wrangler>
* Tracker bug: <will be assigned by the Wrangler>
* Release notes tracker: <will be assigned by the Wrangler>
 
== Detailed Description ==
 
Our goal is to make boot loader updates in all environments: rpm mode, image mode, etc., safer and more reliable, and to add a fallback option so that a system is always bootable. We want to use a single interface, bootupd, to perform the actual boot loader update on a system once all new packages have been installed on that system.
 
On rpm-based systems, most components are updated monolithically along with boot loader packages, which automatically install into the /boot and/or /boot/efi directories, overwriting binaries that were there. Notably, kernel installation is performed via systemd script kernel-install, which runs at the end of the rpm transaction. Each distribution has a single directory structure constituting its bootpath, and if anything goes wrong during the subsequent boot, repair can be difficult or even impossible.
 
On image-based systems, the boot loader update is decoupled from the system update, but, bootupd, once triggered, will also overwrite entries in /boot & /boot/efi, and any problem with the boot loaders has the potential to create an unbootable and unrecoverable system.
 
Rather than using different, yet equally precarious, methods for updating these critical components, we want to adapt bootupd to work on all systems in order to make boot loader updates easier and safer. It would additionally be aware of dependencies between packages, such as boot loaders and kernels. bootupd would be the interface that is used on all systems to perform the actual update once all new packages are available, and it would in the future retain a fallback option in case any problem arises during the subsequent boot process.
 
This change will be split into two phases:
 
Phase 1 (this change, proposed for Fedora 42)
* Install the following packages into /usr/lib/<pkg>/<arch> rather than /boot & /boot/efi
** grub2
** shim
* Separate rpm actions that happen at build time vs. runtime:
** Add a mechanism that installs the bootloader for package mode installations as part of a RPM post trans. It is not yet defined how that will happen. Options that were suggested:
*** Add a dumb Bash script that copies the bootloader to the ESP
*** Add a new action verb to kernel-install, which will run script(s) for given component
*** Adapt bootupd to cover this case
* Teach new boot loader location (/usr) to bootupd (needed for rpm-ostree & Bootable Containers variants)
* Extend systemd package-notes to support PE files
 
Phase 2 (will be proposed for Fedora 43)
* Add A/B support, BootNext to bootupd https://github.com/coreos/bootupd/issues/440
* Unify on bootupd to perform all boot loader updates at both system install (e.g. Anaconda) time and for updates
* Install bootupd on dnf and image based systems by default
* Consider switching to a static GRUB configuration file (to be detailed)
 
In phase 1 of this change, we will focus on moving the content included in the grub and shim packages from /boot and /boot/efi to /usr and adding the logic needed to install them to /boot as part of a posttrans script.
 
Moving the content from /boot and /boot/efi to /usr (in the RPM packages) is a pre-requisite for all the potential future improvements as it decouples the bootloader installation phase via the RPM (that happens offline for all image mode systems and image builds in general) from the actual update in the ESP and any runtime EFI variable updates.
 
As we move the bootloader and shim to /usr, we now need a mechanism to sync the content from /usr to /boot and the ESP (and the MBR for BIOS systems, but we already have to do that). In all cases, the current suggestion is to do this synchronization step as part of a posttrans trigger at the end of the RPM transaction.
 
The first suggested option is to add a “dumb” Bash script that copies the new bootloader to the ESP partition.
 
The second suggested option is to add scripts to the kernel/install.d directory. Currently, when a new kernel gets installed, kernel-install (systemd) runs and invokes a number of bash and python scripts in /usr/lib/kernel/install.d/ which make the initramfs, create BLS entries, etc. We could extend kernel-install to add a new action that will be triggered when the relevant components (shim, grub2, sd-boot) are updated.
 
The third option is to adapt bootupd to install the updated bootloader to cover this case and run as part of the posttrans trigger.
 
In phase 2, we will look at unifying in a single tool how we do bootloader and shim updates, likely using bootupd, and extend the safe of boot loader updates, mainly on EFI based systems.
 
We will teach bootupd how to create a full new boot chain, e.g., shim -> grub2 -> kernel, based on newly installed components while retaining the working boot chain as a fallback option. Upon reboot, the new boot chain will be attempted, and if successful, set as the new default/fallback.
 
We will also need to choose how to trigger the script(s) so that in the end all new content is in a single directory in /boot, and a new efi entry is created for that directory and set to BootNext.
 
It has not yet been decided what trigger will be used to initiate the update. There is an idea to create a new systemd target, but obviously this has to happen before the system is rebooted.
 
One possibility is to use the reboot/poweroff target as the trigger: in case the system is powered off accidentally, no update would occur. If the user chooses to reboot, the new boot chain will be created just before shutdown so that it can be set as BootNext.
 
It has been proposed to use systemd package-notes for version numbers to track dependencies between kernels and boot loaders. This would remove bootupd’s dependency on rpm to scrape package numbers.
 
Architecture comments:
 
Phase 1 is architecture agnostic.
 
Our current targets for phase 2 are UEFI based systems: x86_64 and aarch64. Additionally, we believe ppc64le will want this support and will thus make itself more compliant in the meantime. s390 systems are out of scope at this time.
 
== Feedback ==
 
Q: What about UKIs?
 
A: This should not impact setups with UKIs. We will not touch the bootloader configuration itself or how GRUB works as part of this change.
 
== Benefit to Fedora ==
 
Once phase 1 and 2 are complete:
*  Boot loader updates are safer and more reliable.
* The same mechanism is used for boot loader updates across Fedora products.
* Fallback to known working boot loader is always available.
 
== Scope ==
 
* Proposal owners:
** Packaging changes to move the content from /boot to /usr/lib/… for the shim and grub2 packages.
** Update the scripts needed to copy those files to /boot as part of a post-trans scriptlet
** Teach bootupd about these new paths
 
* Other developers:
** Other packages that install files in /boot and /boot/efi and other bootloader packages should adapt for this change as well. It should still continue to work if they don’t, but they won’t benefit from the changes.
 
* Release engineering: [https://pagure.io/releng/issues #Releng issue number]
 
* Policies and guidelines: N/A (not needed for this Change)
 
* Trademark approval: N/A (not needed for this Change)
 
* Alignment with the Fedora Strategy: Nothing specific
 
== Upgrade/compatibility impact ==
 
Changes will be self-consistent, so upgrading from the previous release should not be affected.
 
<!-- REQUIRED FOR SYSTEM WIDE CHANGES -->
 
== Early Testing (Optional) ==
 
<!-- This is an optional step for system-wide changes to avail of. If you would like to build an initial proof of concept of your change and have a member of Fedora QA help you write and/or run some initial basic tests on your code, please email tests@fedoraproject.org and include the link to your change proposal. This step is *optional*. -->
 
Do you require 'QA Blueprint' support? Unclear yet
 
We will reach out to QA as soon as we have a proof of concept ready for testing.
 
== How To Test ==
 
<!-- This does not need to be a full-fledged document. Describe the dimensions of tests that this change implementation is expected to pass when it is done.  This can be based off of the above section if early testing has been completed. If it needs to be tested with different hardware or software configurations, indicate them.  The more specific you can be, the better the community testing can be.
 
Remember that you are writing this how to for interested testers to use to check out your change implementation - documenting what you do for testing is OK, but it's much better to document what *I* can do to test your change.
 
A good "how to test" should answer these four questions:
 
0. What special hardware / data / etc. is needed (if any)?
1. How do I prepare my system to test this change? What packages
need to be installed, config files edited, etc.?
2. What specific actions do I perform to check that the change is
working like it's supposed to?
3. What are the expected results of those actions?
-->
 
We will make a COPR available with updated packages. Updating an existing system with the packages from this COPR should work and result in a working system without any specific action.
 
== User Experience ==
 
If this is done properly, this should be transparent for users.
 
fwupd does this already, as does systemd-boot (installs itself into /usr/lib/systemd/boot/efi). Other distributions, like Arch and Debian, install boot loaders into /usr/lib/grub/<platform> rather than into /boot directly.
 
== Dependencies ==
 
systemd:
* Extend package-notes to support PE files
* Add a new action to kernel-install script if this is the option that is decided
 
bootupd:
* Update to handle the new filesystem paths for the bootloader and shim components
* Add support to run as posttrans is this is the option that is decided
 
<!-- What other packages (RPMs) depend on this package?  Are there changes outside the developers' control on which completion of this change depends?  In other words, completion of another change owned by someone else and might cause you to not be able to finish on time or that you would need to coordinate?  Other upstream projects like the kernel (if this is not a kernel change)? -->
 
== Contingency Plan ==
 
If each component is updated consistently, then dependency on other components is minimal. Components that are dependent, will wait until dependencies have been fulfilled before making changes.
 
Example:
i) shim changes its installation location to /usr/lib/shim/x86_64/ and then runs a simple cp to move its components to /boot in posttrans;
ii) shim script is added to  /usr/lib/kernel/install.d/ and shim posttrans triggers the script, etc.
 
* Contingency deadline: Beta release
* Blocks release? Yes if not completed and not reverted
 
== Documentation ==
 
Documentation will have to be written.
 
== Release Notes ==
 
Fedora shim and grub2 packages are now installing content in /usr/lib/… and not in /boot and /boot/efi directly.

Latest revision as of 16:51, 19 December 2024