Consolidate test-integration and test-integration-cfs into a single job
using a unified matrix (test_os × variant) matching the structure of
build-and-publish.yml. This eliminates code duplication and simplifies
maintenance.
Updated required-checks sentinel to depend only on the unified job.
Assisted-by: Claude Code (Sonnet 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
Previously, the CI workflow granted packages:write permission at the
workflow level, making GITHUB_TOKEN with write access available to all
jobs including those running on pull requests. While the actual push
steps were gated with conditionals, malicious PR code could use the
token to push arbitrary images to ghcr.io.
Split image publishing into a dedicated build-and-publish.yml workflow
that only runs on push to main, with no PR execution. This follows
GitHub security best practices by isolating write credentials from
untrusted PR code.
The new workflow builds and publishes all image variants using a simple
matrix with explicit exclude for centos-9 UKI (broken per #1812).
Assisted-by: Claude Code (Sonnet 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
This adds a simple integration test for
```
$ bootc install print-configuration --all
```
in the container tests.
Thanks to Colin for suggesting this.
Signed-off-by: Michael Vogt <michael.vogt@gmail.com>
When `install print-configuration` is run some options (notably
the kargs) are currently filtered out. This makes sense because
in general `bootc install to-filesystem` takes care of them.
However with the recent work in image-builder/osbuild to use
bootc containers directly as inputs to build ISOs [0],[1]
we would like to get access to the kernel args too because
when constructing a bootable ISO we also want to add the
bootc container kargs.
[0] https://github.com/orgs/osbuild/discussions/45
[1] https://github.com/osbuild/images/pull/1906
Signed-off-by: Michael Vogt <michael.vogt@gmail.com>
Rename the function `kargs_from_composefs_filesystem` to
`compute_new_kargs` as it now has nothing to do with composefs
Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
The build-sealed script introduced in PR #1810 referenced
BOOTC_buildroot_base which is only defined in GitHub Actions CI,
causing failures when running 'just build-sealed' manually.
This allows manual execution while maintaining CI compatibility.
Signed-off-by: Wei Shi <wshi@redhat.com>
Improve boot entry ordering to work correctly across both Grub and systemd-boot
bootloaders, which have fundamentally different sorting behaviors.
Background:
Grub does not read BLS fields - it parses the filename as an RPM package name
using split_package_string(). The parsing splits on `-` from right to left:
1. Strip .conf suffix
2. Find LAST `-` → extract "release" field
3. Find SECOND-TO-LAST `-` → extract "version" field
4. Remainder → "name" field
5. Sort by (name, version, release) in DESCENDING order
See: https://github.com/ostreedev/ostree/issues/2961
Changes:
- Add comprehensive module documentation explaining bootloader sorting behaviors
- Parse os-release to extract ID field (e.g., "fedora", "rhel")
- Filename format: `bootc_{os_id}-{version}-{priority}.conf`
* Replace `-` with `_` in os_id to prevent Grub mis-parsing
* Priority in release position for Grub compatibility
* Primary: `bootc_fedora-41.20251125.0-1.conf`
* Secondary: `bootc_fedora-41.20251124.0-0.conf`
- Sort-key format for systemd-boot:
* Primary: `bootc-{os_id}-0` (sorts first)
* Secondary: `bootc-{os_id}-1` (sorts second)
- Update rollback logic for new filename format
- Add comprehensive unit tests
Boot entry ordering after upgrade (both bootloaders):
1. Primary: New/upgraded deployment (default boot target)
2. Secondary: Currently booted deployment (rollback option)
Sorting behavior:
- Grub: Descending by (name, version, release) from filename parsing
- Systemd-boot: Ascending by sort-key field, filename mostly irrelevant
Fixes: #1777
Related: https://github.com/ostreedev/ostree/issues/2961
Signed-off-by: Colin Walters <walters@verbum.org>
Assisted-by: Claude Code (Sonnet 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
CentOS 9 lacks systemd.extra-unit.* support which is required for
--bind-storage-ro to work with bcvk. This was causing test failures
on centos-9 while working fine on Fedora.
Change the approach so tests express intent via `extra.try_bind_storage: true`
metadata, and xtask handles the details:
- Detect distro by running the container image and parsing os-release
- Pass distro to tmt via --context=distro=<id>-<version>
- Only add --bind-storage-ro when test wants it AND distro supports it
- When bind storage is available, also set BOOTC_upgrade_image env var
- Tests can detect missing $env.BOOTC_upgrade_image and fall back to
building the upgrade image locally
Add --upgrade-image CLI option to specify the upgrade image path,
replacing the old --env=BOOTC_upgrade_image approach.
Extract magic values to clear const declarations at the top of the file
for better maintainability.
Assisted-by: Claude Code (Sonnet 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
This ensures it all can work much more elegantly/naturally
with sealed UKI builds - we don't want to do the build-on-target
thing.
Signed-off-by: Colin Walters <walters@verbum.org>
Move TMT test runner code from xtask.rs to tmt module:
- `run_tmt()` and `tmt_provision()` functions
- Helper functions for VM management and SSH connectivity
- Related constants
Also refactor `update_integration()` to use serde_yaml::Value for
building YAML structures instead of string concatenation.
Add detailed error reporting for failed TMT tests:
- Assign run IDs using `tmt run --id`
- Display verbose reports with `tmt run -i {id} report -vvv`
Assisted-by: Claude Code (Sonnet 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
We need to run most of our tests in a separate provisioned machine,
which means it needs an individual plan. And then we need a test
for that plan. And then we need the *actual test code*.
This "triplication" is a huge annoying pain.
TMT is soooo complicated, yet as far as I can tell it doesn't offer
us any tools to solve this. So we'll do it here, cut over to
generating the TMT stuff from metadata defined in the test file.
Hence adding a test is just:
- Write a new tests/booted/foo.nu
- `cargo xtask update-generated`
Signed-off-by: Colin Walters <walters@verbum.org>
Handle the following cases we can encounter on `bootc udpate`
1. The verity is the same as that of the currently booted deployment
- Nothing to do here in case of update as we're currently booted. But if we're switching
then we update the target imageref in the .origin file for the deployment
2. The verity is the same as that of the staged deployment
- Nothing to do, as we only get a "staged" deployment if we have
/run/composefs/staged-deployment which is the last thing we create
while upgrading
3. The verity is the same as that of the rollback deployment or any
other deployment we have already deployed
- Nothing to do since this is a rollback deployment which means
this was unstaged at some point
4. The verity is not found
- The update/switch might've been canceled before
/run/composefs/staged-deployment was created, or at any other point
in time, or it's a new one.
Any which way, we can overwrite everything. In this case we remove
all the staged bootloader entries, if any, and remove the entire
state directory, as it would most probably be in an inconsistent
state.
Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
The rhsm feature was not being propagated from the CLI crate to the
lib crate, causing `bootc internals publish-rhsm-facts` to never be
compiled in even when building with CARGO_FEATURES=rhsm.
I think this was broken when I refactored the build recently.
Change things so we build the manpages before the production
binary, ensuring the production binary always ends up with
the right feature flags.
Fixes: https://issues.redhat.com/browse/RHEL-130799
Assisted-by: Claude Code (Sonnet 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
We have a lot of places where we mount the ESP temporarily and a lot of
switch cases for Grub's vs SystemdBoot's 'boot' directory.
We add a `boot_dir` field in Storage which points to `/sysroot/boot` for
systems with Grub as the bootloader and points to the ESP for systems
with SystemdBoot as the bootloader.
Also we mount the ESP temporarily while creating the storage struct,
which cleans up the code quite a bit.
Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
Parse toml files in usr/lib/bootc/kargs.d and append them to kernel
cmdline on install and upgrade/switch. Also, copy over current
deployment's cmdline args on upgrade/switch to another deployment
Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
Users doing `bootc install to-existing-root` previously had no easy
way to find the ostree deployment before rebooting in order to inject
configuration files. This addresses that gap.
Key changes:
- Document using `ostree admin --print-current-dir` to find the newly
created deployment path before rebooting
- Clarify the two distinct scenarios: injecting new configuration
before reboot vs. migrating old data after reboot
- Add examples for both file-based configuration and kernel arguments
(via `systemd.mount-extra`)
- Cross-link documentation between general install docs and the
to-existing-root man page
- Fix typo in path structure documentation
Related: https://github.com/bootc-dev/bootc/issues/531
Assisted-by: Claude Code (Sonnet 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
Function `find_vmlinuz_initrd_duplicates` returns all the deployment ids
that match the current deployment's kernel + initrd SHA256 sum, but only
would actually exist on disk, every other deployment's BLS Config would
simply be pointing to one single directory.
We were incorrectly picking the first entry out of the returned list,
which might or might not exist as an actual directory containing the
kernel.
Fix the bug by iterating over all directory entries in `/boot` or
`/EFI/Linux` and checking if the deployment id in the list actually
exists on the disk or not
Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
Add check to prevent soft reboot when SELinux policies differ
between booted and target deployments, since policy is not
reloaded across soft reboots.
Assisted-by: Cursor (Auto)
Signed-off-by: gursewak1997 <gursmangat@gmail.com>
Except now this wraps the "variant" usage of `just build`. For one,
this is a convenient little piece of shorthand. But perhaps more
importantly, we have this referenced in the docs. Although I could go
change the docs to reflect the new usage, I think it just reads nicer
in the docs for it to remain `just build-sealed`.
Signed-off-by: John Eckersberg <jeckersb@redhat.com>
In order to debug failures more reliably we really always want a virtual
console.
It turns out the Fedora kernel configs for a while have done
9a0d7ce2af
which means hvc0 is available from very early boot.
I am probably going to argue to do this in all Fedora derivatives by
default soon but let's start here.
Signed-off-by: Colin Walters <walters@verbum.org>
Fixes a regression where bootupd detection was happening before the
container was deployed, causing bootc to incorrectly check the host
system instead of the target container image. This led to false negatives
when the container had bootupd but the host didn't.
The fix moves bootloader detection into a new PostFetchState that's
created after the deployment is available, ensuring we check the actual
target filesystem.
Fixes: #1778
Assisted-by: Claude Code (Sonnet 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
Now that we've cut over to always building + installing via
an (RPM) package in our build system, we need to always install
the dracut module.
Signed-off-by: Colin Walters <walters@verbum.org>
We were bit before by just doing a `COPY` of our binaries overtop of
the base image because that doens't remove old files.
Replace the pre-build approach with rpmbuild, and then change to
do an rpm-based upgrade so that we fix that problem.
Note that we still preserve incremental rebuilds by overriding
some of the RPM build process.
Assisted-by: Claude Code (Sonnet 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
- The ci/Dockerfile.fcos has been unused for some time and
testing with FCOS derivatives is already done outside of CI
here
- Drop the bits which reference git in the Makefile, a new rule
I'm trying to impose here is that nothing in the build system
should rely on git (or at least not rely on being built
from a git repository)
Signed-off-by: Colin Walters <walters@verbum.org>
This was used at one point for composefs testing, but no longer.
Assisted-by: Claude Code (Sonnet 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
This implements readonly mounting of /sysroot for composefs systems,
matching the behavior that ostree systems already have. Previously,
composefs left /sysroot mounted read-write, which was inconsistent
and meant the readonly tests had to be skipped for composefs.
The implementation uses a direct `libc::syscall` wrapper for
`mount_setattr` since rustix doesn't yet provide this API. The
`MOUNT_ATTR_RDONLY` flag is applied to three mount
points during initramfs setup:
- The composefs rootfs image mount (becomes `/` after switch-root)
- The test root filesystem mount (used in testing scenarios)
- The sysroot clone mount (becomes `/sysroot` in the booted system)
With this change, the readonly /sysroot tests in test-status.nu
now run for both ostree and composefs systems without conditional
checks.
Assisted-by: Claude Code (Sonnet 4.5)
Co-authored-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
Signed-off-by: Colin Walters <walters@verbum.org>
This fixes bootc's use of the Discoverable Partition Specification (DPS)
to properly support systemd-gpt-auto-generator. Previously, bootc was
incorrectly setting filesystem UUIDs to the DPS partition type UUID value,
which caused UUID collisions and prevented proper DPS functionality.
It's still a TODO on our side to support systemd-repart in this flow.
Note we go back to using random filesystem UUIDs with this, but
per above we should likely reinitialize them on boot via repart.
Note we remove root= parameter from kernel cmdline for composefs sealed images,
allowing systemd-gpt-auto-generator to auto-discover the root partition
and we test this.
Fixes: #1771
Assisted-by: Claude Code (Sonnet 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>