From b08ba3853fa3ad1bc98e197e269599e8f2861e76 Mon Sep 17 00:00:00 2001 From: Chewing_Bever Date: Tue, 13 Jun 2023 12:49:31 +0200 Subject: [PATCH 1/3] feat: add --dry flag --- CHANGELOG.md | 4 +++ Dockerfile | 2 +- src/main.rs | 15 ++++++++++- src/server/command.rs | 63 ++++++++++++++++++++++++++++++++++--------- 4 files changed, 69 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3160ee1..9124e7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased](https://git.rustybever.be/Chewing_Bever/alex/src/branch/dev) +### Added + +* `--dry` flag to inspect command that will be run + ## [0.2.0](https://git.rustybever.be/Chewing_Bever/alex/src/tag/0.2.0) ### Added diff --git a/Dockerfile b/Dockerfile index cb3b9e0..d754728 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,7 +18,7 @@ RUN cargo build && \ # We use ${:-} instead of a default value because the argument is always passed # to the build, it'll just be blank most likely -FROM eclipse-temurin:17-jre-alpine +FROM eclipse-temurin:18-jre-alpine # Build arguments ARG MC_VERSION=1.19.4 diff --git a/src/main.rs b/src/main.rs index 9f993a9..10500b3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -66,6 +66,11 @@ struct Cli { /// How frequently to perform a backup, in minutes; 0 to disable. #[arg(short = 't', long, default_value_t = 0, env = "ALEX_FREQUENCY")] frequency: u64, + + /// Don't actually run the server, but simply output the server configuration that would have + /// been ran + #[arg(short, long, default_value_t = false)] + dry: bool, } fn backups_thread(counter: Arc>, frequency: u64) { @@ -85,7 +90,7 @@ fn main() -> io::Result<()> { let (_, mut signals) = signals::install_signal_handlers()?; let cli = Cli::parse(); - let cmd = server::ServerCommand::new(cli.type_, &cli.server_version) + let mut cmd = server::ServerCommand::new(cli.type_, &cli.server_version) .java(&cli.java) .jar(cli.jar) .config(cli.config) @@ -94,6 +99,14 @@ fn main() -> io::Result<()> { .xms(cli.xms) .xmx(cli.xmx) .max_backups(cli.max_backups); + cmd.canonicalize()?; + + if cli.dry { + print!("{}", cmd); + + return Ok(()); + } + let counter = Arc::new(Mutex::new(cmd.spawn()?)); if cli.frequency > 0 { diff --git a/src/server/command.rs b/src/server/command.rs index 7b6d948..f410c88 100644 --- a/src/server/command.rs +++ b/src/server/command.rs @@ -105,14 +105,19 @@ impl ServerCommand { Ok(()) } - pub fn spawn(self) -> std::io::Result { + /// Canonicalize all paths to absolute paths. Without this command, all paths will be + /// interpreted relatively from the config directory. + pub fn canonicalize(&mut self) -> std::io::Result<()> { // To avoid any issues, we use absolute paths for everything when spawning the process - let jar = self.jar.canonicalize()?; - let config_dir = self.config_dir.canonicalize()?; - let world_dir = self.world_dir.canonicalize()?; - let backup_dir = self.backup_dir.canonicalize()?; + self.jar = self.jar.canonicalize()?; + self.config_dir = self.config_dir.canonicalize()?; + self.world_dir = self.world_dir.canonicalize()?; + self.backup_dir = self.backup_dir.canonicalize()?; - self.accept_eula()?; + Ok(()) + } + + fn create_cmd(&self) -> std::process::Command { let mut cmd = Command::new(&self.java); // Apply JVM optimisation flags @@ -155,24 +160,56 @@ impl ServerCommand { ]); } - cmd.current_dir(&config_dir) + cmd.current_dir(&self.config_dir) .arg("-jar") - .arg(&jar) + .arg(&self.jar) .arg("--universe") - .arg(&world_dir) + .arg(&self.world_dir) .arg("--nogui") .stdin(Stdio::piped()); + cmd + } + + pub fn spawn(&mut self) -> std::io::Result { + let mut cmd = self.create_cmd(); + self.accept_eula()?; let child = cmd.spawn()?; Ok(ServerProcess::new( self.type_, - self.version, - config_dir, - world_dir, - backup_dir, + self.version.clone(), + self.config_dir.clone(), + self.world_dir.clone(), + self.backup_dir.clone(), self.max_backups, child, )) } } + +impl fmt::Display for ServerCommand { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let cmd = self.create_cmd(); + + write!(f, "Command: {}\n", self.java)?; + write!(f, "Working dir: {}\n", self.config_dir.as_path().display())?; + + // Print command env vars + write!(f, "Environment:\n")?; + + for (key, val) in cmd.get_envs().filter(|(_, v)| v.is_some()) { + let val = val.unwrap(); + write!(f, " {}={}\n", key.to_string_lossy(), val.to_string_lossy())?; + } + + // Print command arguments + write!(f, "Arguments:\n")?; + + for arg in cmd.get_args() { + write!(f, " {}\n", arg.to_string_lossy())?; + } + + Ok(()) + } +} From 5ae23c931a607e4f48f9eb1230656e6ad9b98a85 Mon Sep 17 00:00:00 2001 From: Chewing_Bever Date: Tue, 13 Jun 2023 13:00:42 +0200 Subject: [PATCH 2/3] feat: change jvm flags order --- CHANGELOG.md | 4 ++++ src/server/command.rs | 31 +++++++++++++++++++------------ 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9124e7c..2c02234 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * `--dry` flag to inspect command that will be run +### Changed + +* JVM flags now narrowely follow Aikar's specifications + ## [0.2.0](https://git.rustybever.be/Chewing_Bever/alex/src/tag/0.2.0) ### Added diff --git a/src/server/command.rs b/src/server/command.rs index f410c88..e725a38 100644 --- a/src/server/command.rs +++ b/src/server/command.rs @@ -131,15 +131,6 @@ impl ServerCommand { "-XX:+UnlockExperimentalVMOptions", "-XX:+DisableExplicitGC", "-XX:+AlwaysPreTouch", - "-XX:G1HeapWastePercent=5", - "-XX:G1MixedGCCountTarget=4", - "-XX:G1MixedGCLiveThresholdPercent=90", - "-XX:G1RSetUpdatingPauseTimePercent=5", - "-XX:SurvivorRatio=32", - "-XX:+PerfDisableSharedMem", - "-XX:MaxTenuringThreshold=1", - "-Dusing.aikars.flags=https://mcflags.emc.gs", - "-Daikars.new.flags=true", ]); if self.xms > 12 * 1024 { @@ -148,18 +139,34 @@ impl ServerCommand { "-XX:G1MaxNewSizePercent=50", "-XX:G1HeapRegionSize=16M", "-XX:G1ReservePercent=15", - "-XX:InitiatingHeapOccupancyPercent=20", ]); } else { cmd.args([ "-XX:G1NewSizePercent=30", "-XX:G1MaxNewSizePercent=40", "-XX:G1HeapRegionSize=8M", - "-XX:G1ReservePercent=15", - "-XX:InitiatingHeapOccupancyPercent=15", + "-XX:G1ReservePercent=20", ]); } + cmd.args(["-XX:G1HeapWastePercent=5", "-XX:G1MixedGCCountTarget=4"]); + + if self.xms > 12 * 1024 { + cmd.args(["-XX:InitiatingHeapOccupancyPercent=20"]); + } else { + cmd.args(["-XX:InitiatingHeapOccupancyPercent=15"]); + } + + cmd.args([ + "-XX:G1MixedGCLiveThresholdPercent=90", + "-XX:G1RSetUpdatingPauseTimePercent=5", + "-XX:SurvivorRatio=32", + "-XX:+PerfDisableSharedMem", + "-XX:MaxTenuringThreshold=1", + "-Dusing.aikars.flags=https://mcflags.emc.gs", + "-Daikars.new.flags=true", + ]); + cmd.current_dir(&self.config_dir) .arg("-jar") .arg(&self.jar) From ce3dcdd4b1e49d64938e9154457cc8a8f96845e7 Mon Sep 17 00:00:00 2001 From: Chewing_Bever Date: Tue, 13 Jun 2023 13:01:47 +0200 Subject: [PATCH 3/3] chore: please clippy --- src/server/command.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/server/command.rs b/src/server/command.rs index e725a38..641c6b8 100644 --- a/src/server/command.rs +++ b/src/server/command.rs @@ -199,22 +199,22 @@ impl fmt::Display for ServerCommand { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let cmd = self.create_cmd(); - write!(f, "Command: {}\n", self.java)?; - write!(f, "Working dir: {}\n", self.config_dir.as_path().display())?; + writeln!(f, "Command: {}", self.java)?; + writeln!(f, "Working dir: {}", self.config_dir.as_path().display())?; // Print command env vars - write!(f, "Environment:\n")?; + writeln!(f, "Environment:")?; for (key, val) in cmd.get_envs().filter(|(_, v)| v.is_some()) { let val = val.unwrap(); - write!(f, " {}={}\n", key.to_string_lossy(), val.to_string_lossy())?; + writeln!(f, " {}={}", key.to_string_lossy(), val.to_string_lossy())?; } // Print command arguments - write!(f, "Arguments:\n")?; + writeln!(f, "Arguments:")?; for arg in cmd.get_args() { - write!(f, " {}\n", arg.to_string_lossy())?; + writeln!(f, " {}", arg.to_string_lossy())?; } Ok(())