Browse Source

Cow -> AsRef

master
Adrian Heine 5 years ago
parent
commit
64bdf403d4
  1. 59
      src/symbols/factory.rs
  2. 55
      src/symbols/systemd/user_service.rs

59
src/symbols/factory.rs

@ -38,21 +38,14 @@ pub struct DefaultPolicy;
impl Policy for 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, command_runner: &'a C,
acme_factory: AcmeFactory<'a, Cow<'a, str>, PathBuf, &'a str, C>, acme_factory: AcmeFactory<'a, Cow<'a, str>, PathBuf, &'a str, C>,
symbol_runner: &'a R, symbol_runner: &'a R,
policy: &'a P, 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 { 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_user = policy.acme_user();
let acme_home = policy.home_for_user(&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() self.acme_factory.get_init()
} }
pub fn get_systemd_user_service<'a>(
pub fn get_systemd_user_service<'a, U: 'a + AsRef<str> + Clone>(
&'a self, &'a self,
user_name: Cow<'a, str>,
user_name: U,
service_name: &'a str, service_name: &'a str,
config: Cow<'a, str>,
config: String,
) -> impl Symbol + 'a { ) -> 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( UserService::new(
socket_path.into(),
home.into(),
socket_path,
&home,
user_name, user_name,
service_name, service_name,
self.command_runner, self.command_runner,
config.into(),
config,
) )
} }
fn get_nodejs_systemd_user_service<'a, T: Into<Cow<'a, Path>>>(
fn get_nodejs_systemd_user_service<'a, U: 'a + AsRef<str> + Clone>(
&'a self, &'a self,
user_name: Cow<'a, str>,
user_name: U,
service_name: &'a str, service_name: &'a str,
path: T,
path: &'a Path,
) -> impl Symbol + 'a { ) -> 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( UserService::new_nodejs(
home.into(),
&home,
user_name, user_name,
service_name, service_name,
path.into(),
path,
self.command_runner, self.command_runner,
socket_path.into(),
socket_path,
) )
} }
pub fn proxy_socket<'a, T: Into<Cow<'a, Path>>>(
pub fn proxy_socket<'a, T: AsRef<Path>>(
&'a self, &'a self,
host_name: &'static str, host_name: &'static str,
service_name: &'a 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); let socket_path = self.policy.socket_path(&user_name, service_name);
self.get_nginx_acme_server( self.get_nginx_acme_server(
host_name, 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<Cow<'a, Path>>,
SP: 'a + Into<Cow<'a, Path>>,
>(
pub fn serve_nodejs<'a, 'c: 'a, S: 'a + Symbol, SP: 'a + AsRef<Path>>(
&'c self, &'c self,
host: &'static str, host: &'static str,
service_name: &'a str, service_name: &'a str,
path: T,
path: &'a Path,
static_path: SP, static_path: SP,
nodejs_symbol: S, nodejs_symbol: S,
) -> impl Symbol + 'a { ) -> impl Symbol + 'a {
@ -424,7 +411,7 @@ env[PATH] = /usr/local/bin:/usr/bin:/bin
List::from(( List::from((
Hook::new( Hook::new(
nodejs_symbol, 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), self.proxy_socket(host, service_name, static_path),
)) ))

55
src/symbols/systemd/user_service.rs

@ -1,4 +1,3 @@
use std::borrow::Cow;
use std::error::Error; use std::error::Error;
use std::ffi::OsStr; use std::ffi::OsStr;
use std::fmt; use std::fmt;
@ -46,29 +45,31 @@ impl<E: Error> Error for UserServiceError<E> {
impl<E: Error> fmt::Display for UserServiceError<E> { impl<E: Error> fmt::Display for UserServiceError<E> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
write!(f, "{}", self.description())?; write!(f, "{}", self.description())?;
if let UserServiceError::ActivationFailed(Ok(ref log)) = self {
if let Self::ActivationFailed(Ok(ref log)) = self {
write!(f, ": {:?}", log)?; write!(f, ": {:?}", log)?;
}; };
Ok(()) Ok(())
} }
} }
pub struct UserService<'a, C: AsRef<str>, R: CommandRunner> {
socket_path: Cow<'a, Path>,
pub struct UserService<'a, S: AsRef<Path>, U: AsRef<str>, C: AsRef<str>, R: CommandRunner> {
socket_path: S,
service_name: &'a str, service_name: &'a str,
user_name: Cow<'a, str>,
user_name: U,
command_runner: R, command_runner: R,
config: FileSymbol<C, PathBuf>, config: FileSymbol<C, PathBuf>,
} }
impl<'a, R: CommandRunner> UserService<'a, String, SetuidCommandRunner<'a, Cow<'a, str>, R>> {
impl<'a, S: AsRef<Path>, U: AsRef<str> + Clone, R: CommandRunner>
UserService<'a, S, U, String, SetuidCommandRunner<'a, U, R>>
{
pub fn new_nodejs( pub fn new_nodejs(
home: Cow<'a, Path>,
user_name: Cow<'a, str>,
home: &'_ Path,
user_name: U,
service_name: &'a str, service_name: &'a str,
path: Cow<'a, Path>,
path: &'_ Path,
command_runner: &'a R, command_runner: &'a R,
socket_path: Cow<'a, Path>,
socket_path: S,
) -> Self { ) -> Self {
let content = format!( let content = format!(
"[Service] "[Service]
@ -88,9 +89,9 @@ Restart=always
WantedBy=default.target WantedBy=default.target
", ",
path.to_str().unwrap(), path.to_str().unwrap(),
socket_path.to_str().unwrap()
socket_path.as_ref().to_str().unwrap()
); );
UserService::new(
Self::new(
socket_path, socket_path,
home, home,
user_name, user_name,
@ -101,15 +102,15 @@ WantedBy=default.target
} }
pub fn new( 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, service_name: &'a str,
command_runner: &'a R, command_runner: &'a R,
content: String, content: String,
) -> Self { ) -> Self {
let config_path: PathBuf = [ let config_path: PathBuf = [
home.as_ref(),
home,
format!(".config/systemd/user/{}.service", service_name).as_ref(), format!(".config/systemd/user/{}.service", service_name).as_ref(),
] ]
.iter() .iter()
@ -125,19 +126,21 @@ WantedBy=default.target
} }
} }
impl<'a, C: AsRef<str>, R: CommandRunner> UserService<'a, C, R> {
impl<'a, S: AsRef<Path>, U: AsRef<str>, C: AsRef<str>, R: CommandRunner>
UserService<'a, S, U, C, R>
{
fn systemctl_wait_for_dbus(&self, args: &[&OsStr]) -> Result<String, Box<dyn Error>> { fn systemctl_wait_for_dbus(&self, args: &[&OsStr]) -> Result<String, Box<dyn Error>> {
let mut tries = 5; let mut tries = 5;
loop { loop {
let result = self.command_runner.run_with_args("systemctl", args)?; 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 raw_stderr = String::from_utf8(result.stderr)?;
let stderr = raw_stderr.trim_end(); let stderr = raw_stderr.trim_end();
if stderr != "Failed to connect to bus: No such file or directory" { if stderr != "Failed to connect to bus: No such file or directory" {
return Err(stderr.into()); return Err(stderr.into());
} }
} else {
return Ok(String::from_utf8(result.stdout)?.trim_end().to_string());
} }
tries -= 1; tries -= 1;
if tries == 0 { if tries == 0 {
@ -173,7 +176,9 @@ impl<'a, C: AsRef<str>, R: CommandRunner> UserService<'a, C, R> {
} }
} }
impl<'a, C: AsRef<str>, R: CommandRunner> Symbol for UserService<'a, C, R> {
impl<'a, S: AsRef<Path>, U: AsRef<str>, C: AsRef<str>, R: CommandRunner> Symbol
for UserService<'a, S, U, C, R>
{
fn target_reached(&self) -> Result<bool, Box<dyn Error>> { fn target_reached(&self) -> Result<bool, Box<dyn Error>> {
if !(self.config.target_reached()?) { if !(self.config.target_reached()?) {
return Ok(false); return Ok(false);
@ -193,7 +198,7 @@ impl<'a, C: AsRef<str>, R: CommandRunner> Symbol for UserService<'a, C, R> {
)); ));
} }
if self.socket_path.exists() {
if self.socket_path.as_ref().exists() {
return Ok(()); return Ok(());
} }
sleep(Duration::from_millis(500)); sleep(Duration::from_millis(500));
@ -203,7 +208,7 @@ impl<'a, C: AsRef<str>, R: CommandRunner> Symbol for UserService<'a, C, R> {
fn get_prerequisites(&self) -> Vec<Resource> { fn get_prerequisites(&self) -> Vec<Resource> {
let mut r = vec![Resource::new( let mut r = vec![Resource::new(
"file", "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.extend(self.config.get_prerequisites().into_iter());
r r
@ -221,7 +226,9 @@ impl<'a, C: AsRef<str>, R: CommandRunner> Symbol for UserService<'a, C, R> {
} }
} }
impl<'a, C: AsRef<str>, R: CommandRunner> fmt::Display for UserService<'a, C, R> {
impl<'a, S: AsRef<Path>, U: AsRef<str>, C: AsRef<str>, R: CommandRunner> fmt::Display
for UserService<'a, S, U, C, R>
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
write!(f, "Systemd user service unit for {}", self.service_name) write!(f, "Systemd user service unit for {}", self.service_name)
} }

Loading…
Cancel
Save