Command runner args, Paths and AsRef
This commit is contained in:
parent
5d5e9dfcb4
commit
3ccf64fac1
32 changed files with 696 additions and 721 deletions
|
|
@ -26,7 +26,7 @@ impl<'a, C: CommandRunner> Symbol for ReloadService<'a, C> {
|
|||
fn execute(&self) -> Result<(), Box<dyn Error>> {
|
||||
self
|
||||
.command_runner
|
||||
.run_successfully("systemctl", &["reload-or-restart", self.service])
|
||||
.run_successfully("systemctl", args!["reload-or-restart", self.service])
|
||||
}
|
||||
|
||||
fn as_action<'b>(&'b self, runner: &'b dyn SymbolRunner) -> Box<dyn Action + 'b> {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
use std::borrow::Cow;
|
||||
use std::error::Error;
|
||||
use std::ffi::OsStr;
|
||||
use std::fmt;
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::ops::Deref;
|
||||
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Output;
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
|
|
@ -51,29 +55,23 @@ impl<E: Error> fmt::Display for UserServiceError<E> {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct UserService<'a, C, R>
|
||||
where
|
||||
C: Deref<Target = str>,
|
||||
R: CommandRunner,
|
||||
{
|
||||
pub struct UserService<'a, C: AsRef<str>, R: CommandRunner> {
|
||||
socket_path: Cow<'a, Path>,
|
||||
service_name: &'a str,
|
||||
user_name: &'a str,
|
||||
user_name: Cow<'a, str>,
|
||||
command_runner: R,
|
||||
file: FileSymbol<C, String>,
|
||||
config: FileSymbol<C, PathBuf>,
|
||||
}
|
||||
|
||||
impl<'a, R> UserService<'a, String, SetuidCommandRunner<'a, R>>
|
||||
where
|
||||
R: CommandRunner,
|
||||
{
|
||||
pub fn new_nodejs(
|
||||
home: &'a str,
|
||||
user_name: &'a str,
|
||||
impl<'a, R: CommandRunner> UserService<'a, String, SetuidCommandRunner<'a, R>> {
|
||||
pub fn new_nodejs<'b: 'a>(
|
||||
home: Cow<'a, Path>,
|
||||
user_name: Cow<'a, str>,
|
||||
service_name: &'a str,
|
||||
path: &'a str,
|
||||
path: Cow<'a, Path>,
|
||||
command_runner: &'a R,
|
||||
socket_path: Cow<'a, Path>,
|
||||
) -> Self {
|
||||
let port = format!("/var/tmp/{}-{}.socket", user_name, service_name);
|
||||
let content = format!(
|
||||
"[Service]
|
||||
Environment=NODE_ENV=production
|
||||
|
|
@ -91,39 +89,46 @@ Restart=always
|
|||
[Install]
|
||||
WantedBy=default.target
|
||||
",
|
||||
path, port
|
||||
path.to_str().unwrap(),
|
||||
socket_path.to_str().unwrap()
|
||||
);
|
||||
UserService::new(home, user_name, service_name, command_runner, content)
|
||||
UserService::new(
|
||||
socket_path,
|
||||
home,
|
||||
user_name,
|
||||
service_name,
|
||||
command_runner,
|
||||
content,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
home: &'a str,
|
||||
user_name: &'a str,
|
||||
socket_path: Cow<'a, Path>,
|
||||
home: Cow<'a, Path>,
|
||||
user_name: Cow<'a, str>,
|
||||
service_name: &'a str,
|
||||
command_runner: &'a R,
|
||||
content: String,
|
||||
) -> Self {
|
||||
let file_path = format!(
|
||||
"{}/.config/systemd/user/{}.service",
|
||||
home.trim_end(),
|
||||
service_name
|
||||
);
|
||||
let config_path: PathBuf = [
|
||||
home.as_ref(),
|
||||
format!(".config/systemd/user/{}.service", service_name).as_ref(),
|
||||
]
|
||||
.iter()
|
||||
.collect();
|
||||
|
||||
UserService {
|
||||
socket_path,
|
||||
service_name,
|
||||
user_name,
|
||||
user_name: user_name.clone(),
|
||||
command_runner: SetuidCommandRunner::new(user_name, command_runner),
|
||||
file: FileSymbol::new(file_path, content),
|
||||
config: FileSymbol::new(config_path, content),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, C, R> UserService<'a, C, R>
|
||||
where
|
||||
C: Deref<Target = str>,
|
||||
R: CommandRunner,
|
||||
{
|
||||
fn systemctl_wait_for_dbus(&self, args: &[&str]) -> Result<String, Box<dyn Error>> {
|
||||
impl<'a, C: AsRef<str>, R: CommandRunner> UserService<'a, C, R> {
|
||||
fn systemctl_wait_for_dbus(&self, args: &[&OsStr]) -> Result<String, Box<dyn Error>> {
|
||||
let mut tries = 5;
|
||||
loop {
|
||||
let result = self.command_runner.run_with_args("systemctl", args)?;
|
||||
|
|
@ -146,7 +151,7 @@ where
|
|||
|
||||
fn check_if_service(&self) -> Result<bool, Box<dyn Error>> {
|
||||
loop {
|
||||
let active_state = self.systemctl_wait_for_dbus(&[
|
||||
let active_state = self.systemctl_wait_for_dbus(args![
|
||||
"--user",
|
||||
"show",
|
||||
"--property",
|
||||
|
|
@ -160,7 +165,7 @@ where
|
|||
return Err(Box::new(
|
||||
UserServiceError::ActivationFailed(self.command_runner.run_with_args(
|
||||
"journalctl",
|
||||
&["--user", &format!("--user-unit={}", self.service_name)],
|
||||
args!["--user", format!("--user-unit={}", self.service_name)],
|
||||
)) as UserServiceError<io::Error>,
|
||||
))
|
||||
}
|
||||
|
|
@ -170,22 +175,18 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, C, R> Symbol for UserService<'a, C, R>
|
||||
where
|
||||
C: Deref<Target = str>,
|
||||
R: CommandRunner,
|
||||
{
|
||||
impl<'a, C: AsRef<str>, R: CommandRunner> Symbol for UserService<'a, C, R> {
|
||||
fn target_reached(&self) -> Result<bool, Box<dyn Error>> {
|
||||
if !(self.file.target_reached()?) {
|
||||
if !(self.config.target_reached()?) {
|
||||
return Ok(false);
|
||||
}
|
||||
self.check_if_service()
|
||||
}
|
||||
|
||||
fn execute(&self) -> Result<(), Box<dyn Error>> {
|
||||
self.file.execute()?;
|
||||
self.systemctl_wait_for_dbus(&["--user", "enable", self.service_name])?;
|
||||
self.systemctl_wait_for_dbus(&["--user", "restart", self.service_name])?;
|
||||
self.config.execute()?;
|
||||
self.systemctl_wait_for_dbus(args!["--user", "enable", self.service_name])?;
|
||||
self.systemctl_wait_for_dbus(args!["--user", "restart", self.service_name])?;
|
||||
|
||||
if !(self.check_if_service()?) {
|
||||
return Err(Box::new(
|
||||
|
|
@ -193,8 +194,7 @@ where
|
|||
));
|
||||
}
|
||||
|
||||
let file_name = format!("/var/tmp/{}-{}.socket", self.user_name, self.service_name);
|
||||
fs::metadata(&file_name)
|
||||
fs::metadata(&self.socket_path)
|
||||
.map(|_| ())
|
||||
.map_err(|e| Box::new(e) as Box<dyn Error>)
|
||||
}
|
||||
|
|
@ -204,7 +204,7 @@ where
|
|||
"file",
|
||||
format!("/var/lib/systemd/linger/{}", self.user_name),
|
||||
)];
|
||||
r.extend(self.file.get_prerequisites().into_iter());
|
||||
r.extend(self.config.get_prerequisites().into_iter());
|
||||
r
|
||||
}
|
||||
|
||||
|
|
@ -220,11 +220,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, C, R> fmt::Display for UserService<'a, C, R>
|
||||
where
|
||||
C: Deref<Target = str>,
|
||||
R: CommandRunner,
|
||||
{
|
||||
impl<'a, C: AsRef<str>, R: CommandRunner> fmt::Display for UserService<'a, C, R> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
write!(f, "Systemd user service unit for {}", self.service_name)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
use std::borrow::{Borrow, Cow};
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::path::PathBuf;
|
||||
|
|
@ -33,13 +32,13 @@ impl<E: Error> fmt::Display for SystemdUserSessionError<E> {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct SystemdUserSession<'a, C: 'a + CommandRunner> {
|
||||
user_name: Cow<'a, str>,
|
||||
pub struct SystemdUserSession<'a, U: AsRef<str>, C: CommandRunner> {
|
||||
user_name: U,
|
||||
command_runner: &'a C,
|
||||
}
|
||||
|
||||
impl<'a, C: CommandRunner> SystemdUserSession<'a, C> {
|
||||
pub fn new(user_name: Cow<'a, str>, command_runner: &'a C) -> Self {
|
||||
impl<'a, U: AsRef<str>, C: CommandRunner> SystemdUserSession<'a, U, C> {
|
||||
pub fn new(user_name: U, command_runner: &'a C) -> Self {
|
||||
SystemdUserSession {
|
||||
user_name,
|
||||
command_runner,
|
||||
|
|
@ -47,10 +46,10 @@ impl<'a, C: CommandRunner> SystemdUserSession<'a, C> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, C: CommandRunner> Symbol for SystemdUserSession<'a, C> {
|
||||
impl<'a, U: AsRef<str>, C: CommandRunner> Symbol for SystemdUserSession<'a, U, C> {
|
||||
fn target_reached(&self) -> Result<bool, Box<dyn Error>> {
|
||||
let mut path = PathBuf::from("/var/lib/systemd/linger");
|
||||
path.push(self.user_name.borrow() as &str);
|
||||
path.push(self.user_name.as_ref());
|
||||
Ok(path.exists())
|
||||
// Could also do `loginctl show-user ${self.user_name} | grep -F 'Linger=yes`
|
||||
}
|
||||
|
|
@ -58,7 +57,7 @@ impl<'a, C: CommandRunner> Symbol for SystemdUserSession<'a, C> {
|
|||
fn execute(&self) -> Result<(), Box<dyn Error>> {
|
||||
self
|
||||
.command_runner
|
||||
.run_successfully("loginctl", &["enable-linger", self.user_name.borrow()])
|
||||
.run_successfully("loginctl", args!["enable-linger", self.user_name.as_ref()])
|
||||
}
|
||||
|
||||
fn as_action<'b>(&'b self, runner: &'b dyn SymbolRunner) -> Box<dyn Action + 'b> {
|
||||
|
|
@ -73,8 +72,8 @@ impl<'a, C: CommandRunner> Symbol for SystemdUserSession<'a, C> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, C: CommandRunner> fmt::Display for SystemdUserSession<'a, C> {
|
||||
impl<'a, U: AsRef<str>, C: CommandRunner> fmt::Display for SystemdUserSession<'a, U, C> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
write!(f, "Systemd user session for {}", self.user_name)
|
||||
write!(f, "Systemd user session for {}", self.user_name.as_ref())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue