diff --git a/crates/lib/src/bootc_composefs/update.rs b/crates/lib/src/bootc_composefs/update.rs index 78a3d4717..d1990eb1e 100644 --- a/crates/lib/src/bootc_composefs/update.rs +++ b/crates/lib/src/bootc_composefs/update.rs @@ -255,6 +255,13 @@ pub(crate) async fn do_upgrade( ) -> Result<()> { start_finalize_stated_svc()?; + // Pre-flight disk space check before pulling any data. + crate::deploy::check_disk_space_composefs( + &booted_cfs.repo, + &img_manifest_config.manifest, + imgref, + )?; + let (repo, entries, id, fs) = pull_composefs_repo( &imgref.transport, &imgref.image, diff --git a/crates/lib/src/deploy.rs b/crates/lib/src/deploy.rs index acd8f8198..5487b143f 100644 --- a/crates/lib/src/deploy.rs +++ b/crates/lib/src/deploy.rs @@ -411,8 +411,9 @@ pub(crate) fn check_disk_space_ostree( ) } -/// Verify there is sufficient disk space to pull an image into the composefs store. -pub(crate) fn check_disk_space_composefs( +/// Verify there is sufficient disk space to pull an image into the composefs store +/// via the ostree unified-storage path (uses `PreparedImportMeta`). +pub(crate) fn check_disk_space_unified( cfs: &crate::store::ComposefsRepository, image_meta: &PreparedImportMeta, imgref: &ImageReference, @@ -420,6 +421,21 @@ pub(crate) fn check_disk_space_composefs( check_disk_space_inner(cfs.objects_dir()?, image_meta.bytes_to_fetch, 0, imgref) } +/// Verify there is sufficient disk space to pull an image into the composefs store +/// for the native composefs backend (uses a raw `ImageManifest`). +pub(crate) fn check_disk_space_composefs( + cfs: &crate::store::ComposefsRepository, + manifest: &ostree_ext::oci_spec::image::ImageManifest, + imgref: &ImageReference, +) -> Result<()> { + let bytes_to_fetch: u64 = manifest + .layers() + .iter() + .map(|l: &ostree_ext::oci_spec::image::Descriptor| l.size()) + .sum(); + check_disk_space_inner(cfs.objects_dir()?, bytes_to_fetch, 0, imgref) +} + pub(crate) struct PreparedImportMeta { pub imp: ImageImporter, pub prep: Box, @@ -609,7 +625,7 @@ pub(crate) async fn pull_unified( Ok(existing) } PreparedPullResult::Ready(prepared_image_meta) => { - check_disk_space_composefs( + check_disk_space_unified( store.get_ensure_composefs()?.as_ref(), &prepared_image_meta, imgref, diff --git a/crates/lib/src/install.rs b/crates/lib/src/install.rs index 5b412f990..1d59deb63 100644 --- a/crates/lib/src/install.rs +++ b/crates/lib/src/install.rs @@ -188,7 +188,11 @@ use serde::{Deserialize, Serialize}; #[cfg(feature = "install-to-disk")] use self::baseline::InstallBlockDeviceOpts; use crate::bootc_composefs::status::ComposefsCmdline; -use crate::bootc_composefs::{boot::setup_composefs_boot, repo::initialize_composefs_repository}; +use crate::bootc_composefs::{ + boot::setup_composefs_boot, + repo::{get_imgref, initialize_composefs_repository, open_composefs_repo}, + status::get_container_manifest_and_config, +}; use crate::boundimage::{BoundImage, ResolvedBoundImage}; use crate::containerenv::ContainerExecutionInfo; use crate::deploy::{MergeState, PreparedPullResult, prepare_for_pull, pull_from_prepared}; @@ -1951,8 +1955,23 @@ async fn install_to_filesystem_impl( } if state.composefs_options.composefs_backend { - // Load a fd for the mounted target physical root - + // Pre-flight disk space check for native composefs install path. + { + let imgref = &state.source.imageref; + let imgref_repr = get_imgref(&imgref.transport.to_string(), &imgref.name); + let img_manifest_config = get_container_manifest_and_config(&imgref_repr).await?; + crate::store::ensure_composefs_dir(&rootfs.physical_root)?; + let cfs_repo = open_composefs_repo(&rootfs.physical_root)?; + crate::deploy::check_disk_space_composefs( + &cfs_repo, + &img_manifest_config.manifest, + &crate::spec::ImageReference { + image: imgref.name.clone(), + transport: imgref.transport.to_string(), + signature: None, + }, + )?; + } let pull_result = initialize_composefs_repository( state, rootfs, diff --git a/tmt/plans/integration.fmf b/tmt/plans/integration.fmf index 46b14b0fa..b41800930 100644 --- a/tmt/plans/integration.fmf +++ b/tmt/plans/integration.fmf @@ -201,7 +201,6 @@ execute: how: fmf test: - /tmt/tests/tests/test-35-upgrade-preflight-disk-check - extra-fixme_skip_if_composefs: true /plan-36-rollback: summary: Test bootc rollback functionality diff --git a/tmt/tests/booted/test-upgrade-preflight-disk-check.nu b/tmt/tests/booted/test-upgrade-preflight-disk-check.nu index 2d5d5f0e7..0a084529d 100644 --- a/tmt/tests/booted/test-upgrade-preflight-disk-check.nu +++ b/tmt/tests/booted/test-upgrade-preflight-disk-check.nu @@ -2,8 +2,6 @@ # tmt: # summary: Verify pre-flight disk space check rejects images with inflated layer sizes # duration: 10m -# extra: -# fixme_skip_if_composefs: true # # This test does NOT require a reboot. # It constructs a minimal fake OCI image directory that claims to have an