From a3e8d47785beda7ac5f7e86835f7617a77973dac Mon Sep 17 00:00:00 2001 From: Jack Baron Date: Thu, 30 Dec 2021 07:40:50 +0000 Subject: [PATCH 1/4] don't run checks on release CI --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 532f75c..08a68ab 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -60,6 +60,7 @@ jobs: checks: runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/') == false steps: - name: Checkout uses: actions/checkout@v2 From 370cec1a22d53e71423c5a7916247163683e8271 Mon Sep 17 00:00:00 2001 From: Jack Baron Date: Fri, 31 Dec 2021 10:08:14 +0000 Subject: [PATCH 2/4] add timeouts to graceful stop and restart --- Cargo.lock | 10 ++++++++ Cargo.toml | 1 + src/cmd_start_stop.rs | 53 +++++++++++++++++++++++++++++++++++-------- 3 files changed, 55 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9eb8dc5..a11951b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -786,6 +786,7 @@ dependencies = [ "toml", "tracing", "tracing-subscriber 0.3.4", + "wait-timeout", ] [[package]] @@ -1317,6 +1318,15 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + [[package]] name = "walkdir" version = "0.1.8" diff --git a/Cargo.toml b/Cargo.toml index 549d671..ed6e08a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ thiserror = "1.0.30" toml = "0.5.8" tracing = "0.1.29" tracing-subscriber = { version = "0.3.4", features = ["env-filter"] } +wait-timeout = "0.2.0" [profile.release] opt-level = 3 diff --git a/src/cmd_start_stop.rs b/src/cmd_start_stop.rs index 210d083..fabd204 100644 --- a/src/cmd_start_stop.rs +++ b/src/cmd_start_stop.rs @@ -1,6 +1,10 @@ +use std::process::Command; +use std::time::Duration; + use cmd_lib::run_cmd; use color_eyre::Result; -use tracing::{error, info}; +use tracing::{error, info, warn}; +use wait_timeout::ChildExt; use crate::config::{GlobalArgs, StartArgs}; use crate::utils::{self, ServerMemory}; @@ -103,11 +107,25 @@ pub fn stop(global_args: GlobalArgs) -> Result<()> { continue; } - // TODO: Forcefully exit after N seconds + // Wait for server to shut down let exit_handle = format!("{}_exit", &name); - if run_cmd!(tmux wait $exit_handle).is_err() { - error!("failed to stop \"{}\"", &name); - continue; + let mut child = match Command::new("tmux").arg("wait").arg(exit_handle).spawn() { + Ok(child) => child, + Err(_) => { + error!("failed to stop \"{}\"", &name); + continue; + } + }; + + // After N seconds, timeout and kill anyway + match child.wait_timeout(Duration::from_secs(5)) { + Err(_) => { + error!("failed to stop \"{}\"", &name); + continue; + } + + Ok(None) => warn!("reached wait timeout, forcefully killing: {}", &name), + _ => (), } if run_cmd!(tmux kill-session -t $name).is_err() { @@ -138,11 +156,28 @@ pub fn restart(global_args: GlobalArgs, args: StartArgs) -> Result<()> { continue; } - // Wait for server to shutdown + // Wait for server to shut down let exit_handle = format!("{}_exit", &name); - if run_cmd!(tmux wait $exit_handle).is_err() { - error!("failed to restart \"{}\"", &name); - continue; + let mut child = match Command::new("tmux").arg("wait").arg(exit_handle).spawn() { + Ok(child) => child, + Err(_) => { + error!("failed to stop \"{}\"", &name); + continue; + } + }; + + // After N seconds, timeout and restart anyway + match child.wait_timeout(Duration::from_secs(5)) { + Err(_) => { + error!("failed to stop \"{}\"", &name); + continue; + } + + Ok(None) => { + warn!("reached wait timeout, forcefully restarting: {}", &name); + warn!("please manually check that the restart was successful"); + } + _ => (), } let run = format!( From 9cbc2ac7e6098c820e6b80b7fd94d9a2c11dc10c Mon Sep 17 00:00:00 2001 From: Jack Baron Date: Fri, 31 Dec 2021 10:13:03 +0000 Subject: [PATCH 3/4] configure wait timeout from cli flags --- src/cmd_start_stop.rs | 6 ++++-- src/config.rs | 3 +++ src/main.rs | 4 ++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/cmd_start_stop.rs b/src/cmd_start_stop.rs index fabd204..f4596c0 100644 --- a/src/cmd_start_stop.rs +++ b/src/cmd_start_stop.rs @@ -118,7 +118,8 @@ pub fn stop(global_args: GlobalArgs) -> Result<()> { }; // After N seconds, timeout and kill anyway - match child.wait_timeout(Duration::from_secs(5)) { + let wait_duration = Duration::from_secs(global_args.timeout_secs as u64); + match child.wait_timeout(wait_duration) { Err(_) => { error!("failed to stop \"{}\"", &name); continue; @@ -167,7 +168,8 @@ pub fn restart(global_args: GlobalArgs, args: StartArgs) -> Result<()> { }; // After N seconds, timeout and restart anyway - match child.wait_timeout(Duration::from_secs(5)) { + let wait_duration = Duration::from_secs(global_args.timeout_secs as u64); + match child.wait_timeout(wait_duration) { Err(_) => { error!("failed to stop \"{}\"", &name); continue; diff --git a/src/config.rs b/src/config.rs index 08f2b8c..2d18e3b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -20,6 +20,7 @@ pub struct GlobalConfig { server_count: Option, start_port: Option, directory_template: Option, + timeout_secs: Option, } #[derive(Debug, Default, Deserialize)] @@ -61,6 +62,7 @@ pub struct GlobalArgs { pub server_count: u8, pub start_port: u16, pub directory_template: String, + pub timeout_secs: u8, } pub fn global_args(config: GlobalConfig, args: Args) -> GlobalArgs { @@ -71,6 +73,7 @@ pub fn global_args(config: GlobalConfig, args: Args) -> GlobalArgs { .directory_template .or(config.directory_template) .unwrap_or_else(|| "Mammoth Server".into()), + timeout_secs: args.timeout_secs.or(config.timeout_secs).unwrap_or(10), } } diff --git a/src/main.rs b/src/main.rs index 74a67e6..34af897 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,6 +28,10 @@ pub struct Args { #[clap(short, long, value_hint = ValueHint::Other)] directory_template: Option, + /// Graceful stop / restart timeout seconds [default: 10] + #[clap(short, long, value_hint = ValueHint::Other)] + timeout_secs: Option, + #[clap(subcommand)] command: Command, } From b75ade98e570a039068575f1562b447d209541d5 Mon Sep 17 00:00:00 2001 From: Jack Baron Date: Fri, 31 Dec 2021 10:19:59 +0000 Subject: [PATCH 4/4] v0.5.1 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a11951b..cbdac72 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -770,7 +770,7 @@ dependencies = [ [[package]] name = "provisioner" -version = "0.5.0" +version = "0.5.1" dependencies = [ "bytes", "clap", diff --git a/Cargo.toml b/Cargo.toml index ed6e08a..e6387cf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "provisioner" -version = "0.5.0" +version = "0.5.1" edition = "2021" description = "Provision Mammoth-ready Minecraft clusters with ease!"