From 9e9a4032e68676bb8f71e606ca793661951ae7ac Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 25 Aug 2023 10:31:30 -0400 Subject: [PATCH 1/2] main: Move usroverlay parsing back to C++ consistently Otherwise, we end up segfaulting because `rpm-ostree -h usroverlay` confuses things. Unfortunately, if we expose it publicly in our help text it needs to have a C++ trampoline. --- rpmostree-cxxrs.cxx | 13 +++++++++++++ rpmostree-cxxrs.h | 2 ++ rust/src/builtins/usroverlay.rs | 2 +- rust/src/lib.rs | 2 ++ rust/src/main.rs | 2 -- src/app/libmain.cxx | 18 +++++++++++++++++- 6 files changed, 35 insertions(+), 4 deletions(-) diff --git a/rpmostree-cxxrs.cxx b/rpmostree-cxxrs.cxx index 62a8ea164b..b6e88ee241 100644 --- a/rpmostree-cxxrs.cxx +++ b/rpmostree-cxxrs.cxx @@ -2027,6 +2027,9 @@ extern "C" rpmostreecxx$cxxbridge1$Bubblewrap$run (::rpmostreecxx::Bubblewrap &self, const ::rpmostreecxx::GCancellable &cancellable) noexcept; + ::rust::repr::PtrLen + rpmostreecxx$cxxbridge1$usroverlay_entrypoint (const ::rust::Vec< ::rust::String> &args) noexcept; + ::rust::repr::PtrLen rpmostreecxx$cxxbridge1$applylive_entrypoint (const ::rust::Vec< ::rust::String> &args) noexcept; @@ -3534,6 +3537,16 @@ Bubblewrap::run (const ::rpmostreecxx::GCancellable &cancellable) } } +void +usroverlay_entrypoint (const ::rust::Vec< ::rust::String> &args) +{ + ::rust::repr::PtrLen error$ = rpmostreecxx$cxxbridge1$usroverlay_entrypoint (args); + if (error$.ptr) + { + throw ::rust::impl< ::rust::Error>::error (error$); + } +} + void applylive_entrypoint (const ::rust::Vec< ::rust::String> &args) { diff --git a/rpmostree-cxxrs.h b/rpmostree-cxxrs.h index dd2f59e89f..8126733068 100644 --- a/rpmostree-cxxrs.h +++ b/rpmostree-cxxrs.h @@ -1741,6 +1741,8 @@ ::rust::Box< ::rpmostreecxx::Bubblewrap> bubblewrap_new_with_mutability (::std::int32_t rootfs_fd, ::rpmostreecxx::BubblewrapMutability mutability); +void usroverlay_entrypoint (const ::rust::Vec< ::rust::String> &args); + void applylive_entrypoint (const ::rust::Vec< ::rust::String> &args); void applylive_finish (const ::rpmostreecxx::OstreeSysroot &sysroot); diff --git a/rust/src/builtins/usroverlay.rs b/rust/src/builtins/usroverlay.rs index 7057305882..bfb45bf90a 100644 --- a/rust/src/builtins/usroverlay.rs +++ b/rust/src/builtins/usroverlay.rs @@ -7,7 +7,7 @@ use clap::Command; use std::os::unix::prelude::CommandExt; /// Directly exec(ostree admin unlock) - does not return on success. -pub fn entrypoint(args: &[&str]) -> Result<()> { +pub fn usroverlay_entrypoint(args: &Vec) -> Result<()> { let cmd = cli_cmd(); cmd.get_matches_from(args.iter().skip(1)); diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 43b3688521..d680165ac0 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -152,6 +152,7 @@ pub mod ffi { // builtins/apply_live.rs extern "Rust" { + fn usroverlay_entrypoint(args: &Vec) -> Result<()>; fn applylive_entrypoint(args: &Vec) -> Result<()>; fn applylive_finish(sysroot: &OstreeSysroot) -> Result<()>; } @@ -898,6 +899,7 @@ pub mod ffi { } pub mod builtins; +pub(crate) use crate::builtins::usroverlay::usroverlay_entrypoint; pub(crate) use crate::builtins::apply_live::*; pub(crate) use crate::builtins::compose::commit::*; pub(crate) use crate::builtins::compose::*; diff --git a/rust/src/main.rs b/rust/src/main.rs index 63f0bf2168..cb32e817bb 100644 --- a/rust/src/main.rs +++ b/rust/src/main.rs @@ -30,8 +30,6 @@ async fn inner_async_main(args: Vec) -> Result { // Add custom Rust commands here, and also in `libmain.cxx` if user-visible. "countme" => rpmostree_rust::countme::entrypoint(args).map(|_| 0), "cliwrap" => rpmostree_rust::cliwrap::entrypoint(args).map(|_| 0), - // The `unlock` is a hidden alias for "ostree CLI compatibility" - "usroverlay" | "unlock" => builtins::usroverlay::entrypoint(args).map(|_| 0), // A hidden wrapper to intercept some binaries in RPM scriptlets. "scriptlet-intercept" => builtins::scriptlet_intercept::entrypoint(args).map(|_| 0), // This is a deprecated entrypoint diff --git a/src/app/libmain.cxx b/src/app/libmain.cxx index 497bef878b..d30c711c93 100644 --- a/src/app/libmain.cxx +++ b/src/app/libmain.cxx @@ -38,6 +38,17 @@ #include "libglnx.h" +static gboolean +dispatch_usroverlay (int argc, char **argv, RpmOstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) +{ + rust::Vec rustargv; + for (int i = 0; i < argc; i++) + rustargv.push_back (std::string (argv[i])); + CXX_TRY (rpmostreecxx::usroverlay_entrypoint (rustargv), error); + return TRUE; +} + static RpmOstreeCommand commands[] = { { "compose", static_cast (RPM_OSTREE_BUILTIN_FLAG_LOCAL_CMD @@ -91,7 +102,12 @@ static RpmOstreeCommand commands[] = { { "scriptlet-intercept", static_cast (RPM_OSTREE_BUILTIN_FLAG_HIDDEN), "Intercept some commands used by RPM scriptlets", NULL }, { "usroverlay", static_cast (RPM_OSTREE_BUILTIN_FLAG_REQUIRES_ROOT), - "Apply a transient overlayfs to /usr", NULL }, + "Apply a transient overlayfs to /usr", dispatch_usroverlay }, + // Alias for ostree compatibility + { "unlock", + static_cast (RPM_OSTREE_BUILTIN_FLAG_REQUIRES_ROOT + | RPM_OSTREE_BUILTIN_FLAG_HIDDEN), + "Apply a transient overlayfs to /usr", dispatch_usroverlay }, /* Legacy aliases */ { "pkg-add", static_cast (RPM_OSTREE_BUILTIN_FLAG_HIDDEN), NULL, rpmostree_builtin_install }, From fd750f653060d2f546d828b2eaad1a426782fe88 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 25 Aug 2023 10:42:02 -0400 Subject: [PATCH 2/2] usroverlay: Pass arguments to `ostree admin unlock` So that `--help` works. Closes: https://github.com/coreos/rpm-ostree/issues/4508 --- rust/src/builtins/usroverlay.rs | 24 +----------------------- rust/src/lib.rs | 2 +- tests/kolainst/nondestructive/misc.sh | 7 +++++++ 3 files changed, 9 insertions(+), 24 deletions(-) diff --git a/rust/src/builtins/usroverlay.rs b/rust/src/builtins/usroverlay.rs index bfb45bf90a..c8e52b2805 100644 --- a/rust/src/builtins/usroverlay.rs +++ b/rust/src/builtins/usroverlay.rs @@ -3,37 +3,15 @@ // SPDX-License-Identifier: Apache-2.0 OR MIT use anyhow::{Context, Result}; -use clap::Command; use std::os::unix::prelude::CommandExt; /// Directly exec(ostree admin unlock) - does not return on success. pub fn usroverlay_entrypoint(args: &Vec) -> Result<()> { - let cmd = cli_cmd(); - cmd.get_matches_from(args.iter().skip(1)); - let exec_err = std::process::Command::new("ostree") .args(&["admin", "unlock"]) + .args(args.into_iter().skip(1)) .exec(); - // This is only reached if the `exec()` above failed; otherwise // execution got transferred to `ostree` at that point. Err(exec_err).context("Failed to execute 'ostree admin unlock'") } - -/// CLI parser, handle --help and error on extra arguments. -fn cli_cmd() -> Command { - Command::new("rpm-ostree usroverlay") - .bin_name("rpm-ostree usroverlay") - .long_version("") - .long_about("Apply a transient overlayfs to /usr") -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn test_clap_cmd() { - cli_cmd().debug_assert() - } -} diff --git a/rust/src/lib.rs b/rust/src/lib.rs index d680165ac0..d7d767612d 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -899,10 +899,10 @@ pub mod ffi { } pub mod builtins; -pub(crate) use crate::builtins::usroverlay::usroverlay_entrypoint; pub(crate) use crate::builtins::apply_live::*; pub(crate) use crate::builtins::compose::commit::*; pub(crate) use crate::builtins::compose::*; +pub(crate) use crate::builtins::usroverlay::usroverlay_entrypoint; mod bwrap; pub(crate) use bwrap::*; pub mod client; diff --git a/tests/kolainst/nondestructive/misc.sh b/tests/kolainst/nondestructive/misc.sh index 223bd45d61..7b3a090fa1 100755 --- a/tests/kolainst/nondestructive/misc.sh +++ b/tests/kolainst/nondestructive/misc.sh @@ -26,6 +26,13 @@ for verb in container ima-sign; do done echo "ok multicall corectly set up and working" +# Verify that we process arguments correctly +rpm-ostree usroverlay --help >out.txt +assert_file_has_content out.txt "ostree admin unlock" +rm -f out.txt +rpm-ostree -h usroverlay >out.txt +assert_file_has_content out.txt "ostree admin unlock" + # make sure that package-related entries are always present, # even when they're empty. # Validate there's no live state by default.