diff options
author | oxpa <iippolitov@gmail.com> | 2024-09-17 14:21:10 +0100 |
---|---|---|
committer | oxpa <iippolitov@gmail.com> | 2024-09-17 14:21:10 +0100 |
commit | 2417826d8bebf921ee1be102ef8ce702f0683d66 (patch) | |
tree | 76d29a1705415ed7368870826dbb2f04942ee794 /tools/unitctl/unit-client-rs/src/unitd_cmd.rs | |
parent | 0e79d961bb1ea68674961da1703ffedb1ddf6e43 (diff) | |
parent | 24ed91f40634372d99f67f0e4e3c2ac0abde81bd (diff) | |
download | unit-2417826d8bebf921ee1be102ef8ce702f0683d66.tar.gz unit-2417826d8bebf921ee1be102ef8ce702f0683d66.tar.bz2 |
Merge tag '1.33.0' into packaging.
Unit 1.33.0 release.
Diffstat (limited to 'tools/unitctl/unit-client-rs/src/unitd_cmd.rs')
-rw-r--r-- | tools/unitctl/unit-client-rs/src/unitd_cmd.rs | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/tools/unitctl/unit-client-rs/src/unitd_cmd.rs b/tools/unitctl/unit-client-rs/src/unitd_cmd.rs new file mode 100644 index 00000000..17563cb0 --- /dev/null +++ b/tools/unitctl/unit-client-rs/src/unitd_cmd.rs @@ -0,0 +1,88 @@ +use std::error::Error as StdError; +use std::io::{Error as IoError, ErrorKind}; + +use crate::runtime_flags::RuntimeFlags; +use std::path::{Path, PathBuf}; + +#[derive(Debug, Clone)] +pub struct UnitdCmd { + pub(crate) process_executable_path: Option<Box<Path>>, + pub version: Option<String>, + pub flags: Option<RuntimeFlags>, +} + +impl UnitdCmd { + pub(crate) fn new<S>(full_cmd: S, binary_name: &str) -> Result<UnitdCmd, Box<dyn StdError>> + where + S: Into<String>, + { + let process_cmd: String = full_cmd.into(); + let parsable = process_cmd + .strip_prefix("unit: main v") + .and_then(|s| s.strip_suffix(']')); + if parsable.is_none() { + let msg = format!("cmd does not have the expected format: {}", process_cmd); + return Err(IoError::new(ErrorKind::InvalidInput, msg).into()); + } + let parts = parsable + .expect("Unable to parse cmd") + .splitn(2, " [") + .collect::<Vec<&str>>(); + + if parts.len() != 2 { + let msg = format!("cmd does not have the expected format: {}", process_cmd); + return Err(IoError::new(ErrorKind::InvalidInput, msg).into()); + } + + let version = Some(parts[0].to_string()); + let executable_path = UnitdCmd::parse_executable_path_from_cmd(parts[1], binary_name); + let flags = UnitdCmd::parse_runtime_flags_from_cmd(parts[1]); + + Ok(UnitdCmd { + process_executable_path: executable_path, + version, + flags, + }) + } + + fn parse_executable_path_from_cmd<S>(full_cmd: S, binary_name: &str) -> Option<Box<Path>> + where + S: Into<String>, + { + let cmd = full_cmd.into(); + if cmd.is_empty() { + return None; + } + + let split = cmd.splitn(2, binary_name).collect::<Vec<&str>>(); + if split.is_empty() { + return None; + } + + let path = format!("{}{}", split[0], binary_name); + Some(PathBuf::from(path).into_boxed_path()) + } + + fn parse_runtime_flags_from_cmd<S>(full_cmd: S) -> Option<RuntimeFlags> + where + S: Into<String>, + { + let cmd = full_cmd.into(); + if cmd.is_empty() { + return None; + } + + // Split out everything in between the brackets [ and ] + let split = cmd.trim_end_matches(']').splitn(2, '[').collect::<Vec<&str>>(); + if split.is_empty() { + return None; + } + /* Now we need to parse a string like this: + * ./sbin/unitd --no-daemon --tmp /tmp + * and only return what is after the invoking command */ + split[0] + .find("--") + .map(|index| cmd[index..].to_string()) + .map(RuntimeFlags::new) + } +} |