Skip to content

Commit

Permalink
payload/rpmostree: Add support for bootupd
Browse files Browse the repository at this point in the history
The https://github.com/coreos/bootupd project was created to
fill the gap in bootloader management for ostree-based systems.

When it was created, it was just integrated into Fedora CoreOS
and derivatives; this left the Atomic Desktops (Silverblue etc.)
as unfixed, and it was never used by RHEL for Edge.

This PR is aiming to circle back and close that gap.  We
detect if bootupd is in the target root; if it is, then
we should act as if `bootloader --location=none` had been
specified, and just run bootupd to perform the installation.

The other hacks we have around the grub config are no longer
necessary in this mode.
  • Loading branch information
cgwalters committed Nov 2, 2023
1 parent a70ac7c commit 6cfe7b3
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 4 deletions.
17 changes: 13 additions & 4 deletions pyanaconda/modules/payloads/payload/rpm_ostree/installation.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,8 @@ def _run(self):
be fixed to *copy* data into /boot at install time, instead of shipping it in the RPM).
"""
bootloader = STORAGE.get_proxy(BOOTLOADER)
if bootloader.use_bootupd:
return
is_efi = bootloader.IsEFI()

physboot = self._physroot + '/boot'
Expand Down Expand Up @@ -496,8 +498,10 @@ def name(self):
return "Configure OSTree bootloader"

def run(self):
self._move_grub_config()
self._set_kargs()
bootloader = STORAGE.get_proxy(BOOTLOADER)
if not bootloader.use_bootupd:
self._move_grub_config()
self._set_kargs(bootloader)

def _move_grub_config(self):
"""If using GRUB2, move its config file, also with a compatibility symlink."""
Expand All @@ -509,7 +513,7 @@ def _move_grub_config(self):
os.rename(boot_grub2_cfg, target_grub_cfg)
os.symlink('../loader/grub.cfg', boot_grub2_cfg)

def _set_kargs(self):
def _set_kargs(self, bootloader):
"""Set kernel arguments via OSTree-specific utils.
OSTree owns the bootloader configuration, so here we give it an argument list computed
Expand All @@ -520,7 +524,6 @@ def _set_kargs(self):
if conf.target.is_directory:
return

bootloader = STORAGE.get_proxy(BOOTLOADER)
device_tree = STORAGE.get_proxy(DEVICE_TREE)

root_name = device_tree.GetRootDevice()
Expand Down Expand Up @@ -749,3 +752,9 @@ def run(self):
deployment = deployments[0]
deployment_path = sysroot.get_deployment_directory(deployment)
set_system_root(deployment_path.get_path())

have_bootupd = os.path.exists(deployment_path.get_path() + '/usr/bin/bootupctl')
if have_bootupd:
log.info("Found bootupd in target root, disabling Anaconda bootloader installation")
bootloader = STORAGE.get_proxy(BOOTLOADER)
bootloader.set_use_bootupd()
13 changes: 13 additions & 0 deletions pyanaconda/modules/storage/bootloader/bootloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ def __init__(self):
self._password = ""
self._password_is_encrypted = False

# the ostree payload may turn this on if detected
self._use_bootupd = False

def publish(self):
"""Publish the module."""
DBus.publish_object(BOOTLOADER.object_path, BootloaderInterface(self))
Expand Down Expand Up @@ -447,6 +450,16 @@ def collect_requirements(self):

return requirements

@property
def use_bootupd(self):
"""Whether bootupd is enabled"""
return self._use_bootupd

def set_use_bootupd(self):
"""Install the bootloader using https://github.com/coreos/bootupd"""
self._use_bootupd = True
self.set_bootloader_mode(BootloaderMode.SKIPPED)

def install_bootloader_with_tasks(self, payload_type, kernel_versions):
"""Install the bootloader with a list of tasks.
Expand Down
28 changes: 28 additions & 0 deletions pyanaconda/modules/storage/bootloader/installation.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,34 @@ def run(self):
raise BootloaderInstallationError(str(e)) from None


class InstallBootloaderTaskViaBootupd(Task):
"""Installation task for the bootloader via bootupd"""

def __init__(self, storage, sysroot):
"""Create a new task."""
super().__init__()
self._storage = storage
self._sysroot = sysroot

@property
def name(self):
return "Install the bootloader"

def run(self):
"""Run the task.
:raise: BootloaderInstallationError if the installation fails
"""
rc = execWithRedirect(
"bootupctl",
["backend", "install", "--auto", "--with-static-configs",
"--device", self._storage.root_device, self._sysroot],
root=self._sysroot)
if rc:
raise BootloaderInstallationError(
"failed to write boot loader configuration")


class CreateBLSEntriesTask(Task):
"""The installation task that creates BLS entries."""

Expand Down

0 comments on commit 6cfe7b3

Please sign in to comment.