diff --git a/pbs-tools/src/command.rs b/pbs-tools/src/command.rs new file mode 100644 index 00000000..943435cb --- /dev/null +++ b/pbs-tools/src/command.rs @@ -0,0 +1,64 @@ +use anyhow::{bail, format_err, Error}; + +/// Helper to check result from std::process::Command output +/// +/// The exit_code_check() function should return true if the exit code +/// is considered successful. +pub fn command_output( + output: std::process::Output, + exit_code_check: Option bool>, +) -> Result, Error> { + if !output.status.success() { + match output.status.code() { + Some(code) => { + let is_ok = match exit_code_check { + Some(check_fn) => check_fn(code), + None => code == 0, + }; + if !is_ok { + let msg = String::from_utf8(output.stderr) + .map(|m| { + if m.is_empty() { + String::from("no error message") + } else { + m + } + }) + .unwrap_or_else(|_| String::from("non utf8 error message (suppressed)")); + + bail!("status code: {} - {}", code, msg); + } + } + None => bail!("terminated by signal"), + } + } + + Ok(output.stdout) +} + +/// Helper to check result from std::process::Command output, returns String. +/// +/// The exit_code_check() function should return true if the exit code +/// is considered successful. +pub fn command_output_as_string( + output: std::process::Output, + exit_code_check: Option bool>, +) -> Result { + let output = command_output(output, exit_code_check)?; + let output = String::from_utf8(output)?; + Ok(output) +} + +pub fn run_command( + mut command: std::process::Command, + exit_code_check: Option bool>, +) -> Result { + let output = command + .output() + .map_err(|err| format_err!("failed to execute {:?} - {}", command, err))?; + + let output = command_output_as_string(output, exit_code_check) + .map_err(|err| format_err!("command {:?} failed - {}", command, err))?; + + Ok(output) +} diff --git a/pbs-tools/src/lib.rs b/pbs-tools/src/lib.rs index c4221f0d..9bf1368c 100644 --- a/pbs-tools/src/lib.rs +++ b/pbs-tools/src/lib.rs @@ -2,3 +2,6 @@ pub mod borrow; pub mod format; pub mod fs; pub mod str; + +mod command; +pub use command::{run_command, command_output, command_output_as_string}; diff --git a/src/tools/mod.rs b/src/tools/mod.rs index d092b95a..21d33365 100644 --- a/src/tools/mod.rs +++ b/src/tools/mod.rs @@ -23,6 +23,8 @@ use proxmox_http::{ ProxyConfig, }; +pub use pbs_tools::{run_command, command_output, command_output_as_string}; + pub mod acl; pub mod apt; pub mod async_io; @@ -316,64 +318,6 @@ pub fn normalize_uri_path(path: &str) -> Result<(String, Vec<&str>), Error> { Ok((path, components)) } -/// Helper to check result from std::process::Command output -/// -/// The exit_code_check() function should return true if the exit code -/// is considered successful. -pub fn command_output( - output: std::process::Output, - exit_code_check: Option bool>, -) -> Result, Error> { - - if !output.status.success() { - match output.status.code() { - Some(code) => { - let is_ok = match exit_code_check { - Some(check_fn) => check_fn(code), - None => code == 0, - }; - if !is_ok { - let msg = String::from_utf8(output.stderr) - .map(|m| if m.is_empty() { String::from("no error message") } else { m }) - .unwrap_or_else(|_| String::from("non utf8 error message (suppressed)")); - - bail!("status code: {} - {}", code, msg); - } - } - None => bail!("terminated by signal"), - } - } - - Ok(output.stdout) -} - -/// Helper to check result from std::process::Command output, returns String. -/// -/// The exit_code_check() function should return true if the exit code -/// is considered successful. -pub fn command_output_as_string( - output: std::process::Output, - exit_code_check: Option bool>, -) -> Result { - let output = command_output(output, exit_code_check)?; - let output = String::from_utf8(output)?; - Ok(output) -} - -pub fn run_command( - mut command: std::process::Command, - exit_code_check: Option bool>, -) -> Result { - - let output = command.output() - .map_err(|err| format_err!("failed to execute {:?} - {}", command, err))?; - - let output = command_output_as_string(output, exit_code_check) - .map_err(|err| format_err!("command {:?} failed - {}", command, err))?; - - Ok(output) -} - pub fn fd_change_cloexec(fd: RawFd, on: bool) -> Result<(), Error> { use nix::fcntl::{fcntl, FdFlag, F_GETFD, F_SETFD}; let mut flags = FdFlag::from_bits(fcntl(fd, F_GETFD)?)