add setState command, detect crashed/stopped servers periodically

This commit is contained in:
2026-06-12 00:01:23 +02:00
parent 0bbb8b3245
commit 5125aed0da
4 changed files with 54 additions and 2 deletions

View File

@ -4,6 +4,7 @@ pub mod remove;
pub mod ls;
pub mod start;
pub mod stop;
pub mod set_state;
pub mod env_settings;

33
src/cli/set_state.rs Normal file
View File

@ -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::<String>("NAME").unwrap();
let wanted_state = match arguments.get_one::<String>("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(())
}

View File

@ -6,7 +6,7 @@
/* By: tomoron <tomoron@student.42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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?; },

View File

@ -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);
},
}
}