From 141e546e1d7a8385817b3edb46bd91b502563cd9 Mon Sep 17 00:00:00 2001 From: yuzu Date: Tue, 8 Jul 2025 07:12:59 +0000 Subject: working proof of concept -- minecraft git-svn-id: svn+ssh://diminuette.aengel.lesbianunix.dev/salaryman/trunk@9 b9215c17-b818-4693-b096-d1e41a411fef --- src/bin/smd.rs | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 97 ---------------------------------------------------------- src/model.rs | 31 ++++++++----------- 3 files changed, 105 insertions(+), 115 deletions(-) create mode 100644 src/bin/smd.rs delete mode 100644 src/main.rs (limited to 'src') diff --git a/src/bin/smd.rs b/src/bin/smd.rs new file mode 100644 index 0000000..5a8401a --- /dev/null +++ b/src/bin/smd.rs @@ -0,0 +1,92 @@ +use clap::Parser; +use serde::{Deserialize, Serialize}; + +use tokio::fs::read_to_string; + +use std::{net::IpAddr, path::PathBuf}; + +use salaryman::model::{Service, ServiceConf}; + +#[derive(Parser, Debug)] +#[command(version, about, long_about = None)] +struct Args { + #[arg( + short, + long, + value_name = "FILE", + help = "config file override", + default_value = "salaryman.toml" + )] + config: PathBuf, + #[arg( + short, + long, + value_name = "ADDR", + help = "IP address to bind API to", + default_value = "127.0.0.1" + )] + address: IpAddr, + #[arg( + short, + long, + value_name = "PORT", + help = "TCP Port to bind API to", + default_value = "3080" + )] + port: u16, +} + +#[derive(Serialize, Deserialize, Debug)] +struct Config { + address: Option, + port: Option, + service: Vec, +} +impl Config { + fn new() -> Self { + Self { + address: None, + port: None, + service: Vec::new(), + } + } +} + +async fn load_config(file: &PathBuf) -> Config { + let s: String = match read_to_string(file).await { + Ok(s) => s, + Err(_) => String::new(), + }; + match toml::from_str(s.as_str()) { + Ok(c) => c, + Err(_) => Config::new(), + } +} + +#[tokio::main] +async fn main() -> Result<(), Box> { + let args = Args::parse(); + let conf: Config = load_config(&args.config).await; + let mut services: Vec = Vec::new(); + for i in 0..conf.service.len() { + services.push(Service::from_conf(&conf.service[i])); + if conf.service[i].autostart { + services[i].start().await?; + services[i].scan_stdout().await?; + services[i].scan_stderr().await?; + } + } + tokio::time::sleep(std::time::Duration::from_secs(60)).await; + println!("trying to write to stdin!"); + for i in 0..services.len() { + services[i].write_stdin("stop\n".into()).await?; + } + tokio::time::sleep(std::time::Duration::from_secs(30)).await; + for mut service in services { + match service.stop().await { + Ok(_) => println!("lol it was killed"), + Err(_) => println!("it either didn't exist, or failed to kill"), + } + } + Ok(()) +} diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index 09a9376..0000000 --- a/src/main.rs +++ /dev/null @@ -1,97 +0,0 @@ -use clap::Parser; -use serde::{Deserialize, Serialize}; - -use tokio::fs::read_to_string; - -use std::{net::IpAddr, path::PathBuf}; - -use salaryman::model::{Service, ServiceConf}; - -#[derive(Parser, Debug)] -#[command(version, about, long_about = None)] -struct Args { - #[arg( - short, - long, - value_name = "FILE", - help = "config file override", - default_value = "salaryman.toml" - )] - config: PathBuf, - #[arg( - short, - long, - value_name = "ADDR", - help = "IP address to bind API to", - default_value = "127.0.0.1" - )] - address: IpAddr, - #[arg( - short, - long, - value_name = "PORT", - help = "TCP Port to bind API to", - default_value = "3080" - )] - port: u16, -} - -#[derive(Serialize, Deserialize, Debug)] -struct Config { - address: Option, - port: Option, - service: Vec, -} -impl Config { - fn new() -> Self { - Self { - address: None, - port: None, - service: Vec::new(), - } - } -} - -async fn load_config(file: &PathBuf) -> Config { - let s: String = match read_to_string(file).await { - Ok(s) => s, - Err(_) => String::new(), - }; - match toml::from_str(s.as_str()) { - Ok(c) => c, - Err(_) => Config::new(), - } -} - -#[tokio::main] -async fn main() -> Result<(), Box> { - let args = Args::parse(); - let conf: Config = load_config(&args.config).await; - let mut services: Vec = Vec::new(); - for i in 0..conf.service.len() { - services.push(Service::from_conf(&conf.service[i])); - if conf.service[i].autostart { - services[i].start().await?; - } - } - let mut outs: Vec<(String, tokio::sync::mpsc::Receiver)> = Vec::new(); - for i in 0..services.len() { - if services[i].started().await { - outs.push((services[i].name().await, services[i].scan_stdout().await?)); - } - } - for _i in 0..100 { - for out in 0..outs.len() { - if let Some(s) = outs[out].1.recv().await { - println!("got line from {} :: {}", outs[out].0, s); - } - } - } - for mut service in services { - match service.stop().await { - Ok(_) => println!("lol it was killed"), - Err(_) => println!("it either didn't exist, or failed to kill"), - } - } - Ok(()) -} diff --git a/src/model.rs b/src/model.rs index 8f4416b..60960e3 100644 --- a/src/model.rs +++ b/src/model.rs @@ -61,8 +61,8 @@ impl ServiceConf { pub struct Service { conf: ServiceConf, proc: Option>>, - stdout: Option>>>, - stderr: Option>>>, + pub stdout: Option>>>, + pub stderr: Option>>>, } impl Default for Service { fn default() -> Self { @@ -109,23 +109,17 @@ impl Service { ))); } let cmd = &self.conf.command; - let args = if let Some(a) = &self.conf.args { - a.split_whitespace() - } else { - "".split_whitespace() + let mut proc = Command::new(cmd); + proc.stdin(Stdio::piped()); + proc.stdout(Stdio::piped()); + proc.stderr(Stdio::piped()); + if let Some(a) = &self.conf.args { + proc.args(a.split_whitespace()); }; - let cwd = if let Some(c) = &self.conf.directory { - c - } else { - &PathBuf::from("/") + if let Some(c) = &self.conf.directory { + proc.current_dir(c); }; - let child = Command::new(cmd) - .args(args) - .current_dir(cwd) - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .spawn()?; + let child = proc.spawn()?; self.proc = Some(Arc::new(Mutex::new(child))); Ok(()) } @@ -217,7 +211,7 @@ impl Service { spawn(async move { let mut br = BufReader::new(stderr).lines(); while let Ok(Some(line)) = br.next_line().await { - println!("ERR :: {} :: {}", &sname, &line); + eprintln!("{} :: {}", &sname, &line); if let Err(_) = tx.send(line).await { return; }; @@ -247,6 +241,7 @@ impl Service { ))); }; stdin.write(&buf.as_bytes()).await?; + stdin.flush().await?; Ok(()) } else { Err(Box::new(std::io::Error::new( -- cgit 1.4.1-2-gfad0