diff --git a/Cargo.lock b/Cargo.lock index 0789cb98a..9158d7100 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2578,6 +2578,7 @@ dependencies = [ "oci-spec", "rexpect", "rustix", + "scopeguard", "serde", "serde_json", "tempfile", diff --git a/crates/lib/src/cli.rs b/crates/lib/src/cli.rs index 23bae71d9..c59b4dad1 100644 --- a/crates/lib/src/cli.rs +++ b/crates/lib/src/cli.rs @@ -289,7 +289,7 @@ pub(crate) enum InstallOpts { /// /// 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`. - PrintConfiguration, + PrintConfiguration(crate::install::InstallPrintConfigurationOpts), } /// Subcommands which can be executed as part of a container build. @@ -1483,7 +1483,7 @@ async fn run_from_opt(opt: Opt) -> Result<()> { crate::install::install_to_existing_root(opts).await } InstallOpts::Reset(opts) => crate::install::install_reset(opts).await, - InstallOpts::PrintConfiguration => crate::install::print_configuration(), + InstallOpts::PrintConfiguration(opts) => crate::install::print_configuration(opts), InstallOpts::EnsureCompletion {} => { let rootfs = &Dir::open_ambient_dir("/", cap_std::ambient_authority())?; crate::install::completion::run_from_anaconda(rootfs).await diff --git a/crates/lib/src/install.rs b/crates/lib/src/install.rs index a1e5b2b71..b68cbce8f 100644 --- a/crates/lib/src/install.rs +++ b/crates/lib/src/install.rs @@ -437,6 +437,15 @@ pub(crate) struct InstallResetOpts { karg: Option>, } +#[derive(Debug, clap::Parser, PartialEq, Eq)] +pub(crate) struct InstallPrintConfigurationOpts { + /// Print all configuration. + /// + /// Print configuration that is usually handled internally, like kargs. + #[clap(long)] + pub(crate) all: bool, +} + /// Global state captured from the container. #[derive(Debug, Clone)] pub(crate) struct SourceInfo { @@ -722,9 +731,11 @@ impl SourceInfo { } } -pub(crate) fn print_configuration() -> Result<()> { +pub(crate) fn print_configuration(opts: InstallPrintConfigurationOpts) -> Result<()> { let mut install_config = config::load_config()?.unwrap_or_default(); - install_config.filter_to_external(); + if !opts.all { + install_config.filter_to_external(); + } let stdout = std::io::stdout().lock(); anyhow::Ok(install_config.to_canon_json_writer(stdout)?) } diff --git a/crates/tests-integration/Cargo.toml b/crates/tests-integration/Cargo.toml index eb1ca75d5..4b6bbe8e9 100644 --- a/crates/tests-integration/Cargo.toml +++ b/crates/tests-integration/Cargo.toml @@ -29,6 +29,7 @@ bootc-kernel-cmdline = { path = "../kernel_cmdline", version = "0.0.0" } libtest-mimic = "0.8.0" oci-spec = "0.8.0" rexpect = "0.6" +scopeguard = "1.2.0" [lints] workspace = true diff --git a/crates/tests-integration/src/container.rs b/crates/tests-integration/src/container.rs index 55874bd10..40b8c3fb9 100644 --- a/crates/tests-integration/src/container.rs +++ b/crates/tests-integration/src/container.rs @@ -1,3 +1,7 @@ +use indoc::indoc; +use scopeguard::defer; +use serde::Deserialize; +use std::fs; use std::process::Command; use anyhow::{Context, Result}; @@ -36,8 +40,34 @@ pub(crate) fn test_bootc_install_config() -> Result<()> { let config = cmd!(sh, "bootc install print-configuration").read()?; let config: serde_json::Value = serde_json::from_str(&config).context("Parsing install config")?; - // Just verify we parsed the config, if any - drop(config); + // check that it parses okay, but also ensure kargs is not available here (only via --all) + assert!(config.get("kargs").is_none()); + Ok(()) +} + +pub(crate) fn test_bootc_install_config_all() -> Result<()> { + #[derive(Deserialize)] + struct TestInstallConfig { + kargs: Vec, + } + + let config_d = std::path::Path::new("/run/bootc/install/"); + let test_toml_path = config_d.join("10-test.toml"); + std::fs::create_dir_all(&config_d)?; + let content = indoc! {r#" + [install] + kargs = ["karg1=1", "karg2=2"] + "#}; + std::fs::write(&test_toml_path, content)?; + defer! { + fs::remove_file(test_toml_path).expect("cannot remove tempfile"); + } + + let sh = &xshell::Shell::new()?; + let config = cmd!(sh, "bootc install print-configuration --all").read()?; + let config: TestInstallConfig = + serde_json::from_str(&config).context("Parsing install config")?; + assert_eq! {config.kargs, vec!["karg1=1".to_string(), "karg2=2".to_string(), "localtestkarg=somevalue".to_string(), "otherlocalkarg=42".to_string()]}; Ok(()) } @@ -88,6 +118,7 @@ pub(crate) fn run(testargs: libtest_mimic::Arguments) -> Result<()> { new_test("variant-base-crosscheck", test_variant_base_crosscheck), new_test("bootc upgrade", test_bootc_upgrade), 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("system-reinstall --help", test_system_reinstall_help), ];