use std::path::{Path, PathBuf};
use super::common::{moadim_exe, run};
const SYSTEMD_UNIT_NAME: &str = "moadim.service";
pub(super) fn unit_path() -> anyhow::Result<PathBuf> {
let base = dirs::config_dir()
.ok_or_else(|| anyhow::anyhow!("could not determine the config directory"))?;
Ok(base.join("systemd/user").join(SYSTEMD_UNIT_NAME))
}
pub(super) fn render_unit(exe: &Path) -> String {
format!(
"[Unit]\n\
Description=moadim cron/MCP/REST daemon\n\
After=network.target\n\
\n\
[Service]\n\
Type=simple\n\
ExecStart={exe} --interactive\n\
Restart=always\n\
RestartSec=5\n\
\n\
[Install]\n\
WantedBy=default.target\n",
exe = exe.display(),
)
}
fn write_unit(unit: &Path, exe: &Path) -> anyhow::Result<()> {
if let Some(dir) = unit.parent() {
std::fs::create_dir_all(dir)?;
}
std::fs::write(unit, render_unit(exe))?;
Ok(())
}
fn enable_unit() -> anyhow::Result<()> {
run("systemctl", &["--user", "daemon-reload"])?;
run(
"systemctl",
&["--user", "enable", "--now", SYSTEMD_UNIT_NAME],
)
}
fn report_installed(unit: &Path) {
println!("moadim installed as a systemd user service ({SYSTEMD_UNIT_NAME})");
println!(" unit {}", unit.display());
println!(" status systemctl --user status {SYSTEMD_UNIT_NAME}");
}
pub fn install() -> anyhow::Result<()> {
let exe = moadim_exe()?;
let unit = unit_path()?;
write_unit(&unit, &exe)?;
enable_unit()?;
report_installed(&unit);
Ok(())
}
pub fn uninstall() -> anyhow::Result<()> {
let unit = unit_path()?;
if unit.exists() {
let _ = run(
"systemctl",
&["--user", "disable", "--now", SYSTEMD_UNIT_NAME],
);
std::fs::remove_file(&unit)?;
let _ = run("systemctl", &["--user", "daemon-reload"]);
println!("moadim systemd user service removed ({})", unit.display());
} else {
println!(
"moadim systemd user service is not installed (no unit at {})",
unit.display()
);
}
Ok(())
}