From 26a51a6ce26bd3e7fadbb0333cb3e9c9d2aa2a2b Mon Sep 17 00:00:00 2001 From: John Eckersberg Date: Tue, 26 Aug 2025 13:12:10 -0400 Subject: [PATCH] Move kernel cmdline parsing to dedicated crate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Creates a new dedicated crate for kernel command line parsing functionality, moving it out of bootc-lib for better separation of concerns and modularity. Changes: - Create new bootc-kernel-cmdline crate under crates/kernel_cmdline/ - Move kernel_cmdline.rs from bootc-lib to the new crate as lib.rs - Add bootc-kernel-cmdline dependency to bootc-lib - Update imports in bootc-lib to use bootc_kernel_cmdline:: namespace - Add missing Debug derive and documentation to fix lints 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude Signed-off-by: John Eckersberg --- Cargo.lock | 10 ++++++++++ crates/kernel_cmdline/Cargo.toml | 18 ++++++++++++++++++ .../src/lib.rs} | 18 +++++++++++------- crates/lib/Cargo.toml | 1 + crates/lib/src/install.rs | 6 +++--- crates/lib/src/lib.rs | 1 - 6 files changed, 43 insertions(+), 11 deletions(-) create mode 100644 crates/kernel_cmdline/Cargo.toml rename crates/{lib/src/kernel_cmdline.rs => kernel_cmdline/src/lib.rs} (97%) diff --git a/Cargo.lock b/Cargo.lock index bc47458cd..65d88810d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -236,6 +236,15 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "bootc-kernel-cmdline" +version = "0.0.0" +dependencies = [ + "anyhow", + "similar-asserts", + "static_assertions", +] + [[package]] name = "bootc-lib" version = "1.7.1" @@ -245,6 +254,7 @@ dependencies = [ "anyhow", "bootc-internal-blockdev", "bootc-internal-utils", + "bootc-kernel-cmdline", "bootc-mount", "bootc-sysusers", "bootc-tmpfiles", diff --git a/crates/kernel_cmdline/Cargo.toml b/crates/kernel_cmdline/Cargo.toml new file mode 100644 index 000000000..1e51ad034 --- /dev/null +++ b/crates/kernel_cmdline/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "bootc-kernel-cmdline" +description = "Kernel command line parsing utilities for bootc" +version = "0.0.0" +edition = "2021" +license = "MIT OR Apache-2.0" +repository = "https://github.com/bootc-dev/bootc" + +[dependencies] +# Workspace dependencies +anyhow = { workspace = true } + +[dev-dependencies] +similar-asserts = { workspace = true } +static_assertions = { workspace = true } + +[lints] +workspace = true \ No newline at end of file diff --git a/crates/lib/src/kernel_cmdline.rs b/crates/kernel_cmdline/src/lib.rs similarity index 97% rename from crates/lib/src/kernel_cmdline.rs rename to crates/kernel_cmdline/src/lib.rs index a961d2f31..aa3010887 100644 --- a/crates/lib/src/kernel_cmdline.rs +++ b/crates/kernel_cmdline/src/lib.rs @@ -8,16 +8,17 @@ use std::borrow::Cow; use anyhow::Result; /// This is used by dracut. -pub(crate) const INITRD_ARG_PREFIX: &str = "rd."; +pub const INITRD_ARG_PREFIX: &str = "rd."; /// The kernel argument for configuring the rootfs flags. -pub(crate) const ROOTFLAGS: &str = "rootflags"; +pub const ROOTFLAGS: &str = "rootflags"; /// A parsed kernel command line. /// /// Wraps the raw command line bytes and provides methods for parsing and iterating /// over individual parameters. Uses copy-on-write semantics to avoid unnecessary /// allocations when working with borrowed data. -pub(crate) struct Cmdline<'a>(Cow<'a, [u8]>); +#[derive(Debug)] +pub struct Cmdline<'a>(Cow<'a, [u8]>); impl<'a, T: AsRef<[u8]> + ?Sized> From<&'a T> for Cmdline<'a> { /// Creates a new `Cmdline` from any type that can be referenced as bytes. @@ -128,7 +129,7 @@ impl<'a> Cmdline<'a> { /// /// Handles quoted values and treats dashes and underscores in keys as equivalent. #[derive(Debug, Eq)] -pub(crate) struct ParameterKey<'a>(&'a [u8]); +pub struct ParameterKey<'a>(&'a [u8]); impl<'a> std::ops::Deref for ParameterKey<'a> { type Target = [u8]; @@ -148,7 +149,7 @@ impl<'a> From<&'a [u8]> for ParameterKey<'a> { /// /// Otherwise the same as [`ParameterKey`]. #[derive(Debug, Eq)] -pub(crate) struct ParameterKeyStr<'a>(&'a str); +pub struct ParameterKeyStr<'a>(&'a str); impl<'a> From<&'a str> for ParameterKeyStr<'a> { fn from(value: &'a str) -> Self { @@ -158,7 +159,7 @@ impl<'a> From<&'a str> for ParameterKeyStr<'a> { /// A single kernel command line parameter. #[derive(Debug, Eq)] -pub(crate) struct Parameter<'a> { +pub struct Parameter<'a> { /// The full original value pub parameter: &'a [u8], /// The parameter key as raw bytes @@ -169,7 +170,7 @@ pub(crate) struct Parameter<'a> { /// A single kernel command line parameter. #[derive(Debug, PartialEq, Eq)] -pub(crate) struct ParameterStr<'a> { +pub struct ParameterStr<'a> { /// The original value pub parameter: &'a str, /// The parameter key @@ -179,6 +180,9 @@ pub(crate) struct ParameterStr<'a> { } impl<'a> Parameter<'a> { + /// Convert this parameter to a UTF-8 string parameter, if possible. + /// + /// Returns `None` if the parameter contains invalid UTF-8. pub fn to_str(&self) -> Option> { let Ok(parameter) = std::str::from_utf8(self.parameter) else { return None; diff --git a/crates/lib/Cargo.toml b/crates/lib/Cargo.toml index 76935a91d..a555f19ad 100644 --- a/crates/lib/Cargo.toml +++ b/crates/lib/Cargo.toml @@ -16,6 +16,7 @@ include = ["/src", "LICENSE-APACHE", "LICENSE-MIT"] [dependencies] # Internal crates bootc-blockdev = { package = "bootc-internal-blockdev", path = "../blockdev", version = "0.0.0" } +bootc-kernel-cmdline = { path = "../kernel_cmdline", version = "0.0.0" } bootc-mount = { path = "../mount" } bootc-sysusers = { path = "../sysusers" } bootc-tmpfiles = { path = "../tmpfiles" } diff --git a/crates/lib/src/install.rs b/crates/lib/src/install.rs index ae32ca77e..47e46cccc 100644 --- a/crates/lib/src/install.rs +++ b/crates/lib/src/install.rs @@ -56,13 +56,13 @@ use self::baseline::InstallBlockDeviceOpts; use crate::boundimage::{BoundImage, ResolvedBoundImage}; use crate::containerenv::ContainerExecutionInfo; use crate::deploy::{prepare_for_pull, pull_from_prepared, PreparedImportMeta, PreparedPullResult}; -use crate::kernel_cmdline::Cmdline; use crate::lsm; use crate::progress_jsonl::ProgressWriter; use crate::spec::ImageReference; use crate::store::Storage; use crate::task::Task; use crate::utils::sigpolicy_from_opt; +use bootc_kernel_cmdline::Cmdline; use bootc_mount::Filesystem; /// The toplevel boot directory @@ -1639,9 +1639,9 @@ fn find_root_args_to_inherit(cmdline: &Cmdline, root_info: &Filesystem) -> Resul .context("Parsing root= karg")?; // If we have a root= karg, then use that let (mount_spec, kargs) = if let Some(root) = root { - let rootflags = cmdline.find_str(crate::kernel_cmdline::ROOTFLAGS); + let rootflags = cmdline.find_str(bootc_kernel_cmdline::ROOTFLAGS); let inherit_kargs = - cmdline.find_all_starting_with_str(crate::kernel_cmdline::INITRD_ARG_PREFIX); + cmdline.find_all_starting_with_str(bootc_kernel_cmdline::INITRD_ARG_PREFIX); ( root.to_owned(), rootflags diff --git a/crates/lib/src/lib.rs b/crates/lib/src/lib.rs index 309d027a0..9c2f87f99 100644 --- a/crates/lib/src/lib.rs +++ b/crates/lib/src/lib.rs @@ -34,7 +34,6 @@ mod docgen; mod bootloader; mod containerenv; mod install; -mod kernel_cmdline; #[cfg(feature = "composefs-backend")] #[allow(dead_code)]