From 675333cd198bb48b47e20ec4775998cff0a3cf67 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 15 Dec 2023 15:07:02 -0500 Subject: [PATCH] install: Fix exec helper to not swallow unexpected args Our `exec-in-host-mount-namespace` internal helper was intended to be a "passthrough" that accepts whatever child arguments. However I misunderstood how to do this in clap. Before this change we get: ``` $ bootc blabla ERROR Re-exec in host mountns: Missing command ``` i.e. the exec code kicks in because `external_subcommand` takes over *everything* unknown. Fix things to use `trailing_var_arg` which is intended for this case. After this patch: ``` $ bootc blabla error: unrecognized subcommand 'blabla' Usage: bootc For more information, try '--help'. ``` Signed-off-by: Colin Walters --- lib/src/cli.rs | 8 +++++--- lib/src/install.rs | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/src/cli.rs b/lib/src/cli.rs index eaf724153..764b9408e 100644 --- a/lib/src/cli.rs +++ b/lib/src/cli.rs @@ -156,8 +156,10 @@ pub(crate) enum Opt { /// Execute the given command in the host mount namespace #[cfg(feature = "install")] #[clap(hide = true)] - #[command(external_subcommand)] - ExecInHostMountNamespace(Vec), + ExecInHostMountNamespace { + #[clap(trailing_var_arg = true, allow_hyphen_values = true)] + args: Vec, + }, /// Install to the target filesystem. #[cfg(feature = "install")] InstallToFilesystem(crate::install::InstallToFilesystemOpts), @@ -458,7 +460,7 @@ async fn run_from_opt(opt: Opt) -> Result<()> { #[cfg(feature = "install")] Opt::InstallToFilesystem(opts) => crate::install::install_to_filesystem(opts).await, #[cfg(feature = "install")] - Opt::ExecInHostMountNamespace(args) => { + Opt::ExecInHostMountNamespace { args } => { crate::install::exec_in_host_mountns(args.as_slice()) } Opt::Status(opts) => super::status::status(opts).await, diff --git a/lib/src/install.rs b/lib/src/install.rs index 12de3996f..c54174321 100644 --- a/lib/src/install.rs +++ b/lib/src/install.rs @@ -672,7 +672,7 @@ pub(crate) fn run_in_host_mountns(cmd: &str) -> Command { #[context("Re-exec in host mountns")] pub(crate) fn exec_in_host_mountns(args: &[std::ffi::OsString]) -> Result<()> { - let (cmd, args) = args[1..] + let (cmd, args) = args .split_first() .ok_or_else(|| anyhow::anyhow!("Missing command"))?; let pid1mountns = std::fs::File::open("/proc/1/ns/mnt")?;