feat: add stage 2
This commit is contained in:
parent
4e366d10e9
commit
28f0988f5f
8 changed files with 87 additions and 10 deletions
4
log.txt
4
log.txt
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
I: Begin backup log - 1725955295
|
||||||
|
I: Beginning stage 1 backup.
|
||||||
|
I: Beginning stage 2 backup.
|
4
resetenv.sh
Normal file
4
resetenv.sh
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#! /bin/bash
|
||||||
|
rm -r testfiles/dir/*
|
||||||
|
echo "" > log.txt
|
||||||
|
rm -r /run/media/xory/Ventoy/backup/*
|
62
src/lib.rs
62
src/lib.rs
|
@ -15,12 +15,20 @@ pub struct StageConfig {
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, PartialEq)]
|
#[derive(Deserialize, Debug, PartialEq)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub stage_1: StageConfig
|
pub stage_1: StageConfig,
|
||||||
|
pub stage_2: StageConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
pub fn new(config_toml: String) -> Config {
|
pub fn new(config_toml: String) -> Config {
|
||||||
toml::from_str(&config_toml).expect("Invalid Config")
|
let config = match toml::from_str(&config_toml) {
|
||||||
|
Ok(config) => config,
|
||||||
|
Err(err) => {
|
||||||
|
let _ = log("./log.txt".to_string(), format!("Failed to parse config, got error {err}"), LogLevel::Error);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
config
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,6 +63,44 @@ pub fn stage1(config: &Config) -> io::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn stage2(config: &Config) -> io::Result<()> {
|
||||||
|
for file in &config.stage_2.src_files {
|
||||||
|
let filename = match file.split('/').last() {
|
||||||
|
Some(filename) => filename,
|
||||||
|
None => { eprintln!("E: Failed to derive filename from {file}"); break }
|
||||||
|
};
|
||||||
|
|
||||||
|
let target_path = format!("{}/{filename}", &config.stage_2.target_dir);
|
||||||
|
if !Path::new(&config.stage_2.target_dir).exists() {
|
||||||
|
log(".log.txt".to_string(), "External drive missing or not mounted, please insert and/or mount the drive and try again.".to_string(), LogLevel::Error)?;
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if Path::new(file).is_file() {
|
||||||
|
if let Err(err) = fs::copy(file, target_path) {
|
||||||
|
log("./log.txt".to_string(), err.to_string(), LogLevel::Error)?;
|
||||||
|
break
|
||||||
|
};
|
||||||
|
} else if Path::new(file).is_dir() && config.stage_2.recursive {
|
||||||
|
if let Err(err) = fs::create_dir(target_path) {
|
||||||
|
log("./log.txt".to_string(), err.to_string(), LogLevel::Error)?;
|
||||||
|
break
|
||||||
|
}
|
||||||
|
for entry in fs::read_dir(file)? {
|
||||||
|
let target_dir = format!("{}/{}", &config.stage_2.target_dir, filename);
|
||||||
|
let file = entry?;
|
||||||
|
if let Err(err) = fs::copy(Path::new(&file.path()), format!("{}/{}", target_dir, file.file_name().to_str().unwrap())) {
|
||||||
|
log("./log.txt".to_string(), err.to_string(), LogLevel::Error)?;
|
||||||
|
break
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log("./log.txt".to_string(), "Copy conditions not matched for file {file}, skipping.".to_string(), LogLevel::Warning)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -64,7 +110,12 @@ mod tests {
|
||||||
let toml_config = "[stage_1]
|
let toml_config = "[stage_1]
|
||||||
src_files = [ './testfiles/src/file1.txt', './testfiles/src/file2.txt', './testfiles/src/a' ]
|
src_files = [ './testfiles/src/file1.txt', './testfiles/src/file2.txt', './testfiles/src/a' ]
|
||||||
target_dir = './testfiles/dir'
|
target_dir = './testfiles/dir'
|
||||||
recursive = true";
|
recursive = true
|
||||||
|
[stage_2]
|
||||||
|
src_files = [ './testfiles/src/file1.txt', './testfiles/src/file2.txt', './testfiles/src/a' ]
|
||||||
|
target_dir = '/run/media/xory/Ventoy/backup'
|
||||||
|
recursive = true
|
||||||
|
";
|
||||||
|
|
||||||
let parsed_config = Config::new(toml_config.to_string());
|
let parsed_config = Config::new(toml_config.to_string());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -73,6 +124,11 @@ mod tests {
|
||||||
src_files: vec![ "./testfiles/src/file1.txt".to_string(), "./testfiles/src/file2.txt".to_string(), "./testfiles/src/a".to_string() ],
|
src_files: vec![ "./testfiles/src/file1.txt".to_string(), "./testfiles/src/file2.txt".to_string(), "./testfiles/src/a".to_string() ],
|
||||||
target_dir: "./testfiles/dir".to_string(),
|
target_dir: "./testfiles/dir".to_string(),
|
||||||
recursive: true
|
recursive: true
|
||||||
|
},
|
||||||
|
stage_2: StageConfig {
|
||||||
|
src_files: vec![ "./testfiles/src/file1.txt".to_string(), "./testfiles/src/file2.txt".to_string(), "./testfiles/src/a".to_string() ],
|
||||||
|
target_dir: "/run/media/xory/Ventoy/backup".to_string(),
|
||||||
|
recursive: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
parsed_config
|
parsed_config
|
||||||
|
|
15
src/main.rs
15
src/main.rs
|
@ -1,13 +1,18 @@
|
||||||
use cynewave::{Config, stage1};
|
use cynewave::{Config, stage1, stage2};
|
||||||
mod logger;
|
mod logger;
|
||||||
use logger::{log, LogLevel};
|
use logger::{log, LogLevel};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
use std::time::{UNIX_EPOCH, SystemTime};
|
||||||
|
|
||||||
fn main() {
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let current_epoch = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
|
||||||
|
log("./log.txt".to_string(), format!("Begin backup log - {current_epoch}"), LogLevel::Info)?;
|
||||||
let config_file: String = fs::read_to_string("./testconfig.toml").expect("Failed to read config");
|
let config_file: String = fs::read_to_string("./testconfig.toml").expect("Failed to read config");
|
||||||
let config: Config = Config::new(config_file);
|
let config: Config = Config::new(config_file);
|
||||||
dbg!(&config);
|
dbg!(&config);
|
||||||
log("./log.txt".to_string(), "Beginning stage 1 backup.".to_string(), LogLevel::Info).unwrap();
|
log("./log.txt".to_string(), "Beginning stage 1 backup.".to_string(), LogLevel::Info)?;
|
||||||
stage1(&config).unwrap();
|
stage1(&config)?;
|
||||||
|
log("./log.txt".to_string(), "Beginning stage 2 backup.".to_string(), LogLevel::Info)?;
|
||||||
|
stage2(&config)?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
[stage_1]
|
[stage_1]
|
||||||
src_files = [ "./testfiles/src/file1.txt", "./testfiles/src/file2.txt", "./testfiles/src/a" ]
|
src_files = [ "./testfiles/src/file1.txt", "./testfiles/src/file2.txt", "./testfiles/src/a" ]
|
||||||
target_dir = "./testfiles/dir"
|
target_dir = "./testfiles/dir"
|
||||||
recursive = false
|
recursive = true
|
||||||
|
|
||||||
|
[stage_2]
|
||||||
|
src_files = [ "./testfiles/src/file1.txt", "./testfiles/src/file2.txt", "./testfiles/src/a" ]
|
||||||
|
target_dir = "/run/media/xory/Ventoy/backup"
|
||||||
|
recursive = true
|
||||||
|
|
||||||
|
|
||||||
|
|
0
testfiles/dir/a/file3.txt
Normal file
0
testfiles/dir/a/file3.txt
Normal file
1
testfiles/dir/file1.txt
Normal file
1
testfiles/dir/file1.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
a
|
1
testfiles/dir/file2.txt
Normal file
1
testfiles/dir/file2.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
b
|
Loading…
Reference in a new issue