From b10926d0a11543d0d28ff4e186c8401621c23f3a Mon Sep 17 00:00:00 2001 From: John Eckersberg Date: Fri, 5 Dec 2025 16:27:57 -0500 Subject: [PATCH 1/3] cli: Add `container inspect` Prints JSON of container metadata/attributes of interest. For now this just renders out the kargs embedded in the container under the kargs.d drop-in. Future ideas for enhancements would be to include kernel version and whether or not the image uses a UKI. Closes: #1827 Signed-off-by: John Eckersberg --- crates/lib/src/cli.rs | 14 ++++++++++++++ crates/lib/src/spec.rs | 8 ++++++++ crates/tests-integration/src/container.rs | 15 +++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/crates/lib/src/cli.rs b/crates/lib/src/cli.rs index c59b4dad1..6ab4bdab2 100644 --- a/crates/lib/src/cli.rs +++ b/crates/lib/src/cli.rs @@ -295,6 +295,12 @@ pub(crate) enum InstallOpts { /// Subcommands which can be executed as part of a container build. #[derive(Debug, clap::Subcommand, PartialEq, Eq)] pub(crate) enum ContainerOpts { + /// Output JSON to stdout containing the container image metadata. + Inspect { + /// Operate on the provided rootfs. + #[clap(long, default_value = "/")] + rootfs: Utf8PathBuf, + }, /// Perform relatively inexpensive static analysis checks as part of a container /// build. /// @@ -1345,6 +1351,14 @@ async fn run_from_opt(opt: Opt) -> Result<()> { } } Opt::Container(opts) => match opts { + ContainerOpts::Inspect { rootfs } => { + let root = &Dir::open_ambient_dir(&rootfs, cap_std::ambient_authority())?; + let kargs = crate::bootc_kargs::get_kargs_in_root(root, std::env::consts::ARCH)?; + let kargs: Vec = kargs.iter_str().map(|s| s.to_owned()).collect(); + let inspect = crate::spec::ContainerInspect { kargs }; + serde_json::to_writer_pretty(std::io::stdout().lock(), &inspect)?; + Ok(()) + } ContainerOpts::Lint { rootfs, fatal_warnings, diff --git a/crates/lib/src/spec.rs b/crates/lib/src/spec.rs index 86b8556a1..bc16b2a2f 100644 --- a/crates/lib/src/spec.rs +++ b/crates/lib/src/spec.rs @@ -275,6 +275,14 @@ pub(crate) struct DeploymentEntry<'a> { pub(crate) pinned: bool, } +/// The result of a `bootc container inspect` command. +#[derive(Debug, Serialize)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct ContainerInspect { + /// Kernel arguments embedded in the container image. + pub(crate) kargs: Vec, +} + impl Host { /// Create a new host pub fn new(spec: HostSpec) -> Self { diff --git a/crates/tests-integration/src/container.rs b/crates/tests-integration/src/container.rs index 40b8c3fb9..3d09cadf9 100644 --- a/crates/tests-integration/src/container.rs +++ b/crates/tests-integration/src/container.rs @@ -21,6 +21,20 @@ pub(crate) fn test_bootc_status() -> Result<()> { Ok(()) } +pub(crate) fn test_bootc_container_inspect() -> Result<()> { + let sh = Shell::new()?; + let inspect: serde_json::Value = + serde_json::from_str(&cmd!(sh, "bootc container inspect").read()?)?; + + // check kargs processing + let kargs = inspect.get("kargs").unwrap().as_array().unwrap(); + assert!(kargs.iter().any(|arg| arg == "kargsd-test=1")); + assert!(kargs.iter().any(|arg| arg == "kargsd-othertest=2")); + assert!(kargs.iter().any(|arg| arg == "testing-kargsd=3")); + + Ok(()) +} + pub(crate) fn test_bootc_upgrade() -> Result<()> { for c in ["upgrade", "update"] { let o = Command::new("bootc").arg(c).output()?; @@ -120,6 +134,7 @@ pub(crate) fn run(testargs: libtest_mimic::Arguments) -> Result<()> { new_test("install config", test_bootc_install_config), new_test("printconfig --all", test_bootc_install_config_all), new_test("status", test_bootc_status), + new_test("container inspect", test_bootc_container_inspect), new_test("system-reinstall --help", test_system_reinstall_help), ]; From d75b858cb124cf8ddba2ddb13f455e946c731731 Mon Sep 17 00:00:00 2001 From: John Eckersberg Date: Fri, 5 Dec 2025 17:08:30 -0500 Subject: [PATCH 2/3] Run `cargo xtask update-generated` Signed-off-by: John Eckersberg --- docs/src/host-v1.schema.json | 2 +- docs/src/man/bootc-container-inspect.8.md | 34 +++++++++++++++++++ docs/src/man/bootc-container.8.md | 1 + .../bootc-install-print-configuration.8.md | 6 ++++ 4 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 docs/src/man/bootc-container-inspect.8.md diff --git a/docs/src/host-v1.schema.json b/docs/src/host-v1.schema.json index e0bdf2880..4aa4161f8 100644 --- a/docs/src/host-v1.schema.json +++ b/docs/src/host-v1.schema.json @@ -199,7 +199,7 @@ "description": "Bootloader type to determine whether system was booted via Grub or Systemd", "oneOf": [ { - "description": "Use Grub as the booloader", + "description": "Use Grub as the bootloader", "type": "string", "const": "Grub" }, diff --git a/docs/src/man/bootc-container-inspect.8.md b/docs/src/man/bootc-container-inspect.8.md new file mode 100644 index 000000000..9bbaedab5 --- /dev/null +++ b/docs/src/man/bootc-container-inspect.8.md @@ -0,0 +1,34 @@ +# NAME + +bootc-container-inspect - Output JSON to stdout containing the container image metadata + +# SYNOPSIS + +bootc container inspect + +# DESCRIPTION + +Output JSON to stdout containing the container image metadata + +# OPTIONS + + +**--rootfs**=*ROOTFS* + + Operate on the provided rootfs + + Default: / + + + +# EXAMPLES + +TODO: Add practical examples showing how to use this command. + +# SEE ALSO + +**bootc**(8) + +# VERSION + + diff --git a/docs/src/man/bootc-container.8.md b/docs/src/man/bootc-container.8.md index 313f7d59e..0cc53849a 100644 --- a/docs/src/man/bootc-container.8.md +++ b/docs/src/man/bootc-container.8.md @@ -19,6 +19,7 @@ Operations which can be executed as part of a container build | Command | Description | |---------|-------------| +| **bootc container inspect** | Output JSON to stdout containing the container image metadata | | **bootc container lint** | Perform relatively inexpensive static analysis checks as part of a container build | diff --git a/docs/src/man/bootc-install-print-configuration.8.md b/docs/src/man/bootc-install-print-configuration.8.md index bf50664a5..67928c9f1 100644 --- a/docs/src/man/bootc-install-print-configuration.8.md +++ b/docs/src/man/bootc-install-print-configuration.8.md @@ -19,7 +19,13 @@ filesystem type from the container image. At the current time, the only output key is `root-fs-type` which is a string-valued filesystem name suitable for passing to `mkfs.\$type`. +# OPTIONS + +**--all** + + Print all configuration + # VERSION From 3c5cc1f8ccaaa7442caf632a2adcaa201b4973e5 Mon Sep 17 00:00:00 2001 From: John Eckersberg Date: Fri, 5 Dec 2025 17:35:06 -0500 Subject: [PATCH 3/3] docs: Replace autogenerated TODO in bootc-container-inspect Signed-off-by: John Eckersberg --- docs/src/man/bootc-container-inspect.8.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/src/man/bootc-container-inspect.8.md b/docs/src/man/bootc-container-inspect.8.md index 9bbaedab5..758ff4186 100644 --- a/docs/src/man/bootc-container-inspect.8.md +++ b/docs/src/man/bootc-container-inspect.8.md @@ -23,7 +23,9 @@ Output JSON to stdout containing the container image metadata # EXAMPLES -TODO: Add practical examples showing how to use this command. +Inspect container image metadata: + + bootc container inspect # SEE ALSO