diff --git a/src/symbols/factory.rs b/src/symbols/factory.rs index b7051a7..2eb5829 100644 --- a/src/symbols/factory.rs +++ b/src/symbols/factory.rs @@ -38,21 +38,14 @@ pub struct DefaultPolicy; impl Policy for DefaultPolicy {} -pub struct SymbolFactory< - 'a, - C: 'a + CommandRunner, - R: 'a + SymbolRunner, - P: 'a + Policy, -> { +pub struct SymbolFactory<'a, C: 'a + CommandRunner, R: 'a + SymbolRunner, P: 'a + Policy> { command_runner: &'a C, acme_factory: AcmeFactory<'a, Cow<'a, str>, PathBuf, &'a str, C>, symbol_runner: &'a R, policy: &'a P, } -impl<'b, C: 'b + CommandRunner, R: 'b + SymbolRunner, P: 'b + Policy> - SymbolFactory<'b, C, R, P> -{ +impl<'b, C: 'b + CommandRunner, R: 'b + SymbolRunner, P: 'b + Policy> SymbolFactory<'b, C, R, P> { pub fn new(command_runner: &'b C, symbol_runner: &'b R, policy: &'b P, cert: &'b str) -> Self { let acme_user = policy.acme_user(); let acme_home = policy.home_for_user(&acme_user); @@ -356,43 +349,43 @@ env[PATH] = /usr/local/bin:/usr/bin:/bin self.acme_factory.get_init() } - pub fn get_systemd_user_service<'a>( + pub fn get_systemd_user_service<'a, U: 'a + AsRef + Clone>( &'a self, - user_name: Cow<'a, str>, + user_name: U, service_name: &'a str, - config: Cow<'a, str>, + config: String, ) -> impl Symbol + 'a { - let socket_path = self.policy.socket_path(&user_name, service_name); - let home = self.policy.home_for_user(&user_name); + let socket_path = self.policy.socket_path(user_name.as_ref(), service_name); + let home = self.policy.home_for_user(user_name.as_ref()); UserService::new( - socket_path.into(), - home.into(), + socket_path, + &home, user_name, service_name, self.command_runner, - config.into(), + config, ) } - fn get_nodejs_systemd_user_service<'a, T: Into>>( + fn get_nodejs_systemd_user_service<'a, U: 'a + AsRef + Clone>( &'a self, - user_name: Cow<'a, str>, + user_name: U, service_name: &'a str, - path: T, + path: &'a Path, ) -> impl Symbol + 'a { - let socket_path = self.policy.socket_path(&user_name, service_name); - let home = self.policy.home_for_user(&user_name); + let socket_path = self.policy.socket_path(user_name.as_ref(), service_name); + let home = self.policy.home_for_user(user_name.as_ref()); UserService::new_nodejs( - home.into(), + &home, user_name, service_name, - path.into(), + path, self.command_runner, - socket_path.into(), + socket_path, ) } - pub fn proxy_socket<'a, T: Into>>( + pub fn proxy_socket<'a, T: AsRef>( &'a self, host_name: &'static str, service_name: &'a str, @@ -402,21 +395,15 @@ env[PATH] = /usr/local/bin:/usr/bin:/bin let socket_path = self.policy.socket_path(&user_name, service_name); self.get_nginx_acme_server( host_name, - NginxServer::new_proxy(host_name, socket_path, root_dir.into(), self.command_runner), + NginxServer::new_proxy(host_name, socket_path, root_dir, self.command_runner), ) } - pub fn serve_nodejs< - 'a, - 'c: 'a, - S: 'a + Symbol, - T: 'a + Into>, - SP: 'a + Into>, - >( + pub fn serve_nodejs<'a, 'c: 'a, S: 'a + Symbol, SP: 'a + AsRef>( &'c self, host: &'static str, service_name: &'a str, - path: T, + path: &'a Path, static_path: SP, nodejs_symbol: S, ) -> impl Symbol + 'a { @@ -424,7 +411,7 @@ env[PATH] = /usr/local/bin:/usr/bin:/bin List::from(( Hook::new( nodejs_symbol, - self.get_nodejs_systemd_user_service(user_name.into(), service_name, path), + self.get_nodejs_systemd_user_service(user_name, service_name, path), ), self.proxy_socket(host, service_name, static_path), )) diff --git a/src/symbols/systemd/user_service.rs b/src/symbols/systemd/user_service.rs index 253d404..b3e9359 100644 --- a/src/symbols/systemd/user_service.rs +++ b/src/symbols/systemd/user_service.rs @@ -1,4 +1,3 @@ -use std::borrow::Cow; use std::error::Error; use std::ffi::OsStr; use std::fmt; @@ -46,29 +45,31 @@ impl Error for UserServiceError { impl fmt::Display for UserServiceError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { write!(f, "{}", self.description())?; - if let UserServiceError::ActivationFailed(Ok(ref log)) = self { + if let Self::ActivationFailed(Ok(ref log)) = self { write!(f, ": {:?}", log)?; }; Ok(()) } } -pub struct UserService<'a, C: AsRef, R: CommandRunner> { - socket_path: Cow<'a, Path>, +pub struct UserService<'a, S: AsRef, U: AsRef, C: AsRef, R: CommandRunner> { + socket_path: S, service_name: &'a str, - user_name: Cow<'a, str>, + user_name: U, command_runner: R, config: FileSymbol, } -impl<'a, R: CommandRunner> UserService<'a, String, SetuidCommandRunner<'a, Cow<'a, str>, R>> { +impl<'a, S: AsRef, U: AsRef + Clone, R: CommandRunner> + UserService<'a, S, U, String, SetuidCommandRunner<'a, U, R>> +{ pub fn new_nodejs( - home: Cow<'a, Path>, - user_name: Cow<'a, str>, + home: &'_ Path, + user_name: U, service_name: &'a str, - path: Cow<'a, Path>, + path: &'_ Path, command_runner: &'a R, - socket_path: Cow<'a, Path>, + socket_path: S, ) -> Self { let content = format!( "[Service] @@ -88,9 +89,9 @@ Restart=always WantedBy=default.target ", path.to_str().unwrap(), - socket_path.to_str().unwrap() + socket_path.as_ref().to_str().unwrap() ); - UserService::new( + Self::new( socket_path, home, user_name, @@ -101,15 +102,15 @@ WantedBy=default.target } pub fn new( - socket_path: Cow<'a, Path>, - home: Cow<'a, Path>, - user_name: Cow<'a, str>, + socket_path: S, + home: &'_ Path, + user_name: U, service_name: &'a str, command_runner: &'a R, content: String, ) -> Self { let config_path: PathBuf = [ - home.as_ref(), + home, format!(".config/systemd/user/{}.service", service_name).as_ref(), ] .iter() @@ -125,19 +126,21 @@ WantedBy=default.target } } -impl<'a, C: AsRef, R: CommandRunner> UserService<'a, C, R> { +impl<'a, S: AsRef, U: AsRef, C: AsRef, R: CommandRunner> + UserService<'a, S, U, C, R> +{ fn systemctl_wait_for_dbus(&self, args: &[&OsStr]) -> Result> { let mut tries = 5; loop { let result = self.command_runner.run_with_args("systemctl", args)?; - if !result.status.success() { + if result.status.success() { + return Ok(String::from_utf8(result.stdout)?.trim_end().to_string()); + } else { let raw_stderr = String::from_utf8(result.stderr)?; let stderr = raw_stderr.trim_end(); if stderr != "Failed to connect to bus: No such file or directory" { return Err(stderr.into()); } - } else { - return Ok(String::from_utf8(result.stdout)?.trim_end().to_string()); } tries -= 1; if tries == 0 { @@ -173,7 +176,9 @@ impl<'a, C: AsRef, R: CommandRunner> UserService<'a, C, R> { } } -impl<'a, C: AsRef, R: CommandRunner> Symbol for UserService<'a, C, R> { +impl<'a, S: AsRef, U: AsRef, C: AsRef, R: CommandRunner> Symbol + for UserService<'a, S, U, C, R> +{ fn target_reached(&self) -> Result> { if !(self.config.target_reached()?) { return Ok(false); @@ -193,7 +198,7 @@ impl<'a, C: AsRef, R: CommandRunner> Symbol for UserService<'a, C, R> { )); } - if self.socket_path.exists() { + if self.socket_path.as_ref().exists() { return Ok(()); } sleep(Duration::from_millis(500)); @@ -203,7 +208,7 @@ impl<'a, C: AsRef, R: CommandRunner> Symbol for UserService<'a, C, R> { fn get_prerequisites(&self) -> Vec { let mut r = vec![Resource::new( "file", - format!("/var/lib/systemd/linger/{}", self.user_name), + format!("/var/lib/systemd/linger/{}", self.user_name.as_ref()), )]; r.extend(self.config.get_prerequisites().into_iter()); r @@ -221,7 +226,9 @@ impl<'a, C: AsRef, R: CommandRunner> Symbol for UserService<'a, C, R> { } } -impl<'a, C: AsRef, R: CommandRunner> fmt::Display for UserService<'a, C, R> { +impl<'a, S: AsRef, U: AsRef, C: AsRef, R: CommandRunner> fmt::Display + for UserService<'a, S, U, C, R> +{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { write!(f, "Systemd user service unit for {}", self.service_name) }