From 2c7b5bd865646fb7f98a42561aed350692b7e56a Mon Sep 17 00:00:00 2001 From: Adrian Heine Date: Wed, 3 May 2017 10:29:14 +0200 Subject: [PATCH] Streamline node_js_user_service --- src/symbols/systemd/node_js_user_service.rs | 108 +++++++++----------- 1 file changed, 51 insertions(+), 57 deletions(-) diff --git a/src/symbols/systemd/node_js_user_service.rs b/src/symbols/systemd/node_js_user_service.rs index 21d5f41..b5dc221 100644 --- a/src/symbols/systemd/node_js_user_service.rs +++ b/src/symbols/systemd/node_js_user_service.rs @@ -2,9 +2,8 @@ use std::error::Error; use std::os::unix::fs::PermissionsExt; use std::fmt; use std::io; -use std::fs; +use std::fs::{self, Metadata}; use std::process::Output; -use std::path::Path; use std::thread::sleep; use std::time::Duration; use std::ops::Deref; @@ -53,19 +52,16 @@ impl fmt::Display for NodeJsSystemdUserServiceError { } } -pub struct NodeJsSystemdUserService<'a, P, C> where P: AsRef + fmt::Display, C: Deref { - name: &'a str, +pub struct NodeJsSystemdUserService<'a, C> where C: Deref { + service_name: &'a str, user_name: &'a str, - path: P, command_runner: &'a CommandRunner, - file: FileSymbol> + file: FileSymbol } -use std::borrow::Cow; - -impl<'a> NodeJsSystemdUserService<'a, Cow<'a, str>, String> { +impl<'a> NodeJsSystemdUserService<'a, String> { pub fn new(home: &'a str, user_name: &'a str, name: &'a str, path: &'a str, command_runner: &'a CommandRunner) -> Self { - let file_path: Cow = Cow::from(String::from(home.trim_right()) + "/.config/systemd/user/" + name + ".service"); + let file_path = format!("{}/.config/systemd/user/{}.service", home.trim_right(), name); let content = format!("[Service] ExecStartPre=rm /var/tmp/{1}-{2}.socket @@ -81,21 +77,21 @@ Environment=PORT=/var/tmp/{1}-{2}.socket [Install] WantedBy=default.target ", path, user_name, name); + NodeJsSystemdUserService { - name: name, + service_name: name, user_name: user_name, - path: file_path.clone(), command_runner: command_runner, file: FileSymbol::new(file_path, content) } } } -impl<'a, P, C> NodeJsSystemdUserService<'a, P, C> where P: AsRef + fmt::Display, C: Deref { +impl<'a, C> NodeJsSystemdUserService<'a, C> where C: Deref { fn check_if_service(&self) -> Result> { loop { // Check if service is registered - let active_state = try!(self.command_runner.run_with_args("systemctl", &["--user", "show", "--property", "ActiveState", self.name])); + let active_state = try!(self.command_runner.run_with_args("systemctl", &["--user", "show", "--property", "ActiveState", self.service_name])); if !active_state.status.success() { return Err(String::from_utf8(active_state.stderr).unwrap().trim_right().into()); } @@ -103,62 +99,60 @@ impl<'a, P, C> NodeJsSystemdUserService<'a, P, C> where P: AsRef + fmt::Dis match String::from_utf8(active_state.stdout).unwrap().trim_right() { "ActiveState=activating" => sleep(Duration::from_millis(500)), "ActiveState=active" => return Ok(true), - "ActiveState=failed" => return Err(Box::new(NodeJsSystemdUserServiceError::ActivationFailed(self.command_runner.run_with_args("journalctl", &["--user", &format!("--user-unit={}", self.name)])) as NodeJsSystemdUserServiceError)), + "ActiveState=failed" => return Err(Box::new(NodeJsSystemdUserServiceError::ActivationFailed(self.command_runner.run_with_args("journalctl", &["--user", &format!("--user-unit={}", self.service_name)])) as NodeJsSystemdUserServiceError)), _ => return Ok(false) } } } } -impl<'a, P, C> Symbol for NodeJsSystemdUserService<'a, P, C> where P: AsRef + fmt::Display, C: Deref { - fn target_reached(&self) -> Result> { - match self.file.target_reached() { - Ok(false) => return Ok(false), - Ok(true) => {}, - Err(e) => return Err(Box::new(NodeJsSystemdUserServiceError::GenericError as NodeJsSystemdUserServiceError)) +fn wait_for_metadata(file_name: &str) -> Result> { + let result; + let mut tries = 5; + loop { + let metadata = fs::metadata(file_name.clone()); + match metadata { + Ok(metadata) => { + result = metadata; + break; + }, + Err(e) => { + if e.kind() != io::ErrorKind::NotFound { + return Err(Box::new(e)); + } + } } -/* + tries -= 1; + if tries == 0 { + return Err("Gave up waiting for socket to appear".to_string().into()); + } + sleep(Duration::from_millis(500)); + } + Ok(result) +} + +impl<'a, C> Symbol for NodeJsSystemdUserService<'a, C> where C: Deref { + fn target_reached(&self) -> Result> { if !(try!(self.file.target_reached())) { - return Ok(false) + return Ok(false); } -*/ self.check_if_service() } fn execute(&self) -> Result<(), Box> { - match self.file.execute() { - Ok(_) => {}, - Err(e) => return Err(e) - } - try!(self.command_runner.run_with_args("systemctl", &["--user", "enable", self.name])); - try!(self.command_runner.run_with_args("systemctl", &["--user", "start", self.name])); - - if !(try!(self.check_if_service())) { return Err(Box::new(NodeJsSystemdUserServiceError::GenericError as NodeJsSystemdUserServiceError)); } - - let file_name = format!("/var/tmp/{}-{}.socket", self.user_name, self.name); -// try!(self.command_runner.run_with_args("chmod", &["666", &file_name])); + try!(self.file.execute()); + try!(self.command_runner.run_with_args("systemctl", &["--user", "enable", self.service_name])); + try!(self.command_runner.run_with_args("systemctl", &["--user", "start", self.service_name])); - let mut tries = 5; - loop { - let metadata = fs::metadata(file_name.clone()); - match metadata { - Ok(metadata) => { - let mut perms = metadata.permissions(); - perms.set_mode(0o666); - try!(fs::set_permissions(file_name, perms)); - break; - }, - Err(e) => { - if e.kind() == io::ErrorKind::NotFound { - tries -= 1; - if tries == 0 { return Err("Gave up waiting for socket to appear".to_string().into()); } - sleep(Duration::from_millis(500)); - } else { - return Err(Box::new(e)); - } - } - } + if !(try!(self.check_if_service())) { + return Err(Box::new(NodeJsSystemdUserServiceError::GenericError as NodeJsSystemdUserServiceError)); } + + let file_name = format!("/var/tmp/{}-{}.socket", self.user_name, self.service_name); + let metadata = try!(wait_for_metadata(&file_name)); + let mut perms = metadata.permissions(); + perms.set_mode(0o666); + try!(fs::set_permissions(file_name, perms)); Ok(()) } @@ -169,8 +163,8 @@ impl<'a, P, C> Symbol for NodeJsSystemdUserService<'a, P, C> where P: AsRef } } -impl<'a, P, C> fmt::Display for NodeJsSystemdUserService<'a, P, C> where P: AsRef + fmt::Display, C: Deref { +impl<'a, C> fmt::Display for NodeJsSystemdUserService<'a, C> where C: Deref { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(),fmt::Error>{ - write!(f, "Systemd Node.js user service unit for {}", self.path) + write!(f, "Systemd Node.js user service unit for {}", self.service_name) } }