When `--src-imgref` is passed, the deployed systemd does not match the
running environnement. In this case, let's run bootupd from inside
the deployment. This makes sure we are using the binaries
shipped in the image (and relevant config files such as grub fragements).
We use bwrap to set up the chroot for a easier handling of the API
filesystems.
We could do that in all cases but i kept it behind the `--src-imgref`
option since when using the target container as the buildroot it will
have no impact, and we expect this scenario to be the most common.
In CoreOS we have a specific test that checks if the bootloader was
installed with the `grub2-install` of the image.
Fixes https://github.com/bootc-dev/bootc/issues/1559
Also see https://github.com/bootc-dev/bootc/issues/1455
Assisted-by: OpenCode (Opus 4.5)
Signed-off-by: jbtrystram <jbtrystram@redhat.com>
This allows registries to distinguish "image pulls for bootc client
runs" from other skopeo/containers-image users. The user agent will
be in the format "bootc/<version> skopeo/<version>".
All places in bootc that create ImageProxyConfig now use a new helper
function that sets the user_agent_prefix field.
Closes: https://github.com/bootc-dev/bootc/issues/1686
Assisted-by: OpenCode (Sonnet 4)
Signed-off-by: Colin Walters <walters@verbum.org>
Add `cargo xtask local-rust-deps` which uses `cargo metadata` to find
local path dependencies outside the workspace (e.g., from [patch] sections)
and outputs podman bind mount arguments.
This enables a cleaner workflow for local development against modified
dependencies like composefs-rs:
1. Add a [patch] section to Cargo.toml with real local paths
2. Run `just build` - the Justfile auto-detects and bind-mounts them
Benefits over the previous BOOTC_extra_src approach:
- No manual env var needed
- Paths work for both local `cargo build` and container builds
- No /run/extra-src indirection or Cargo.toml path munging required
- Auto-detection means it Just Works™
The Justfile's build target now calls `cargo xtask local-rust-deps` to
get bind mount args, falling back gracefully if there are no external deps.
The old BOOTC_extra_src mechanism is still supported for backwards compat.
Assisted-by: OpenCode (Opus 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
The composefs-rs PR 209 has been merged to main. This updates
bootc to use the containers/composefs-rs repository at the
merge commit.
Key API changes:
- Directory::default() -> Directory::new(Stat::uninitialized())
- read_filesystem() no longer takes stat_root parameter
- New read_container_root() for OCI containers (propagates /usr metadata to root)
- stat_root CLI flag renamed to no_propagate_usr_to_root with inverted logic
See https://github.com/containers/composefs-rs/pull/209
Signed-off-by: Colin Walters <walters@verbum.org>
Update composefs-rs from rev b636e0e9 to e9008489, adapting to API changes:
- merge_splitstream now takes 4 arguments instead of 3
- import_layer takes digest as string directly
- pull/seal return (digest, verity) as (String, ObjectID)
- SplitStreamWriter::new and write_stream have new signatures
- initialize_composefs_repository returns String instead of Sha256Digest
Co-authored-by: Allison Karlitskaya <allison.karlitskaya@redhat.com>
Assisted-by: OpenCode (Claude claude-sonnet-4-20250514)
Signed-off-by: Colin Walters <walters@verbum.org>
Migrate all crates from edition 2021 to 2024. This includes
updating Cargo.toml files and fixing code compatibility issues.
The MSRV is bumped to 1.85.0 to support edition 2024.
Note: global_init() requires #[allow(unsafe_code)] for
std::env::set_var which is now unsafe in edition 2024.
This is safe because the function is called early in main()
before any threads are spawned.
Closes: #1414
Signed-off-by: Daniele Guarascio <guarascio.daniele@gmail.com>
Instead of handling the history,metadata,annotations ourselves, delegate
them to `ocidir` crate. Also take into account the source and target
image references
Finally call `skopeo::copy` to copy to containers-storage
Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
Export a composefs repository as an OCI image. In this iteration the
outputted files are in OCI Directory format and are plain TARs, i.e. not
compressed
Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
`target` field in Args was not being used. Use it if it is passed in the
args. Also helps us mount the new root at `/run/nextroot`
Also, use Cmdline struct instead of String to represent the kernel
command line
Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
Pass SOURCE_DATE_EPOCH from git commit timestamp through to rpmbuild,
enabling bit-for-bit reproducible RPM builds. This is useful for
verification and caching.
Then fix the idempotency of the default `just build` to ensure
we're not incorrectly invalidating caches.
Add `just check-buildsys` command that builds packages twice and
verifies checksums match, confirming reproducibility. The CI package
job now uses this to catch regressions.
Assisted-by: OpenCode (Opus 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>
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>
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>
Renovate is currently failing because of the composefs-rs git
submodule (trying to debug that) so we're behind. At least this
one gets rid of multiple copies of rustix and an old toml version.
Signed-off-by: Colin Walters <walters@verbum.org>
Part 1: Use bcvk
For local tests, right now testcloud+tmt doesn't support UEFI, see
https://github.com/teemtee/tmt/issues/4203
This is a blocker for us doing more testing with UKIs.
In this patch we switch to provisioning VMs with bcvk, which
fixes this - but beyond that a really compelling thing about
this is that bcvk is *also* designed to be ergonomic and efficient
beyond just being a test runner, with things like virtiofs
mounting of host container storage, etc.
In other words, bcvk is the preferred way to run local virt
with bootc, and this makes our TMT tests use it.
Now a major downside of this though is we're effectively
implementing a new "provisioner" for tmt (bypassing the
existing `virtual`). In the more medium term I think we
want to add `bcvk` as a provisioner option to tmt.
Anyways for now, this works by discovers test plans via `tmt plan ls`,
spawning a separate VM per test, and then using uses tmt's connect
provisioner to run tests targeting these externally provisioned
systems.
Part 2: Rework the Justfile and Dockerfile
This adds `base` and `variant` arguments which are propagated through
the system, and we have a new `variant` for sealed composefs.
The readonly tests now pass with composefs.
Drop the continuous repo tests...as while we could keep
that it's actually a whole *other* entry in this matrix.
Assisted-by: Claude Code (Sonnet 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
Check for verity inside the json returned by `bootc status --json`
and compare it with the compsefs digest from kernel cmdline
Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
Signed-off-by: Colin Walters <walters@verbum.org>
This fleshes out what we had with a more rigorous
binding to the spec.
As part of this though, the ESP constant we had here was uppercase,
but the spec version uses lowercase. Add APIs to find a partition
by type, comparing case insensitively.
Assisted-by: Claude Code
Signed-off-by: Colin Walters <walters@verbum.org>
- Change the install logic to detect UKIs and automatically
enable composefs
- Change the install logic to detect absence of bootupd
and default to installing systemd-boot
- Move sealing bits to the toplevel
- Add Justfile entrypoints
- Add basic end-to-end CI coverage (install + run) using
our integration tests
- Change lints to ignore `/boot/EFI`
Signed-off-by: Colin Walters <walters@verbum.org>
Add #[context()] attribute macro to all functions that return Result
to improve error reporting. This includes adding the fn-error-context
dependency and importing the context macro in all relevant modules.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: John Eckersberg <jeckersb@redhat.com>
See the updates to `Justfile` for how to use this.
Closes: #1428
Assisted-By: Claude Code (opus + sonnet)
Signed-off-by: Colin Walters <walters@verbum.org>
As part of the tracing-subscriber CVE I did a quick audit
for usages of `tracing::error!` and I noticed when
we updated the `main()` function in the primary
crate we missed also doing the same for system-reinstall-bootc.
Move the handling of that to utils.
xref: https://bugzilla.redhat.com/show_bug.cgi?id=2392017
Signed-off-by: Colin Walters <walters@verbum.org>
While merging, existing directory in new_etc was being recursively
deleted which is not correct as any new files might also be deleted.
Instead, we simply create a directory if it doesn't exists, or if it
does exists, we update its metadata accordingly.
Add some test cases for the above.
Signed-off-by: Johan-Liebert1 <pragyanpoudyal41999@gmail.com>
cli: Add internal opt for printing etc-diff
Signed-off-by: Johan-Liebert1 <pragyanpoudyal41999@gmail.com>
etc-merge: Add license to Cargo.toml
Signed-off-by: Johan-Liebert1 <pragyanpoudyal41999@gmail.com>
etc-merge: More refactoring
Signed-off-by: Johan-Liebert1 <pragyanpoudyal41999@gmail.com>
Merge added, modified, removed files from the current etc into the new
etc directory, following the rules
1. If file is removed from current_etc, it will be removed from new_etc
2. If file is modified in current_etc, it will be copied to the new_etc
overwriting any existing files
3. If a file is added in current_etc, then the above modification rule
applies
Modification includes change in content/permissions. Changed in Xattrs
and/or ownership is not handled yet.
Signed-off-by: Johan-Liebert1 <pragyanpoudyal41999@gmail.com>
etc-merge: Handle ownership changes
Signed-off-by: Johan-Liebert1 <pragyanpoudyal41999@gmail.com>
etc-merge: Handle xattrs
Signed-off-by: Johan-Liebert1 <pragyanpoudyal41999@gmail.com>
etc-merge: Ignore mtime while comparing stat
Signed-off-by: Johan-Liebert1 <pragyanpoudyal41999@gmail.com>
Remove chown test
Signed-off-by: Johan-Liebert1 <pragyanpoudyal41999@gmail.com>
etc-merge: Use `llistxattr` and `lgetxattr`
Use the non symlink following counterparts for getting xattrs. Document
public functions and structures
Signed-off-by: Johan-Liebert1 <pragyanpoudyal41999@gmail.com>