Some people want to use container build tools, but for compatibility
with older systems export a tar format of the OS state e.g.
Anaconda liveimg expects this.
Basically this is only *slightly* more than just `tar cf`; we need
to handle SELinux labeling and move the kernel.
Ref: #1957
Assisted-by: OpenCode (Sonnet 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
Add a new subcommand that builds a Unified Kernel Image (UKI) by
computing the necessary arguments from a container image and invoking
ukify. This simplifies the sealed image build workflow by having bootc
internally compute:
- The composefs digest (via existing compute-composefs-digest logic)
- Kernel arguments from /usr/lib/bootc/kargs.d/*.toml files
- Paths to kernel, initrd, and os-release
Any additional arguments are passed through to ukify unchanged, allowing
full control over signing, output paths, and other ukify options.
The seal-uki script is updated to use this new command instead of
manually computing these values and invoking ukify directly.
Also adds kargs.d configuration files for the sealed UKI workflow:
- 10-rootfs-rw.toml: Mount root filesystem read-write
- 21-console-hvc0.toml: Console configuration for QEMU/virtio
Closes: #1955
Assisted-by: OpenCode (Opus 4.5)
Signed-off-by: John Eckersberg <jeckersb@redhat.com>
Wrap bare URLs in angle brackets to make them proper hyperlinks,
escape angle brackets in doc comments that look like HTML tags,
and fix broken intra-doc links.
Assisted-by: OpenCode (Sonnet 4)
Signed-off-by: Colin Walters <walters@verbum.org>
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>
Until now while checking if a deployment is capable of being soft
rebooted, we were not taking into account any differences in SELinux
policies between the two deployments. This commit adds such a check
We only check for policy diff if SELinux is enabled
Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
composefs: Refactor
Add doc comments for StagedDeployment struct
Use `serde_json::to_writer` to prevent intermediate string allocation
Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
composefs/selinux: More refactor
Move SELinux realted oprations to a separate module
Minor refactoring and add some comments
Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
When `--download-only` is passed, only download the image into the
composefs repository but don't finalize it.
Conver the /run/composefs/staged-deployment to a JSON file and Add a
finalization_locked field depending upon which the finalize service will
either finalize the staged deployment or leave it as is for garbage
collection (even though GC is not fully implemented right now).
Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
After bootc/commit/49d753f996747a9b1f531abf35ba4e207cf4f020,
composefs-rs saves config in the format `oci-config-sha256:`.
Update to match the same
Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
Aligning with ostree API, now we only initiate soft-reboot if `--apply`
is passed to `bootc update`, `bootc switch`, else we only prepare the
soft reboot
Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
Allow configuring the root and boot filesystem mount
specs via the install configuration file under [install].
As for other options, CLI arguments take precedence.
For the to-existing-root flow, mount specs from config are ignored.
Example configuration:
```
[install]
root-mount-spec = "LABEL=rootfs"
boot-mount-spec = "UUID=abcd-1234"
```
Fixes https://github.com/bootc-dev/bootc/issues/1939
Assisted-by: Opencode (Claude Opus 4.5)
Signed-off-by: jbtrystram <jbtrystram@redhat.com>
Support for configuring the stateroot name through the install
configuration file under `[install.ostree]`.
The CLI flag will override config file values, as for other options.
Partial fix for https://github.com/bootc-dev/bootc/issues/1939
Assisted-by: Opencode (Claude Opus 4.5)
Signed-off-by: jbtrystram <jbtrystram@redhat.com>
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>
If a directory is modified/added in the current etc, but deleted in the
new etc, we'd want it in the new etc. This case prior to this commit
resulted in a panic as we were not taking it into account
Fixes: https://github.com/bootc-dev/bootc/issues/1924
Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
Add a helper function that returns WalkConfiguration with noxdev()
enabled by default. This ensures consistent behavior across all
filesystem walks in the linting code.
The doc comment clarifies that noxdev skips directory mount points
(to avoid descending into bind mounts, tmpfs, etc.) but non-directory
mount points like bind-mounted regular files will still be visited.
Assisted-by: OpenCode (Opus 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
Add a lint that warns when /run or /tmp contain any content. These
directories are tmpfs at runtime and should be empty in container images.
Common causes of content in these directories include:
- podman/buildah's RUN --mount leaving directory stubs
- Build tools leaving temporary files
This is particularly important for bootc with composefs because content
in these directories can cause digest mismatches between build-time
(mounted filesystem) and install-time (OCI tar layers) views, leading
to sealed boot failures.
The lint uses the walk API with noxdev() to automatically skip mount
points, and filters out content injected by container runtimes
(.containerenv, secrets, packages).
Assisted-by: OpenCode (Opus 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
If we were waiting on a lock as part of `bootc status --format=json`
this information message would end up in stderr, corrupting the output.
Signed-off-by: Colin Walters <walters@verbum.org>
This fixes a regression from https://github.com/bootc-dev/bootc/pull/1727
by removing the unnecessary mount point check prior to the recursive
function call. Also adds some tracing statements and updates the
integration test to validate the mount check works for this scenario:
/boot/efi mounted with contents in /boot/efi/EFI/firmware/foo
Signed-off-by: ckyrouac <ckyrouac@redhat.com>
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>
- status.rs: Use UnicodeWidthStr::width() for correct display alignment
- container.rs: Use as_bytes().len() for hex string length verification
- Add unicode-width dependency (already a transitive dep via comfy-table)
Assisted-by: Cursor (Auto)
Signed-off-by: Shion Tanaka <shtanaka@redhat.com>
Previous implementation had undefined behavior and was coincidentally correct under conditions where no rollback was performed, see #1887
Matches deployment entries in composefs deploy folder that are neither staged nor booted against entires defined in /boot to find out rollback entry.
Fixes #1887
Signed-off-by: Chaser Huang <huangkangjing@gmail.com>
The sysroot lock was being taken by `get_host` before it was released by
the caller. Move the `get_host` function up the stack of calls
Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
Inline the tar parsing/unpacking
Check for two NULL 512 blocks instead of just one
Share source image and target image generating code between composefs
and ostree
Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@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>
On FCOS, esp is not mounted after booted, need to find esp and
mount before cleaning, or `/boot/efi` will be removed.
Signed-off-by: Huijing Hei <hhei@redhat.com>
When running `install to-filesystem` on ostree OS, should use
`target_root_path` for bootupctl to install bootloader.
Signed-off-by: Huijing Hei <hhei@redhat.com>
The container inspect command previously only supported JSON output.
This extends it to support human-readable output (now the default)
and YAML, matching the output format options available in other
bootc commands like status.
The --json flag provides backward compatibility for scripts that
expect JSON output, while --format allows explicit selection of
any supported format.
Assisted-by: OpenCode (Sonnet 4)
Signed-off-by: Colin Walters <walters@verbum.org>
The container-inspect command previously only reported kernel arguments.
Extend it to also report kernel information, including whether the image
contains a traditional kernel or a Unified Kernel Image (UKI).
This consolidates UKI detection logic previously in bootc_composefs::boot
into a new kernel module that can find kernels via either the traditional
/usr/lib/modules/<version>/vmlinuz path or UKI files in /boot/EFI/Linux/.
The ContainerInspect output now includes a "kernel" field with version
and unified (boolean) properties, enabling tooling to determine the
boot method before installation.
Assisted-by: OpenCode (Claude Opus 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
On `UpdateAction::UpdateOrigin` the origin for the container image used
was not properly formatted. Fixed it
Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
Similar to soft reboots for Type1 entries, we compute the SHA256Sum of
.linux + .initrd sections in the UKI, and compare them to check for
kernel skew
Next, compare the .cmdline section skipping the `composefs=` parameter
as that will always be different
Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
Similar to what we do with Type1 entries, we save the SHA256Sum of
.linux + .initrd sections of the UKI under `boot_digest` key in the
origin file
Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
After a soft reboot the kernel cmdline doesn't change so we can't rely
on the `composefs=` parameter in the cmdline. Instead, we check the
source of the root mount point
Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
Add an internal command for soft rebooting the system. Similar to how
it's done for ostree, we only allow soft reboot if the other deployment
has the same kernel state, i.e. the SHASum of kernel + initrd is the
same as that of the current deployment.
soft reboot is not possible in case of UKI deployment
Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
Add a new `bootc container compute-composefs-digest` command that computes
the bootable composefs digest directly from a filesystem directory path,
defaulting to `/target`. This enables computing digests in container
environments without requiring access to container storage or a booted
host system.
The existing container-storage-based behavior is preserved and renamed
to `compute-composefs-digest-from-storage` (hidden). The `hack/compute-composefs-digest`
script is updated to use the renamed command.
The core digest computation logic is extracted into a new
`bootc_composefs::digest` module with:
- `new_temp_composefs_repo()` helper for DRY temp repository creation
- `compute_composefs_digest()` function with "/" path rejection
Unit tests and an integration test verify the command works correctly,
producing valid SHA-512 hex digests with consistent results across
multiple invocations. Exact digest values are not asserted due to
environmental variations (SELinux labels, timestamps, etc.).
Closes: https://github.com/bootc-dev/bootc/issues/1862
Assisted-by: OpenCode (Claude Opus 4.5)
Signed-off-by: John Eckersberg <jeckersb@redhat.com>