Skip to content

Add support for multiple composefs= digests#2248

Open
cgwalters wants to merge 3 commits into
bootc-dev:mainfrom
cgwalters:adapt-composefs-rs-v1-erofs-2
Open

Add support for multiple composefs= digests#2248
cgwalters wants to merge 3 commits into
bootc-dev:mainfrom
cgwalters:adapt-composefs-rs-v1-erofs-2

Conversation

@cgwalters

Copy link
Copy Markdown
Collaborator

This adapts bootc to build on top of the work in composefs/composefs-rs#297

A toplevel goal here is supporting both the v1 and v2 EROFS formats, which means we'll work with RHEL9 era systems.

Right now bootc container ukify still generates composefs= i.e. v2, but I'd like to change that to do both - it's a pretty cheap thing (the main cost is generating the fsverity digests).

@github-actions github-actions Bot added the area/install Issues related to `bootc install` label Jun 12, 2026
@bootc-bot bootc-bot Bot requested a review from jeckersb June 12, 2026 10:42
@cgwalters cgwalters mentioned this pull request Jun 22, 2026
@jmarrero jmarrero self-requested a review June 22, 2026 13:28
@cgwalters

Copy link
Copy Markdown
Collaborator Author

OK I think the chain here should be:

@cgwalters cgwalters force-pushed the adapt-composefs-rs-v1-erofs-2 branch from 3b90847 to f92013b Compare June 22, 2026 17:30
@cgwalters cgwalters marked this pull request as ready for review June 22, 2026 18:51
@bootc-bot bootc-bot Bot requested a review from henrywang June 22, 2026 18:51
@cgwalters cgwalters added the ci/tier-1 Run CI for tier-1 OS (centos-10) only label Jun 22, 2026
@cgwalters cgwalters force-pushed the adapt-composefs-rs-v1-erofs-2 branch from f92013b to 69757fc Compare June 22, 2026 21:56
jmarrero
jmarrero previously approved these changes Jun 28, 2026

@jmarrero jmarrero left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

just needs a rebase I think.

The only nit is that

            config.erofs_formats = composefs_ctl::composefs::erofs::format::FormatConfig {
                default: composefs_ctl::composefs::erofs::format::FormatVersion::V1,
                extra: [composefs_ctl::composefs::erofs::format::FormatVersion::V2].into(),
            };

Is duplicated 3 times here. So if we add a new version in the future we need to care about 3 places. Maybe it should be a helper function?

@Johan-Liebert1 Johan-Liebert1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lots of .clone() that I believe shouldn't be needed, I might be wrong though. Supporting both V1 and V2 are great, but it is a bit messy, not sure if there's a better way to do this. Also, some inconsistencies here and there (esp in comments) regarding whether V1 is the default or V2

Comment thread contrib/packaging/seal-uki Outdated
seal_state=$1
shift
# EROFS format version to pass to bootc container ukify (optional, default: v2)
erofs_version=${1:-v2}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kind of conflicts with composefs/composefs-rs#330. We'd probably want to have the same defaults everywhere

Comment thread crates/lib/src/bootc_composefs/boot.rs Outdated
os_id: Option<String>,
boot_digest: String,
/// The composefs image digest parsed from (and validated against) the UKI's
/// own cmdline. This is the authoritative deployment key for UKI boots:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for every boot right, not just UKIs?

Comment thread crates/lib/src/bootc_composefs/boot.rs Outdated
let composefs_info = BootComposefsCmdline::<Sha512HashValue>::from_cmdline(&cmdline)
.context("Parsing composefs=")?
.ok_or_else(|| anyhow::anyhow!("No composefs= or composefs.digest.v1= karg found in UKI cmdline"))?;
let composefs_cmdline = composefs_info.digest().clone();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This name is a bit confusing. afaiu this is only the digest and not the entire cmdline?


if test "${boot_type}" = "uki"; then
/run/packaging/seal-uki /run/target /out /run/secrets "${allow_missing_verity}" "${seal_state}"
/run/packaging/seal-uki /run/target /out /run/secrets "${allow_missing_verity}" "${seal_state}" "${erofs_version}"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also need this in tmt/tests/booted/test-install-to-filesystem-var-mount.sh

// (see setup_composefs_boot for the full rationale). Provisional value for
// BLS (where bootc writes the karg from this same id); overridden for UKI by
// the digest the UKI cmdline actually carries.
let provisional_deploy_id = boot_id_v2.clone().unwrap_or_else(|| id.clone());

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

id here is confusing especially with both boot_id_v1/v2 defined. I believe it's the erofs digest corresponding to the erofs version that the repo is currently using?

// Authoritative collision check against the final deploy key. For UKI this
// may differ from the provisional checked above (the UKI may carry a
// non-default digest), so this is the load-bearing guarantee.
ensure_no_deploy_collision(host, &deploy_id)?;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need to do this again?

Comment thread crates/lib/src/bootc_composefs/boot.rs Outdated
// setup-root opens `state/deploy/<this>` using that same karg, so we must
// key the deployment off exactly this value -- whether the UKI was sealed
// with the V2 (default) or V1 EROFS digest.
let deploy_id = uki_info.composefs_cmdline.clone();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we shouldn't need to clone this?

@cgwalters cgwalters added this to the 1.17 milestone Jul 6, 2026
@cgwalters cgwalters force-pushed the adapt-composefs-rs-v1-erofs-2 branch from 69757fc to 4ecc241 Compare July 7, 2026 22:55
cgwalters added 3 commits July 7, 2026 19:08
The `--bind-storage-ro` host container-storage passthrough relies on a
libvirt-managed virtiofsd, which cannot run in some environments such as
nested user namespaces or cloud/non-qemu setups. Plans that normally
request bind-storage previously had no way to opt out short of editing
plan metadata.

Add a `--skip-bind-storage` flag (and matching `BOOTC_skip_bind_storage`
env var) that forces those plans to run without the host
container-storage mount. Default behavior is unchanged: bind-storage is
still used wherever it is requested and supported. Plans that depend on a
locally built upgrade image reaching the VM via bind-storage will be
unable to perform the upgrade/switch step when this is set.

Signed-off-by: Colin Walters <walters@verbum.org>
composefs-rs landed support for V1 EROFS, which we need to enable
composefs on RHEL9.

Make new installs produce both V1 and V2 EROFS images for committed
composefs images, and make V1 the default wherever a single format
must be chosen: the repository's default EROFS format, the
`--erofs-version` flag on `bootc container ukify` and
`compute-composefs-digest`, and the provisional BLS deploy key
computed at install time.  V2 remains available via
`--erofs-version=v2` and is always generated alongside V1, so a
deployment can still be booted via the legacy `composefs=` karg.

This keeps the install path consistent with the upgrade and GC paths,
which already prefer V1.

Critically, a V1 digest must be written as a `composefs.digest=v1-...`
karg, not the legacy `composefs=` shorthand (which upstream reserves
for V2).  Add `build_composefs_karg`, which selects the correct form
via composefs-boot's own `ComposefsCmdline::new_v1`/`new_v2` and
`to_cmdline_arg`, and use it everywhere bootc writes a new karg
(install, upgrade, `container ukify`, soft-reboot) instead of the
version-unaware helper that only ever emitted `composefs=`.

Signed-off-by: Colin Walters <walters@verbum.org>
With V1 EROFS as the default, sealed UKIs are now viable on CentOS-9.
Replace the blanket composefs exclusion for centos-9 with targeted
exclusions for the modes that still don't work: BLS (needs newer
dracut) and unsealed composefs.  This leaves composefs + sealed + UKI
enabled.

Signed-off-by: Colin Walters <walters@verbum.org>
@cgwalters cgwalters force-pushed the adapt-composefs-rs-v1-erofs-2 branch from 4ecc241 to 6ec1bf4 Compare July 8, 2026 00:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/install Issues related to `bootc install` ci/tier-1 Run CI for tier-1 OS (centos-10) only

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants