Ensure all RUN instructions after the "external dependency cutoff point"
marker include `--network=none` right after `RUN`.
This enforces that external dependencies are clearly delineated in the early stages of the Dockerfile.
The check is part of `cargo xtask check-buildsys` and includes unit tests.
Assisted-by: OpenCode (Sonnet 4)
Signed-off-by: Colin Walters <walters@verbum.org>
Removing localhost/bootc-pkg at the end of the package target
also deletes the build stage layers, causing subsequent builds
to miss the cache and rebuild the RPMs from scratch.
Keep the image around; use `just clean-local-images` to reclaim space.
Signed-off-by: Colin Walters <walters@verbum.org>
The previous commit consolidated test content (nushell, cloud-init, etc.)
into the base image. This completes that work by removing the separate
`build-integration-test-image` target and updating all references.
Now `just build` produces the complete test-ready image directly,
simplifying the build pipeline and eliminating the intermediate
`localhost/bootc-integration` image.
Also adds SKIP_CONFIGS support for the coreos testing workflow, which
skips LBIs, test kargs, and install configs that would conflict with FCOS.
Signed-off-by: Colin Walters <walters@verbum.org>
Move all content from the derived test image (hack/Containerfile) into
the main Dockerfile base image. This includes nushell, cloud-init, and
the other testing packages from packages.txt.
This simplifies the build by avoiding the need to juggle multiple images
during testing workflows - the base image now contains everything needed.
Assisted-by: OpenCode (Claude Sonnet 4)
Signed-off-by: Colin Walters <walters@verbum.org>
# Conflicts:
# hack/Containerfile
We were previously trying to support a direct `podman/docker build`
*and* injecting externally built packages (for CI).
Looking to rework for sealed images it was too hacky; let's
just accept that a raw `podman build` no longer works, the canonical
entry for local build is `just build` which builds both a package
and a container.
This way CI and local work exactly the same.
Signed-off-by: Colin Walters <walters@verbum.org>
When exporting derived container images via store::export, content in
derived layers that was originally at /etc (stored in ostree as /usr/etc)
was incorrectly output as /usr/etc instead of being remapped back to /etc.
This was because the "remaining layers" (non-ostree derived layers) were
exported using the raw ostree CLI which doesn't perform the remapping.
Fix this by adding a "raw" export mode to the tar export machinery that
outputs plain filesystem content with proper /usr/etc -> /etc remapping
but without ostree repository structure (no hardlinks to object store,
no commit metadata). This mode also preserves xattrs via PAX extensions.
Assisted-by: OpenCode (Sonnet 4)
Signed-off-by: Colin Walters <walters@verbum.org>
The docs workflow now also generates rustdoc for all workspace crates
and publishes them as a subdirectory of the main documentation site.
This makes internal API documentation available at
bootc-dev.github.io/bootc/internals.html with links to each crate.
Note this required switching the docs container to CentOS Stream 10 for newer Rust (1.91).
Assisted-by: OpenCode (Opus 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
Under some circumstances--for example, if a new exclusive component has
been added since the prior build--packing with a prior build structure
can fail. When this happens, we can simply discard the prior build
data and make a new packing structure, rather than having chunking fail
entirely.
Signed-off-by: Daniel Hast <hast.daniel@protonmail.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>
Previously we were mounting a rw overlay on top of /usr using
`mount -t overlay -olowerdir=/usr,workdir=...,upperdir=... overlay /usr`
which caused the kernel to throw
`overlayfs: maximum fs stacking depth exceeded`
possibly because the mountpoint was the same as the lowerdir
Also, move the overlay mount BEFORE we mask off `/sysroot/ostree` else
bootc throws `error: Read only filesystem`
Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
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>
`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>
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>
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>
Move the --mutate-in-place handling before get_storage() so it doesn't
require a fully booted ostree environment. This enables use cases like
Anaconda where we're chrooted into a non-booted system.
Closes: #1854
Assisted-by: OpenCode (claude-sonnet-4-20250514)
Signed-off-by: Colin Walters <walters@verbum.org>
This started warning with:
warning: value assigned to `no_signature_verification` is never read
--> crates/ostree-ext/src/cli.rs:1265:21
|
1265 | mut no_signature_verification,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: maybe it is overwritten before being read?
= note: `#[warn(unused_assignments)]` (part of `#[warn(unused)]`) on by default
Which is true in this case, we never actually read the pattern-matched
value. Change it to be explicitly unused with '_' and then shadow it
with a `let` binding.
Signed-off-by: John Eckersberg <jeckersb@redhat.com>
We should match exactly the logic we use with containers-image-proxy.
- If bootc doesn't have auth setup, then we need to not let podman
fall back to the defaults
- Always pass a copy of the auth in a tempfile so we aren't
reliant on absolute paths as we're continually trying to
reduce our usage of those.
Signed-off-by: Colin Walters <walters@verbum.org>
ostree-ext explicitly handles authfile paths as relative; this works
fine for most callers of get_global_authfile, as they only read the
returned open file descriptor, and ignore the path. However, pulling
logically bound images requires passing the actual authfile path to
Podman, so we must resolve the absolute path in this case - otherwise,
we see errors like the following:
```
[root@fedora ~]# bootc upgrade
layers already present: 69; layers needed: 1 (242.2 MB)
Fetched layers: 230.95 MiB in 3 seconds (90.88 MiB/s)
Deploying: done (3 seconds)
Fetching bound image: quay.io/prometheus/node-exporter:v1.10.2: done (0 seconds)
error: Upgrading: Staging: Pulling bound images: Pulling bound images: Failed to pull image: Subprocess failed: ExitStatus(unix_wait_status(32000))
Error: credential file is not accessible: faccessat etc/ostree/auth.json: no such file or directory
```
Since cap_std::fs::Dir intentionally does not expose its filesystem
path, we must resort to reconstructing it from a file descriptor. We
could do this by inspectingthe file descriptor for `sysroot` and
combining that with the relative path returned by get_global_authfile,
but since get_global_authfile returns the descriptor of the actual
authfile, we can simply read that directly.
Signed-off-by: James Forcier <csssuf@csssuf.net>
systemd-boot has support for automatically enrolling keys
for Secure Boot, this adds support for copying these keys
as embedded in the input container image into the location
where systemd-boot can perform automatic enrollment on them.
Commit-message-written-by: Colin Walters <walters@verbum.org>
Signed-off-by: Gareth Widlansky <gareth.widlansky@proton.me>
Previously, `BootedStorage::new()` unconditionally tried to open
`/sysroot` before checking the environment type. This caused
`bootc status` to fail on non-ostree/composefs systems.
(We did work in containers and we had tests for that; but
the container case is special cased even earlier)
Fixes: https://issues.redhat.com/browse/RHEL-135687
Assisted-by: Claude Code (Opus 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>