diff --git a/crates/lib/Cargo.toml b/crates/lib/Cargo.toml index 83ed261ab..cdc278d49 100644 --- a/crates/lib/Cargo.toml +++ b/crates/lib/Cargo.toml @@ -74,13 +74,11 @@ similar-asserts = { workspace = true } static_assertions = { workspace = true } [features] -default = ["install-to-disk", "composefs-backend"] +default = ["install-to-disk"] # This feature enables `bootc install to-disk`, which is considered just a "demo" # or reference installer; we expect most nontrivial use cases to be using # `bootc install to-filesystem`. install-to-disk = [] -# Enable support for the composefs native backend -composefs-backend = [] # This featuares enables `bootc internals publish-rhsm-facts` to integrate with # Red Hat Subscription Manager rhsm = [] diff --git a/crates/lib/src/bootc_composefs/delete.rs b/crates/lib/src/bootc_composefs/delete.rs index f7f3f71cb..54258de42 100644 --- a/crates/lib/src/bootc_composefs/delete.rs +++ b/crates/lib/src/bootc_composefs/delete.rs @@ -43,8 +43,8 @@ fn delete_type1_entry(depl: &DeploymentEntry, boot_dir: &Dir, deleting_staged: b // We reuse kernel + initrd if they're the same for two deployments // We don't want to delete the (being deleted) deployment's kernel + initrd // if it's in use by any other deployment - let should_del_kernel = match &depl.deployment.boot_digest { - Some(digest) => find_vmlinuz_initrd_duplicates(&digest)? + let should_del_kernel = match depl.deployment.boot_digest.as_ref() { + Some(digest) => find_vmlinuz_initrd_duplicates(digest)? .is_some_and(|vec| vec.iter().any(|digest| *digest != depl.deployment.verity)), None => false, }; diff --git a/crates/lib/src/bootloader.rs b/crates/lib/src/bootloader.rs index 411baec2f..fb9a81521 100644 --- a/crates/lib/src/bootloader.rs +++ b/crates/lib/src/bootloader.rs @@ -8,7 +8,6 @@ use fn_error_context::context; use bootc_blockdev::{Partition, PartitionTable}; use bootc_mount as mount; -#[cfg(any(feature = "composefs-backend", feature = "install-to-disk"))] use crate::bootc_composefs::boot::mount_esp; use crate::{discoverable_partition_specification, utils}; @@ -72,7 +71,6 @@ pub(crate) fn install_via_bootupd( } #[context("Installing bootloader")] -#[cfg(any(feature = "composefs-backend", feature = "install-to-disk"))] pub(crate) fn install_systemd_boot( device: &PartitionTable, _rootfs: &Utf8Path, diff --git a/crates/lib/src/cli.rs b/crates/lib/src/cli.rs index 3425c88af..34973abaa 100644 --- a/crates/lib/src/cli.rs +++ b/crates/lib/src/cli.rs @@ -33,9 +33,7 @@ use schemars::schema_for; use serde::{Deserialize, Serialize}; use tempfile::tempdir_in; -#[cfg(feature = "composefs-backend")] use crate::bootc_composefs::delete::delete_composefs_deployment; -#[cfg(feature = "composefs-backend")] use crate::bootc_composefs::{ finalize::{composefs_backend_finalize, get_etc_diff}, rollback::composefs_rollback, @@ -669,13 +667,12 @@ pub(crate) enum Opt { #[clap(subcommand)] #[clap(hide = true)] Internals(InternalsOpts), - #[cfg(feature = "composefs-backend")] ComposefsFinalizeStaged, - #[cfg(feature = "composefs-backend")] /// Diff current /etc configuration versus default ConfigDiff, - #[cfg(feature = "composefs-backend")] - DeleteDeployment { depl_id: String }, + DeleteDeployment { + depl_id: String, + }, } /// Ensure we've entered a mount namespace, so that we can remount @@ -1267,38 +1264,26 @@ async fn run_from_opt(opt: Opt) -> Result<()> { let root = &Dir::open_ambient_dir("/", cap_std::ambient_authority())?; match opt { Opt::Upgrade(opts) => { - #[cfg(feature = "composefs-backend")] if composefs_booted()?.is_some() { upgrade_composefs(opts).await } else { upgrade(opts).await } - - #[cfg(not(feature = "composefs-backend"))] - upgrade(opts).await } Opt::Switch(opts) => { - #[cfg(feature = "composefs-backend")] if composefs_booted()?.is_some() { switch_composefs(opts).await } else { switch(opts).await } - - #[cfg(not(feature = "composefs-backend"))] - switch(opts).await } Opt::Rollback(opts) => { - #[cfg(feature = "composefs-backend")] if composefs_booted()?.is_some() { composefs_rollback().await? } else { rollback(&opts).await? } - #[cfg(not(feature = "composefs-backend"))] - rollback(&opts).await?; - if opts.apply { crate::reboot::reboot()?; } @@ -1307,15 +1292,11 @@ async fn run_from_opt(opt: Opt) -> Result<()> { } Opt::Edit(opts) => edit(opts).await, Opt::UsrOverlay => { - #[cfg(feature = "composefs-backend")] if composefs_booted()?.is_some() { composefs_usr_overlay() } else { usroverlay().await } - - #[cfg(not(feature = "composefs-backend"))] - usroverlay().await } Opt::Container(opts) => match opts { ContainerOpts::Lint { @@ -1608,13 +1589,10 @@ async fn run_from_opt(opt: Opt) -> Result<()> { } }, - #[cfg(feature = "composefs-backend")] Opt::ComposefsFinalizeStaged => composefs_backend_finalize().await, - #[cfg(feature = "composefs-backend")] Opt::ConfigDiff => get_etc_diff().await, - #[cfg(feature = "composefs-backend")] Opt::DeleteDeployment { depl_id } => delete_composefs_deployment(&depl_id).await, } } diff --git a/crates/lib/src/install.rs b/crates/lib/src/install.rs index 9f8fb2105..08631a0e6 100644 --- a/crates/lib/src/install.rs +++ b/crates/lib/src/install.rs @@ -53,7 +53,6 @@ use serde::{Deserialize, Serialize}; #[cfg(feature = "install-to-disk")] use self::baseline::InstallBlockDeviceOpts; -#[cfg(feature = "composefs-backend")] use crate::bootc_composefs::{boot::setup_composefs_boot, repo::initialize_composefs_repository}; use crate::boundimage::{BoundImage, ResolvedBoundImage}; use crate::containerenv::ContainerExecutionInfo; @@ -66,7 +65,6 @@ use crate::task::Task; use crate::utils::sigpolicy_from_opt; use bootc_kernel_cmdline::{bytes, utf8, INITRD_ARG_PREFIX, ROOTFLAGS}; use bootc_mount::Filesystem; -#[cfg(feature = "composefs-backend")] use composefs::fsverity::FsVerityHashValue; /// The toplevel boot directory @@ -88,7 +86,6 @@ const SELINUXFS: &str = "/sys/fs/selinux"; pub(crate) const EFIVARFS: &str = "/sys/firmware/efi/efivars"; pub(crate) const ARCH_USES_EFI: bool = cfg!(any(target_arch = "x86_64", target_arch = "aarch64")); -#[cfg(feature = "composefs-backend")] pub(crate) const EFI_LOADER_INFO: &str = "LoaderInfo-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f"; const DEFAULT_REPO_CONFIG: &[(&str, &str)] = &[ @@ -278,7 +275,6 @@ pub(crate) struct InstallToDiskOpts { #[clap(flatten)] #[serde(flatten)] - #[cfg(feature = "composefs-backend")] pub(crate) composefs_opts: InstallComposefsOpts, } @@ -356,7 +352,6 @@ pub(crate) struct InstallToFilesystemOpts { #[clap(flatten)] pub(crate) config_opts: InstallConfigOpts, - #[cfg(feature = "composefs-backend")] #[clap(flatten)] pub(crate) composefs_opts: InstallComposefsOpts, } @@ -391,7 +386,6 @@ pub(crate) struct InstallToExistingRootOpts { #[clap(default_value = ALONGSIDE_ROOT_MOUNT)] pub(crate) root_path: Utf8PathBuf, - #[cfg(feature = "composefs-backend")] #[clap(flatten)] pub(crate) composefs_opts: InstallComposefsOpts, } @@ -434,7 +428,6 @@ pub(crate) struct State { pub(crate) composefs_required: bool, // If Some, then --composefs_native is passed - #[cfg(feature = "composefs-backend")] pub(crate) composefs_options: InstallComposefsOpts, /// Detected bootloader type for the target system @@ -565,7 +558,7 @@ impl FromStr for MountSpec { } } -#[cfg(all(feature = "install-to-disk", feature = "composefs-backend"))] +#[cfg(feature = "install-to-disk")] impl InstallToDiskOpts { pub(crate) fn validate(&self) -> Result<()> { if !self.composefs_opts.composefs_backend { @@ -1221,11 +1214,7 @@ async fn verify_target_fetch( } fn root_has_uki(root: &Dir) -> Result { - #[cfg(feature = "composefs-backend")] - return crate::bootc_composefs::boot::container_root_has_uki(root); - - #[cfg(not(feature = "composefs-backend"))] - Ok(false) + crate::bootc_composefs::boot::container_root_has_uki(root) } /// Preparation for an install; validates and prepares some (thereafter immutable) global state. @@ -1233,7 +1222,7 @@ async fn prepare_install( config_opts: InstallConfigOpts, source_opts: InstallSourceOpts, target_opts: InstallTargetOpts, - #[cfg(feature = "composefs-backend")] mut composefs_options: InstallComposefsOpts, + mut composefs_options: InstallComposefsOpts, ) -> Result> { tracing::trace!("Preparing install"); let rootfs = cap_std::fs::Dir::open_ambient_dir("/", cap_std::ambient_authority()) @@ -1308,7 +1297,6 @@ async fn prepare_install( tracing::debug!("Composefs required: {composefs_required}"); - #[cfg(feature = "composefs-backend")] if composefs_required { composefs_options.composefs_backend = true; } @@ -1381,7 +1369,6 @@ async fn prepare_install( // Determine bootloader type for the target system // Priority: user-specified > bootupd availability > systemd-boot fallback - #[cfg(feature = "composefs-backend")] let detected_bootloader = { if let Some(bootloader) = composefs_options.bootloader.clone() { bootloader @@ -1393,8 +1380,6 @@ async fn prepare_install( } } }; - #[cfg(not(feature = "composefs-backend"))] - let detected_bootloader = crate::spec::Bootloader::Grub; println!("Bootloader: {detected_bootloader}"); // Create our global (read-only) state which gets wrapped in an Arc @@ -1413,7 +1398,6 @@ async fn prepare_install( host_is_container, composefs_required, detected_bootloader, - #[cfg(feature = "composefs-backend")] composefs_options, }); @@ -1585,7 +1569,6 @@ async fn install_to_filesystem_impl( } } - #[cfg(feature = "composefs-backend")] if state.composefs_options.composefs_backend { // Load a fd for the mounted target physical root @@ -1596,9 +1579,6 @@ async fn install_to_filesystem_impl( ostree_install(state, rootfs, cleanup).await?; } - #[cfg(not(feature = "composefs-backend"))] - ostree_install(state, rootfs, cleanup).await?; - // Finalize mounted filesystems if !rootfs.skip_finalize { let bootfs = rootfs.boot.as_ref().map(|_| ("boot", "boot")); @@ -1618,7 +1598,6 @@ fn installation_complete() { #[context("Installing to disk")] #[cfg(feature = "install-to-disk")] pub(crate) async fn install_to_disk(mut opts: InstallToDiskOpts) -> Result<()> { - #[cfg(feature = "composefs-backend")] opts.validate()?; // Log the disk installation operation to systemd journal @@ -1667,7 +1646,6 @@ pub(crate) async fn install_to_disk(mut opts: InstallToDiskOpts) -> Result<()> { opts.config_opts, opts.source_opts, opts.target_opts, - #[cfg(feature = "composefs-backend")] opts.composefs_opts, ) .await?; @@ -1905,7 +1883,6 @@ pub(crate) async fn install_to_filesystem( opts.config_opts, opts.source_opts, opts.target_opts, - #[cfg(feature = "composefs-backend")] opts.composefs_opts, ) .await?; @@ -2177,7 +2154,6 @@ pub(crate) async fn install_to_existing_root(opts: InstallToExistingRootOpts) -> source_opts: opts.source_opts, target_opts: opts.target_opts, config_opts: opts.config_opts, - #[cfg(feature = "composefs-backend")] composefs_opts: opts.composefs_opts, }; diff --git a/crates/lib/src/lib.rs b/crates/lib/src/lib.rs index 16ccc10ec..905f167ad 100644 --- a/crates/lib/src/lib.rs +++ b/crates/lib/src/lib.rs @@ -4,7 +4,6 @@ //! to provide a fully "container native" tool for using //! bootable container images. -#[cfg(feature = "composefs-backend")] mod bootc_composefs; pub(crate) mod bootc_kargs; mod bootloader; diff --git a/crates/lib/src/lints.rs b/crates/lib/src/lints.rs index 55b4f1978..96446fff2 100644 --- a/crates/lib/src/lints.rs +++ b/crates/lib/src/lints.rs @@ -27,7 +27,6 @@ use linkme::distributed_slice; use ostree_ext::ostree_prepareroot; use serde::Serialize; -#[cfg(feature = "composefs-backend")] use crate::bootc_composefs::boot::EFI_LINUX; /// Reference to embedded default baseimage content that should exist. @@ -770,7 +769,6 @@ fn check_boot(root: &Dir, config: &LintExecutionConfig) -> LintResult { }) .collect(); let mut entries = entries?; - #[cfg(feature = "composefs-backend")] { // Work around https://github.com/containers/composefs-rs/issues/131 let efidir = Utf8Path::new(EFI_LINUX) diff --git a/crates/lib/src/spec.rs b/crates/lib/src/spec.rs index 75b1962e3..83fd0b3ab 100644 --- a/crates/lib/src/spec.rs +++ b/crates/lib/src/spec.rs @@ -11,7 +11,6 @@ use ostree_ext::{container::OstreeImageReference, oci_spec}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -#[cfg(feature = "composefs-backend")] use crate::bootc_composefs::boot::BootType; use crate::{k8sapitypes, status::Slot}; @@ -201,7 +200,6 @@ impl FromStr for Bootloader { /// A bootable entry #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "camelCase")] -#[cfg(feature = "composefs-backend")] pub struct BootEntryComposefs { /// The erofs verity pub verity: String, @@ -235,7 +233,6 @@ pub struct BootEntry { /// If this boot entry is ostree based, the corresponding state pub ostree: Option, /// If this boot entry is composefs based, the corresponding state - #[cfg(feature = "composefs-backend")] pub composefs: Option, } @@ -272,7 +269,6 @@ pub struct HostStatus { pub ty: Option, } -#[cfg(feature = "composefs-backend")] pub(crate) struct DeploymentEntry<'a> { pub(crate) ty: Option, pub(crate) deployment: &'a BootEntryComposefs, @@ -315,7 +311,6 @@ impl Host { } } - #[cfg(feature = "composefs-backend")] pub(crate) fn require_composefs_booted(&self) -> anyhow::Result<&BootEntryComposefs> { let cfs = self .status @@ -328,7 +323,6 @@ impl Host { } /// Returns all composefs deployments in a list - #[cfg(feature = "composefs-backend")] #[fn_error_context::context("Getting all composefs deployments")] pub(crate) fn all_composefs_deployments<'a>(&'a self) -> Result>> { let mut all_deps = vec![]; @@ -636,7 +630,6 @@ mod tests { pinned: false, store: None, ostree: None, - #[cfg(feature = "composefs-backend")] composefs: None, } } diff --git a/crates/lib/src/status.rs b/crates/lib/src/status.rs index 5f5305509..1583c81c9 100644 --- a/crates/lib/src/status.rs +++ b/crates/lib/src/status.rs @@ -19,10 +19,8 @@ use ostree_ext::sysroot::SysrootLock; use ostree_ext::ostree; -#[cfg(feature = "composefs-backend")] use crate::bootc_composefs::status::{composefs_booted, composefs_deployment_status}; use crate::cli::OutputFormat; -#[cfg(feature = "composefs-backend")] use crate::spec::BootEntryComposefs; use crate::spec::ImageStatus; use crate::spec::{BootEntry, BootOrder, Host, HostSpec, HostStatus, HostType}; @@ -212,7 +210,6 @@ fn boot_entry_from_deployment( deploy_serial: deployment.deployserial().try_into().unwrap(), stateroot: deployment.stateroot().into(), }), - #[cfg(feature = "composefs-backend")] composefs: None, }; Ok(r) @@ -234,7 +231,6 @@ impl BootEntry { } } - #[cfg(feature = "composefs-backend")] pub(crate) fn require_composefs(&self) -> Result<&BootEntryComposefs> { self.composefs.as_ref().ok_or(anyhow::anyhow!( "BootEntry is not a composefs native boot entry" @@ -349,7 +345,6 @@ pub(crate) fn get_status( Ok((deployments, host)) } -#[cfg(feature = "composefs-backend")] async fn get_host() -> Result { let host = if ostree_booted()? { let sysroot = super::cli::get_storage().await?; @@ -366,21 +361,6 @@ async fn get_host() -> Result { Ok(host) } -#[cfg(not(feature = "composefs-backend"))] -async fn get_host() -> Result { - let host = if ostree_booted()? { - let sysroot = super::cli::get_storage().await?; - let ostree = sysroot.get_ostree()?; - let booted_deployment = ostree.booted_deployment(); - let (_deployments, host) = get_status(&ostree, booted_deployment.as_ref())?; - host - } else { - Default::default() - }; - - Ok(host) -} - /// Implementation of the `bootc status` CLI command. #[context("Status")] pub(crate) async fn status(opts: super::cli::StatusOpts) -> Result<()> { @@ -524,7 +504,6 @@ fn human_render_slot( writeln!(out, "{digest} ({arch})")?; // Write the EROFS verity if present - #[cfg(feature = "composefs-backend")] if let Some(composefs) = &entry.composefs { write_row_name(&mut out, "Verity", prefix_len)?; writeln!(out, "{}", composefs.verity)?; @@ -631,7 +610,6 @@ fn human_render_slot_ostree( } /// Output a rendering of a non-container composefs boot entry. -#[cfg(feature = "composefs-backend")] fn human_render_slot_composefs( mut out: impl Write, slot: Slot, @@ -666,7 +644,6 @@ fn human_readable_output_booted(mut out: impl Write, host: &Host, verbose: bool) writeln!(out)?; } - #[cfg(feature = "composefs-backend")] if let Some(image) = &host_status.image { human_render_slot(&mut out, Some(slot_name), host_status, image, verbose)?; } else if let Some(ostree) = host_status.ostree.as_ref() { @@ -682,21 +659,6 @@ fn human_readable_output_booted(mut out: impl Write, host: &Host, verbose: bool) } else { writeln!(out, "Current {slot_name} state is unknown")?; } - - #[cfg(not(feature = "composefs-backend"))] - if let Some(image) = &host_status.image { - human_render_slot(&mut out, Some(slot_name), host_status, image, verbose)?; - } else if let Some(ostree) = host_status.ostree.as_ref() { - human_render_slot_ostree( - &mut out, - Some(slot_name), - host_status, - &ostree.checksum, - verbose, - )?; - } else { - writeln!(out, "Current {slot_name} state is unknown")?; - } } } diff --git a/crates/lib/src/store/mod.rs b/crates/lib/src/store/mod.rs index 7dfbafb2a..8ce41f54a 100644 --- a/crates/lib/src/store/mod.rs +++ b/crates/lib/src/store/mod.rs @@ -37,7 +37,6 @@ use crate::utils::deployment_fd; /// See https://github.com/containers/composefs-rs/issues/159 pub type ComposefsRepository = composefs::repository::Repository; -#[cfg(feature = "composefs-backend")] pub type ComposefsFilesystem = composefs::tree::FileSystem; /// Path to the physical root diff --git a/crates/lib/src/utils.rs b/crates/lib/src/utils.rs index 59d377743..aa7bee255 100644 --- a/crates/lib/src/utils.rs +++ b/crates/lib/src/utils.rs @@ -1,7 +1,6 @@ use std::future::Future; use std::io::Write; use std::os::fd::BorrowedFd; -#[cfg(feature = "composefs-backend")] use std::path::{Component, Path, PathBuf}; use std::process::Command; use std::time::Duration; @@ -202,7 +201,6 @@ pub(crate) fn digested_pullspec(image: &str, digest: &str) -> String { format!("{image}@{digest}") } -#[cfg(feature = "composefs-backend")] #[derive(Debug)] pub enum EfiError { SystemNotUEFI, @@ -213,14 +211,12 @@ pub enum EfiError { Io(std::io::Error), } -#[cfg(feature = "composefs-backend")] impl From for EfiError { fn from(e: std::io::Error) -> Self { EfiError::Io(e) } } -#[cfg(feature = "composefs-backend")] pub fn read_uefi_var(var_name: &str) -> Result { use crate::install::EFIVARFS; use cap_std_ext::cap_std::ambient_authority; @@ -262,7 +258,6 @@ pub fn read_uefi_var(var_name: &str) -> Result { /// Computes a relative path from `from` to `to`. /// /// Both `from` and `to` must be absolute paths. -#[cfg(feature = "composefs-backend")] pub(crate) fn path_relative_to(from: &Path, to: &Path) -> Result { if !from.is_absolute() || !to.is_absolute() { anyhow::bail!("Paths must be absolute"); @@ -321,7 +316,6 @@ mod tests { } #[test] - #[cfg(feature = "composefs-backend")] fn test_relative_path() { let from = Path::new("/sysroot/state/deploy/image_id"); let to = Path::new("/sysroot/state/os/default/var"); diff --git a/docs/src/experimental-composefs.md b/docs/src/experimental-composefs.md index 4965988e4..37d94d7cd 100644 --- a/docs/src/experimental-composefs.md +++ b/docs/src/experimental-composefs.md @@ -9,7 +9,7 @@ Tracking issue: The composefs backend is an experimental alternative storage backend that uses [composefs-rs](https://github.com/containers/composefs-rs) instead of ostree for storing and managing bootc system deployments. -**Status**: Experimental. The composefs backend is under active development and not yet suitable for production use. The feature is currently gated behind the `composefs-backend` compile-time feature flag, which in current git main is enabled by default. +**Status**: Experimental. The composefs backend is under active development and not yet suitable for production use. The feature is always compiled in as of bootc v1.10.1. ## Key Benefits