Compare commits

...

3 Commits

Author SHA1 Message Date
Jef Roosens ce3dcdd4b1
chore: please clippy
ci/woodpecker/push/build unknown status Details
ci/woodpecker/push/clippy unknown status Details
ci/woodpecker/push/lint unknown status Details
ci/woodpecker/push/release Pipeline was successful Details
2023-06-13 13:01:47 +02:00
Jef Roosens 5ae23c931a
feat: change jvm flags order 2023-06-13 13:00:42 +02:00
Jef Roosens b08ba3853f
feat: add --dry flag 2023-06-13 12:53:50 +02:00
4 changed files with 92 additions and 27 deletions

View File

@ -7,6 +7,14 @@ 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
### 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

View File

@ -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

View File

@ -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<Mutex<server::ServerProcess>>, 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 {

View File

@ -105,14 +105,19 @@ impl ServerCommand {
Ok(())
}
pub fn spawn(self) -> std::io::Result<ServerProcess> {
/// 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
@ -126,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 {
@ -143,36 +139,84 @@ 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.current_dir(&config_dir)
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(&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<ServerProcess> {
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();
writeln!(f, "Command: {}", self.java)?;
writeln!(f, "Working dir: {}", self.config_dir.as_path().display())?;
// Print command env vars
writeln!(f, "Environment:")?;
for (key, val) in cmd.get_envs().filter(|(_, v)| v.is_some()) {
let val = val.unwrap();
writeln!(f, " {}={}", key.to_string_lossy(), val.to_string_lossy())?;
}
// Print command arguments
writeln!(f, "Arguments:")?;
for arg in cmd.get_args() {
writeln!(f, " {}", arg.to_string_lossy())?;
}
Ok(())
}
}