pull/10/head
Dennis Schwerdel 2017-03-22 14:10:42 +01:00
parent 70905fa5e8
commit bc152b6609
5 changed files with 18 additions and 6 deletions

View File

@ -145,6 +145,11 @@ impl BundleDb {
Ok((new, gone)) Ok((new, gone))
} }
pub fn save_cache(&self) -> Result<(), BundleDbError> {
let bundles: Vec<_> = self.remote_bundles.values().cloned().collect();
Ok(try!(StoredBundle::save_list_to(&bundles, &self.remote_cache_path)))
}
pub fn update_cache(&mut self, new: &[StoredBundle], gone: &[StoredBundle]) -> Result<(), BundleDbError> { pub fn update_cache(&mut self, new: &[StoredBundle], gone: &[StoredBundle]) -> Result<(), BundleDbError> {
for bundle in new { for bundle in new {
if bundle.info.mode == BundleMode::Meta { if bundle.info.mode == BundleMode::Meta {
@ -237,7 +242,7 @@ impl BundleDb {
} }
let (folder, filename) = bundle_path(&id, self.remote_path.clone(), self.remote_bundles.len()); let (folder, filename) = bundle_path(&id, self.remote_path.clone(), self.remote_bundles.len());
try!(fs::create_dir_all(&folder).context(&folder as &Path)); try!(fs::create_dir_all(&folder).context(&folder as &Path));
let bundle = try!(bundle.copy_to(folder.join(filename))); let bundle = try!(bundle.move_to(folder.join(filename)));
self.remote_bundles.insert(bundle.id(), bundle.clone()); self.remote_bundles.insert(bundle.id(), bundle.clone());
Ok(bundle.info) Ok(bundle.info)
} }

View File

@ -11,7 +11,8 @@ pub enum Arguments {
chunker: ChunkerType, chunker: ChunkerType,
compression: Option<Compression>, compression: Option<Compression>,
encryption: bool, encryption: bool,
hash: HashMethod hash: HashMethod,
remote: String
}, },
Backup { Backup {
repo_path: String, repo_path: String,
@ -200,6 +201,7 @@ pub fn parse() -> Arguments {
(@arg compression: --compression -c +takes_value "compression to use [default: brotli/3]") (@arg compression: --compression -c +takes_value "compression to use [default: brotli/3]")
(@arg encryption: --encryption -e "generate a keypair and enable encryption") (@arg encryption: --encryption -e "generate a keypair and enable encryption")
(@arg hash: --hash +takes_value "hash method to use [default: blake2]") (@arg hash: --hash +takes_value "hash method to use [default: blake2]")
(@arg remote: --remote -r +takes_value +required "path to the mounted remote storage")
(@arg REPO: +required "path of the repository") (@arg REPO: +required "path of the repository")
) )
(@subcommand backup => (@subcommand backup =>
@ -299,6 +301,7 @@ pub fn parse() -> Arguments {
encryption: args.is_present("encryption"), encryption: args.is_present("encryption"),
hash: parse_hash(args.value_of("hash").unwrap_or(DEFAULT_HASH)), hash: parse_hash(args.value_of("hash").unwrap_or(DEFAULT_HASH)),
repo_path: repository.to_string(), repo_path: repository.to_string(),
remote: args.value_of("remote").unwrap().to_string()
} }
} }
if let Some(args) = args.subcommand_matches("backup") { if let Some(args) = args.subcommand_matches("backup") {

View File

@ -136,14 +136,14 @@ pub fn run() {
exit(-1) exit(-1)
} }
match args::parse() { match args::parse() {
Arguments::Init{repo_path, bundle_size, chunker, compression, encryption, hash} => { Arguments::Init{repo_path, bundle_size, chunker, compression, encryption, hash, remote} => {
let mut repo = Repository::create(repo_path, Config { let mut repo = 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
}).unwrap(); }, remote).unwrap();
if encryption { if encryption {
let (public, secret) = gen_keypair(); let (public, secret) = gen_keypair();
println!("Public key: {}", to_hex(&public[..])); println!("Public key: {}", to_hex(&public[..]));

View File

@ -15,6 +15,7 @@ use std::cmp::max;
use std::path::{PathBuf, Path}; use std::path::{PathBuf, Path};
use std::fs; use std::fs;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::os::unix::fs::symlink;
pub use self::error::RepositoryError; pub use self::error::RepositoryError;
pub use self::config::Config; pub use self::config::Config;
@ -41,11 +42,12 @@ pub struct Repository {
impl Repository { impl Repository {
pub fn create<P: AsRef<Path>>(path: P, config: Config) -> Result<Self, RepositoryError> { pub fn create<P: AsRef<Path>, R: AsRef<Path>>(path: P, config: Config, remote: R) -> Result<Self, RepositoryError> {
let path = path.as_ref().to_owned(); let path = path.as_ref().to_owned();
try!(fs::create_dir(&path)); try!(fs::create_dir(&path));
try!(fs::create_dir(path.join("keys"))); try!(fs::create_dir(path.join("keys")));
let crypto = Arc::new(Mutex::new(try!(Crypto::open(path.join("keys"))))); let crypto = Arc::new(Mutex::new(try!(Crypto::open(path.join("keys")))));
try!(symlink(remote, path.join("remote")));
let bundles = try!(BundleDb::create( let bundles = try!(BundleDb::create(
path.join("remote/bundles"), path.join("remote/bundles"),
path.join("bundles"), path.join("bundles"),
@ -101,6 +103,7 @@ impl Repository {
for bundle in gone { for bundle in gone {
try!(repo.remove_gone_remote_bundle(bundle)) try!(repo.remove_gone_remote_bundle(bundle))
} }
try!(repo.save_bundle_map());
repo.next_meta_bundle = repo.next_free_bundle_id(); repo.next_meta_bundle = repo.next_free_bundle_id();
repo.next_content_bundle = repo.next_free_bundle_id(); repo.next_content_bundle = repo.next_free_bundle_id();
Ok(repo) Ok(repo)
@ -162,6 +165,7 @@ impl Repository {
self.next_meta_bundle = self.next_free_bundle_id() self.next_meta_bundle = self.next_free_bundle_id()
} }
try!(self.save_bundle_map()); try!(self.save_bundle_map());
try!(self.bundles.save_cache());
Ok(()) Ok(())
} }

View File

@ -138,7 +138,7 @@ impl Repository {
}; };
let entry = self.index.get_entry(pos).unwrap(); let entry = self.index.get_entry(pos).unwrap();
if rewrite_bundles.contains(&entry.data.bundle) { if rewrite_bundles.contains(&entry.data.bundle) {
panic!("Removed bundle is still referenced from index"); panic!("Removed bundle is still referenced in index");
} }
pos += 1; pos += 1;
} }