diff --git a/src/cli/archive.rs b/src/cli/archive.rs index c38f4bd..995d054 100644 --- a/src/cli/archive.rs +++ b/src/cli/archive.rs @@ -4,15 +4,12 @@ use clap::{Command, ArgMatches}; use diesel::{SelectableHelper}; use diesel::result::Error::NotFound; -use crate::models::Servers; use crate::status::ServerStatus; use crate::{DbPool, schema, models}; use diesel::prelude::*; -use crate::srvmgr; - -use async_process; +use crate::srvmgr::{self, archive_server}; pub fn create_subcommand() -> Command { Command::new("archive") @@ -48,22 +45,3 @@ pub async fn subcommand(arguments: &ArgMatches, pool: &DbPool, docker: &Docker) Ok(()) } -pub async fn archive_server(server: &Servers, pool: &DbPool) -> Result<(), String> { - use schema::servers::dsl::*; - let conn = &mut pool.get().unwrap(); - - let config = crate::Config::load(); - - diesel::update(servers).filter(name.eq(&server.name)).set(status.eq(ServerStatus::Archiving)).execute(conn).map_err(|e| format!("Failed to set the server as archiving :{}", e))?; - - println!("Starting compression (this might take a while)"); - - let cmd = format!("cd {} && tar cf /dev/stdout {} | lrzip - -Q -o {}.tar.lrz", config.config_path, server.name, server.name); - - let _ = async_process::Command::new("sh").arg("-c").arg(cmd).output().await.map_err(|e| format!("compression failed : {}", e))?; - - std::fs::remove_dir_all(config.config_path.to_owned() + "/" + &server.name).map_err(|e| format!("Failed to delete server directory: {}", e))?; - - diesel::update(servers).filter(name.eq(&server.name)).set(status.eq(ServerStatus::Archived)).execute(conn).map_err(|e| format!("Failed to set the server as achived :{}", e))?; - Ok(()) -} diff --git a/src/minecraft/manager_loop.rs b/src/minecraft/manager_loop.rs index ecc83ff..bde588b 100644 --- a/src/minecraft/manager_loop.rs +++ b/src/minecraft/manager_loop.rs @@ -1,7 +1,7 @@ use bollard::Docker; use chrono::{TimeDelta, Utc}; -use crate::{ DbPool, cli::archive::archive_server, srvmgr, models::{self, Servers}, schema, status::ServerStatus }; +use crate::{ DbPool, models::{self, Servers}, schema, srvmgr::{self, archive_server}, status::ServerStatus }; use async_std::task; diff --git a/src/srvmgr/archive.rs b/src/srvmgr/archive.rs new file mode 100644 index 0000000..0536195 --- /dev/null +++ b/src/srvmgr/archive.rs @@ -0,0 +1,36 @@ +use crate::{ models::Servers, DbPool, schema, status::ServerStatus}; + +use diesel::prelude::*; + +pub async fn archive_server(server: &Servers, pool: &DbPool) -> Result<(), String> { + use schema::servers::dsl::*; + let conn = &mut pool.get().unwrap(); + + let config = crate::Config::load(); + + diesel::update(servers).filter(name.eq(&server.name)).set(status.eq(ServerStatus::Archiving)).execute(conn).map_err(|e| format!("Failed to set the server as archiving :{}", e))?; + + println!("Starting compression (this might take a while)"); + + let cmd = format!("cd {} && tar cf /dev/stdout {} | lrzip - -Q -o {}.tar.lrz", config.config_path, server.name, server.name); + + let _ = async_process::Command::new("sh").arg("-c").arg(cmd).output().await.map_err(|e| format!("compression failed : {}", e))?; + + std::fs::remove_dir_all(config.config_path.to_owned() + "/" + &server.name).map_err(|e| format!("Failed to delete server directory: {}", e))?; + + diesel::update(servers).filter(name.eq(&server.name)).set(status.eq(ServerStatus::Archived)).execute(conn).map_err(|e| format!("Failed to set the server as achived :{}", e))?; + Ok(()) +} + +pub async fn unarchive_server(server: &Servers) -> Result<(), String> { + let config = crate::Config::load(); + + println!("Starting decompression (this might take a while)"); + + let cmd = format!("cd {} && cat {}.tar.lrz | lrzip -d - | tar x", config.config_path, server.name); + + let _ = async_process::Command::new("sh").arg("-c").arg(cmd).output().await.map_err(|e| format!("decompression failed : {}", e))?; + + std::fs::remove_file(config.config_path + "/" + &server.name + ".tar.lrz").map_err(|e| format!("Failed to delete the archive of the server : {}", e))?; + Ok(()) +} diff --git a/src/srvmgr/mod.rs b/src/srvmgr/mod.rs index 275dfd5..477dff6 100644 --- a/src/srvmgr/mod.rs +++ b/src/srvmgr/mod.rs @@ -5,3 +5,6 @@ pub mod utils; mod stop; pub use stop::stop_server; + +mod archive; +pub use archive::archive_server; diff --git a/src/srvmgr/start.rs b/src/srvmgr/start.rs index f900ccb..4ce518f 100644 --- a/src/srvmgr/start.rs +++ b/src/srvmgr/start.rs @@ -1,7 +1,7 @@ use bollard::{Docker, plugin::{ContainerCreateBody, HostConfig, Mount, MountType}, query_parameters::CreateContainerOptionsBuilder}; use diesel::{prelude::*, result::Error::NotFound}; -use crate::{srvmgr::utils::get_image_tag, models, schema, status::ServerStatus}; +use crate::{models, schema, srvmgr::{archive::unarchive_server, utils::get_image_tag}, status::ServerStatus}; use crate::{DbPool, srvmgr::utils::{self, get_container_ip}}; @@ -75,12 +75,17 @@ pub async fn start_server(docker: &Docker, pool: &DbPool, server_name: &String) return Err("Server is starting, please wait".to_string()); } - if server.status != ServerStatus::Stopped { + if server.status != ServerStatus::Stopped && server.status != ServerStatus::Archived { return Err(format!("Invalid server state ({}), refusing to start", server.status)); } + diesel::update(servers).filter(name.eq(server_name)).set(status.eq(ServerStatus::Starting)).execute(conn).map_err(|e| format!("Failed to set server to starting : {}", e))?; + if server.status == ServerStatus::Archived { + unarchive_server(&server).await?; + } + let ip = start_docker_container(docker, server_name).await?; diesel::update(servers).filter(name.eq(server_name)).set((status.eq(ServerStatus::Running), redirect_ip.eq(ip.to_string() + ":25565"))).execute(conn).map_err(|e| format!("Failed to set server to starting : {}", e))?;