use std::{process::Command, time::Duration}; use serde::Deserialize; use tokio::sync::watch::Sender; use crate::{Error, Status}; use super::ServiceSpawner; #[derive(Debug, Clone, Deserialize)] pub struct Systemd { pub service: String, } impl ServiceSpawner for Systemd { async fn spawn(self, tx: Sender) -> Result<(), Error> { let mut command = Command::new("systemctl"); command.arg("is-active").arg(&self.service); let mut interval = tokio::time::interval(Duration::from_secs(5)); loop { interval.tick().await; let status = command.output().map_or_else(Into::into, |o| { if o.status.success() { Status::Ok } else { let stdout = String::from_utf8_lossy(&o.stdout).trim().to_string(); Status::Error(Some(format!("Service state: {}", stdout))) } }); tx.send_if_modified(|s| s.update(status)); } } }