summaryrefslogtreecommitdiffhomepage
path: root/tools/unitctl/unit-client-rs/src/unitd_cmd.rs
diff options
context:
space:
mode:
authoroxpa <iippolitov@gmail.com>2024-09-17 14:21:10 +0100
committeroxpa <iippolitov@gmail.com>2024-09-17 14:21:10 +0100
commit2417826d8bebf921ee1be102ef8ce702f0683d66 (patch)
tree76d29a1705415ed7368870826dbb2f04942ee794 /tools/unitctl/unit-client-rs/src/unitd_cmd.rs
parent0e79d961bb1ea68674961da1703ffedb1ddf6e43 (diff)
parent24ed91f40634372d99f67f0e4e3c2ac0abde81bd (diff)
downloadunit-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.rs88
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)
+ }
+}