From a30a2e454506b10bc34e831d78c92d15648f4e6c Mon Sep 17 00:00:00 2001 From: Sibi Prabakaran Date: Sat, 4 Nov 2023 08:46:50 +0530 Subject: [PATCH] Support for running with specific user id and group id Also some improvements related to typesafety. Note that with this change, it makes it feature wise complete with the Haskell's pid1. --- README.md | 20 ++++++++++++++++++++ pid1-exe/src/cli.rs | 28 ++++++++++++++++++++-------- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 4655351..8b08ce2 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,26 @@ RUN chmod +x /usr/bin/pid1 ENTRYPOINT [ "pid1" ] ``` +Various options supported by the binary: + +``` shellsession +❯ pid1 --help +Usage: + +Arguments: + Process to run + [ARGS]... Arguments to the process + +Options: + -w, --workdir Specify working direcory + -t, --timeout Timeout (in seconds) to wait for child proess to exit [default: 2] + -v, --verbose Turn on verbose output + -e, --env Override environment variables. Can specify multiple times + -u, --user-id Run command with user ID + -g, --group-id Run command with group ID + -h, --help Print help +``` + ## Development The testing steps are documented in [Development.md](./Development.md). We only have diff --git a/pid1-exe/src/cli.rs b/pid1-exe/src/cli.rs index 8fbb03e..44a4449 100644 --- a/pid1-exe/src/cli.rs +++ b/pid1-exe/src/cli.rs @@ -26,19 +26,34 @@ pub(crate) struct Pid1App { /// Override environment variables. Can specify multiple times. #[arg(short, long, value_parser=parse_key_val::)] pub(crate) env: Vec<(OsString, OsString)>, - /// Process arguments + /// Run command with user ID + #[arg(short, long, value_name = "USER_ID")] + user_id: Option, + /// Run command with group ID + #[arg(short, long, value_name = "GROUP_ID")] + group_id: Option, + /// Process to run #[arg(required = true)] - child_process: Vec, + pub(crate) command: String, + /// Arguments to the process + #[arg(required = false)] + pub(crate) args: Vec, } impl Pid1App { #[cfg(target_family = "unix")] pub(crate) fn run(self) -> ! { - let mut child = std::process::Command::new(&self.child_process[0]); - let child = child.args(&self.child_process[1..]); + let mut child = std::process::Command::new(&self.command); + let child = child.args(&self.args[..]); if let Some(workdir) = &self.workdir { child.current_dir(workdir); } + if let Some(user_id) = &self.user_id { + child.uid(*user_id); + } + if let Some(group_id) = &self.group_id { + child.gid(*group_id); + } for (key, value) in &self.env { child.env(key, value); } @@ -55,10 +70,7 @@ impl Pid1App { let child = match child { Ok(child) => child, Err(err) => { - eprintln!( - "pid1: {} spawn failed. Got error: {err}", - self.child_process[0] - ); + eprintln!("pid1: {} spawn failed. Got error: {err}", self.command); std::process::exit(1); } };