Compare commits
No commits in common. "03e21fda87c9368ed1aaabca93acbeeed65ffb4d" and "0a459ee30b840fbc08ab85c1f04e04c7351c8a27" have entirely different histories.
03e21fda87
...
0a459ee30b
|
|
@ -1,3 +1,3 @@
|
||||||
[alias]
|
[alias]
|
||||||
runs = "run -- run --config data/config --backup data/backups --world data/worlds --jar paper-1.19.4-550.jar --layers 2min,2,4,4;3min,3,2,2"
|
runs = "run -- run --config data/config --backup data/backups --world data/worlds --jar paper-1.19.4-550.jar --frequency 2"
|
||||||
runrs = "run --release -- paper 1.19.4-545 --config data/config --backup data/backups --world data/worlds --jar data/paper-1.19.4-525.jar"
|
runrs = "run --release -- paper 1.19.4-545 --config data/config --backup data/backups --world data/worlds --jar data/paper-1.19.4-525.jar"
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,3 @@
|
||||||
mod config;
|
|
||||||
mod meta;
|
|
||||||
|
|
||||||
pub use config::ManagerConfig;
|
|
||||||
pub use meta::MetaManager;
|
|
||||||
|
|
||||||
use super::Backup;
|
use super::Backup;
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
@ -32,6 +26,7 @@ where
|
||||||
{
|
{
|
||||||
const METADATA_FILE: &str = "alex.json";
|
const METADATA_FILE: &str = "alex.json";
|
||||||
|
|
||||||
|
/// Initialize a new instance of a `BackupManager`.
|
||||||
pub fn new<P1: Into<PathBuf>, P2: Into<PathBuf>, P3: Into<PathBuf>>(
|
pub fn new<P1: Into<PathBuf>, P2: Into<PathBuf>, P3: Into<PathBuf>>(
|
||||||
backup_dir: P1,
|
backup_dir: P1,
|
||||||
config_dir: P2,
|
config_dir: P2,
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
use std::error::Error;
|
|
||||||
use std::fmt;
|
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct ManagerConfig {
|
|
||||||
pub name: String,
|
|
||||||
pub frequency: u32,
|
|
||||||
pub chains: u64,
|
|
||||||
pub chain_len: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct ParseManagerConfigErr;
|
|
||||||
|
|
||||||
impl Error for ParseManagerConfigErr {}
|
|
||||||
|
|
||||||
impl fmt::Display for ParseManagerConfigErr {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
write!(f, "parse manager config err")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromStr for ManagerConfig {
|
|
||||||
type Err = ParseManagerConfigErr;
|
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
||||||
let splits: Vec<&str> = s.split(',').collect();
|
|
||||||
|
|
||||||
if let [name, frequency, chains, chain_len] = splits[..] {
|
|
||||||
let name: String = name.parse().map_err(|_| ParseManagerConfigErr)?;
|
|
||||||
let frequency: u32 = frequency.parse().map_err(|_| ParseManagerConfigErr)?;
|
|
||||||
let chains: u64 = chains.parse().map_err(|_| ParseManagerConfigErr)?;
|
|
||||||
let chain_len: u64 = chain_len.parse().map_err(|_| ParseManagerConfigErr)?;
|
|
||||||
|
|
||||||
Ok(ManagerConfig {
|
|
||||||
name,
|
|
||||||
chains,
|
|
||||||
chain_len,
|
|
||||||
frequency,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
Err(ParseManagerConfigErr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,102 +0,0 @@
|
||||||
use super::{Manager, ManagerConfig};
|
|
||||||
use chrono::Utc;
|
|
||||||
use serde::Deserialize;
|
|
||||||
use serde::Serialize;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::io;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
pub struct MetaManager<T>
|
|
||||||
where
|
|
||||||
T: Clone + Serialize + for<'de> Deserialize<'de>,
|
|
||||||
{
|
|
||||||
backup_dir: PathBuf,
|
|
||||||
config_dir: PathBuf,
|
|
||||||
world_dir: PathBuf,
|
|
||||||
default_metadata: T,
|
|
||||||
managers: HashMap<String, Manager<T>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> MetaManager<T>
|
|
||||||
where
|
|
||||||
T: Clone + Serialize + for<'de> Deserialize<'de>,
|
|
||||||
{
|
|
||||||
pub fn new<P1: Into<PathBuf>, P2: Into<PathBuf>, P3: Into<PathBuf>>(
|
|
||||||
backup_dir: P1,
|
|
||||||
config_dir: P2,
|
|
||||||
world_dir: P3,
|
|
||||||
default_metadata: T,
|
|
||||||
) -> Self {
|
|
||||||
MetaManager {
|
|
||||||
backup_dir: backup_dir.into(),
|
|
||||||
config_dir: config_dir.into(),
|
|
||||||
world_dir: world_dir.into(),
|
|
||||||
default_metadata,
|
|
||||||
managers: HashMap::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add(&mut self, config: &ManagerConfig) -> io::Result<()> {
|
|
||||||
// Backup dir itself should exist, but we control its contents, so we can create
|
|
||||||
// separate directories for each layer
|
|
||||||
let path = self.backup_dir.join(&config.name);
|
|
||||||
|
|
||||||
// If the directory already exists, that's okay
|
|
||||||
match std::fs::create_dir(&path) {
|
|
||||||
Ok(()) => (),
|
|
||||||
Err(e) => match e.kind() {
|
|
||||||
io::ErrorKind::AlreadyExists => (),
|
|
||||||
_ => return Err(e),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut manager = Manager::new(
|
|
||||||
path,
|
|
||||||
self.config_dir.clone(),
|
|
||||||
self.world_dir.clone(),
|
|
||||||
self.default_metadata.clone(),
|
|
||||||
config.chain_len,
|
|
||||||
config.chains,
|
|
||||||
chrono::Duration::minutes(config.frequency.into()),
|
|
||||||
);
|
|
||||||
manager.load()?;
|
|
||||||
self.managers.insert(config.name.clone(), manager);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_all(&mut self, configs: &Vec<ManagerConfig>) -> io::Result<()> {
|
|
||||||
for config in configs {
|
|
||||||
self.add(config)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn next_scheduled_layer(&self) -> Option<&str> {
|
|
||||||
self.managers
|
|
||||||
.iter()
|
|
||||||
.min_by_key(|(_, m)| m.next_scheduled_time())
|
|
||||||
.map(|(k, _)| k.as_str())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn next_scheduled_time(&self) -> Option<chrono::DateTime<Utc>> {
|
|
||||||
self.managers
|
|
||||||
.values()
|
|
||||||
.map(|m| m.next_scheduled_time())
|
|
||||||
.min()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn perform_backup_cycle(&mut self) -> io::Result<()> {
|
|
||||||
if let Some(manager) = self
|
|
||||||
.managers
|
|
||||||
.values_mut()
|
|
||||||
.min_by_key(|m| m.next_scheduled_time())
|
|
||||||
{
|
|
||||||
manager.create_backup()?;
|
|
||||||
manager.remove_old_backups()
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
mod delta;
|
mod delta;
|
||||||
pub mod manager;
|
mod manager;
|
||||||
mod path;
|
mod path;
|
||||||
|
|
||||||
use delta::Delta;
|
use delta::Delta;
|
||||||
pub use manager::Manager;
|
pub use manager::Manager;
|
||||||
pub use manager::ManagerConfig;
|
|
||||||
pub use manager::MetaManager;
|
|
||||||
|
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use flate2::write::GzEncoder;
|
use flate2::write::GzEncoder;
|
||||||
|
|
|
||||||
33
src/cli.rs
33
src/cli.rs
|
|
@ -1,4 +1,3 @@
|
||||||
use crate::backup::ManagerConfig;
|
|
||||||
use crate::server::ServerType;
|
use crate::server::ServerType;
|
||||||
use clap::{Args, Parser, Subcommand};
|
use clap::{Args, Parser, Subcommand};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
@ -36,10 +35,34 @@ pub struct Cli {
|
||||||
)]
|
)]
|
||||||
pub backup: PathBuf,
|
pub backup: PathBuf,
|
||||||
|
|
||||||
/// What backup layers to employ, provided as a list of tuples name,frequency,chain_len,chains
|
/// Length of a backup chain
|
||||||
/// delimited by semicolons (;).
|
#[arg(
|
||||||
#[arg(long, env = "ALEX_LAYERS", global = true, value_delimiter = ';')]
|
short = 'l',
|
||||||
pub layers: Vec<ManagerConfig>,
|
long,
|
||||||
|
default_value_t = 4,
|
||||||
|
env = "ALEX_CHAIN_LEN",
|
||||||
|
global = true
|
||||||
|
)]
|
||||||
|
pub chain_len: u64,
|
||||||
|
/// How many backup chains to keep
|
||||||
|
#[arg(
|
||||||
|
short = 'n',
|
||||||
|
long,
|
||||||
|
default_value_t = 7,
|
||||||
|
env = "ALEX_CHAINS",
|
||||||
|
global = true
|
||||||
|
)]
|
||||||
|
pub chains: u64,
|
||||||
|
|
||||||
|
/// How frequently to perform a backup, in minutes; 0 to disable.
|
||||||
|
#[arg(
|
||||||
|
short = 't',
|
||||||
|
long,
|
||||||
|
default_value_t = 0,
|
||||||
|
env = "ALEX_FREQUENCY",
|
||||||
|
global = true
|
||||||
|
)]
|
||||||
|
pub frequency: u32,
|
||||||
|
|
||||||
/// Type of server
|
/// Type of server
|
||||||
#[arg(long, default_value = "unknown", env = "ALEX_SERVER", global = true)]
|
#[arg(long, default_value = "unknown", env = "ALEX_SERVER", global = true)]
|
||||||
|
|
|
||||||
43
src/main.rs
43
src/main.rs
|
|
@ -5,7 +5,7 @@ mod signals;
|
||||||
mod stdin;
|
mod stdin;
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use cli::{Cli, Commands, RunArgs};
|
use cli::{BackupArgs, Cli, Commands, RunArgs};
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
|
@ -13,7 +13,7 @@ fn backups_thread(counter: Arc<Mutex<server::ServerProcess>>) {
|
||||||
loop {
|
loop {
|
||||||
let next_scheduled_time = {
|
let next_scheduled_time = {
|
||||||
let server = counter.lock().unwrap();
|
let server = counter.lock().unwrap();
|
||||||
server.backups.next_scheduled_time().unwrap()
|
server.backups.next_scheduled_time()
|
||||||
};
|
};
|
||||||
|
|
||||||
let now = chrono::offset::Utc::now();
|
let now = chrono::offset::Utc::now();
|
||||||
|
|
@ -39,9 +39,11 @@ fn command_run(cli: &Cli, args: &RunArgs) -> io::Result<()> {
|
||||||
.config(cli.config.clone())
|
.config(cli.config.clone())
|
||||||
.world(cli.world.clone())
|
.world(cli.world.clone())
|
||||||
.backup(cli.backup.clone())
|
.backup(cli.backup.clone())
|
||||||
.managers(cli.layers.clone())
|
|
||||||
.xms(args.xms)
|
.xms(args.xms)
|
||||||
.xmx(args.xmx);
|
.xmx(args.xmx)
|
||||||
|
.chain_len(cli.chain_len)
|
||||||
|
.chains_to_keep(cli.chains)
|
||||||
|
.frequency(cli.frequency);
|
||||||
cmd.canonicalize()?;
|
cmd.canonicalize()?;
|
||||||
|
|
||||||
if args.dry {
|
if args.dry {
|
||||||
|
|
@ -52,7 +54,7 @@ fn command_run(cli: &Cli, args: &RunArgs) -> io::Result<()> {
|
||||||
|
|
||||||
let counter = Arc::new(Mutex::new(cmd.spawn()?));
|
let counter = Arc::new(Mutex::new(cmd.spawn()?));
|
||||||
|
|
||||||
if !cli.layers.is_empty() {
|
if cli.frequency > 0 {
|
||||||
let clone = Arc::clone(&counter);
|
let clone = Arc::clone(&counter);
|
||||||
std::thread::spawn(move || backups_thread(clone));
|
std::thread::spawn(move || backups_thread(clone));
|
||||||
}
|
}
|
||||||
|
|
@ -65,23 +67,32 @@ fn command_run(cli: &Cli, args: &RunArgs) -> io::Result<()> {
|
||||||
signals::handle_signals(&mut signals, counter)
|
signals::handle_signals(&mut signals, counter)
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn commands_backup(cli: &Cli, _args: &BackupArgs) -> io::Result<()> {
|
fn commands_backup(cli: &Cli, _args: &BackupArgs) -> io::Result<()> {
|
||||||
// let metadata = server::Metadata {
|
let metadata = server::Metadata {
|
||||||
// server_type: cli.server,
|
server_type: cli.server,
|
||||||
// server_version: cli.server_version.clone(),
|
server_version: cli.server_version.clone(),
|
||||||
// };
|
};
|
||||||
// let mut meta = MetaManager::new(cli.backup, cli.config, cli.world, metadata);
|
|
||||||
// meta.add_all(&cli.layers)?;
|
|
||||||
|
|
||||||
// manager.create_backup()?;
|
let mut manager = backup::Manager::new(
|
||||||
// manager.remove_old_backups()
|
cli.backup.clone(),
|
||||||
// }
|
cli.config.clone(),
|
||||||
|
cli.world.clone(),
|
||||||
|
metadata,
|
||||||
|
cli.chain_len,
|
||||||
|
cli.chains,
|
||||||
|
chrono::Duration::minutes(cli.frequency.into()),
|
||||||
|
);
|
||||||
|
manager.load()?;
|
||||||
|
|
||||||
|
manager.create_backup()?;
|
||||||
|
manager.remove_old_backups()
|
||||||
|
}
|
||||||
|
|
||||||
fn main() -> io::Result<()> {
|
fn main() -> io::Result<()> {
|
||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
|
|
||||||
match &cli.command {
|
match &cli.command {
|
||||||
Commands::Run(args) => command_run(&cli, args),
|
Commands::Run(args) => command_run(&cli, args),
|
||||||
Commands::Backup(_) => Ok(()),
|
Commands::Backup(args) => commands_backup(&cli, args),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,40 @@
|
||||||
use crate::backup::ManagerConfig;
|
use crate::backup::Manager as BackupManager;
|
||||||
use crate::backup::MetaManager;
|
use crate::server::ServerProcess;
|
||||||
use crate::server::{Metadata, ServerProcess, ServerType};
|
use clap::ValueEnum;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::{Command, Stdio};
|
use std::process::{Command, Stdio};
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum, Serialize, Deserialize)]
|
||||||
|
pub enum ServerType {
|
||||||
|
Unknown,
|
||||||
|
Paper,
|
||||||
|
Forge,
|
||||||
|
Vanilla,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for ServerType {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
let s = match self {
|
||||||
|
ServerType::Unknown => "Unknown",
|
||||||
|
ServerType::Paper => "PaperMC",
|
||||||
|
ServerType::Forge => "Forge",
|
||||||
|
ServerType::Vanilla => "Vanilla",
|
||||||
|
};
|
||||||
|
|
||||||
|
write!(f, "{}", s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Metadata {
|
||||||
|
pub server_type: ServerType,
|
||||||
|
pub server_version: String,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct ServerCommand {
|
pub struct ServerCommand {
|
||||||
type_: ServerType,
|
type_: ServerType,
|
||||||
version: String,
|
version: String,
|
||||||
|
|
@ -17,7 +45,9 @@ pub struct ServerCommand {
|
||||||
backup_dir: PathBuf,
|
backup_dir: PathBuf,
|
||||||
xms: u64,
|
xms: u64,
|
||||||
xmx: u64,
|
xmx: u64,
|
||||||
managers: Vec<ManagerConfig>,
|
chain_len: u64,
|
||||||
|
chains_to_keep: u64,
|
||||||
|
frequency: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServerCommand {
|
impl ServerCommand {
|
||||||
|
|
@ -32,7 +62,9 @@ impl ServerCommand {
|
||||||
backup_dir: PathBuf::from("backups"),
|
backup_dir: PathBuf::from("backups"),
|
||||||
xms: 1024,
|
xms: 1024,
|
||||||
xmx: 2048,
|
xmx: 2048,
|
||||||
managers: Vec::new(),
|
chain_len: 4,
|
||||||
|
chains_to_keep: 7,
|
||||||
|
frequency: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,9 +105,18 @@ impl ServerCommand {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn managers(mut self, configs: Vec<ManagerConfig>) -> Self {
|
pub fn chain_len(mut self, v: u64) -> Self {
|
||||||
self.managers = configs;
|
self.chain_len = v;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn chains_to_keep(mut self, v: u64) -> Self {
|
||||||
|
self.chains_to_keep = v;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn frequency(mut self, v: u32) -> Self {
|
||||||
|
self.frequency = v;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -166,19 +207,22 @@ impl ServerCommand {
|
||||||
server_type: self.type_,
|
server_type: self.type_,
|
||||||
server_version: self.version.clone(),
|
server_version: self.version.clone(),
|
||||||
};
|
};
|
||||||
let mut meta = MetaManager::new(
|
let mut manager = BackupManager::new(
|
||||||
self.backup_dir.clone(),
|
self.backup_dir.clone(),
|
||||||
self.config_dir.clone(),
|
self.config_dir.clone(),
|
||||||
self.world_dir.clone(),
|
self.world_dir.clone(),
|
||||||
metadata,
|
metadata,
|
||||||
|
self.chain_len,
|
||||||
|
self.chains_to_keep,
|
||||||
|
chrono::Duration::minutes(self.frequency.into()),
|
||||||
);
|
);
|
||||||
meta.add_all(&self.managers)?;
|
manager.load()?;
|
||||||
|
|
||||||
let mut cmd = self.create_cmd();
|
let mut cmd = self.create_cmd();
|
||||||
self.accept_eula()?;
|
self.accept_eula()?;
|
||||||
let child = cmd.spawn()?;
|
let child = cmd.spawn()?;
|
||||||
|
|
||||||
Ok(ServerProcess::new(meta, child))
|
Ok(ServerProcess::new(manager, child))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,5 @@
|
||||||
mod command;
|
mod command;
|
||||||
mod process;
|
mod process;
|
||||||
|
|
||||||
pub use command::ServerCommand;
|
pub use command::{Metadata, ServerCommand, ServerType};
|
||||||
pub use process::ServerProcess;
|
pub use process::ServerProcess;
|
||||||
|
|
||||||
use clap::ValueEnum;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum, Serialize, Deserialize)]
|
|
||||||
pub enum ServerType {
|
|
||||||
Unknown,
|
|
||||||
Paper,
|
|
||||||
Forge,
|
|
||||||
Vanilla,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for ServerType {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
let s = match self {
|
|
||||||
ServerType::Unknown => "Unknown",
|
|
||||||
ServerType::Paper => "PaperMC",
|
|
||||||
ServerType::Forge => "Forge",
|
|
||||||
ServerType::Vanilla => "Vanilla",
|
|
||||||
};
|
|
||||||
|
|
||||||
write!(f, "{}", s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Serialize, Deserialize)]
|
|
||||||
pub struct Metadata {
|
|
||||||
pub server_type: ServerType,
|
|
||||||
pub server_version: String,
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
use crate::backup::MetaManager;
|
use crate::backup::Manager as BackupManager;
|
||||||
use crate::server::Metadata;
|
use crate::server::Metadata;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::process::Child;
|
use std::process::Child;
|
||||||
|
|
||||||
pub struct ServerProcess {
|
pub struct ServerProcess {
|
||||||
child: Child,
|
child: Child,
|
||||||
pub backups: MetaManager<Metadata>,
|
pub backups: BackupManager<Metadata>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServerProcess {
|
impl ServerProcess {
|
||||||
pub fn new(manager: MetaManager<Metadata>, child: Child) -> ServerProcess {
|
pub fn new(manager: BackupManager<Metadata>, child: Child) -> ServerProcess {
|
||||||
ServerProcess {
|
ServerProcess {
|
||||||
child,
|
child,
|
||||||
backups: manager,
|
backups: manager,
|
||||||
|
|
@ -48,8 +48,7 @@ impl ServerProcess {
|
||||||
/// Perform a backup by disabling the server's save feature and flushing its data, before
|
/// Perform a backup by disabling the server's save feature and flushing its data, before
|
||||||
/// creating an archive file.
|
/// creating an archive file.
|
||||||
pub fn backup(&mut self) -> std::io::Result<()> {
|
pub fn backup(&mut self) -> std::io::Result<()> {
|
||||||
let layer_name = String::from(self.backups.next_scheduled_layer().unwrap());
|
self.custom("say backing up server")?;
|
||||||
self.custom(&format!("say starting backup for layer '{}'", layer_name))?;
|
|
||||||
|
|
||||||
// Make sure the server isn't modifying the files during the backup
|
// Make sure the server isn't modifying the files during the backup
|
||||||
self.custom("save-off")?;
|
self.custom("save-off")?;
|
||||||
|
|
@ -60,12 +59,16 @@ impl ServerProcess {
|
||||||
std::thread::sleep(std::time::Duration::from_secs(10));
|
std::thread::sleep(std::time::Duration::from_secs(10));
|
||||||
|
|
||||||
let start_time = chrono::offset::Utc::now();
|
let start_time = chrono::offset::Utc::now();
|
||||||
let res = self.backups.perform_backup_cycle();
|
let res = self.backups.create_backup();
|
||||||
|
|
||||||
// The server's save feature needs to be enabled again even if the archive failed to create
|
// The server's save feature needs to be enabled again even if the archive failed to create
|
||||||
self.custom("save-on")?;
|
self.custom("save-on")?;
|
||||||
self.custom("save-all")?;
|
self.custom("save-all")?;
|
||||||
|
|
||||||
|
if res.is_ok() {
|
||||||
|
self.backups.remove_old_backups()?;
|
||||||
|
}
|
||||||
|
|
||||||
let duration = chrono::offset::Utc::now() - start_time;
|
let duration = chrono::offset::Utc::now() - start_time;
|
||||||
let duration_str = format!(
|
let duration_str = format!(
|
||||||
"{}m{}s",
|
"{}m{}s",
|
||||||
|
|
@ -74,14 +77,11 @@ impl ServerProcess {
|
||||||
);
|
);
|
||||||
|
|
||||||
if res.is_ok() {
|
if res.is_ok() {
|
||||||
self.custom(&format!(
|
self.custom(&format!("say server backed up in {}", duration_str))?;
|
||||||
"say backup created for layer '{}' in {}",
|
|
||||||
layer_name, duration_str
|
|
||||||
))?;
|
|
||||||
} else {
|
} else {
|
||||||
self.custom(&format!(
|
self.custom(&format!(
|
||||||
"an error occured after {} while creating backup for layer '{}'",
|
"an error occured after {} while backing up the server",
|
||||||
duration_str, layer_name
|
duration_str
|
||||||
))?;
|
))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue