Skip to content

install: Add a bootloader none install option#1997

Open
martinezjavier wants to merge 3 commits intobootc-dev:mainfrom
martinezjavier:add-no-bootloader-opt
Open

install: Add a bootloader none install option#1997
martinezjavier wants to merge 3 commits intobootc-dev:mainfrom
martinezjavier:add-no-bootloader-opt

Conversation

@martinezjavier
Copy link

@martinezjavier martinezjavier commented Feb 11, 2026

Currently, the bootc install workflow assumes that the bootloader must be
managed by bootupd. This works well for server and edge environments, but
it is too inflexible for embedded or custom platforms where the bootloader
is managed externally (e.g., aboot for automotive use cases).

In these scenarios, users want to install the filesystem content (OSTree
commit, kernel, initramfs, etc), without bootc assuming that a boot or ESP
partition exists that have to be setup or udpated by bootupd.

By adding a --bootloader=none option users can have explicit control over
how the boot loading is handled, without bootc or bootupd intervention.

Note that so far only support for the ostree backend has been added and
the bootloader=none option is not supported by the composefs backend.

@github-actions github-actions bot added area/install Issues related to `bootc install` area/documentation Updates to the documentation labels Feb 11, 2026
@bootc-bot bootc-bot bot requested a review from henrywang February 11, 2026 12:47
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a --no-bootloader flag to skip bootloader management during installation, which is a valuable feature for custom environments. However, the current implementation has significant security implications and logic errors. In the ostree installation path, using this flag unintentionally skips all post-deployment operations, including the installation of logically bound images which may contain critical security components, potentially leaving the system in an insecure or incomplete state. Furthermore, in the composefs installation path, the --no-bootloader flag is completely ignored, leading to unexpected bootloader installation. These issues need to be addressed to ensure the flag behaves as expected and doesn't leave the system in an insecure or inconsistent state. My review includes detailed comments on how to resolve these problems.

@martinezjavier martinezjavier force-pushed the add-no-bootloader-opt branch 5 times, most recently from 1d743c2 to ea65bef Compare February 11, 2026 15:51
@ckyrouac
Copy link
Collaborator

If the approach is found to be
acceptable, a follow-up would be for bootc install to-filesystem to infer if the
option has to be set implicitly. For example if neither boot nor EFI partition exist.

Implicitly assuming the installation target will manage its own bootloader is a bit risky. The lack of an EFI partition could be the result of a mistake which would result in an installation that is not bootable. So I think it'd be best to keep this as an explicit option.

@cgwalters
Copy link
Collaborator

We already detect if bootupd is missing and assume systemd-boot (except for s390x). Arguably, we could extend that and just allow bootupd to be missing, and assume that bootloader state is handled after installation.

But I dunno...

Currently, the bootc install workflow assumes that the bootloader must be
managed by bootupd. This works well for server and edge environments, but
it is too inflexible for embedded or custom platforms where the bootloader
is managed externally (e.g., aboot for automotive use cases).

Also coreos/bootupd#766 is related here in that I think there's an argument that bootupd should gain support for other things.

Anyways just for my understanding, we still relying on the ostree aboot backend (which isn't implemented for composefs), correct?

To combine these two things, how about instead of --no-bootloader we detect the presence of aboot, and set it as the backend if it's part of the tree?

@alexlarsson
Copy link
Contributor

Currently, the bootc install workflow assumes that the bootloader must be
managed by bootupd. This works well for server and edge environments, but
it is too inflexible for embedded or custom platforms where the bootloader
is managed externally (e.g., aboot for automotive use cases).

Also coreos/bootupd#766 is related here in that I think there's an argument that bootupd should gain support for other things.

IMHO bootupd should be able to support more things, like rpi firmware, etc. And, it should be made to handle the aboot case "cleanly". I.e. not fall over itself if there is no EFI in the system at all. However, in the short term I think it makes sense to just drop bootupd in the "pure aboot" case, as it has no current value, and the full solution is more long term.

Anyways just for my understanding, we still relying on the ostree aboot backend (which isn't implemented for composefs), correct?

Yes. However, note that there are two ways we can use the ostree aboot backend. Either with a "pure" android boot firmware, in which case there will be no EFI partition at all, or with ukiboot, which is an EFI implementation of aboot. In the ukiboot case we do have an EFI partition, and we will need bootupd to properly install and update ukiboot.efi.

To combine these two things, how about instead of --no-bootloader we detect the presence of aboot, and set it as the backend if it's part of the tree?

So, this would be fine in the "pure aboot" case, but would not work with ukiboot. So the "detect the presence" case here need to be careful about this.

@martinezjavier
Copy link
Author

If the approach is found to be
acceptable, a follow-up would be for bootc install to-filesystem to infer if the
option has to be set implicitly. For example if neither boot nor EFI partition exist.

Implicitly assuming the installation target will manage its own bootloader is a bit risky. The lack of an EFI partition could be the result of a mistake which would result in an installation that is not bootable. So I think it'd be best to keep this as an explicit option.

That is fair. And what about using whether bootupd is present or not as the heuristic to know if bootc has to handle the boot and EFI partitions or just ignore everything that is related to the boot loading?

Yes, it could be a mistake and bootupd should had been present but bootc could print an info message to be explicit that skipped doing the boot setup.

@ckyrouac
Copy link
Collaborator

Yes, it could be a mistake and bootupd should had been present but bootc could print an info message to be explicit that skipped doing the boot setup.

Not a huge deal but I prefer to limit the chances a user could end up with a non-bootable system that is difficult to troubleshoot, which could be the case if we just print a message that will likely be ignored. Ideally we would explicitly handle each bootloader we intend to support.

@cgwalters
Copy link
Collaborator

So, this would be fine in the "pure aboot" case, but would not work with ukiboot. So the "detect the presence" case here need to be careful about this.

Can't we detect ukiboot too?

BTW one big picture thing here is that we must support configuring things via files in the container image (also supporting CLI args is fine too), but I think the former should be generally preferred.

Previous relevant changes:

etc.

@martinezjavier
Copy link
Author

So, this would be fine in the "pure aboot" case, but would not work with ukiboot. So the "detect the presence" case here need to be careful about this.

Can't we detect ukiboot too?

We could but IMO explicit is better than trying to come up with heuristics and make assumptions about this.

BTW one big picture thing here is that we must support configuring things via files in the container image (also supporting CLI args is fine too), but I think the former should be generally preferred.

Previous relevant changes:

etc.

I see. Thanks a lot for the references! Any suggestions on how the file config option should be named?

There's already a bootloader CLI arg for bootc install to-filesystem (https://bootc-dev.github.io/bootc//man/bootc-install-to-filesystem.8.html), although it seems to only be useful when used with --composefs-backend (systemd-boot is not supported for ostree-based installs).

@cgwalters
Copy link
Collaborator

We could but IMO explicit is better than trying to come up with heuristics and make assumptions about this.

I think we could reasonably make the detection not feel heuristic though...but it would need some bikeshedding.

I see. Thanks a lot for the references! Any suggestions on how the file config option should be named?

Well...at this point this has a very high overlap with the ostree "bootloader" backend right? I guess we could extend our enum Bootloader and make that an explicit option in the installation config.

@martinezjavier
Copy link
Author

martinezjavier commented Feb 16, 2026

We could but IMO explicit is better than trying to come up with heuristics and make assumptions about this.

I think we could reasonably make the detection not feel heuristic though...but it would need some bikeshedding.

I see. Thanks a lot for the references! Any suggestions on how the file config option should be named?

Well...at this point this has a very high overlap with the ostree "bootloader" backend right? I guess we could extend

Yes, there' s a lot of overlap here. Can bootc just query the ostree configuration?

our enum Bootloader and make that an explicit option in the installation config.

We could. As mentioned currently that enum Bootloader is only relevant for the composefs backend. So it should first be made a config (and command line option) that could be used for both composefs and ostree backends.

@alexlarsson
Copy link
Contributor

Please, lets not tie bootc to the ostree configure more than necessarily. Long term we want a composefs backend that doesn't use ostree.

What I would like is that bootupd just had a "raw" backend for EFI, which didn't do any special grub or shim related special stuff, just copied things to the ESP, and didn't fall over in the case where there isn't an ESP, or any EFI files (like in aboot). Then we could have on top of that an extra option to enable "grub" related changes, but ideally these two should be different "setting" (with maybe some heuristics to pick which one.

aboot and ukiboot doesn't need anything else, so I much like to avoid anything saying bootloader=ukiboot or suchlike.

However, I think such fixes to bootupd is a bit more long term, and right now I think the easiest solution would be if we can set something in a file in /usr/lib/bootc/install/ to trigger using something like crate::spec::Bootloader::None. Then we can just set that in our aboot images.

Copy link
Contributor

@alexlarsson alexlarsson left a comment

Choose a reason for hiding this comment

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

lgtm

@martinezjavier martinezjavier changed the title WIP: install: Add --no-bootloader to skip bootloader setup install: Add a bootloader none install option Feb 17, 2026
This command line argument can be also be used by the ostree backend. For
example, when using Android Boot Images (aboot) there is a need to avoid
calling to bootupd since all the boot setup is managed outside of bootc.

A future change will add a bootloader=none option to force this behavior.

Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Copy link
Collaborator

@ckyrouac ckyrouac left a comment

Choose a reason for hiding this comment

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

Looks generally good, thanks! Just a few things:

  • could you update the bootloaders.md docs with a section explaining none and why it would be used?
  • I'd feel more confident if there were some TMT tests for this, especially to validate things like bootc upgrade/switch/rollback/status on a booted system. Although I'm not totally sure how we could install with no bootloader in a TMT test so I guess it's OK for now if you have manually validated those still work?
  • We should disallow --generic-image with --bootloader=none
  • We can disallow --bootloader=none for s390x, similar to composefs

@martinezjavier
Copy link
Author

Looks generally good, thanks! Just a few things:

Thanks for your review and feedback!

  • could you update the bootloaders.md docs with a section explaining none and why it would be used?

Done.

  • I'd feel more confident if there were some TMT tests for this, especially to validate things like bootc upgrade/switch/rollback/status on a booted system. Although I'm not totally sure how we could install with no bootloader in a TMT test so I guess it's OK for now if you have manually validated those still work?

I've manually tested boot install using automotive-image-builder with the changes in this PR. I've not tested the upgrade/switch/rollback paths on a booted system, I'll try that now and let you know.

  • We should disallow --generic-image with --bootloader=none
  • We can disallow --bootloader=none for s390x, similar to composefs

Done these too.

@martinezjavier
Copy link
Author

  • We should disallow --generic-image with --bootloader=none
  • We can disallow --bootloader=none for s390x, similar to composefs

Done these too.

Actually, we are hitting the --generic-image code path in automotive-image-builder due this option being automatically enabled when installing via a loopback device. So I've reverted the check and just added the one for s390x (which does make sense IMO).

Currently, the bootc install workflow assumes that the bootloader must be
managed by bootupd. This works well for server and edge environments, but
it is too inflexible for embedded or custom platforms where the bootloader
is managed externally (e.g., aboot for automotive use cases).

In these scenarios, users want to install the filesystem content (OSTree
commit, kernel, initramfs, etc), without bootc assuming that a boot or ESP
partition exists that have to be setup or udpated by bootupd.

By adding a --bootloader=none option users can have explicit control over
how the boot loading is handled, without bootc or bootupd intervention.

Note that so far only support for the ostree backend has been added and
the bootloader=none option is not supported by the composefs backend.

Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
There is already a --bootloader command line argument. Make it this to
also be available as an install file configuration option.

Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
@ckyrouac
Copy link
Collaborator

Actually, we are hitting the --generic-image code path in automotive-image-builder due this option being automatically enabled when installing via a loopback device.

Ah, yea I guess there's no avoiding that without adding another option like --skip-firmware or something. I'm fine with --generic-image --bootloader=none as long as we document the behavior.

@ckyrouac
Copy link
Collaborator

I've not tested the upgrade/switch/rollback paths on a booted system, I'll try that now and let you know.

I'm fine merging this and fixing any bugs related to ^ in a follow up.

@martinezjavier
Copy link
Author

martinezjavier commented Feb 19, 2026

I've not tested the upgrade/switch/rollback paths on a booted system, I'll try that now and let you know.

I'm fine merging this and fixing any bugs related to ^ in a follow up.

Perfect, thanks! I've tested bootc install and bootc status (for both botloader=none and default behaviour) but couldn't test the upgrade/switch/rollback operations yet due lack of infra on my side.

@martinezjavier
Copy link
Author

Actually, we are hitting the --generic-image code path in automotive-image-builder due this option being automatically enabled when installing via a loopback device.

Ah, yea I guess there's no avoiding that without adding another option like --skip-firmware or something. I'm fine with --generic-image --bootloader=none as long as we document the behavior.

Ok, is the existing documentation in bootloaders.md enough for you or do you think that more information is missing ?

@ckyrouac
Copy link
Collaborator

Ok, is the existing documentation in bootloaders.md enough for you or do you think that more information is missing ?

It can be added in a followup. I think just noting in the --generic-image command docs that when used with --bootloader=none then no bootloaders are installed and the firmware isn't updated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/documentation Updates to the documentation area/install Issues related to `bootc install`

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

Comments