Added compressed backups and removing old backups
+ Added docs + Backups are compressed as `tar.gz` files + a configurable amount of backups are keptbackup_error_fix
parent
c11748d696
commit
c2cdbd56ac
|
@ -1,5 +1,11 @@
|
||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
|
[[package]]
|
||||||
|
name = "adler32"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "0.7.10"
|
version = "0.7.10"
|
||||||
|
@ -16,11 +22,12 @@ dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
"config",
|
"config",
|
||||||
|
"flate2",
|
||||||
"log",
|
"log",
|
||||||
"regex",
|
"regex",
|
||||||
"serde 1.0.111",
|
"serde 1.0.111",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"walkdir",
|
"tar",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -103,6 +110,39 @@ dependencies = [
|
||||||
"yaml-rust",
|
"yaml-rust",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crc32fast"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "filetime"
|
||||||
|
version = "0.2.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "affc17579b132fc2461adf7c575cc6e8b134ebca52c51f5411388965227dc695"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"redox_syscall",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flate2"
|
||||||
|
version = "1.0.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2cfff41391129e0a856d6d822600b8d71179d46879e310417eb9c762eb178b42"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"crc32fast",
|
||||||
|
"libc",
|
||||||
|
"miniz_oxide",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.1.13"
|
version = "0.1.13"
|
||||||
|
@ -167,6 +207,15 @@ version = "2.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
|
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "miniz_oxide"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aa679ff6578b1cddee93d7e82e263b94a575e0bfced07284eb0c037c1d2416a5"
|
||||||
|
dependencies = [
|
||||||
|
"adler32",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nom"
|
name = "nom"
|
||||||
version = "4.2.3"
|
version = "4.2.3"
|
||||||
|
@ -223,6 +272,12 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_syscall"
|
||||||
|
version = "0.1.56"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.3.9"
|
version = "1.3.9"
|
||||||
|
@ -253,15 +308,6 @@ version = "1.0.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "same-file"
|
|
||||||
version = "1.0.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
|
||||||
dependencies = [
|
|
||||||
"winapi-util",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "0.8.23"
|
version = "0.8.23"
|
||||||
|
@ -335,6 +381,18 @@ dependencies = [
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tar"
|
||||||
|
version = "0.4.28"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c058ad0bd6ccb84faa24cc44d4fc99bee8a5d7ba9ff33aa4d993122d1aeeac2"
|
||||||
|
dependencies = [
|
||||||
|
"filetime",
|
||||||
|
"libc",
|
||||||
|
"redox_syscall",
|
||||||
|
"xattr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "textwrap"
|
name = "textwrap"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
|
@ -396,17 +454,6 @@ version = "0.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
|
checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "walkdir"
|
|
||||||
version = "2.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
|
|
||||||
dependencies = [
|
|
||||||
"same-file",
|
|
||||||
"winapi",
|
|
||||||
"winapi-util",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.8"
|
version = "0.3.8"
|
||||||
|
@ -423,21 +470,21 @@ version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi-util"
|
|
||||||
version = "0.1.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
|
||||||
dependencies = [
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-x86_64-pc-windows-gnu"
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xattr"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yaml-rust"
|
name = "yaml-rust"
|
||||||
version = "0.4.4"
|
version = "0.4.4"
|
||||||
|
|
|
@ -13,5 +13,6 @@ serde_derive = "1.0.104"
|
||||||
config = "0.9"
|
config = "0.9"
|
||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
walkdir = "2.3.1"
|
|
||||||
regex = "1.3.9"
|
regex = "1.3.9"
|
||||||
|
flate2 = "1.0.14"
|
||||||
|
tar = "0.4.28"
|
||||||
|
|
|
@ -1,14 +1,19 @@
|
||||||
use config::{Config, ConfigError, File};
|
use config::{Config, ConfigError, File};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
/// World types supported
|
||||||
#[derive(Debug, Deserialize, Clone)]
|
#[derive(Debug, Deserialize, Clone)]
|
||||||
pub enum WorldType {
|
pub enum WorldType {
|
||||||
|
/// The End (DIM1)
|
||||||
END,
|
END,
|
||||||
|
/// Nether (DIM-1)
|
||||||
NETHER,
|
NETHER,
|
||||||
|
/// Overworld
|
||||||
OVERWORLD,
|
OVERWORLD,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<String> for WorldType {
|
impl From<String> for WorldType {
|
||||||
|
/// Convert config strings to WorldType
|
||||||
fn from(string: String) -> Self {
|
fn from(string: String) -> Self {
|
||||||
match string.as_str() {
|
match string.as_str() {
|
||||||
"END" => WorldType::END,
|
"END" => WorldType::END,
|
||||||
|
@ -18,6 +23,7 @@ impl From<String> for WorldType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Config for individual WorldConfig
|
||||||
#[derive(Debug, Deserialize, Clone)]
|
#[derive(Debug, Deserialize, Clone)]
|
||||||
pub struct WorldConfig {
|
pub struct WorldConfig {
|
||||||
pub world_name: String,
|
pub world_name: String,
|
||||||
|
@ -25,6 +31,7 @@ pub struct WorldConfig {
|
||||||
pub world_type: Option<WorldType>,
|
pub world_type: Option<WorldType>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Config for doing backups
|
||||||
#[derive(Debug, Deserialize, Clone)]
|
#[derive(Debug, Deserialize, Clone)]
|
||||||
pub struct BackupConfig {
|
pub struct BackupConfig {
|
||||||
pub minecraft_dir: PathBuf,
|
pub minecraft_dir: PathBuf,
|
||||||
|
@ -32,6 +39,7 @@ pub struct BackupConfig {
|
||||||
pub backups_to_keep: u64,
|
pub backups_to_keep: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Configs
|
||||||
#[derive(Debug, Deserialize, Clone)]
|
#[derive(Debug, Deserialize, Clone)]
|
||||||
pub struct AlbatrossConfig {
|
pub struct AlbatrossConfig {
|
||||||
pub backup: BackupConfig,
|
pub backup: BackupConfig,
|
||||||
|
@ -39,6 +47,7 @@ pub struct AlbatrossConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AlbatrossConfig {
|
impl AlbatrossConfig {
|
||||||
|
/// Create new backup from file
|
||||||
pub fn new(config_path: &str) -> Result<Self, ConfigError> {
|
pub fn new(config_path: &str) -> Result<Self, ConfigError> {
|
||||||
let mut cfg = Config::new();
|
let mut cfg = Config::new();
|
||||||
cfg.merge(File::with_name(config_path))?;
|
cfg.merge(File::with_name(config_path))?;
|
||||||
|
|
164
src/main.rs
164
src/main.rs
|
@ -3,18 +3,23 @@ extern crate serde;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
use chrono::Utc;
|
use chrono::{NaiveDateTime, Utc};
|
||||||
use clap::{App, Arg};
|
use clap::{App, Arg};
|
||||||
|
use flate2::write::GzEncoder;
|
||||||
|
use flate2::Compression;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::fs::{copy, create_dir, create_dir_all};
|
use std::fs::{copy, create_dir, create_dir_all, remove_dir_all, remove_file, DirEntry, File};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
mod albatross_config;
|
mod albatross_config;
|
||||||
|
|
||||||
use albatross_config::{AlbatrossConfig, WorldConfig, WorldType};
|
use albatross_config::{AlbatrossConfig, WorldConfig, WorldType};
|
||||||
|
|
||||||
|
/// Struct to store information about the region
|
||||||
struct Region {
|
struct Region {
|
||||||
|
/// x position of the region
|
||||||
x: i64,
|
x: i64,
|
||||||
|
/// y position of the region
|
||||||
y: i64,
|
y: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +39,11 @@ impl Region {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Backup a directory
|
||||||
|
///
|
||||||
|
/// # Param
|
||||||
|
/// * `world_path` - path to the world folder
|
||||||
|
/// * `backup_path` - path to the backup folder
|
||||||
fn backup_dir(
|
fn backup_dir(
|
||||||
dir_name: &str,
|
dir_name: &str,
|
||||||
world_path: &PathBuf,
|
world_path: &PathBuf,
|
||||||
|
@ -56,6 +66,13 @@ fn backup_dir(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Backup the regions
|
||||||
|
///
|
||||||
|
/// # Param
|
||||||
|
/// * `dir_name` - name of the backup folder
|
||||||
|
/// * `save_radius` - block radius to save
|
||||||
|
/// * `world_path` - path to the world folder
|
||||||
|
/// * `backup_path` - path to the backup folder
|
||||||
fn backup_region(
|
fn backup_region(
|
||||||
dir_name: &str,
|
dir_name: &str,
|
||||||
save_radius: u64,
|
save_radius: u64,
|
||||||
|
@ -91,6 +108,12 @@ fn backup_region(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Backup a world
|
||||||
|
///
|
||||||
|
/// # Param
|
||||||
|
/// * `world_path` - path to the world folder
|
||||||
|
/// * `backup_path` - path to the backup folder
|
||||||
|
/// * `world_config` - world config options
|
||||||
fn backup_world(
|
fn backup_world(
|
||||||
world_path: PathBuf,
|
world_path: PathBuf,
|
||||||
backup_path: PathBuf,
|
backup_path: PathBuf,
|
||||||
|
@ -112,6 +135,12 @@ fn backup_world(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Backup the overworld
|
||||||
|
///
|
||||||
|
/// # Param
|
||||||
|
/// * `world_path` - path to the world folder
|
||||||
|
/// * `backup_path` - path to the backup folder
|
||||||
|
/// * `world_config` - world config options
|
||||||
fn backup_overworld(
|
fn backup_overworld(
|
||||||
world_path: PathBuf,
|
world_path: PathBuf,
|
||||||
backup_path: PathBuf,
|
backup_path: PathBuf,
|
||||||
|
@ -121,13 +150,119 @@ fn backup_overworld(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Backup the nether
|
||||||
|
///
|
||||||
|
/// # Param
|
||||||
|
/// * `world_path` - path to the world folder
|
||||||
|
/// * `backup_path` - path to the backup folder
|
||||||
|
/// * `world_config` - world config options
|
||||||
|
fn backup_nether(
|
||||||
|
world_path: PathBuf,
|
||||||
|
backup_path: PathBuf,
|
||||||
|
world_config: &WorldConfig,
|
||||||
|
) -> Result<(), std::io::Error> {
|
||||||
|
let mut nether_path = world_path.clone();
|
||||||
|
nether_path.push("DIM-1");
|
||||||
|
|
||||||
|
backup_world(nether_path, backup_path, world_config)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Backup the end
|
||||||
|
///
|
||||||
|
/// # Param
|
||||||
|
/// * `world_path` - path to the world folder
|
||||||
|
/// * `backup_path` - path to the backup folder
|
||||||
|
/// * `world_config` - world config options
|
||||||
|
fn backup_end(
|
||||||
|
world_path: PathBuf,
|
||||||
|
backup_path: PathBuf,
|
||||||
|
world_config: &WorldConfig,
|
||||||
|
) -> Result<(), std::io::Error> {
|
||||||
|
let mut end_path = world_path.clone();
|
||||||
|
end_path.push("DIM1");
|
||||||
|
|
||||||
|
backup_world(end_path, backup_path, world_config)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compress the backup after the files have been copied
|
||||||
|
///
|
||||||
|
/// # Param
|
||||||
|
/// * `tmp_dir`: tmp directory with the backed up files
|
||||||
|
/// * `output_file`: output archive
|
||||||
|
fn compress_backup(tmp_dir: &PathBuf, output_file: &PathBuf) -> Result<(), std::io::Error> {
|
||||||
|
let archive = File::create(output_file)?;
|
||||||
|
let enc = GzEncoder::new(archive, Compression::default());
|
||||||
|
let mut tar_builder = tar::Builder::new(enc);
|
||||||
|
tar_builder.append_dir_all(".", tmp_dir)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the time of the backup from a file name
|
||||||
|
///
|
||||||
|
/// # Param
|
||||||
|
/// * `archive_entry`: archive entry
|
||||||
|
fn get_time_from_file_name(
|
||||||
|
archive_entry: &DirEntry,
|
||||||
|
) -> Result<Option<NaiveDateTime>, std::io::Error> {
|
||||||
|
let file_name = archive_entry.file_name().to_str().unwrap().to_string();
|
||||||
|
let name: Vec<&str> = file_name.split("_").collect();
|
||||||
|
|
||||||
|
Ok(chrono::NaiveDateTime::parse_from_str(name[0], "%d-%m-%y-%H:%M:%S").ok())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Removes the old backups from the ouput directory
|
||||||
|
///
|
||||||
|
/// # Params
|
||||||
|
/// * `output_dir` - output directory containing
|
||||||
|
/// * `keep` - number of backups to keep
|
||||||
|
fn remove_old_backups(output_dir: &PathBuf, keep: u64) -> Result<(), std::io::Error> {
|
||||||
|
let mut backups = vec![];
|
||||||
|
|
||||||
|
for entry in output_dir.read_dir()? {
|
||||||
|
let entry = entry?;
|
||||||
|
|
||||||
|
if let Some(ext) = entry.path().extension() {
|
||||||
|
if ext == "gz" {
|
||||||
|
backups.push(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if backups.len() > keep as usize {
|
||||||
|
backups.sort_by(|a, b| {
|
||||||
|
let a_time = get_time_from_file_name(a).unwrap().unwrap();
|
||||||
|
let b_time = get_time_from_file_name(b).unwrap().unwrap();
|
||||||
|
|
||||||
|
b_time.cmp(&a_time)
|
||||||
|
});
|
||||||
|
|
||||||
|
let number_to_remove = backups.len() - keep as usize;
|
||||||
|
|
||||||
|
for _i in 0..number_to_remove {
|
||||||
|
let oldest = backups.pop().unwrap();
|
||||||
|
remove_file(oldest.path())?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Backup the configured worlds from a minecraft server
|
||||||
|
///
|
||||||
|
/// # Params
|
||||||
|
/// * `cfg` - config file
|
||||||
fn do_backup(cfg: AlbatrossConfig) -> Result<(), std::io::Error> {
|
fn do_backup(cfg: AlbatrossConfig) -> Result<(), std::io::Error> {
|
||||||
let server_base_dir = cfg.backup.minecraft_dir.clone();
|
let server_base_dir = cfg.backup.minecraft_dir.clone();
|
||||||
let worlds = cfg.world_config.unwrap().clone();
|
let worlds = cfg.world_config.unwrap().clone();
|
||||||
let time_str = Utc::now().format("%d-%m-%y_%H:%M%S").to_string();
|
let time_str = Utc::now().format("%d-%m-%y-%H:%M:%S").to_string();
|
||||||
let backup_name = format!("{}-backup", time_str);
|
let backup_name = format!("{}_backup.tar.gz", time_str);
|
||||||
|
let mut output_archive = cfg.backup.output_dir.clone();
|
||||||
|
output_archive.push(backup_name);
|
||||||
let mut tmp_dir = cfg.backup.output_dir.clone();
|
let mut tmp_dir = cfg.backup.output_dir.clone();
|
||||||
tmp_dir.push(backup_name);
|
tmp_dir.push("tmp");
|
||||||
|
remove_dir_all(&tmp_dir).ok();
|
||||||
|
|
||||||
create_dir_all(tmp_dir.clone()).unwrap();
|
create_dir_all(tmp_dir.clone()).unwrap();
|
||||||
|
|
||||||
|
@ -143,18 +278,33 @@ fn do_backup(cfg: AlbatrossConfig) -> Result<(), std::io::Error> {
|
||||||
if world_dir.exists() && world_dir.is_dir() {
|
if world_dir.exists() && world_dir.is_dir() {
|
||||||
match world_type {
|
match world_type {
|
||||||
WorldType::OVERWORLD => {
|
WorldType::OVERWORLD => {
|
||||||
backup_overworld(world_dir, tmp_dir.clone(), &world)?;
|
backup_overworld(world_dir.clone(), tmp_dir.clone(), &world)?;
|
||||||
|
backup_dir("playerdata", &world_dir, &tmp_dir)?;
|
||||||
|
}
|
||||||
|
WorldType::NETHER => {
|
||||||
|
backup_nether(world_dir, tmp_dir.clone(), &world)?;
|
||||||
|
}
|
||||||
|
WorldType::END => {
|
||||||
|
backup_end(world_dir, tmp_dir.clone(), &world)?;
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
println!("World \"{}\" not found", world_name.clone());
|
println!("World \"{}\" not found", world_name.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compress_backup(&tmp_dir, &output_archive)?;
|
||||||
|
|
||||||
|
remove_dir_all(&tmp_dir)?;
|
||||||
|
|
||||||
|
remove_old_backups(&cfg.backup.output_dir, cfg.backup.backups_to_keep)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Albatross
|
||||||
|
///
|
||||||
|
/// Run backups of a Minecraft world
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut app = App::new("Albatross").about("Backup your worlds").arg(
|
let mut app = App::new("Albatross").about("Backup your worlds").arg(
|
||||||
Arg::with_name("config")
|
Arg::with_name("config")
|
||||||
|
|
Loading…
Reference in New Issue