diff --git a/lib/src/install.rs b/lib/src/install.rs index b46b009fc..025293e93 100644 --- a/lib/src/install.rs +++ b/lib/src/install.rs @@ -7,8 +7,8 @@ // This sub-module is the "basic" installer that handles creating basic block device // and filesystem setup. pub(crate) mod baseline; -mod osbuild; pub(crate) mod config; +mod osbuild; pub(crate) mod osconfig; use std::io::Write; @@ -1185,7 +1185,7 @@ async fn prepare_install( // creating multiple. let tempdir = cap_std_ext::cap_tempfile::TempDir::new(cap_std::ambient_authority())?; // And continue to init global state - osbuild::adjust_for_bootc_image_builder(&tempdir)?; + osbuild::adjust_for_bootc_image_builder(&rootfs, &tempdir)?; if !target_opts.skip_fetch_check { verify_target_fetch(&tempdir, &target_imgref).await?; diff --git a/lib/src/install/osbuild.rs b/lib/src/install/osbuild.rs index d33418404..1540b946a 100644 --- a/lib/src/install/osbuild.rs +++ b/lib/src/install/osbuild.rs @@ -41,10 +41,33 @@ fn adjust_etc_containers(tempdir: &Dir) -> Result<()> { Ok(()) } +/// osbuild mounts the host's /var/lib/containers at /run/osbuild/containers; mount +/// it back to /var/lib/containers where the default container stack expects to find it. +fn propagate_run_osbuild_containers(root: &Dir) -> Result<()> { + let osbuild_run_containers = Utf8Path::new("run/osbuild/containers"); + // If we're not apparently running under osbuild, then we no-op. + if !root.try_exists(osbuild_run_containers)? { + return Ok(()); + } + // If we do seem to have a valid container store though, use that + if crate::podman::storage_exists_default(root)? { + return Ok(()); + } + let relative_storage = Utf8Path::new(crate::podman::CONTAINER_STORAGE.trim_start_matches('/')); + root.create_dir_all(relative_storage)?; + Task::new("Creating bind mount for run/osbuild/containers", "mount") + .arg("--rbind") + .args([osbuild_run_containers, relative_storage]) + .cwd(root)? + .run()?; + Ok(()) +} + /// bootc-image-builder today does a few things that we need to /// deal with. #[context("bootc-image-builder adjustments")] -pub(crate) fn adjust_for_bootc_image_builder(tempdir: &Dir) -> Result<()> { +pub(crate) fn adjust_for_bootc_image_builder(root: &Dir, tempdir: &Dir) -> Result<()> { adjust_etc_containers(tempdir)?; + propagate_run_osbuild_containers(root)?; Ok(()) } diff --git a/lib/src/podman.rs b/lib/src/podman.rs index f5f7fd966..a2ea36507 100644 --- a/lib/src/podman.rs +++ b/lib/src/podman.rs @@ -1,4 +1,6 @@ use anyhow::{anyhow, Result}; +use camino::Utf8Path; +use cap_std_ext::cap_std::fs::Dir; use serde::Deserialize; use crate::install::run_in_host_mountns; @@ -27,3 +29,21 @@ pub(crate) fn imageid_to_digest(imgid: &str) -> Result { .ok_or_else(|| anyhow!("No images returned for inspect"))?; Ok(i.digest) } + +/// Return true if there is apparently an active container store at the target path. +pub(crate) fn storage_exists(root: &Dir, path: impl AsRef) -> Result { + fn impl_storage_exists(root: &Dir, path: &Utf8Path) -> Result { + let lock = "storage.lock"; + root.try_exists(path.join(lock)).map_err(Into::into) + } + impl_storage_exists(root, path.as_ref()) +} + +/// Return true if there is apparently an active container store in the default path +/// for the target root. +/// +/// Note this does not attempt to parse the root filesystem's container storage configuration, +/// this uses a hardcoded default path. +pub(crate) fn storage_exists_default(root: &Dir) -> Result { + storage_exists(root, CONTAINER_STORAGE.trim_start_matches('/')) +}