diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b05af3f3b..6e39e2fac 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -236,9 +236,6 @@ jobs: seal_state: ["sealed", "unsealed"] exclude: - # https://github.com/bootc-dev/bootc/issues/1812 - - test_os: centos-9 - variant: composefs - seal_state: "sealed" boot_type: bls - seal_state: "sealed" diff --git a/Cargo.lock b/Cargo.lock index abf77face..86952fa75 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -77,7 +77,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -88,7 +88,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -192,9 +192,9 @@ checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64" -version = "0.22.1" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +checksum = "b25655df2c3cdd83c5e5b293b88acd880332b2ddadd7c30ac43144fdc0033da9" [[package]] name = "bcvk-qemu" @@ -496,7 +496,7 @@ dependencies = [ "maybe-owned", "rustix", "rustix-linux-procfs", - "windows-sys 0.60.2", + "windows-sys 0.61.2", "winx", ] @@ -537,7 +537,7 @@ dependencies = [ "rustix", "rustix-linux-procfs", "uuid", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -739,7 +739,7 @@ checksum = "55b672471b4e9f9e95499ea597ff64941a309b2cdbffcc46f2cc5e2d971fd335" [[package]] name = "composefs" version = "0.7.0" -source = "git+https://github.com/composefs/composefs-rs?rev=0a819c351951864071aa9ec23d6594710bf3173f#0a819c351951864071aa9ec23d6594710bf3173f" +source = "git+https://github.com/composefs/composefs-rs?rev=5a227a01ed389d29884181ec8aabc75f484e966d#5a227a01ed389d29884181ec8aabc75f484e966d" dependencies = [ "anyhow", "composefs-ioctls", @@ -766,7 +766,7 @@ dependencies = [ [[package]] name = "composefs-boot" version = "0.7.0" -source = "git+https://github.com/composefs/composefs-rs?rev=0a819c351951864071aa9ec23d6594710bf3173f#0a819c351951864071aa9ec23d6594710bf3173f" +source = "git+https://github.com/composefs/composefs-rs?rev=5a227a01ed389d29884181ec8aabc75f484e966d#5a227a01ed389d29884181ec8aabc75f484e966d" dependencies = [ "anyhow", "composefs", @@ -782,7 +782,7 @@ dependencies = [ [[package]] name = "composefs-ctl" version = "0.7.0" -source = "git+https://github.com/composefs/composefs-rs?rev=0a819c351951864071aa9ec23d6594710bf3173f#0a819c351951864071aa9ec23d6594710bf3173f" +source = "git+https://github.com/composefs/composefs-rs?rev=5a227a01ed389d29884181ec8aabc75f484e966d#5a227a01ed389d29884181ec8aabc75f484e966d" dependencies = [ "anyhow", "cap-std-ext", @@ -811,7 +811,7 @@ dependencies = [ [[package]] name = "composefs-fuse" version = "0.7.0" -source = "git+https://github.com/composefs/composefs-rs?rev=0a819c351951864071aa9ec23d6594710bf3173f#0a819c351951864071aa9ec23d6594710bf3173f" +source = "git+https://github.com/composefs/composefs-rs?rev=5a227a01ed389d29884181ec8aabc75f484e966d#5a227a01ed389d29884181ec8aabc75f484e966d" dependencies = [ "anyhow", "composefs", @@ -826,7 +826,7 @@ dependencies = [ [[package]] name = "composefs-ioctls" version = "0.7.0" -source = "git+https://github.com/composefs/composefs-rs?rev=0a819c351951864071aa9ec23d6594710bf3173f#0a819c351951864071aa9ec23d6594710bf3173f" +source = "git+https://github.com/composefs/composefs-rs?rev=5a227a01ed389d29884181ec8aabc75f484e966d#5a227a01ed389d29884181ec8aabc75f484e966d" dependencies = [ "rustix", "thiserror 2.0.18", @@ -835,11 +835,11 @@ dependencies = [ [[package]] name = "composefs-oci" version = "0.7.0" -source = "git+https://github.com/composefs/composefs-rs?rev=0a819c351951864071aa9ec23d6594710bf3173f#0a819c351951864071aa9ec23d6594710bf3173f" +source = "git+https://github.com/composefs/composefs-rs?rev=5a227a01ed389d29884181ec8aabc75f484e966d#5a227a01ed389d29884181ec8aabc75f484e966d" dependencies = [ "anyhow", "async-compression", - "base64 0.22.1", + "base64 0.23.0", "bytes", "cap-std-ext", "composefs", @@ -869,7 +869,7 @@ dependencies = [ [[package]] name = "composefs-splitdirfdstream" version = "0.7.0" -source = "git+https://github.com/composefs/composefs-rs?rev=0a819c351951864071aa9ec23d6594710bf3173f#0a819c351951864071aa9ec23d6594710bf3173f" +source = "git+https://github.com/composefs/composefs-rs?rev=5a227a01ed389d29884181ec8aabc75f484e966d#5a227a01ed389d29884181ec8aabc75f484e966d" dependencies = [ "rand 0.10.2", "rand_pcg", @@ -882,10 +882,10 @@ dependencies = [ [[package]] name = "composefs-storage" version = "0.7.0" -source = "git+https://github.com/composefs/composefs-rs?rev=0a819c351951864071aa9ec23d6594710bf3173f#0a819c351951864071aa9ec23d6594710bf3173f" +source = "git+https://github.com/composefs/composefs-rs?rev=5a227a01ed389d29884181ec8aabc75f484e966d#5a227a01ed389d29884181ec8aabc75f484e966d" dependencies = [ "anyhow", - "base64 0.22.1", + "base64 0.23.0", "cap-std", "cap-std-ext", "composefs-splitdirfdstream", @@ -1295,7 +1295,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -1436,15 +1436,15 @@ dependencies = [ [[package]] name = "fuser" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80a5eca878900c2e39e9e52fd797954b7fc39eeefc8558257114bfea6a698fcf" +checksum = "b82b6597d216503555ead6b358f341ef748869bf5c6fbae6a0cb9dd231baecfd" dependencies = [ "bitflags 2.11.1", "libc", "log", "memchr", - "nix 0.30.1", + "nix 0.31.2", "num_enum", "page_size", "parking_lot", @@ -1937,7 +1937,7 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82cb6a9f675da968c63b6208c641b9dca58fc0133ae53375736b1767b0cab8bd" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -2227,19 +2227,6 @@ dependencies = [ "memoffset", ] -[[package]] -name = "nix" -version = "0.30.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" -dependencies = [ - "bitflags 2.11.1", - "cfg-if", - "cfg_aliases", - "libc", - "memoffset", -] - [[package]] name = "nix" version = "0.31.2" @@ -2250,6 +2237,7 @@ dependencies = [ "cfg-if", "cfg_aliases", "libc", + "memoffset", ] [[package]] @@ -2267,7 +2255,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -2894,7 +2882,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -3183,7 +3171,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -3328,10 +3316,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom 0.4.2", "once_cell", "rustix", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -3341,7 +3329,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "230a1b821ccbd75b185820a1f1ff7b14d21da1e442e22c0863ea5f08771a8874" dependencies = [ "rustix", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -3492,7 +3480,7 @@ dependencies = [ "toml_datetime", "toml_parser", "toml_writer", - "winnow", + "winnow 1.0.2", ] [[package]] @@ -3513,7 +3501,7 @@ dependencies = [ "indexmap", "toml_datetime", "toml_parser", - "winnow", + "winnow 1.0.2", ] [[package]] @@ -3522,7 +3510,7 @@ version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ - "winnow", + "winnow 1.0.2", ] [[package]] @@ -4103,6 +4091,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" +[[package]] +name = "winnow" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" + [[package]] name = "winnow" version = "1.0.2" @@ -4299,19 +4293,20 @@ checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" [[package]] name = "zlink" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0799145a2e15a8ea97e44771916f8630c870ee302c178a313269fc8e3b6f9736" +checksum = "dd5961645cac87b613e8b3c6fb1743a567e6459bc8c1d00f7bf9884020fc98d4" dependencies = [ + "zlink-core", "zlink-smol", "zlink-tokio", ] [[package]] name = "zlink-core" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2526043182746855a331d62e03c19964c7e1a714259ebe4764d1f5ce330ef01" +checksum = "0314bb8bc5a5693f4625a6ea9681731a5f4bcc0a952bfca28184f268db15dcc2" dependencies = [ "futures-util", "itoa", @@ -4322,25 +4317,36 @@ dependencies = [ "serde", "serde_json", "tracing", + "zlink-idl", "zlink-macros", ] +[[package]] +name = "zlink-idl" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7990f15bd88a2b37d55c5fc13a1dd662ee98674ec9c6ac904fe46066523932a" +dependencies = [ + "winnow 0.7.15", +] + [[package]] name = "zlink-macros" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34cc16c0526f6721144e1cfeb37fec13e2058993f435015527ec27bf00c2234e" +checksum = "2fc623b8323797bf2d48333e7633e143077dd92cc66d9cca170014b66c43b1b5" dependencies = [ "proc-macro2", "quote", "syn 2.0.117", + "zlink-idl", ] [[package]] name = "zlink-smol" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce083a1715cabf50e1af55e7444d7fe04c912cd2dc27cef0fe378e78d6158699" +checksum = "4bc4150b8af92eb0ae7007e0ced3eb2bcf8a7fa49457de2f30b11752ea538f46" dependencies = [ "async-broadcast", "async-channel", @@ -4353,9 +4359,9 @@ dependencies = [ [[package]] name = "zlink-tokio" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "228414d41219fb9c8a02b6bd71a677ed8b585c461670101b5da09c06a0dd3f56" +checksum = "4c4fe0f232dd656bcb0594e9646b86c69f6257e3d5194f28715a044c4d10c8fa" dependencies = [ "futures-util", "pin-project-lite", diff --git a/Cargo.toml b/Cargo.toml index 393f6a37e..87ef781d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,7 +48,7 @@ clap_mangen = { version = "0.3.0" } # pulls), which drags in rustls-webpki/untrusted/webpki-root-certs whose # licenses aren't in our cargo-deny allow list. Re-enable once that's sorted. # See: https://github.com/bootc-dev/bootc/pull/2295 -composefs-ctl = { git = "https://github.com/composefs/composefs-rs", rev = "0a819c351951864071aa9ec23d6594710bf3173f", default-features = false, features = [ +composefs-ctl = { git = "https://github.com/composefs/composefs-rs", rev = "5a227a01ed389d29884181ec8aabc75f484e966d", default-features = false, features = [ "pre-6.15", "pre-6.16", "oci", diff --git a/Makefile b/Makefile index ff96de692..5577e9b0a 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,15 @@ prefix ?= /usr # We may in the future also want to include Fedora+derivatives as # the code is really tiny. # (Note we should also make installation of the units conditional on the rhsm feature) -CARGO_FEATURES_DEFAULT ?= $(shell . /usr/lib/os-release; if echo "$$ID_LIKE" |grep -qF rhel; then echo rhsm; fi) +# +# Enable the rhel9 feature on RHEL/CentOS Stream 9, which runs kernel 5.14. +# That kernel cannot mount an erofs image directly from a file descriptor; +# composefs-ctl's rhel9 feature activates a loopback-device fallback instead. +CARGO_FEATURES_DEFAULT ?= $(shell . /usr/lib/os-release; \ + features=""; \ + if echo "$$ID_LIKE" | grep -qF rhel; then features="$$features rhsm"; fi; \ + if echo "$$ID_LIKE" | grep -qF rhel && [ "$$VERSION_ID" = "9" ]; then features="$$features rhel9"; fi; \ + echo $$features) # You can set this to override all cargo features, including the defaults CARGO_FEATURES ?= $(CARGO_FEATURES_DEFAULT) diff --git a/contrib/packaging/bootc.spec b/contrib/packaging/bootc.spec index 7ce0f7fd2..1865a4a7e 100644 --- a/contrib/packaging/bootc.spec +++ b/contrib/packaging/bootc.spec @@ -12,6 +12,14 @@ %bcond_with rhsm %endif +# kernel 5.14 (RHEL/CentOS 9) cannot mount an erofs image directly from a file +# descriptor; composefs-ctl's rhel9 feature enables a loopback-device fallback. +%if 0%{?rhel} == 9 + %bcond_without rhel9 +%else + %bcond_with rhel9 +%endif + %global rust_minor %(rustc --version | cut -f2 -d" " | cut -f2 -d".") # https://github.com/bootc-dev/bootc/issues/1640 @@ -132,13 +140,16 @@ make manpages # Build all binaries %if 0%{?container_build} # Container build: use cargo directly with cached dependencies to avoid RPM macro overhead -cargo build -j%{_smp_build_ncpus} --release %{?with_rhsm:--features rhsm} --bins +cargo build -j%{_smp_build_ncpus} --release %{?with_rhsm:--features rhsm} %{?with_rhel9:--features rhel9} --bins %else # Non-container build: use RPM macros for proper dependency tracking %if %new_cargo_macros - %cargo_build %{?with_rhsm:-f rhsm} -- --bins + # Note: %%cargo_build's own -f option only accepts a single value, so a + # second -f would silently clobber the first; pass extra features as + # plain --features args after -- instead, which cargo unions correctly. + %cargo_build -- %{?with_rhsm:--features rhsm} %{?with_rhel9:--features rhel9} --bins %else - %cargo_build %{?with_rhsm:--features rhsm} -- --bins + %cargo_build %{?with_rhsm:--features rhsm} %{?with_rhel9:--features rhel9} -- --bins %endif %endif @@ -152,7 +163,7 @@ sed -i -e '/https:\/\//d' cargo-vendor.txt %install # Pass CARGO_FEATURES explicitly to prevent auto-detection rebuild in install environment -%make_install INSTALL="install -p -c" CARGO_FEATURES="%{?with_rhsm:rhsm}" +%make_install INSTALL="install -p -c" CARGO_FEATURES="%{?with_rhsm:rhsm} %{?with_rhel9:rhel9}" %if %{with ostree_ext} make install-ostree-hooks DESTDIR=%{?buildroot} %endif diff --git a/crates/lib/src/cli.rs b/crates/lib/src/cli.rs index 31567f7f9..a856a242e 100644 --- a/crates/lib/src/cli.rs +++ b/crates/lib/src/cli.rs @@ -1244,6 +1244,7 @@ async fn upgrade( .ok_or_else(|| anyhow::anyhow!("No staged deployment found"))?; if staged_deployment.is_finalization_locked() { + crate::boundimage::pull_bound_images(storage, &staged_deployment).await?; ostree.change_finalization(&staged_deployment)?; println!("Staged deployment will now be applied on reboot"); } else { diff --git a/crates/lib/src/deploy.rs b/crates/lib/src/deploy.rs index 739f54d81..fcd2a7636 100644 --- a/crates/lib/src/deploy.rs +++ b/crates/lib/src/deploy.rs @@ -1007,6 +1007,82 @@ impl MergeState { } } +/// Mount an ostree commit as a composefs filesystem, returning a read-only +/// directory handle. +/// +/// This uses `checkout_composefs` to generate an erofs metadata image from +/// the commit, then mounts it via composefs with the ostree repo objects +/// as the backing data store. The returned `Dir` is a detached mount — +/// it stays alive as long as the fd is open. +/// +/// The erofs image is written into the ostree repo's own `tmp/` directory +/// (which lives on the real root filesystem) because erofs file-backed +/// mounts require a non-stacked backing filesystem. +#[context("Mounting ostree commit {commit}")] +pub(crate) fn mount_ostree_commit(repo: &ostree::Repo, commit: &str) -> Result