supports space-separated service names in start, stop, restart, enable, disable commands. each service result returned on its own line.
182 lines
4.6 KiB
Rust
182 lines
4.6 KiB
Rust
mod cli;
|
|
mod config;
|
|
mod daemon;
|
|
mod ipc;
|
|
mod log;
|
|
mod state;
|
|
mod supervisor;
|
|
|
|
use clap::Parser;
|
|
use cli::{Cli, Commands};
|
|
|
|
|
|
fn main() {
|
|
let cli = Cli::parse();
|
|
|
|
match cli.command {
|
|
Commands::Daemon => {
|
|
let config_path = resolve_config_path(cli.config.as_deref());
|
|
daemon::run(config_path);
|
|
}
|
|
Commands::Start { ref names } => cmd_start(names),
|
|
Commands::Stop { ref names } => cmd_stop(names),
|
|
Commands::Restart { ref names } => cmd_restart(names),
|
|
Commands::Status { ref name } => cmd_status(name.as_deref()),
|
|
Commands::List => cmd_list(),
|
|
Commands::Logs { ref name, lines, follow } => cmd_logs(name, lines, follow),
|
|
Commands::Enable { ref names, now } => cmd_enable(names, now),
|
|
Commands::Disable { ref names } => cmd_disable(names),
|
|
Commands::Supervise { .. } => {
|
|
eprintln!("error: supervise is internal, use daemon");
|
|
std::process::exit(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn resolve_config_path(custom: Option<&str>) -> String {
|
|
if let Some(path) = custom {
|
|
return path.to_string();
|
|
}
|
|
if let Ok(path) = std::env::var("RSS_CONFIG") {
|
|
return path;
|
|
}
|
|
state::config_dir().join("config.toml").to_string_lossy().to_string()
|
|
}
|
|
|
|
fn cmd_start(names: &[String]) {
|
|
let cmd = format!("start {}", names.join(" "));
|
|
match ipc::send_cmd(&cmd) {
|
|
Ok(lines) => {
|
|
for line in lines {
|
|
println!("{}", line);
|
|
}
|
|
}
|
|
Err(e) => {
|
|
eprintln!("error: {}", e);
|
|
std::process::exit(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn cmd_stop(names: &[String]) {
|
|
let cmd = format!("stop {}", names.join(" "));
|
|
match ipc::send_cmd(&cmd) {
|
|
Ok(lines) => {
|
|
for line in lines {
|
|
println!("{}", line);
|
|
}
|
|
}
|
|
Err(e) => {
|
|
eprintln!("error: {}", e);
|
|
std::process::exit(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn cmd_restart(names: &[String]) {
|
|
let cmd = format!("restart {}", names.join(" "));
|
|
match ipc::send_cmd(&cmd) {
|
|
Ok(lines) => {
|
|
for line in lines {
|
|
println!("{}", line);
|
|
}
|
|
}
|
|
Err(e) => {
|
|
eprintln!("error: {}", e);
|
|
std::process::exit(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn cmd_status(name: Option<&str>) {
|
|
let cmd = match name {
|
|
Some(n) => format!("status {}", n),
|
|
None => "status".to_string(),
|
|
};
|
|
match ipc::send_cmd(&cmd) {
|
|
Ok(lines) => {
|
|
for line in lines {
|
|
println!("{}", line);
|
|
}
|
|
}
|
|
Err(e) => {
|
|
eprintln!("error: {}", e);
|
|
std::process::exit(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn cmd_list() {
|
|
match ipc::send_cmd("list") {
|
|
Ok(lines) => {
|
|
if lines.is_empty() {
|
|
println!("no services configured");
|
|
return;
|
|
}
|
|
for line in &lines {
|
|
let parts: Vec<&str> = line.splitn(4, ' ').collect();
|
|
if parts.len() >= 4 {
|
|
println!("{:<12} {:<7} {:>6} {}", parts[0], parts[1], parts[2], parts[3]);
|
|
} else {
|
|
println!("{}", line);
|
|
}
|
|
}
|
|
}
|
|
Err(e) => {
|
|
eprintln!("error: {}", e);
|
|
std::process::exit(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn cmd_logs(name: &str, mut lines: Option<usize>, follow: bool) {
|
|
if lines.is_none() && follow {
|
|
lines = Some(10);
|
|
}
|
|
|
|
let log_path = state::log_path(name);
|
|
|
|
if !log_path.exists() {
|
|
eprintln!("error: no logs for '{}'", name);
|
|
std::process::exit(1);
|
|
}
|
|
|
|
if let Err(e) = log::show_logs(log_path.to_str().unwrap_or(""), lines, follow) {
|
|
eprintln!("error: reading logs: {}", e);
|
|
std::process::exit(1);
|
|
}
|
|
}
|
|
|
|
fn cmd_enable(names: &[String], now: bool) {
|
|
let cmd = if now {
|
|
format!("enable {} now", names.join(" "))
|
|
} else {
|
|
format!("enable {}", names.join(" "))
|
|
};
|
|
match ipc::send_cmd(&cmd) {
|
|
Ok(lines) => {
|
|
for line in lines {
|
|
println!("{}", line);
|
|
}
|
|
}
|
|
Err(e) => {
|
|
eprintln!("error: {}", e);
|
|
std::process::exit(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn cmd_disable(names: &[String]) {
|
|
let cmd = format!("disable {}", names.join(" "));
|
|
match ipc::send_cmd(&cmd) {
|
|
Ok(lines) => {
|
|
for line in lines {
|
|
println!("{}", line);
|
|
}
|
|
}
|
|
Err(e) => {
|
|
eprintln!("error: {}", e);
|
|
std::process::exit(1);
|
|
}
|
|
}
|
|
}
|