use std::{fs, path::Path}; use serde::Deserialize; use std::collections::BTreeMap; use toml; use tokio; use crate::processes; #[derive(Deserialize, Debug)] pub struct Service { pub name: String, pub level: u16, pub start: Start, pub stop: Option, } #[derive(Deserialize, Debug)] pub struct Start { pub command: String, pub args: Vec } #[derive(Deserialize, Debug)] pub struct Stop { pub command: String, pub args: Vec } pub fn get_services() -> BTreeMap> { let mut services = BTreeMap::new(); let mini_dir = Path::new("/etc/mini/"); if mini_dir.exists() && mini_dir.is_dir() { let dir = fs::read_dir(mini_dir).unwrap(); for file in dir { // TODO: check ext let svc_file_contents = fs::read_to_string(file.unwrap().path()).unwrap(); let svc : Service = toml::from_str(&svc_file_contents).unwrap(); let lvl = services.entry(svc.level).or_insert(Vec::new()); lvl.push(svc); } } services } pub async fn launch_services() { let services = get_services(); for (level, svc_list) in services { for s in svc_list { tokio::spawn(async move { println!("starting {}[{}]", s.name, level); let args: Vec<&str> = s.start.args.iter().map(|e| e.as_str()).collect(); processes::run(&s.start.command, &args[..]).await; }); } } } pub fn stop_services() { let services = get_services(); for (level, svc_list) in services.iter().rev() { for s in svc_list { println!("stopping {}[{}]", s.name, level); if let Some(stop) = &s.stop { let args: Vec<&str> = stop.args.iter().map(|e| e.as_str()).collect(); processes::sync_run_wait(&stop.command, &args[..]); } } } }