mirror of https://github.com/dswd/zvault
Added `copy` subcommand
This commit is contained in:
parent
148db7d627
commit
ca28d3ebff
|
@ -3,6 +3,10 @@
|
|||
This project follows [semantic versioning](http://semver.org).
|
||||
|
||||
|
||||
### UNRELEASED
|
||||
* [added] Added `copy` subcommand
|
||||
|
||||
|
||||
### v0.3.2 (2017-05-11)
|
||||
* [modified] Changed order of arguments in `addkey` to match src-dst scheme
|
||||
* [modified] Skip root folder on restore
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
zvault-copy(1) -- Create a copy of a backup
|
||||
===========================================
|
||||
|
||||
## SYNOPSIS
|
||||
|
||||
`zvault copy [OPTIONS] <SRC> <DST>`
|
||||
|
||||
|
||||
## DESCRIPTION
|
||||
|
||||
This subcommand copies the backup `SRC` to a new name `DST`.
|
||||
|
||||
The backups given by `SRC` and `DST` must be in the format
|
||||
`[repository]::backup_name[::subtree]` as described in _zvault(1)_.
|
||||
If `repository` is omitted, the default repository location is used instead.
|
||||
|
||||
|
||||
## OPTIONS
|
||||
|
||||
* `-h`, `--help`:
|
||||
|
||||
Prints help information
|
||||
|
||||
|
||||
## COPYRIGHT
|
||||
|
||||
Copyright (C) 2017 Dennis Schwerdel
|
||||
This software is licensed under GPL-3 or newer (see LICENSE.md)
|
|
@ -43,6 +43,7 @@ location.
|
|||
* `info` Display information on a repository, a backup or a subtree, _zvault-info(1)_
|
||||
* `mount` Mount the repository, a backup or a subtree, _zvault-mount(1)_
|
||||
* `remove` Remove a backup or a subtree, _zvault-remove(1)_
|
||||
* `copy` Create a copy of a backup, _zvault-copy(1)_
|
||||
* `prune` Remove backups based on age, _zvault-prune(1)_
|
||||
* `vacuum` Reclaim space by rewriting bundles, _zvault-vacuum(1)_
|
||||
|
||||
|
|
|
@ -74,6 +74,12 @@ pub enum Arguments {
|
|||
backup_name: Option<String>,
|
||||
inode: Option<String>
|
||||
},
|
||||
Copy {
|
||||
repo_path_src: String,
|
||||
backup_name_src: String,
|
||||
repo_path_dst: String,
|
||||
backup_name_dst: String,
|
||||
},
|
||||
Mount {
|
||||
repo_path: String,
|
||||
backup_name: Option<String>,
|
||||
|
@ -396,6 +402,11 @@ pub fn parse() -> Result<(LogLevel, Arguments), ErrorCode> {
|
|||
.validator(|val| validate_repo_path(val, true, Some(true), None)))
|
||||
.arg(Arg::from_usage("<NEW> 'New version, [repository]::backup[::subpath]'")
|
||||
.validator(|val| validate_repo_path(val, true, Some(true), None))))
|
||||
.subcommand(SubCommand::with_name("copy").alias("cp").about("Create a copy of a backup")
|
||||
.arg(Arg::from_usage("<SRC> 'Existing backup, [repository]::backup'")
|
||||
.validator(|val| validate_repo_path(val, true, Some(true), Some(false))))
|
||||
.arg(Arg::from_usage("<DST> 'Destination backup, [repository]::backup'")
|
||||
.validator(|val| validate_repo_path(val, true, Some(true), Some(false)))))
|
||||
.subcommand(SubCommand::with_name("config").about("Display or change the configuration")
|
||||
.arg(Arg::from_usage("[bundle_size] --bundle-size [SIZE] 'Set the target bundle size in MiB'")
|
||||
.validator(validate_num))
|
||||
|
@ -551,6 +562,16 @@ pub fn parse() -> Result<(LogLevel, Arguments), ErrorCode> {
|
|||
inode: inode.map(|v| v.to_string())
|
||||
}
|
||||
},
|
||||
("copy", Some(args)) => {
|
||||
let (repository_src, backup_src, _inode) = parse_repo_path(args.value_of("SRC").unwrap(), true, Some(true), Some(false)).unwrap();
|
||||
let (repository_dst, backup_dst, _inode) = parse_repo_path(args.value_of("DST").unwrap(), true, Some(true), Some(false)).unwrap();
|
||||
Arguments::Copy {
|
||||
repo_path_src: repository_src.to_string(),
|
||||
backup_name_src: backup_src.unwrap().to_string(),
|
||||
repo_path_dst: repository_dst.to_string(),
|
||||
backup_name_dst: backup_dst.unwrap().to_string(),
|
||||
}
|
||||
},
|
||||
("mount", Some(args)) => {
|
||||
let (repository, backup, inode) = parse_repo_path(args.value_of("PATH").unwrap(), true, None, None).unwrap();
|
||||
Arguments::Mount {
|
||||
|
|
|
@ -404,6 +404,19 @@ pub fn run() -> Result<(), ErrorCode> {
|
|||
}
|
||||
info!("Restore finished");
|
||||
},
|
||||
Arguments::Copy{repo_path_src, backup_name_src, repo_path_dst, backup_name_dst} => {
|
||||
if repo_path_src != repo_path_dst {
|
||||
error!("Can only run copy on same repository");
|
||||
return Err(ErrorCode::InvalidArgs)
|
||||
}
|
||||
let mut repo = try!(open_repository(&repo_path_src));
|
||||
if repo.has_backup(&backup_name_dst) {
|
||||
error!("A backup with that name already exists");
|
||||
return Err(ErrorCode::BackupAlreadyExists)
|
||||
}
|
||||
let backup = try!(get_backup(&repo, &backup_name_src));
|
||||
checked!(repo.save_backup(&backup, &backup_name_dst), "save backup file", ErrorCode::SaveBackup);
|
||||
},
|
||||
Arguments::Remove{repo_path, backup_name, inode, force} => {
|
||||
let mut repo = try!(open_repository(&repo_path));
|
||||
if let Some(inode) = inode {
|
||||
|
|
Loading…
Reference in New Issue