From 347a29348cb420575b20ebe44120e7465afc9584 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 17 Jul 2024 18:42:42 -0400 Subject: [PATCH 1/3] boundimage: use utils::sysroot_fd These landed independently; use the shared helper. Signed-off-by: Colin Walters --- lib/src/boundimage.rs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/lib/src/boundimage.rs b/lib/src/boundimage.rs index eeb99db01..85cfae946 100644 --- a/lib/src/boundimage.rs +++ b/lib/src/boundimage.rs @@ -6,18 +6,11 @@ use cap_std_ext::dirext::CapStdExtDirExt; use fn_error_context::context; use ostree_ext::ostree::Deployment; use ostree_ext::sysroot::SysrootLock; -use rustix::fd::BorrowedFd; const BOUND_IMAGE_DIR: &str = "usr/lib/bootc-experimental/bound-images.d"; -// Access the file descriptor for a sysroot -#[allow(unsafe_code)] -pub(crate) fn sysroot_fd(sysroot: &ostree_ext::ostree::Sysroot) -> BorrowedFd { - unsafe { BorrowedFd::borrow_raw(sysroot.fd()) } -} - pub(crate) fn pull_bound_images(sysroot: &SysrootLock, deployment: &Deployment) -> Result<()> { - let sysroot_fd = sysroot_fd(&sysroot); + let sysroot_fd = crate::utils::sysroot_fd(&sysroot); let sysroot_fd = Dir::reopen_dir(&sysroot_fd)?; let deployment_root_path = sysroot.deployment_dirpath(&deployment); let deployment_root = &sysroot_fd.open_dir(&deployment_root_path)?; From 5362c9b218acdf4b576f2e37ed51d872292777aa Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 17 Jul 2024 18:45:11 -0400 Subject: [PATCH 2/3] boundimage: Add some module docs Signed-off-by: Colin Walters --- lib/src/boundimage.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/lib/src/boundimage.rs b/lib/src/boundimage.rs index 85cfae946..dff7b2019 100644 --- a/lib/src/boundimage.rs +++ b/lib/src/boundimage.rs @@ -1,3 +1,10 @@ +//! # Implementation of "logically bound" container images +//! +//! This module implements the design in +//! for "logically bound" container images. These container images are +//! pre-pulled (and in the future, pinned) before a new image root +//! is considered ready. + use crate::task::Task; use anyhow::{Context, Result}; use camino::Utf8Path; @@ -7,8 +14,11 @@ use fn_error_context::context; use ostree_ext::ostree::Deployment; use ostree_ext::sysroot::SysrootLock; +/// The path in a root for bound images; this directory should only contain +/// symbolic links to `.container` or `.image` files. const BOUND_IMAGE_DIR: &str = "usr/lib/bootc-experimental/bound-images.d"; +/// Given a deployment, pull all container images it references. pub(crate) fn pull_bound_images(sysroot: &SysrootLock, deployment: &Deployment) -> Result<()> { let sysroot_fd = crate::utils::sysroot_fd(&sysroot); let sysroot_fd = Dir::reopen_dir(&sysroot_fd)?; @@ -111,6 +121,11 @@ fn pull_images(_deployment_root: &Dir, bound_images: Vec) -> Result< Ok(()) } +/// A subset of data parsed from a `.image` or `.container` file with +/// the minimal information necessary to fetch the image. +/// +/// In the future this may be extended to include e.g. certificates or +/// other pull options. #[derive(PartialEq, Eq)] struct BoundImage { image: String, @@ -131,6 +146,10 @@ impl BoundImage { } } +/// Given a string, parse it in a way similar to how systemd would do it. +/// The primary thing here is that we reject any "specifiers" such as `%a` +/// etc. We do allow a quoted `%%` to appear in the string, which will +/// result in a single unquoted `%`. fn parse_spec_value(value: &str) -> Result { let mut it = value.chars(); let mut ret = String::new(); From 5550b7e2d6c3419b25bab5e9276066e1b273c1cc Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 17 Jul 2024 20:45:09 -0400 Subject: [PATCH 3/3] boundimage: Add some tracing::debug To debug things. Signed-off-by: Colin Walters --- lib/src/boundimage.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/src/boundimage.rs b/lib/src/boundimage.rs index dff7b2019..07c8f2c28 100644 --- a/lib/src/boundimage.rs +++ b/lib/src/boundimage.rs @@ -34,6 +34,7 @@ pub(crate) fn pull_bound_images(sysroot: &SysrootLock, deployment: &Deployment) #[context("parse bound image spec dir")] fn parse_spec_dir(root: &Dir, spec_dir: &str) -> Result> { let Some(bound_images_dir) = root.open_dir_optional(spec_dir)? else { + tracing::debug!("Missing {spec_dir}"); return Ok(Default::default()); }; // And open a view of the dir that uses RESOLVE_IN_ROOT so we @@ -107,6 +108,7 @@ fn parse_container_file(file_contents: &tini::Ini) -> Result { #[context("pull bound images")] fn pull_images(_deployment_root: &Dir, bound_images: Vec) -> Result<()> { + tracing::debug!("Pulling bound images: {}", bound_images.len()); //TODO: do this in parallel for bound_image in bound_images { let mut task = Task::new("Pulling bound image", "/usr/bin/podman")