Skip to main content

crabtalk_command/service/
linux.rs

1//! Linux systemd service management.
2
3use anyhow::Result;
4use wcore::paths::LOGS_DIR;
5
6pub fn install(rendered: &str, label: &str) -> Result<()> {
7    let unit_name = format!("{label}.service");
8
9    let unit_dir = dirs::home_dir()
10        .ok_or_else(|| anyhow::anyhow!("cannot determine home directory"))?
11        .join(".config/systemd/user");
12    std::fs::create_dir_all(&unit_dir)?;
13    std::fs::create_dir_all(&*LOGS_DIR)?;
14
15    let unit_path = unit_dir.join(&unit_name);
16    std::fs::write(&unit_path, rendered)?;
17    println!("wrote {}", unit_path.display());
18
19    let status = std::process::Command::new("systemctl")
20        .args(["--user", "enable", "--now", &unit_name])
21        .status()?;
22    if status.success() {
23        println!("service enabled and started");
24    } else {
25        anyhow::bail!("systemctl enable failed (exit {})", status);
26    }
27    Ok(())
28}
29
30pub fn uninstall(label: &str) -> Result<()> {
31    let unit_name = format!("{label}.service");
32
33    let unit_path = dirs::home_dir()
34        .ok_or_else(|| anyhow::anyhow!("cannot determine home directory"))?
35        .join(".config/systemd/user")
36        .join(&unit_name);
37
38    if !unit_path.exists() {
39        anyhow::bail!("service not installed ({})", unit_path.display());
40    }
41
42    let status = std::process::Command::new("systemctl")
43        .args(["--user", "disable", "--now", &unit_name])
44        .status()?;
45    if !status.success() {
46        eprintln!("warning: systemctl disable exited with {}", status);
47    }
48
49    std::fs::remove_file(&unit_path)?;
50    println!("service uninstalled");
51    Ok(())
52}