feat: also allow run args to be passed from toml file

main
Jef Roosens 2023-08-11 23:13:17 +02:00
parent 34d016fd3f
commit db3bba5a42
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
6 changed files with 99 additions and 57 deletions

View File

@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Extract command for working with the output of export
* Arch packages are now published to my bur repo
* Allow passing configuration variables from TOML file
### Changed

View File

@ -15,7 +15,7 @@ flate2 = "1.0.26"
chrono = { version = "0.4.26", features = ["serde"] }
clap = { version = "4.3.1", features = ["derive", "env"] }
signal-hook = "0.3.15"
serde = { version = "1.0.164", features = ["derive", "rc"] }
serde = { version = "1.0.164", features = ["derive"] }
serde_json = "1.0.96"
figment = { version = "0.10.10", features = ["env", "toml"] }

View File

@ -3,14 +3,14 @@ world = "data/worlds"
backup = "data/backups"
server = "Paper"
[[layers]]
name = "2min"
frequency = 2
chains = 4
chain_len = 4
# [[layers]]
# name = "2min"
# frequency = 2
# chains = 4
# chain_len = 4
[[layers]]
name = "3min"
frequency = 3
chains = 2
chain_len = 2
# [[layers]]
# name = "3min"
# frequency = 3
# chains = 2
# chain_len = 2

View File

@ -5,7 +5,7 @@ mod run;
pub use crate::backup::MetaManager;
pub use crate::server::Metadata;
pub use backup::{BackupArgs, BackupCommands};
pub use run::RunArgs;
pub use run::RunCli;
use crate::backup::ManagerConfig;
use crate::server::ServerType;
@ -16,13 +16,12 @@ use figment::{
Figment,
};
use serde::{Deserialize, Serialize};
use std::io;
use std::path::PathBuf;
#[derive(Subcommand)]
pub enum Commands {
/// Run the server
Run(RunArgs),
Run(RunCli),
/// Interact with the backup system without starting a server
Backup(BackupArgs),
}
@ -78,20 +77,28 @@ pub struct Cli {
impl Cli {
pub fn run(&self) -> crate::Result<()> {
let config = self.config(&self.args)?;
match &self.command {
Commands::Run(args) => args.run(self, &config),
Commands::Backup(args) => Ok(args.run(&config)?),
}
}
pub fn config<T, U>(&self, args: &U) -> Result<T, figment::Error>
where
T: Default + Serialize + for<'de> Deserialize<'de>,
U: Serialize,
{
let toml_file = self
.config_file
.clone()
.unwrap_or(PathBuf::from(Env::var_or("ALEX_CONFIG_FILE", "")));
let config: Config = Figment::new()
.merge(Serialized::defaults(Config::default()))
Figment::new()
.merge(Serialized::defaults(T::default()))
.merge(Toml::file(toml_file))
.merge(Env::prefixed("ALEX_"))
.merge(Serialized::defaults(&self.args))
.extract()?;
match &self.command {
Commands::Run(args) => args.run(&config),
Commands::Backup(args) => Ok(args.run(&config)?),
}
.merge(Serialized::defaults(args))
.extract()
}
}

View File

@ -0,0 +1,22 @@
use std::path::PathBuf;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
pub struct Config {
pub jar: PathBuf,
pub java: String,
pub xms: u64,
pub xmx: u64,
}
impl Default for Config {
fn default() -> Self {
Self {
jar: PathBuf::from("server.jar"),
java: String::from("java"),
xms: 1024,
xmx: 2048,
}
}
}

View File

@ -1,33 +1,19 @@
use crate::cli::Cli;
mod config;
use crate::server;
use crate::signals;
use crate::stdin;
use clap::Args;
use std::io;
use config::Config;
use std::path::PathBuf;
use std::sync::{Arc, Mutex};
use serde::{Deserialize, Serialize};
#[derive(Args)]
pub struct RunArgs {
/// Server jar to execute
#[arg(
long,
value_name = "JAR_PATH",
default_value = "server.jar",
env = "ALEX_JAR"
)]
pub jar: PathBuf,
/// Java command to run the server jar with
#[arg(long, value_name = "JAVA_CMD", default_value_t = String::from("java"), env = "ALEX_JAVA")]
pub java: String,
/// XMS value in megabytes for the server instance
#[arg(long, default_value_t = 1024, env = "ALEX_XMS")]
pub xms: u64,
/// XMX value in megabytes for the server instance
#[arg(long, default_value_t = 2048, env = "ALEX_XMX")]
pub xmx: u64,
pub struct RunCli {
#[command(flatten)]
pub args: RunArgs,
/// Don't actually run the server, but simply output the server configuration that would have
/// been ran
@ -35,6 +21,29 @@ pub struct RunArgs {
pub dry: bool,
}
#[derive(Args, Serialize, Deserialize, Clone)]
pub struct RunArgs {
/// Server jar to execute
#[arg(long, value_name = "JAR_PATH")]
#[serde(skip_serializing_if = "::std::option::Option::is_none")]
pub jar: Option<PathBuf>,
/// Java command to run the server jar with
#[arg(long, value_name = "JAVA_CMD")]
#[serde(skip_serializing_if = "::std::option::Option::is_none")]
pub java: Option<String>,
/// XMS value in megabytes for the server instance
#[arg(long)]
#[serde(skip_serializing_if = "::std::option::Option::is_none")]
pub xms: Option<u64>,
/// XMX value in megabytes for the server instance
#[arg(long)]
#[serde(skip_serializing_if = "::std::option::Option::is_none")]
pub xmx: Option<u64>,
}
fn backups_thread(counter: Arc<Mutex<server::ServerProcess>>) {
loop {
let next_scheduled_time = {
@ -56,19 +65,22 @@ fn backups_thread(counter: Arc<Mutex<server::ServerProcess>>) {
}
}
impl RunArgs {
pub fn run(&self, config: &super::Config) -> crate::Result<()> {
impl RunCli {
pub fn run(&self, cli: &super::Cli, global: &super::Config) -> crate::Result<()> {
let config: Config = cli.config(&self.args)?;
println!("{:?}", config);
let (_, mut signals) = signals::install_signal_handlers()?;
let mut cmd = server::ServerCommand::new(config.server, &config.server_version)
.java(&self.java)
.jar(self.jar.clone())
.config(config.config.clone())
.world(config.world.clone())
.backup(config.backup.clone())
.managers(config.layers.clone())
.xms(self.xms)
.xmx(self.xmx);
let mut cmd = server::ServerCommand::new(global.server, &global.server_version)
.java(&config.java)
.jar(config.jar.clone())
.config(global.config.clone())
.world(global.world.clone())
.backup(global.backup.clone())
.managers(global.layers.clone())
.xms(config.xms)
.xmx(config.xmx);
cmd.canonicalize()?;
if self.dry {
@ -79,7 +91,7 @@ impl RunArgs {
let counter = Arc::new(Mutex::new(cmd.spawn()?));
if !config.layers.is_empty() {
if !global.layers.is_empty() {
let clone = Arc::clone(&counter);
std::thread::spawn(move || backups_thread(clone));
}