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).
|
This project follows [semantic versioning](http://semver.org).
|
||||||
|
|
||||||
|
|
||||||
|
### UNRELEASED
|
||||||
|
* [added] Added `copy` subcommand
|
||||||
|
|
||||||
|
|
||||||
### v0.3.2 (2017-05-11)
|
### v0.3.2 (2017-05-11)
|
||||||
* [modified] Changed order of arguments in `addkey` to match src-dst scheme
|
* [modified] Changed order of arguments in `addkey` to match src-dst scheme
|
||||||
* [modified] Skip root folder on restore
|
* [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)_
|
* `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)_
|
* `mount` Mount the repository, a backup or a subtree, _zvault-mount(1)_
|
||||||
* `remove` Remove a backup or a subtree, _zvault-remove(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)_
|
* `prune` Remove backups based on age, _zvault-prune(1)_
|
||||||
* `vacuum` Reclaim space by rewriting bundles, _zvault-vacuum(1)_
|
* `vacuum` Reclaim space by rewriting bundles, _zvault-vacuum(1)_
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,12 @@ pub enum Arguments {
|
||||||
backup_name: Option<String>,
|
backup_name: Option<String>,
|
||||||
inode: Option<String>
|
inode: Option<String>
|
||||||
},
|
},
|
||||||
|
Copy {
|
||||||
|
repo_path_src: String,
|
||||||
|
backup_name_src: String,
|
||||||
|
repo_path_dst: String,
|
||||||
|
backup_name_dst: String,
|
||||||
|
},
|
||||||
Mount {
|
Mount {
|
||||||
repo_path: String,
|
repo_path: String,
|
||||||
backup_name: Option<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)))
|
.validator(|val| validate_repo_path(val, true, Some(true), None)))
|
||||||
.arg(Arg::from_usage("<NEW> 'New version, [repository]::backup[::subpath]'")
|
.arg(Arg::from_usage("<NEW> 'New version, [repository]::backup[::subpath]'")
|
||||||
.validator(|val| validate_repo_path(val, true, Some(true), None))))
|
.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")
|
.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'")
|
.arg(Arg::from_usage("[bundle_size] --bundle-size [SIZE] 'Set the target bundle size in MiB'")
|
||||||
.validator(validate_num))
|
.validator(validate_num))
|
||||||
|
@ -551,6 +562,16 @@ pub fn parse() -> Result<(LogLevel, Arguments), ErrorCode> {
|
||||||
inode: inode.map(|v| v.to_string())
|
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)) => {
|
("mount", Some(args)) => {
|
||||||
let (repository, backup, inode) = parse_repo_path(args.value_of("PATH").unwrap(), true, None, None).unwrap();
|
let (repository, backup, inode) = parse_repo_path(args.value_of("PATH").unwrap(), true, None, None).unwrap();
|
||||||
Arguments::Mount {
|
Arguments::Mount {
|
||||||
|
|
|
@ -404,6 +404,19 @@ pub fn run() -> Result<(), ErrorCode> {
|
||||||
}
|
}
|
||||||
info!("Restore finished");
|
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} => {
|
Arguments::Remove{repo_path, backup_name, inode, force} => {
|
||||||
let mut repo = try!(open_repository(&repo_path));
|
let mut repo = try!(open_repository(&repo_path));
|
||||||
if let Some(inode) = inode {
|
if let Some(inode) = inode {
|
||||||
|
|
Loading…
Reference in New Issue