From d7c3f9f4aaf89eefe7c1ff7e5f2512b3fd010131 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 14 Aug 2024 12:04:48 -0400 Subject: [PATCH] Split off an internal "bootc-utils" crate In general the codebase is starting to get to the size where some internal crates make sense. Let's start with the inevitable catchall "utils" crate which starts off just holding our helper traits for subprocesses. Signed-off-by: Colin Walters --- Cargo.lock | 15 ++++++++++++++ lib/Cargo.toml | 1 + lib/src/blockdev.rs | 2 +- lib/src/image.rs | 3 ++- lib/src/imgstorage.rs | 3 +-- lib/src/install.rs | 2 +- lib/src/lib.rs | 1 - lib/src/mount.rs | 3 ++- lib/src/podman.rs | 2 +- utils/Cargo.toml | 22 +++++++++++++++++++++ lib/src/cmdutils.rs => utils/src/command.rs | 8 ++++---- utils/src/lib.rs | 6 ++++++ 12 files changed, 56 insertions(+), 12 deletions(-) create mode 100644 utils/Cargo.toml rename lib/src/cmdutils.rs => utils/src/command.rs (97%) create mode 100644 utils/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 3653dab8d..b81e788b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -170,6 +170,7 @@ dependencies = [ "anstream", "anstyle", "anyhow", + "bootc-utils", "camino", "cap-std-ext", "chrono", @@ -204,6 +205,20 @@ dependencies = [ "xshell", ] +[[package]] +name = "bootc-utils" +version = "0.0.0" +dependencies = [ + "anyhow", + "serde", + "serde_json", + "similar-asserts", + "static_assertions", + "tempfile", + "tokio", + "tracing", +] + [[package]] name = "bstr" version = "0.2.17" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index c888a853b..96dcb2d39 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -17,6 +17,7 @@ include = ["/src", "LICENSE-APACHE", "LICENSE-MIT"] anstream = "0.6.13" anstyle = "1.0.6" anyhow = { workspace = true } +bootc-utils = { path = "../utils" } camino = { workspace = true, features = ["serde1"] } ostree-ext = { version = "0.14.0" } chrono = { workspace = true, features = ["serde"] } diff --git a/lib/src/blockdev.rs b/lib/src/blockdev.rs index 89ee8e02f..8631902fb 100644 --- a/lib/src/blockdev.rs +++ b/lib/src/blockdev.rs @@ -10,9 +10,9 @@ use fn_error_context::context; use regex::Regex; use serde::Deserialize; -use crate::cmdutils::CommandRunExt; use crate::install::run_in_host_mountns; use crate::task::Task; +use bootc_utils::CommandRunExt; #[derive(Debug, Deserialize)] struct DevicesOutput { diff --git a/lib/src/image.rs b/lib/src/image.rs index 7e5908d2e..eac891a0d 100644 --- a/lib/src/image.rs +++ b/lib/src/image.rs @@ -3,10 +3,11 @@ //! APIs for operating on container images in the bootc storage. use anyhow::{Context, Result}; +use bootc_utils::CommandRunExt; use fn_error_context::context; use ostree_ext::container::{ImageReference, Transport}; -use crate::{cmdutils::CommandRunExt, imgstorage::Storage}; +use crate::imgstorage::Storage; /// The name of the image we push to containers-storage if nothing is specified. const IMAGE_DEFAULT: &str = "localhost/bootc"; diff --git a/lib/src/imgstorage.rs b/lib/src/imgstorage.rs index 63586a2a9..8a4f1d149 100644 --- a/lib/src/imgstorage.rs +++ b/lib/src/imgstorage.rs @@ -12,6 +12,7 @@ use std::process::{Command, Stdio}; use std::sync::Arc; use anyhow::{Context, Result}; +use bootc_utils::{AsyncCommandRunExt, CommandRunExt, ExitStatusExt}; use camino::Utf8Path; use cap_std_ext::cap_std; use cap_std_ext::cap_std::fs::Dir; @@ -22,8 +23,6 @@ use fn_error_context::context; use std::os::fd::OwnedFd; use tokio::process::Command as AsyncCommand; -use crate::cmdutils::{AsyncCommandRunExt, CommandRunExt, ExitStatusExt}; - // Pass only 100 args at a time just to avoid potentially overflowing argument // vectors; not that this should happen in reality, but just in case. const SUBCMD_ARGV_CHUNKING: usize = 100; diff --git a/lib/src/install.rs b/lib/src/install.rs index 456363c69..607623f62 100644 --- a/lib/src/install.rs +++ b/lib/src/install.rs @@ -22,6 +22,7 @@ use std::time::Duration; use anyhow::Ok; use anyhow::{anyhow, Context, Result}; +use bootc_utils::CommandRunExt; use camino::Utf8Path; use camino::Utf8PathBuf; use cap_std::fs::{Dir, MetadataExt}; @@ -43,7 +44,6 @@ use rustix::fs::{FileTypeExt, MetadataExt as _}; use serde::{Deserialize, Serialize}; use self::baseline::InstallBlockDeviceOpts; -use crate::cmdutils::CommandRunExt; use crate::containerenv::ContainerExecutionInfo; use crate::mount::Filesystem; use crate::spec::ImageReference; diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 6142b0794..b2263b017 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -10,7 +10,6 @@ mod boundimage; pub mod cli; -mod cmdutils; pub(crate) mod deploy; pub(crate) mod generator; mod image; diff --git a/lib/src/mount.rs b/lib/src/mount.rs index 4acb90b11..f830df327 100644 --- a/lib/src/mount.rs +++ b/lib/src/mount.rs @@ -3,11 +3,12 @@ use std::process::Command; use anyhow::{anyhow, Result}; +use bootc_utils::CommandRunExt; use camino::Utf8Path; use fn_error_context::context; use serde::Deserialize; -use crate::{cmdutils::CommandRunExt, task::Task}; +use crate::task::Task; #[derive(Deserialize, Debug)] #[serde(rename_all = "kebab-case")] diff --git a/lib/src/podman.rs b/lib/src/podman.rs index d10457e95..2f8d0196a 100644 --- a/lib/src/podman.rs +++ b/lib/src/podman.rs @@ -24,7 +24,7 @@ pub(crate) struct ImageListEntry { /// Given an image ID, return its manifest digest #[cfg(feature = "install")] pub(crate) fn imageid_to_digest(imgid: &str) -> Result { - use crate::cmdutils::CommandRunExt; + use bootc_utils::CommandRunExt; let o: Vec = crate::install::run_in_host_mountns("podman") .args(["inspect", imgid]) .run_and_parse_json()?; diff --git a/utils/Cargo.toml b/utils/Cargo.toml new file mode 100644 index 000000000..0a28b807e --- /dev/null +++ b/utils/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "bootc-utils" +publish = false +version = "0.0.0" +edition = "2021" +license = "MIT OR Apache-2.0" +repository = "https://github.com/containers/bootc" + +[dependencies] +anyhow = { workspace = true } +serde = { workspace = true, features = ["derive"] } +serde_json = { workspace = true } +tempfile = { workspace = true } +tracing = { workspace = true } +tokio = { workspace = true, features = ["process"] } + +[dev-dependencies] +similar-asserts = { version = "1.5.0" } +static_assertions = "1.1.0" + +[lints] +workspace = true diff --git a/lib/src/cmdutils.rs b/utils/src/command.rs similarity index 97% rename from lib/src/cmdutils.rs rename to utils/src/command.rs index 73d5d9fc8..3a360caae 100644 --- a/lib/src/cmdutils.rs +++ b/utils/src/command.rs @@ -6,14 +6,14 @@ use std::{ use anyhow::{Context, Result}; /// Helpers intended for [`std::process::Command`]. -pub(crate) trait CommandRunExt { +pub trait CommandRunExt { fn run(&mut self) -> Result<()>; /// Execute the child process, parsing its stdout as JSON. fn run_and_parse_json(&mut self) -> Result; } /// Helpers intended for [`std::process::ExitStatus`]. -pub(crate) trait ExitStatusExt { +pub trait ExitStatusExt { /// If the exit status signals it was not successful, return an error. /// Note that we intentionally *don't* include the command string /// in the output; we leave it to the caller to add that if they want, @@ -82,8 +82,8 @@ impl CommandRunExt for Command { } /// Helpers intended for [`tokio::process::Command`]. -#[allow(dead_code)] -pub(crate) trait AsyncCommandRunExt { +#[allow(async_fn_in_trait)] +pub trait AsyncCommandRunExt { async fn run(&mut self) -> Result<()>; } diff --git a/utils/src/lib.rs b/utils/src/lib.rs new file mode 100644 index 000000000..6976ce24d --- /dev/null +++ b/utils/src/lib.rs @@ -0,0 +1,6 @@ +//! The inevitable catchall "utils" crate. Generally only add +//! things here that only depend on the standard library and +//! "core" crates. +//! +mod command; +pub use command::*;