alex/src/main.rs

99 lines
2.5 KiB
Rust

mod backup;
mod cli;
mod server;
mod signals;
mod stdin;
use clap::Parser;
use cli::{BackupArgs, Cli, Commands, RunArgs};
use std::io;
use std::sync::{Arc, Mutex};
fn backups_thread(counter: Arc<Mutex<server::ServerProcess>>) {
loop {
let next_scheduled_time = {
let server = counter.lock().unwrap();
server.backups.next_scheduled_time()
};
let now = chrono::offset::Utc::now();
if next_scheduled_time > now {
std::thread::sleep((next_scheduled_time - now).to_std().unwrap());
}
{
let mut server = counter.lock().unwrap();
// We explicitely ignore the error here, as we don't want the thread to fail
let _ = server.backup();
}
}
}
fn command_run(cli: &Cli, args: &RunArgs) -> io::Result<()> {
let (_, mut signals) = signals::install_signal_handlers()?;
let mut cmd = server::ServerCommand::new(cli.server, &cli.server_version)
.java(&args.java)
.jar(args.jar.clone())
.config(cli.config.clone())
.world(cli.world.clone())
.backup(cli.backup.clone())
.xms(args.xms)
.xmx(args.xmx)
.chain_len(cli.chain_len)
.chains_to_keep(cli.chains)
.frequency(cli.frequency);
cmd.canonicalize()?;
if args.dry {
print!("{}", cmd);
return Ok(());
}
let counter = Arc::new(Mutex::new(cmd.spawn()?));
if cli.frequency > 0 {
let clone = Arc::clone(&counter);
std::thread::spawn(move || backups_thread(clone));
}
// Spawn thread that handles the main stdin loop
let clone = Arc::clone(&counter);
std::thread::spawn(move || stdin::handle_stdin(clone));
// Signal handler loop exits the process when necessary
signals::handle_signals(&mut signals, counter)
}
fn commands_backup(cli: &Cli, _args: &BackupArgs) -> io::Result<()> {
let metadata = server::Metadata {
server_type: cli.server,
server_version: cli.server_version.clone(),
};
let mut manager = backup::Manager::new(
cli.backup.clone(),
cli.config.clone(),
cli.world.clone(),
metadata,
cli.chain_len,
cli.chains,
chrono::Duration::minutes(cli.frequency.into()),
);
manager.load()?;
manager.create_backup()?;
manager.remove_old_backups()
}
fn main() -> io::Result<()> {
let cli = Cli::parse();
match &cli.command {
Commands::Run(args) => command_run(&cli, args),
Commands::Backup(args) => commands_backup(&cli, args),
}
}