install-to-filesystem-var-mount test requires packages which should
be built into image for Packit provision (system-reinstall-bootc on
package mode testing farm runner)
Signed-off-by: Xiaofeng Wang <henrywangxf@me.com>
When rpm -qa returns no packages, xargs would still invoke
rpm -e with no arguments, causing failure with "no packages
given for erase" (exit code 123).
Add -r flag to xargs to skip execution when input is empty.
Signed-off-by: Xiaofeng Wang <henrywangxf@me.com>
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>
In C9S there's something leaking files in `/tmp` so let's just
enforce use of tmpfs for `/run` at build time too.
But fix `RUN bootc container lint` to *not* have those mounts
becuase otherwise we don't actually see the leaked content.
Assisted-by: Cursor (Opus 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
Use copy-to-storage to add the booted container to podman storage
instead of pulling a remote image. This matches the pattern used
by other TMT tests and ensures we test the actual bootc under test.
Changes:
- Use localhost/bootc from copy-to-storage instead of remote image
- Disable LBIs via bind mount of /usr/share/empty
- Remove unnecessary host modifications (usr-overlay, dnf install, etc.)
- Use 100%FREE for root LV to ensure sufficient space for deployment
Assisted-by: OpenCode (Opus 4.5)
Signed-off-by: ckyrouac <ckyrouac@redhat.com>
Signed-off-by: Colin Walters <walters@verbum.org>
The base image may be built from a compose that has newer packages
than what's available on the public mirrors. This causes version skew
where packages like bootupd have different versions between the base
image and our built image.
For example, bootupd 0.2.32 changed the EFI file layout from
/usr/lib/bootupd/updates/EFI/ to /usr/lib/efi/, and if we build
with an older bootupd from mirrors while the target image has
the newer layout, bootloader installation fails.
Enable the CentOS Stream compose repos with higher priority to ensure
we get matching versions.
xref https://gitlab.com/redhat/centos-stream/containers/bootc/-/issues/1174
Signed-off-by: Colin Walters <walters@verbum.org>
Assisted-by: OpenCode (Opus 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
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>
When using --mount=type=bind,target=/run/foo, podman/buildah creates
the mount point directory in the image layer even though the mounted
content is not committed. These empty directory stubs pollute /run
in the final image.
Fix by using --mount=type=tmpfs,target=/run with bind mounts nested
inside. This ensures /run remains empty in the committed layer.
Also move the lint invocation in Dockerfile.cfsuki to a separate RUN
command so it runs after the bind mount is released.
Assisted-by: OpenCode (Opus 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
Due to https://bugzilla.redhat.com/show_bug.cgi?id=2429501
This reverts the prior change to make the test non gating
because the problem is we'd consistently fail to do a bootc install
*for each test* which dramatically slowed down that job.
We could fix that but it's easier to just disable the job.
Signed-off-by: Colin Walters <walters@verbum.org>
When G_MESSAGES_DEBUG is set (e.g., 'all'), GLib and OSTree emit debug
messages to stdout instead of stderr. This corrupts the commit hash
that we parse from the ostree commit subprocess output, causing derived
layer content to be silently lost during container imports.
The issue manifests as packages installed via 'dnf install' in a
Containerfile not appearing in the deployed system's rpmdb after
a rebase/upgrade operation.
Fixes: https://issues.redhat.com/browse/OCPBUGS-64692
Assisted-by: OpenCode (Claude Opus 4.5)
Signed-off-by: Joseph Marrero Corchado <jmarrero@redhat.com>
The "install to-filesystem with separate /var mount" test was causing
disk space issues on GitHub Actions runners due to its large disk
image requirements (12GB for partitions with LVM). Moving it to a TMT
test allows it to run in a dedicated VM where disk space is not as
constrained.
The test verifies that bootc install to-filesystem correctly handles
scenarios where /var is on a separate filesystem, which is a common
production setup.
Changes:
- Remove the test from Rust integration tests (install.rs)
- Add new TMT test: test-32-install-to-filesystem-var-mount.sh
- Add package requirements (parted, lvm2, dosfstools, e2fsprogs)
- Update tests.fmf and integration.fmf with new test entry
Assisted-by: Claude Code (Opus 4.5)
Signed-off-by: ckyrouac <ckyrouac@redhat.com>
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>
Add a `gating` matrix property to test-integration jobs.
Jobs with `gating: false` use `continue-on-error: true`, allowing
them to fail without blocking PR merges.
Mark fedora-44 as non-gating due to a grub2 regression in the base
image (https://bugzilla.redhat.com/show_bug.cgi?id=2429501).
Assisted-by: OpenCode (Claude Sonnet 4)
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>
The `cp -a lbi/usr/. /usr` command was preserving local directory
permissions which in one case for me have a restrictive mode 0750
which breaks booting.
Switch to `install -D -m 0644` which explicitly sets file modes and
creates parent directories with correct 755 permissions, while also
simplifying the directory structure.
Assisted-by: OpenCode (Opus 4.5)
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>
When cargo-binstall fetches pre-built binaries from GitHub, it can hit
API rate limits (403 Forbidden) when unauthenticated. This causes it to
fall back to building from source, which fails for mdbook-linkcheck
because the devenv container lacks openssl-devel and the perl modules
needed to build OpenSSL from source.
Pass the GitHub Actions token through to the container build as a secret,
allowing cargo-binstall to make authenticated requests with higher rate
limits.
Assisted-by: OpenCode (claude-sonnet-4-20250514)
Signed-off-by: Colin Walters <walters@verbum.org>
Add a comment noting that changes to the composefs-rs crate list should
also update the documentation files that reference them.
Assisted-by: OpenCode (Opus 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
These external git dependencies don't have docs on docs.rs, so include
them in the internal documentation alongside our workspace crates.
Assisted-by: OpenCode (Opus 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
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>
The CoreOS install test was previously run conditionally within the
test-integration matrix job. Running it separately avoids disk space
issues that can occur when both tests run in the same job, as the
CoreOS test requires building additional container images.
Assisted-by: OpenCode (Opus 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
Remove the separate build-from-packages and _build-from-package helper
recipes. The build logic is now inlined directly in the build recipe.
Add BOOTC_SKIP_PACKAGE=1 environment variable support to skip the
package build step when packages are provided externally (e.g. from
CI artifacts). This is used in ci.yml for the test-integration job.
Assisted-by: OpenCode (Sonnet 4)
Signed-off-by: Colin Walters <walters@verbum.org>
Now that we're building a from-scratch image it won't have `/ostree`
in it; this line was always pruning the wrong repo.
Signed-off-by: Colin Walters <walters@verbum.org>
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>