diff --git a/src/cli/args.rs b/src/cli/args.rs index 71aaa37..5c4a1b4 100644 --- a/src/cli/args.rs +++ b/src/cli/args.rs @@ -12,7 +12,7 @@ pub enum Arguments { compression: Option, encryption: bool, hash: HashMethod, - remote: String + remote_path: String }, Backup { repo_path: String, @@ -301,7 +301,7 @@ pub fn parse() -> Arguments { encryption: args.is_present("encryption"), hash: parse_hash(args.value_of("hash").unwrap_or(DEFAULT_HASH)), repo_path: repository.to_string(), - remote: args.value_of("remote").unwrap().to_string() + remote_path: args.value_of("remote").unwrap().to_string() } } if let Some(args) = args.subcommand_matches("backup") { diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 53a1e9c..311f819 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -136,14 +136,14 @@ pub fn run() { exit(-1) } match args::parse() { - Arguments::Init{repo_path, bundle_size, chunker, compression, encryption, hash, remote} => { + Arguments::Init{repo_path, bundle_size, chunker, compression, encryption, hash, remote_path} => { let mut repo = Repository::create(repo_path, Config { bundle_size: bundle_size, chunker: chunker, compression: compression, encryption: None, hash: hash - }, remote).unwrap(); + }, remote_path).unwrap(); if encryption { let (public, secret) = gen_keypair(); println!("Public key: {}", to_hex(&public[..])); @@ -284,9 +284,8 @@ pub fn run() { println!(); } }, - Arguments::Import{..} => { - error!("Import is not implemented yet"); - return + Arguments::Import{repo_path, remote_path} => { + Repository::import(repo_path, remote_path).unwrap(); }, Arguments::Configure{repo_path, bundle_size, chunker, compression, encryption, hash} => { let mut repo = open_repository(&repo_path); diff --git a/src/main.rs b/src/main.rs index 3de5284..457a0a0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,7 +30,7 @@ mod prelude; // TODO: Remove backup subtrees // TODO: Recompress & combine bundles // TODO: list --tree -// TODO: Import repository from remote folder +// TODO: Give crypto keys for import // TODO: More detailed errors with nicer text // TODO: Allow to use tar files for backup and restore (--tar, http://alexcrichton.com/tar-rs/tar/index.html) diff --git a/src/repository/backup.rs b/src/repository/backup.rs index dab492f..4ca35bc 100644 --- a/src/repository/backup.rs +++ b/src/repository/backup.rs @@ -88,7 +88,8 @@ pub struct Backup { pub file_count: usize, pub dir_count: usize, pub host: String, - pub path: String + pub path: String, + pub config: Config, } serde_impl!(Backup(u8) { root: Vec => 0, @@ -104,7 +105,8 @@ serde_impl!(Backup(u8) { file_count: usize => 10, dir_count: usize => 11, host: String => 12, - path: String => 13 + path: String => 13, + config: Config => 14 }); impl Backup { @@ -307,6 +309,7 @@ impl Repository { let mut save_stack = vec![]; let mut directories = HashMap::new(); let mut backup = Backup::default(); + backup.config = self.config.clone(); backup.host = get_hostname().unwrap_or_else(|_| "".to_string()); backup.path = path.as_ref().to_string_lossy().to_string(); let info_before = self.info(); diff --git a/src/repository/config.rs b/src/repository/config.rs index 4ac8623..b8fffaf 100644 --- a/src/repository/config.rs +++ b/src/repository/config.rs @@ -149,7 +149,7 @@ serde_impl!(ConfigYaml(String) { -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct Config { pub compression: Option, pub encryption: Option, @@ -157,6 +157,25 @@ pub struct Config { pub chunker: ChunkerType, pub hash: HashMethod } +impl Default for Config { + fn default() -> Self { + Config { + compression: None, + encryption: None, + bundle_size: 25, + chunker: ChunkerType::from_string("fastcdc/16").unwrap(), + hash: HashMethod::Blake2 + } + } +} +serde_impl!(Config(u64) { + compression: Option => 0, + encryption: Option => 1, + bundle_size: usize => 2, + chunker: ChunkerType => 3, + hash: HashMethod => 4 +}); + impl Config { fn from_yaml(yaml: ConfigYaml) -> Result { let compression = if let Some(c) = yaml.compression { diff --git a/src/repository/error.rs b/src/repository/error.rs index 1702eaa..5bbeddb 100644 --- a/src/repository/error.rs +++ b/src/repository/error.rs @@ -11,6 +11,7 @@ use super::metadata::InodeError; quick_error!{ #[derive(Debug)] + #[allow(unknown_lints,large_enum_variant)] pub enum RepositoryError { Index(err: IndexError) { from() diff --git a/src/repository/mod.rs b/src/repository/mod.rs index 1c9b989..562b0d7 100644 --- a/src/repository/mod.rs +++ b/src/repository/mod.rs @@ -109,6 +109,19 @@ impl Repository { Ok(repo) } + pub fn import, R: AsRef>(path: P, remote: R) -> Result { + let path = path.as_ref(); + try!(Repository::create(path, Config::default(), remote)); + let mut repo = try!(Repository::open(path)); + let mut backups: Vec = try!(repo.get_backups()).into_iter().map(|(_, v)| v).collect(); + backups.sort_by_key(|b| b.date); + if let Some(backup) = backups.pop() { + repo.config = backup.config; + try!(repo.save_config()) + } + Ok(repo) + } + #[inline] pub fn register_key(&mut self, public: PublicKey, secret: SecretKey) -> Result<(), RepositoryError> { Ok(try!(self.crypto.lock().unwrap().register_secret_key(public, secret)))