From b783278544d659d6f7f5035efc703a78cb4fd334 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 7 Nov 2024 16:56:25 -0500 Subject: [PATCH] install: Stop reading kargs from container root, use ostree Part of https://github.com/containers/bootc/issues/879 Basically we want to be able to `bootc install` outside of a container. For the same reasons actually that we already support parsing kargs from an ostree commit (without materializing it as a filesystem), just expose a small wrapper for that API via `pub(crate)` and use it in between the "pull" and "deploy" phases. We basically do the same thing on `bootc upgrade`. - v2: Clean up the multiple copies of the kargs path into a `const` Signed-off-by: Colin Walters --- lib/src/install.rs | 23 +++++++++++++++-------- lib/src/kargs.rs | 21 ++++++++++++++++----- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/lib/src/install.rs b/lib/src/install.rs index d8b73a803..b3655e45c 100644 --- a/lib/src/install.rs +++ b/lib/src/install.rs @@ -660,8 +660,6 @@ async fn install_container( let sepolicy = sepolicy.as_ref(); let stateroot = state.stateroot(); - let container_rootfs = &Dir::open_ambient_dir("/", cap_std::ambient_authority())?; - let (src_imageref, proxy_cfg) = if !state.source.in_host_mountns { (state.source.imageref.clone(), None) } else { @@ -703,17 +701,26 @@ async fn install_container( // Pull the container image into the target root filesystem. Since this is // an install path, we don't need to fsync() individual layers. - { + let pulled_image = { let spec_imgref = ImageReference::from(src_imageref.clone()); let repo = &sysroot.repo(); repo.set_disable_fsync(true); - crate::deploy::pull(repo, &spec_imgref, Some(&state.target_imgref), false).await?; + let r = crate::deploy::pull(repo, &spec_imgref, Some(&state.target_imgref), false).await?; repo.set_disable_fsync(false); - } + r + }; - // Load the kargs from the /usr/lib/bootc/kargs.d from the running root, - // which should be the same as the filesystem we'll deploy. - let kargsd = crate::kargs::get_kargs_in_root(container_rootfs, std::env::consts::ARCH)?; + // We need to read the kargs from the target merged ostree commit before + // we do the deployment. + let merged_ostree_root = sysroot + .repo() + .read_commit(pulled_image.ostree_commit.as_str(), gio::Cancellable::NONE)? + .0; + let kargsd = crate::kargs::get_kargs_from_ostree_root( + &sysroot.repo(), + merged_ostree_root.downcast_ref().unwrap(), + std::env::consts::ARCH, + )?; let kargsd = kargsd.iter().map(|s| s.as_str()); let install_config_kargs = state diff --git a/lib/src/kargs.rs b/lib/src/kargs.rs index 07743e5f1..dccd27a27 100644 --- a/lib/src/kargs.rs +++ b/lib/src/kargs.rs @@ -15,6 +15,8 @@ use serde::Deserialize; use crate::deploy::ImageState; use crate::store::Storage; +const KARGS_PATH: &str = "usr/lib/bootc/kargs.d"; + /// The kargs.d configuration file. #[derive(Deserialize)] #[serde(rename_all = "kebab-case", deny_unknown_fields)] @@ -37,10 +39,7 @@ impl Config { /// a combined list. pub(crate) fn get_kargs_in_root(d: &Dir, sys_arch: &str) -> Result> { // If the directory doesn't exist, that's OK. - let Some(d) = d - .open_dir_optional("usr/lib/bootc/kargs.d")? - .map(DirUtf8::from_cap_std) - else { + let Some(d) = d.open_dir_optional(KARGS_PATH)?.map(DirUtf8::from_cap_std) else { return Ok(Default::default()); }; let mut ret = Vec::new(); @@ -54,6 +53,18 @@ pub(crate) fn get_kargs_in_root(d: &Dir, sys_arch: &str) -> Result> } /// Load kargs.d files from the target ostree commit root +#[cfg(feature = "install")] +pub(crate) fn get_kargs_from_ostree_root( + repo: &ostree::Repo, + root: &ostree::RepoFile, + sys_arch: &str, +) -> Result> { + let kargsd = root.resolve_relative_path(KARGS_PATH); + let kargsd = kargsd.downcast_ref::().expect("downcast"); + get_kargs_from_ostree(repo, kargsd, sys_arch) +} + +/// Load kargs.d files from the target dir fn get_kargs_from_ostree( repo: &ostree::Repo, fetched_tree: &ostree::RepoFile, @@ -119,7 +130,7 @@ pub(crate) fn get_kargs( // Get the kargs in kargs.d of the pending image let (fetched_tree, _) = repo.read_commit(fetched.ostree_commit.as_str(), cancellable)?; - let fetched_tree = fetched_tree.resolve_relative_path("/usr/lib/bootc/kargs.d"); + let fetched_tree = fetched_tree.resolve_relative_path(KARGS_PATH); let fetched_tree = fetched_tree .downcast::() .expect("downcast");