Skip to content

extend-payload-to-esp: extends any src_input_dir to esp #935

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

say-paul
Copy link
Collaborator

@say-paul say-paul commented May 27, 2025

should fix: #651
To support raspberry pi 4, which works well for rpm-ostree, but in bootc. I intend(commented out) to copy over the uboot binary

RUN dnf install -y uboot-images-armv8
 # cp -P /usr/share/uboot/rpi_arm64/u-boot.bin /boot/efi/rpi-u-boot.bin

my steps to achieve this:

@say-paul
Copy link
Collaborator Author

I am still trying to build an image with this feature , but with no luck,
My Containerfile looks like this:

FROM quay.io/fedora/fedora-iot:42-x86_64
RUN dnf install -y make cargo rust glib2-devel openssl-devel ostree-devel git
    
RUN git clone -b firmware-copy https://github.com/say-paul/bootupd.git && \
    mkdir -p /boot/efi && \
    touch /boot/efi/dummy.{dtb,dat,efi,elf,bin}

WORKDIR bootupd
RUN export CARGO_HOME=/tmp/.cargo && \
    mkdir -p $CARGO_HOME && \
    cargo build --release
RUN make install

After building the image with bib, I don't see the files in /boot/efi.

@say-paul say-paul changed the title Copy firmware blobs to boot/efi to ensure that the aarch64 Copy firmware blobs to boot/efi of the disk image May 28, 2025
@say-paul say-paul changed the title Copy firmware blobs to boot/efi of the disk image Copy firmware blobs to /boot/efi of the disk image May 28, 2025
Copy link
Member

@cgwalters cgwalters left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this!

src/efi.rs Outdated

/// Copy firmware files from /boot/efi to target directory
fn copy_firmware_blobs(&self, src_root: &openat::Dir, dest_root: &str) -> Result<()> {
let src_efi = "boot/efi";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A core design principle that bootupd tries to maintain is that the operating system payload is underneath /usr as much as possible.

Today in bootc (and prior ostree) we encourage /boot to be empty in the container image. bootupd takes care at build time of moving the payloads to /usr.

It also has infrastructure to keep track of the versions of things it installs so it knows when to update.

So the problem domain is just more complex than this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's more discussion in #766 (let's make that the canonical issue).

Copy link
Collaborator Author

@say-paul say-paul May 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ran: #936 on my current implementation with an additional step of creating the files in /boot:

# Build from the current git into a c9s-bootc container image.
# Use e.g. --build-arg=base=quay.io/fedora/fedora-bootc:41 to target
# Fedora or another base image instead.
#
ARG base=quay.io/centos-bootc/centos-bootc:stream9

FROM $base as build
# This installs our package dependencies, and we want to cache it independently of the rest.
# Basically we don't want changing a .rs file to blow out the cache of packages.
RUN <<EORUN
set -xeuo pipefail
dnf -y install cargo git openssl-devel
EORUN

RUN mkdir -p /boot/firmware/efi && \
    touch /boot/firmware/efi/dummy.{dtb,dat,efi,elf,bin}
# Now copy the source
COPY . /build
WORKDIR /build
# See https://www.reddit.com/r/rust/comments/126xeyx/exploring_the_problem_of_faster_cargo_docker/
# We aren't using the full recommendations there, just the simple bits.
RUN --mount=type=cache,target=/build/target --mount=type=cache,target=/var/roothome \
    make && make install-all DESTDIR=/out
  
# FROM $base
# # Clean out the default to ensure we're using our updated content
# RUN rpm -e bootupd
# COPY --from=build /out/ /
# # Sanity check this too
# RUN bootc container lint --fatal-warnings
  
    

From #755

Content shipped in an RPM with files in /boot that are present in the initial base image build where bootupctl backend generate-update-payload is invoked

The build container has the dummy files:

bash-5.2# ls /boot/firmware/efi/          
dummy.bin  dummy.dat  dummy.dtb  dummy.efi  dummy.elf

but the final image that is built using the COPY --from=build /out/ / doesn't have the files, 😕

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this function can be modified into a generic one to copy files, but I am not sure how to trigger it from the container build process

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but the final image that is built using the COPY --from=build /out/ / doesn't have the files, 😕

The build image is only intended to hold the result of building the bootupd binary itself. If you want to modify the final image for other reasons (e.g. injecting kernel arguments, adding debug tools or other configuration, and as in this case inject arbitrary other content) then you should put it on the last stage.

Or better even - don't modify the dockerfile, make a new one and have it be FROM localhost/bootupd.

@cgwalters
Copy link
Member

My Containerfile looks like this:

Can you try out #936 ? It has several advantages, but the biggest will be that you can just podman build it and it will do incremental builds from what's in local git, instead of hardcoding your repo.

@say-paul say-paul changed the title Copy firmware blobs to /boot/efi of the disk image Copy files using sub command install-to-filesystem Jun 5, 2025
@say-paul say-paul requested a review from cgwalters June 5, 2025 14:33
@cgwalters
Copy link
Member

Thank you for working on this. I propose that we continue design discussion (e.g. what the interface should look like) in #766 (comment) and I'll comment on the PR for code review.

But a specific downside of what you're doing here is that it would require all tools calling bootupd to be changed (particularly bootc) and to have specific knowledge of what should be installed.

Whereas the goal of bootupd is to abstract that from callers (like bootc) - the person building the container extends the payload, and bootc shouldn't need to know it's copying more files to the ESP.

Also, crucially, my proposal there would also transparently handle updates, which is an important goal.

@say-paul say-paul changed the title Copy files using sub command install-to-filesystem extend-payload-to-esp: extends any src_input_dir to esp Jun 19, 2025
@say-paul say-paul force-pushed the firmware-copy branch 3 times, most recently from 634cf2f to 9bac770 Compare June 19, 2025 12:09
@say-paul
Copy link
Collaborator Author

It should now stage the updates for any user input path,
I think we have to additionally chain this in efi::{install,run_update}
Its very similar to generate_update_metadata but with an user_input.

@travier
Copy link
Member

travier commented Jun 20, 2025

A lot of questions are unanswered here:

  • Is those firmware files versioned?
  • Is it always installed under the same name?
  • Is it tied to a kernel version?
  • What happens when we rollback?

Overall, I would suggest we work toward #926 which should get us to #766.

@say-paul
Copy link
Collaborator Author

say-paul commented Jun 20, 2025

The goal has changed with iterations of the idea and other effort on: #938 , So I updated the PR's main goal on my first comment

Is those firmware files versioned?

Yes, i can keep checks (rpm -qa) if we want to harden it.

Is it always installed under the same name?

I dont understand, User can extend _any_payload
example:
user can do this:

RUN dnf install -y uboot-images-armv8  # which installs  /usr/lib/uboot/rpi4/Uboot.bin
RUN bootupctl backend extend-payload-to-esp  /usr/lib/uboot/rpi4

Is it tied to a kernel version?

I don't know, since the command is flexible to extend anything , do we need some sort of check?

What happens when we rollback?

Since this integrates with bootupd, by moving the files to /usr/lib/bootupd/updates/ , I think(<100% sure) rollback will work....!!!

Overall, I would suggest we work toward #926 which should get us to #766.

Here's how it plays in with #926 : bootupctl backend extend-payload-to-esp /usr/lib/uboot/rpi4 can put the files in the necessary format as laid out by #926 so that generate-update-metadata can read from it.(some modifications required in the PR)

@say-paul
Copy link
Collaborator Author

This should now be inline with to what is required by #926

@say-paul
Copy link
Collaborator Author

say-paul commented Jun 20, 2025

We need to teach generate-update-metadata in #938 to read from /firmware/
and stage it for updates:
bootup extend-payload-to-esp /boot/efi to extend firmware to /usr usecase - > files installed in /bbot/efi by bcm2711-firmware.rpm
and also:
bootup extend-payload-to-esp /usr/share/uboot/rpi_arm64 -> use-case: copy /usr/share/uboot/rpi_arm64/rpi-u-boot.bin installed by uboot-images-armv8.rpm

Bootup extend_payload_to_esp <path> will move the it to /usr

This features gives user ability to stage payloads to be picked up by
metadata generator.This will help in mounting fimwares and uboot binaries
to esp as required by rpi4.
example usage: `bootupctl backend extend_payload_to_esp /usr/lib/mydata`
will move the content of the dir to
`/usr/lib/efi/firmware/<name>/<version>/EFI/boot/efi/`
@say-paul
Copy link
Collaborator Author

@travier please let me know if I am missing anything.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support for Raspberry Pi firmwares/bootloaders
4 participants