2021-09-21 07:33:50 +00:00
|
|
|
use std::process::Command;
|
|
|
|
|
|
|
|
use anyhow::{bail, format_err, Error};
|
|
|
|
|
|
|
|
fn run_command(mut command: Command) -> Result<(), Error> {
|
|
|
|
let output = command
|
|
|
|
.output()
|
|
|
|
.map_err(|err| format_err!("failed to execute {:?} - {}", command, err))?;
|
|
|
|
|
|
|
|
proxmox::try_block!({
|
|
|
|
if !output.status.success() {
|
|
|
|
match output.status.code() {
|
|
|
|
Some(code) => {
|
|
|
|
if code != 0 {
|
|
|
|
let msg = String::from_utf8(output.stderr)
|
|
|
|
.map(|m| {
|
|
|
|
if m.is_empty() {
|
|
|
|
String::from("no error message")
|
|
|
|
} else {
|
|
|
|
m
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.unwrap_or_else(|_| String::from("non utf8 error message (suppressed)"));
|
|
|
|
|
|
|
|
bail!("status code: {} - {}", code, msg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None => bail!("terminated by signal"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}).map_err(|err| format_err!("command {:?} failed - {}", command, err))?;
|
2021-07-07 08:10:33 +00:00
|
|
|
|
2021-09-21 07:33:50 +00:00
|
|
|
Ok(())
|
|
|
|
}
|
2021-07-07 08:10:33 +00:00
|
|
|
|
|
|
|
pub fn reload_daemon() -> Result<(), Error> {
|
|
|
|
let mut command = std::process::Command::new("systemctl");
|
|
|
|
command.arg("daemon-reload");
|
|
|
|
|
2021-09-21 07:33:50 +00:00
|
|
|
run_command(command)?;
|
2021-07-07 08:10:33 +00:00
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn disable_unit(unit: &str) -> Result<(), Error> {
|
|
|
|
let mut command = std::process::Command::new("systemctl");
|
|
|
|
command.arg("disable");
|
|
|
|
command.arg(unit);
|
|
|
|
|
2021-09-21 07:33:50 +00:00
|
|
|
run_command(command)?;
|
2021-07-07 08:10:33 +00:00
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn enable_unit(unit: &str) -> Result<(), Error> {
|
|
|
|
let mut command = std::process::Command::new("systemctl");
|
|
|
|
command.arg("enable");
|
|
|
|
command.arg(unit);
|
|
|
|
|
2021-09-21 07:33:50 +00:00
|
|
|
run_command(command)?;
|
2021-07-07 08:10:33 +00:00
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn start_unit(unit: &str) -> Result<(), Error> {
|
|
|
|
let mut command = std::process::Command::new("systemctl");
|
|
|
|
command.arg("start");
|
|
|
|
command.arg(unit);
|
|
|
|
|
2021-09-21 07:33:50 +00:00
|
|
|
run_command(command)?;
|
2021-07-07 08:10:33 +00:00
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn stop_unit(unit: &str) -> Result<(), Error> {
|
|
|
|
let mut command = std::process::Command::new("systemctl");
|
|
|
|
command.arg("stop");
|
|
|
|
command.arg(unit);
|
|
|
|
|
2021-09-21 07:33:50 +00:00
|
|
|
run_command(command)?;
|
2021-07-07 08:10:33 +00:00
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn reload_unit(unit: &str) -> Result<(), Error> {
|
|
|
|
let mut command = std::process::Command::new("systemctl");
|
|
|
|
command.arg("try-reload-or-restart");
|
|
|
|
command.arg(unit);
|
|
|
|
|
2021-09-21 07:33:50 +00:00
|
|
|
run_command(command)?;
|
2021-07-07 08:10:33 +00:00
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_escape_unit() -> Result<(), Error> {
|
|
|
|
fn test_escape(i: &str, expected: &str, is_path: bool) {
|
2021-09-22 10:46:44 +00:00
|
|
|
|
|
|
|
use proxmox::tools::systemd::{escape_unit, unescape_unit};
|
|
|
|
|
2021-07-07 08:10:33 +00:00
|
|
|
let escaped = escape_unit(i, is_path);
|
|
|
|
assert_eq!(escaped, expected);
|
|
|
|
let unescaped = unescape_unit(&escaped).unwrap();
|
|
|
|
if is_path {
|
|
|
|
let mut p = i.trim_matches('/');
|
|
|
|
if p.is_empty() {
|
|
|
|
p = "/";
|
|
|
|
}
|
|
|
|
assert_eq!(p, unescaped);
|
|
|
|
} else {
|
|
|
|
assert_eq!(i, unescaped);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
test_escape(".test", "\\x2etest", false);
|
|
|
|
test_escape("t.est", "t.est", false);
|
|
|
|
test_escape("_test_", "_test_", false);
|
|
|
|
|
|
|
|
test_escape("/", "-", false);
|
|
|
|
test_escape("//", "--", false);
|
|
|
|
|
|
|
|
test_escape("/", "-", true);
|
|
|
|
test_escape("//", "-", true);
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|