Update
This commit is contained in:
parent
27e6531119
commit
301b39a80a
6 changed files with 212 additions and 21 deletions
|
|
@ -1,6 +1,9 @@
|
|||
use std::error::Error;
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
use std::fs;
|
||||
use std::process::Output;
|
||||
use std::path::Path;
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
|
|
@ -12,6 +15,7 @@ use symbols::file::File as FileSymbol;
|
|||
|
||||
#[derive(Debug)]
|
||||
pub enum NodeJsSystemdUserServiceError<E: Error> {
|
||||
ActivationFailed(io::Result<Output>),
|
||||
ExecError(E),
|
||||
GenericError
|
||||
}
|
||||
|
|
@ -26,7 +30,8 @@ impl<E: Error> Error for NodeJsSystemdUserServiceError<E> {
|
|||
fn description(&self) -> &str {
|
||||
match self {
|
||||
&NodeJsSystemdUserServiceError::ExecError(ref e) => e.description(),
|
||||
&NodeJsSystemdUserServiceError::GenericError => "Generic error"
|
||||
&NodeJsSystemdUserServiceError::GenericError => "Generic error",
|
||||
&NodeJsSystemdUserServiceError::ActivationFailed(_) => "Activation of service failed"
|
||||
}
|
||||
}
|
||||
fn cause(&self) -> Option<&Error> {
|
||||
|
|
@ -39,12 +44,17 @@ impl<E: Error> Error for NodeJsSystemdUserServiceError<E> {
|
|||
|
||||
impl<E: Error> fmt::Display for NodeJsSystemdUserServiceError<E> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
write!(f, "{}", self.description())
|
||||
try!(write!(f, "{}", self.description()));
|
||||
if let &NodeJsSystemdUserServiceError::ActivationFailed(Ok(ref log)) = self {
|
||||
try!(write!(f, ": {:?}", log));
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NodeJsSystemdUserService<'a, P, C> where P: AsRef<str> + fmt::Display, C: Deref<Target=str> {
|
||||
name: &'a str,
|
||||
home: &'a str,
|
||||
path: P,
|
||||
command_runner: &'a CommandRunner,
|
||||
file: FileSymbol<C, Cow<'a, str>>
|
||||
|
|
@ -53,8 +63,7 @@ pub struct NodeJsSystemdUserService<'a, P, C> where P: AsRef<str> + fmt::Display
|
|||
use std::borrow::Cow;
|
||||
|
||||
impl<'a> NodeJsSystemdUserService<'a, Cow<'a, str>, String> {
|
||||
pub fn new(name: &'a str, path: &'a str, command_runner: &'a CommandRunner) -> Self {
|
||||
let home = String::from_utf8(command_runner.run_with_args("sh", &["-c", "echo \"$HOME\""]).unwrap().stdout).unwrap();
|
||||
pub fn new(home: &'a str, name: &'a str, path: &'a str, command_runner: &'a CommandRunner) -> Self {
|
||||
let file_path: Cow<str> = Cow::from(String::from(home.trim_right()) + "/.config/systemd/user/" + name + ".service");
|
||||
|
||||
let content = format!("[Service]
|
||||
|
|
@ -68,6 +77,7 @@ WantedBy=default.target
|
|||
", path, home);
|
||||
NodeJsSystemdUserService {
|
||||
name: name,
|
||||
home: home,
|
||||
path: file_path.clone(),
|
||||
command_runner: command_runner,
|
||||
file: FileSymbol::new(file_path, content)
|
||||
|
|
@ -75,6 +85,25 @@ WantedBy=default.target
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, P, C> NodeJsSystemdUserService<'a, P, C> where P: AsRef<str> + fmt::Display, C: Deref<Target=str> {
|
||||
fn check_if_service(&self) -> Result<bool, <Self as Symbol>::Error> {
|
||||
loop {
|
||||
// Check if service is registered
|
||||
let active_state = try!(self.command_runner.run_with_args("systemctl", &["--user", "show", "--property", "ActiveState", self.name]));
|
||||
if !active_state.status.success() {
|
||||
return Ok(false);
|
||||
}
|
||||
// Check if service is running
|
||||
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(NodeJsSystemdUserServiceError::ActivationFailed(self.command_runner.run_with_args("journalctl", &["--user", &format!("--user-unit={}", self.name)]))),
|
||||
_ => return Ok(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, P, C> Symbol for NodeJsSystemdUserService<'a, P, C> where P: AsRef<str> + fmt::Display, C: Deref<Target=str> {
|
||||
type Error = NodeJsSystemdUserServiceError<io::Error>;
|
||||
fn target_reached(&self) -> Result<bool, Self::Error> {
|
||||
|
|
@ -88,22 +117,13 @@ impl<'a, P, C> Symbol for NodeJsSystemdUserService<'a, P, C> where P: AsRef<str>
|
|||
return Ok(false)
|
||||
}
|
||||
*/
|
||||
loop {
|
||||
// Check if service is registered
|
||||
let active_state = try!(self.command_runner.run_with_args("systemctl", &["--user", "show", "--property", "ActiveState", self.name]));
|
||||
if !active_state.status.success() {
|
||||
return Ok(false);
|
||||
}
|
||||
// Check if service is running
|
||||
match String::from_utf8(active_state.stdout).unwrap().trim_right() {
|
||||
"ActiveState=activating" => sleep(Duration::from_millis(500)),
|
||||
"ActiveState=active" => return Ok(true),
|
||||
_ => return Ok(false)
|
||||
}
|
||||
}
|
||||
self.check_if_service()
|
||||
}
|
||||
|
||||
fn execute(&self) -> Result<(), Self::Error> {
|
||||
try!(self.command_runner.run_with_args("mkdir", &["-p", &format!("{}/var", self.home)]));
|
||||
try!(self.command_runner.run_with_args("rm", &[&format!("{}/var/service.socket", self.home)]));
|
||||
|
||||
try!(self.command_runner.run_with_args("mkdir", &["-p", Path::new(self.path.as_ref()).parent().unwrap().to_str().unwrap()]));
|
||||
// FIXME: Permissions
|
||||
// try!(create_dir_all(Path::new(&path).parent().unwrap()));
|
||||
|
|
@ -113,6 +133,18 @@ impl<'a, P, C> Symbol for NodeJsSystemdUserService<'a, P, C> where P: AsRef<str>
|
|||
}
|
||||
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(NodeJsSystemdUserServiceError::GenericError); }
|
||||
|
||||
let file_name = format!("{}/var/service.socket", self.home);
|
||||
// try!(self.command_runner.run_with_args("chmod", &["666", &file_name]));
|
||||
|
||||
sleep(Duration::from_millis(500));
|
||||
let metadata = try!(fs::metadata(file_name.clone()));
|
||||
let mut perms = metadata.permissions();
|
||||
perms.set_mode(0o666);
|
||||
try!(fs::set_permissions(file_name, perms));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue