From cd986ee64cf627ab0d39138e2cb24b115c4032b4 Mon Sep 17 00:00:00 2001 From: Kjetil Orbekk Date: Wed, 24 May 2017 08:32:53 -0400 Subject: unit: Renamed from job. Improved unit parsing and some refactoring. --- src/main.rs | 9 ++++--- src/systemd/job.rs | 44 ----------------------------------- src/systemd/mod.rs | 2 +- src/systemd/unit.rs | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 72 insertions(+), 50 deletions(-) delete mode 100644 src/systemd/job.rs create mode 100644 src/systemd/unit.rs diff --git a/src/main.rs b/src/main.rs index 3fe1b7f..ce50828 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,8 +21,7 @@ use iron::{Iron, Request, IronResult, Response, Chain}; use router::Router; use horrorshow::prelude::*; use horrorshow::Raw; -use std::process::Command; -use systemhttp::systemd::job; +use systemhttp::systemd::unit; struct Aaa(String); @@ -38,7 +37,7 @@ impl iron_sessionstorage::Value for Aaa { } } -fn render_message(message: &str, units: &[job::Unit]) -> String { +fn render_message(message: &str, units: &[unit::Unit]) -> String { (html!{ : Raw(""); html { @@ -76,14 +75,14 @@ fn hello(r: &mut Request) -> IronResult { .find("name") .unwrap_or("World").to_owned(); - let jobs = job::get_jobs().unwrap(); + let units = unit::get_units().unwrap(); let res = Ok(Response::with((status::Ok, Header(ContentType::html()), render_message(&format!("Hello, {} ({})", name, session_value.0), - &jobs)))); + &units)))); info!("Updating session value. Current value: {}", session_value.0); session_value.0.push('a'); diff --git a/src/systemd/job.rs b/src/systemd/job.rs deleted file mode 100644 index 967bb42..0000000 --- a/src/systemd/job.rs +++ /dev/null @@ -1,44 +0,0 @@ -use std::collections::HashMap; -use std::process::Command; - -use std::io; - -#[derive(Debug)] -pub struct Unit { - pub name: String, - pub type_: String -} - -pub fn parse_key_value(line: &str) -> Option<(String, String)> { - let pos = line.find('='); - pos.map(|pos| { - let (k, v) = line.split_at(pos); - (k.to_owned(), v[1..].to_owned()) - }) -} - -#[test] -fn test_parse_key_value() { - assert_eq!(None, parse_key_value("ab")); - assert_eq!(Some(("a".to_owned(), "b".to_owned())), parse_key_value("a=b")); - assert_eq!(Some(("a".to_owned(), "b=c".to_owned())), parse_key_value("a=b=c")); -} - -pub fn get_jobs() -> io::Result> { - let mut units = Vec::new(); - let status = try!(Command::new("systemctl") - .args(&["show", "*"]).output()); - - let mut unit_info = HashMap::new(); - for line in String::from_utf8_lossy(&status.stdout).split('\n') { - if let Some((k, v)) = parse_key_value(line) { - unit_info.insert(k, v); - } else { - if let Some(id) = unit_info.remove("Id") { - units.push(Unit { name: id, type_: String::new() }); - } - unit_info = HashMap::new(); - } - } - return Ok(units); -} diff --git a/src/systemd/mod.rs b/src/systemd/mod.rs index 80daa3e..a5acbce 100644 --- a/src/systemd/mod.rs +++ b/src/systemd/mod.rs @@ -1 +1 @@ -pub mod job; +pub mod unit; diff --git a/src/systemd/unit.rs b/src/systemd/unit.rs new file mode 100644 index 0000000..3be7fa5 --- /dev/null +++ b/src/systemd/unit.rs @@ -0,0 +1,67 @@ +use std::collections::HashMap; +use std::process::Command; + +use std::io; + +#[derive(Debug, PartialEq, Eq)] +pub struct Unit { + pub name: String, + pub type_: String +} + +pub fn parse_key_value(line: &str) -> Option<(String, String)> { + let pos = line.find('='); + pos.map(|pos| { + let (k, v) = line.split_at(pos); + (k.to_owned(), v[1..].to_owned()) + }) +} + +#[test] +fn test_parse_key_value() { + assert_eq!(None, parse_key_value("ab")); + assert_eq!(Some(("a".to_owned(), "b".to_owned())), parse_key_value("a=b")); + assert_eq!(Some(("a".to_owned(), "b=c".to_owned())), parse_key_value("a=b=c")); +} + +fn make_unit(info: HashMap) -> Option { + fn from_id(id: &str) -> Option { + id.rsplit('.').next().map(|t| t.to_owned()) + }; + let id = info.get("Id").map(|id| id.clone()); + let type_ = id.as_ref().and_then(|id| from_id(&id)); + + if let (Some(id), Some(type_)) = (id, type_) { + Some(Unit { name: id, type_: type_ }) + } else { + None + } +} + +#[test] +fn test_make_unit() { + let s = |s: &str| -> String { s.to_owned() }; + let info = [(s("Id"), s("Test.service"))] + .iter().cloned().collect::>(); + assert_eq!(Some(Unit { name: s("Test.service"), type_: s("service") }), make_unit(info)); + + let info = HashMap::new(); + assert_eq!(None, make_unit(info)); +} + +pub fn get_units() -> io::Result> { + let mut units = Vec::new(); + let status = try!(Command::new("systemctl") + .args(&["show", "*"]).output()); + + let mut unit_info = HashMap::new(); + for line in String::from_utf8_lossy(&status.stdout).split('\n') { + if let Some((k, v)) = parse_key_value(line) { + unit_info.insert(k, v); + } else { + make_unit(unit_info).map(|u| units.push(u)); + unit_info = HashMap::new(); + } + } + return Ok(units); +} -- cgit v1.2.3