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 * Extract command for working with the output of export
* Arch packages are now published to my bur repo * Arch packages are now published to my bur repo
* Allow passing configuration variables from TOML file
### Changed ### Changed

View File

@ -15,7 +15,7 @@ flate2 = "1.0.26"
chrono = { version = "0.4.26", features = ["serde"] } chrono = { version = "0.4.26", features = ["serde"] }
clap = { version = "4.3.1", features = ["derive", "env"] } clap = { version = "4.3.1", features = ["derive", "env"] }
signal-hook = "0.3.15" 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" serde_json = "1.0.96"
figment = { version = "0.10.10", features = ["env", "toml"] } figment = { version = "0.10.10", features = ["env", "toml"] }

View File

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

View File

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

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::server;
use crate::signals; use crate::signals;
use crate::stdin; use crate::stdin;
use clap::Args; use clap::Args;
use std::io; use config::Config;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use serde::{Deserialize, Serialize};
#[derive(Args)] #[derive(Args)]
pub struct RunArgs { pub struct RunCli {
/// Server jar to execute #[command(flatten)]
#[arg( pub args: RunArgs,
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,
/// Don't actually run the server, but simply output the server configuration that would have /// Don't actually run the server, but simply output the server configuration that would have
/// been ran /// been ran
@ -35,6 +21,29 @@ pub struct RunArgs {
pub dry: bool, 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>>) { fn backups_thread(counter: Arc<Mutex<server::ServerProcess>>) {
loop { loop {
let next_scheduled_time = { let next_scheduled_time = {
@ -56,19 +65,22 @@ fn backups_thread(counter: Arc<Mutex<server::ServerProcess>>) {
} }
} }
impl RunArgs { impl RunCli {
pub fn run(&self, config: &super::Config) -> crate::Result<()> { 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 signals) = signals::install_signal_handlers()?;
let mut cmd = server::ServerCommand::new(config.server, &config.server_version) let mut cmd = server::ServerCommand::new(global.server, &global.server_version)
.java(&self.java) .java(&config.java)
.jar(self.jar.clone()) .jar(config.jar.clone())
.config(config.config.clone()) .config(global.config.clone())
.world(config.world.clone()) .world(global.world.clone())
.backup(config.backup.clone()) .backup(global.backup.clone())
.managers(config.layers.clone()) .managers(global.layers.clone())
.xms(self.xms) .xms(config.xms)
.xmx(self.xmx); .xmx(config.xmx);
cmd.canonicalize()?; cmd.canonicalize()?;
if self.dry { if self.dry {
@ -79,7 +91,7 @@ impl RunArgs {
let counter = Arc::new(Mutex::new(cmd.spawn()?)); let counter = Arc::new(Mutex::new(cmd.spawn()?));
if !config.layers.is_empty() { if !global.layers.is_empty() {
let clone = Arc::clone(&counter); let clone = Arc::clone(&counter);
std::thread::spawn(move || backups_thread(clone)); std::thread::spawn(move || backups_thread(clone));
} }