mirror of https://github.com/dswd/zvault
Nice errors
This commit is contained in:
parent
5377c5f8df
commit
b346f6e291
|
@ -112,7 +112,6 @@ Recommended: Brotli/2-7
|
||||||
### CLI functionality
|
### CLI functionality
|
||||||
- Remove backup subtrees
|
- Remove backup subtrees
|
||||||
- list --tree
|
- list --tree
|
||||||
- More detailed errors with nicer text
|
|
||||||
|
|
||||||
### Other
|
### Other
|
||||||
- Stability
|
- Stability
|
||||||
|
|
|
@ -7,6 +7,7 @@ use ::prelude::*;
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::fmt::Display;
|
||||||
|
|
||||||
use self::args::Arguments;
|
use self::args::Arguments;
|
||||||
|
|
||||||
|
@ -18,24 +19,22 @@ pub const DEFAULT_BUNDLE_SIZE: usize = 25;
|
||||||
pub const DEFAULT_VACUUM_RATIO: f32 = 0.5;
|
pub const DEFAULT_VACUUM_RATIO: f32 = 0.5;
|
||||||
|
|
||||||
|
|
||||||
fn open_repository(path: &str) -> Repository {
|
fn checked<T, E: Display>(result: Result<T, E>, msg: &'static str) -> T {
|
||||||
match Repository::open(path) {
|
match result {
|
||||||
Ok(repo) => repo,
|
Ok(val) => val,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("Failed to open repository: {}", err);
|
error!("Failed to {}\n\tcaused by: {}", msg, err);
|
||||||
exit(2);
|
exit(3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn open_repository(path: &str) -> Repository {
|
||||||
|
checked(Repository::open(path), "load repository")
|
||||||
|
}
|
||||||
|
|
||||||
fn get_backup(repo: &Repository, backup_name: &str) -> Backup {
|
fn get_backup(repo: &Repository, backup_name: &str) -> Backup {
|
||||||
match repo.get_backup(backup_name) {
|
checked(repo.get_backup(backup_name), "load backup")
|
||||||
Ok(backup) => backup,
|
|
||||||
Err(err) => {
|
|
||||||
error!("Failed to load backup: {}", err);
|
|
||||||
exit(3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_reference_backup(repo: &Repository, path: &str) -> Option<Backup> {
|
fn find_reference_backup(repo: &Repository, path: &str) -> Option<Backup> {
|
||||||
|
@ -137,20 +136,20 @@ pub fn run() {
|
||||||
}
|
}
|
||||||
match args::parse() {
|
match args::parse() {
|
||||||
Arguments::Init{repo_path, bundle_size, chunker, compression, encryption, hash, remote_path} => {
|
Arguments::Init{repo_path, bundle_size, chunker, compression, encryption, hash, remote_path} => {
|
||||||
let mut repo = Repository::create(repo_path, Config {
|
let mut repo = checked(Repository::create(repo_path, Config {
|
||||||
bundle_size: bundle_size,
|
bundle_size: bundle_size,
|
||||||
chunker: chunker,
|
chunker: chunker,
|
||||||
compression: compression,
|
compression: compression,
|
||||||
encryption: None,
|
encryption: None,
|
||||||
hash: hash
|
hash: hash
|
||||||
}, remote_path).unwrap();
|
}, remote_path), "create repository");
|
||||||
if encryption {
|
if encryption {
|
||||||
let (public, secret) = gen_keypair();
|
let (public, secret) = gen_keypair();
|
||||||
println!("public: {}", to_hex(&public[..]));
|
println!("public: {}", to_hex(&public[..]));
|
||||||
println!("secret: {}", to_hex(&secret[..]));
|
println!("secret: {}", to_hex(&secret[..]));
|
||||||
repo.set_encryption(Some(&public));
|
repo.set_encryption(Some(&public));
|
||||||
repo.register_key(public, secret).unwrap();
|
checked(repo.register_key(public, secret), "add key");
|
||||||
repo.save_config().unwrap();
|
checked(repo.save_config(), "save config");
|
||||||
println!();
|
println!();
|
||||||
}
|
}
|
||||||
print_config(&repo.config);
|
print_config(&repo.config);
|
||||||
|
@ -180,17 +179,17 @@ pub fn run() {
|
||||||
exit(3)
|
exit(3)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
repo.save_backup(&backup, &backup_name).unwrap();
|
checked(repo.save_backup(&backup, &backup_name), "save backup file");
|
||||||
print_backup(&backup);
|
print_backup(&backup);
|
||||||
},
|
},
|
||||||
Arguments::Restore{repo_path, backup_name, inode, dst_path} => {
|
Arguments::Restore{repo_path, backup_name, inode, dst_path} => {
|
||||||
let mut repo = open_repository(&repo_path);
|
let mut repo = open_repository(&repo_path);
|
||||||
let backup = get_backup(&repo, &backup_name);
|
let backup = get_backup(&repo, &backup_name);
|
||||||
if let Some(inode) = inode {
|
if let Some(inode) = inode {
|
||||||
let inode = repo.get_backup_inode(&backup, &inode).unwrap();
|
let inode = checked(repo.get_backup_inode(&backup, &inode), "load subpath inode");
|
||||||
repo.restore_inode_tree(inode, &dst_path).unwrap();
|
checked(repo.restore_inode_tree(inode, &dst_path), "restore subpath");
|
||||||
} else {
|
} else {
|
||||||
repo.restore_backup(&backup, &dst_path).unwrap();
|
checked(repo.restore_backup(&backup, &dst_path), "restore backup");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Arguments::Remove{repo_path, backup_name, inode} => {
|
Arguments::Remove{repo_path, backup_name, inode} => {
|
||||||
|
@ -200,7 +199,7 @@ pub fn run() {
|
||||||
error!("Removing backup subtrees is not implemented yet");
|
error!("Removing backup subtrees is not implemented yet");
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
repo.delete_backup(&backup_name).unwrap();
|
checked(repo.delete_backup(&backup_name), "delete backup");
|
||||||
info!("The backup has been deleted, run vacuum to reclaim space");
|
info!("The backup has been deleted, run vacuum to reclaim space");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -210,14 +209,14 @@ pub fn run() {
|
||||||
error!("This would remove all those backups");
|
error!("This would remove all those backups");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
repo.prune_backups(&prefix, daily, weekly, monthly, yearly, force).unwrap();
|
checked(repo.prune_backups(&prefix, daily, weekly, monthly, yearly, force), "prune backups");
|
||||||
if !force {
|
if !force {
|
||||||
info!("Run with --force to actually execute this command");
|
info!("Run with --force to actually execute this command");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Arguments::Vacuum{repo_path, ratio, force} => {
|
Arguments::Vacuum{repo_path, ratio, force} => {
|
||||||
let mut repo = open_repository(&repo_path);
|
let mut repo = open_repository(&repo_path);
|
||||||
repo.vacuum(ratio, force).unwrap();
|
checked(repo.vacuum(ratio, force), "vacuum");
|
||||||
if !force {
|
if !force {
|
||||||
info!("Run with --force to actually execute this command");
|
info!("Run with --force to actually execute this command");
|
||||||
}
|
}
|
||||||
|
@ -228,24 +227,24 @@ pub fn run() {
|
||||||
if let Some(backup_name) = backup_name {
|
if let Some(backup_name) = backup_name {
|
||||||
let backup = get_backup(&repo, &backup_name);
|
let backup = get_backup(&repo, &backup_name);
|
||||||
if let Some(inode) = inode {
|
if let Some(inode) = inode {
|
||||||
let inode = repo.get_backup_inode(&backup, inode).unwrap();
|
let inode = checked(repo.get_backup_inode(&backup, inode), "load subpath inode");
|
||||||
repo.check_inode(&inode).unwrap()
|
checked(repo.check_inode(&inode), "check inode")
|
||||||
} else {
|
} else {
|
||||||
repo.check_backup(&backup).unwrap()
|
checked(repo.check_backup(&backup), "check backup")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
repo.check(full).unwrap()
|
checked(repo.check(full), "check repository")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Arguments::List{repo_path, backup_name, inode} => {
|
Arguments::List{repo_path, backup_name, inode} => {
|
||||||
let mut repo = open_repository(&repo_path);
|
let mut repo = open_repository(&repo_path);
|
||||||
if let Some(backup_name) = backup_name {
|
if let Some(backup_name) = backup_name {
|
||||||
let backup = get_backup(&repo, &backup_name);
|
let backup = get_backup(&repo, &backup_name);
|
||||||
let inode = repo.get_backup_inode(&backup, inode.as_ref().map(|v| v as &str).unwrap_or("/")).unwrap();
|
let inode = checked(repo.get_backup_inode(&backup, inode.as_ref().map(|v| v as &str).unwrap_or("/")), "load subpath inode");
|
||||||
println!("{}", format_inode_one_line(&inode));
|
println!("{}", format_inode_one_line(&inode));
|
||||||
if let Some(children) = inode.children {
|
if let Some(children) = inode.children {
|
||||||
for chunks in children.values() {
|
for chunks in children.values() {
|
||||||
let inode = repo.get_inode(chunks).unwrap();
|
let inode = checked(repo.get_inode(chunks), "load child inode");
|
||||||
println!("- {}", format_inode_one_line(&inode));
|
println!("- {}", format_inode_one_line(&inode));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -286,7 +285,7 @@ pub fn run() {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Arguments::Import{repo_path, remote_path, key_files} => {
|
Arguments::Import{repo_path, remote_path, key_files} => {
|
||||||
Repository::import(repo_path, remote_path, key_files).unwrap();
|
checked(Repository::import(repo_path, remote_path, key_files), "import repository");
|
||||||
},
|
},
|
||||||
Arguments::Configure{repo_path, bundle_size, chunker, compression, encryption, hash} => {
|
Arguments::Configure{repo_path, bundle_size, chunker, compression, encryption, hash} => {
|
||||||
let mut repo = open_repository(&repo_path);
|
let mut repo = open_repository(&repo_path);
|
||||||
|
@ -307,7 +306,7 @@ pub fn run() {
|
||||||
warn!("Changing the hash makes it impossible to use existing data for deduplication");
|
warn!("Changing the hash makes it impossible to use existing data for deduplication");
|
||||||
repo.config.hash = hash
|
repo.config.hash = hash
|
||||||
}
|
}
|
||||||
repo.save_config().unwrap();
|
checked(repo.save_config(), "save config");
|
||||||
print_config(&repo.config);
|
print_config(&repo.config);
|
||||||
},
|
},
|
||||||
Arguments::GenKey{file} => {
|
Arguments::GenKey{file} => {
|
||||||
|
@ -315,23 +314,23 @@ pub fn run() {
|
||||||
println!("public: {}", to_hex(&public[..]));
|
println!("public: {}", to_hex(&public[..]));
|
||||||
println!("secret: {}", to_hex(&secret[..]));
|
println!("secret: {}", to_hex(&secret[..]));
|
||||||
if let Some(file) = file {
|
if let Some(file) = file {
|
||||||
Crypto::save_keypair_to_file(&public, &secret, file).unwrap();
|
checked(Crypto::save_keypair_to_file(&public, &secret, file), "save key pair");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Arguments::AddKey{repo_path, set_default, file} => {
|
Arguments::AddKey{repo_path, set_default, file} => {
|
||||||
let mut repo = open_repository(&repo_path);
|
let mut repo = open_repository(&repo_path);
|
||||||
let (public, secret) = if let Some(file) = file {
|
let (public, secret) = if let Some(file) = file {
|
||||||
Crypto::load_keypair_from_file(file).unwrap()
|
checked(Crypto::load_keypair_from_file(file), "load key pair")
|
||||||
} else {
|
} else {
|
||||||
let (public, secret) = gen_keypair();
|
let (public, secret) = gen_keypair();
|
||||||
println!("public: {}", to_hex(&public[..]));
|
println!("public: {}", to_hex(&public[..]));
|
||||||
println!("secret: {}", to_hex(&secret[..]));
|
println!("secret: {}", to_hex(&secret[..]));
|
||||||
(public, secret)
|
(public, secret)
|
||||||
};
|
};
|
||||||
repo.register_key(public, secret).unwrap();
|
checked(repo.register_key(public, secret), "add key pair");
|
||||||
if set_default {
|
if set_default {
|
||||||
repo.set_encryption(Some(&public));
|
repo.set_encryption(Some(&public));
|
||||||
repo.save_config().unwrap();
|
checked(repo.save_config(), "save config");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Arguments::AlgoTest{bundle_size, chunker, compression, encrypt, hash, file} => {
|
Arguments::AlgoTest{bundle_size, chunker, compression, encrypt, hash, file} => {
|
||||||
|
|
Loading…
Reference in New Issue