use std::env;
use rpassword;
use borg;
use config;
use password;
use state;
use utils;
use errors::*;
pub fn ask_and_set_new_password() -> Result<()> {
let pwd1 = rpassword::prompt_password_stdout("New password: ")?;
let pwd2 = rpassword::prompt_password_stdout("Confirm password: ")?;
if pwd1 != pwd2 {
bail!("passwords do not match");
}
password::set_password(pwd1.as_str())
}
pub fn backup() -> Result<()> {
let config = config::Config::load_user()?;
let home_dir = match env::home_dir() {
None => bail!("cannot determine home directory"),
Some(x) => x,
};
let passphrase = password::get_password()?;
let mut state = state::State::load()?;
for destination in &config.destinations {
let repo = utils::expanded(destination.repo.as_ref())?;
let repo = repo.as_ref();
macro_rules! or_continue {
($x:expr) => {
match $x {
Err(ref e) => {
warn!("backup to {} failed", repo);
warn!("caused by: {}", e);
continue;
},
Ok(x) => x,
}
}
}
if !destination.before_backup.is_empty() {
info!("before backup: {}", destination.before_backup.join(" "));
or_continue!(utils::run(&destination.before_backup));
}
info!("backing up to {}", repo);
or_continue!(borg::borg_init(repo, passphrase.as_str()));
or_continue!(borg::borg_create(
repo,
passphrase.as_str(),
&home_dir,
&config.exclude,
));
info!("pruning old backups");
or_continue!(borg::borg_prune(repo, passphrase.as_str()));
if !destination.after_backup.is_empty() {
info!("after backup: {}", destination.after_backup.join(" "));
or_continue!(utils::run(&destination.after_backup));
}
debug!("updating state file");
state.mark_success(destination)?;
}
Ok(())
}