diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 65063f9..e0e6e07 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -4,6 +4,7 @@ pub mod remove; pub mod ls; pub mod start; pub mod stop; +pub mod set_state; pub mod env_settings; diff --git a/src/cli/set_state.rs b/src/cli/set_state.rs new file mode 100644 index 0000000..15c85e0 --- /dev/null +++ b/src/cli/set_state.rs @@ -0,0 +1,33 @@ +use clap::Arg; +use clap::ArgMatches; +use clap::Command; + +use diesel::prelude::*; +use crate::DbPool; +use crate::schema; +use crate::status::ServerStatus; + +pub fn create_subcommand() -> Command { + Command::new("setState") + .about("force the known state of a server (will not change the actual state)") + .arg(Arg::new("NAME").required(true)) + .arg(Arg::new("STATE").required(true)) +} + +pub async fn subcommand(arguments: &ArgMatches, pool: DbPool) -> Result<(), String> { + use schema::servers::dsl::*; + + + let server_name = arguments.get_one::("NAME").unwrap(); + let wanted_state = match arguments.get_one::("STATE").unwrap().as_str() { + "stopped" => {ServerStatus::Stopped}, + "running" => {ServerStatus::Running}, + _ => { return Err("invalid state, must be `stoppped` or `running`".to_string()) } + }; + + let conn = &mut pool.get().unwrap(); + + diesel::update(servers).filter(name.eq(server_name)).set(status.eq(wanted_state)).execute(conn).map_err(|e| format!("Failed to set the server to the wanted state : {}", e))?; + + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index 26a4022..1229985 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/05/29 21:22:17 by tomoron #+# #+# */ -/* Updated: 2026/06/10 13:16:50 by tomoron ### ########.fr */ +/* Updated: 2026/06/11 23:41:49 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -60,6 +60,7 @@ fn cli() -> Command { .subcommand(remove::create_subcommand()) .subcommand(edit::create_subcommand()) .subcommand(ls::create_subcommand()) + .subcommand(set_state::create_subcommand()) .subcommand(start::create_subcommand()) .subcommand(stop::create_subcommand()) } @@ -79,6 +80,7 @@ async fn main() -> Result<(), String> { Some(("remove", sub_matches)) => { remove::subcommand(sub_matches, &pool, &docker).await?; }, Some(("ls", sub_matches)) => { ls::subcommand(sub_matches, pool).await?; }, Some(("edit", sub_matches)) => { edit::subcommand(sub_matches, pool).await?; }, + Some(("setState", sub_matches)) => { set_state::subcommand(sub_matches, pool).await? } Some(("start", sub_matches)) => { start::subcommand(sub_matches, &pool, &docker).await?; }, Some(("stop", sub_matches)) => { stop::subcommand(sub_matches, &pool, &docker).await?; }, diff --git a/src/minecraft/manager_loop.rs b/src/minecraft/manager_loop.rs index 4f5576b..94e7eb9 100644 --- a/src/minecraft/manager_loop.rs +++ b/src/minecraft/manager_loop.rs @@ -63,8 +63,9 @@ pub async fn server_manager_loop(pool: DbPool, docker: Docker) for srv in a_servers { let time_diff = Utc::now().naive_utc() - srv.last_login.unwrap(); should_stop(&docker, &pool, &time_diff, &srv).await; + check_still_online(&docker, &pool, &srv).await; } - task::sleep(Duration::from_secs(5)).await; + task::sleep(Duration::from_secs(30)).await; } } @@ -77,3 +78,18 @@ async fn should_stop(docker: &Docker, pool: &DbPool, diff: &TimeDelta, srv: &Ser println!("{} stopped", srv.name); } } + +async fn check_still_online(docker: &Docker, pool: &DbPool, srv: &Servers) { + use schema::servers::dsl::*; + + if srv.status != ServerStatus::Running { return ; } + + match docker.inspect_container(&format!("minecraft-{}", srv.name), None).await { + Ok(_) => {}, + Err(_) => { + println!("Failed to find minecraft-{} container, setting it as Stopped", srv.name); + let conn = &mut pool.get().unwrap(); + let _ = diesel::update(servers).filter(name.eq(&srv.name)).set(status.eq(ServerStatus::Stopped)).execute(conn); + }, + } +}