mirror of https://github.com/dswd/zvault
Remove folders of backups (re #5)
This commit is contained in:
parent
650ab331c0
commit
8a57476da3
|
@ -3,7 +3,7 @@ zvault-remove(1) -- Remove a backup or a subtree
|
||||||
|
|
||||||
## SYNOPSIS
|
## SYNOPSIS
|
||||||
|
|
||||||
`zvault remove <BACKUP>`
|
`zvault remove [OPTIONS] <BACKUP>`
|
||||||
|
|
||||||
|
|
||||||
## DESCRIPTION
|
## DESCRIPTION
|
||||||
|
@ -17,6 +17,9 @@ If `repository` is omitted, the default repository location is used instead.
|
||||||
If a backup is referenced, this backup will be deleted. If a subtree is given,
|
If a backup is referenced, this backup will be deleted. If a subtree is given,
|
||||||
the backup is instead rewritten to not include that subtree anymore.
|
the backup is instead rewritten to not include that subtree anymore.
|
||||||
|
|
||||||
|
If a folder of backups is referenced by `BACKUP` the flag `--force` must be set
|
||||||
|
in order to remove all backups in that folder (also recursively).
|
||||||
|
|
||||||
Note: When removing backup subtrees, the meta information of that backup is left
|
Note: When removing backup subtrees, the meta information of that backup is left
|
||||||
unchanged and still contains the data (e.g. duration and size) of the original
|
unchanged and still contains the data (e.g. duration and size) of the original
|
||||||
backup run.
|
backup run.
|
||||||
|
@ -32,6 +35,11 @@ data of the deleted backups becomes inaccessible and can not be restored.**
|
||||||
|
|
||||||
## OPTIONS
|
## OPTIONS
|
||||||
|
|
||||||
|
* `-f`, `--force`:
|
||||||
|
|
||||||
|
Remove multiple backups in a backup folder
|
||||||
|
|
||||||
|
|
||||||
* `-h`, `--help`:
|
* `-h`, `--help`:
|
||||||
|
|
||||||
Prints help information
|
Prints help information
|
||||||
|
|
|
@ -37,7 +37,8 @@ pub enum Arguments {
|
||||||
Remove {
|
Remove {
|
||||||
repo_path: String,
|
repo_path: String,
|
||||||
backup_name: String,
|
backup_name: String,
|
||||||
inode: Option<String>
|
inode: Option<String>,
|
||||||
|
force: bool
|
||||||
},
|
},
|
||||||
Prune {
|
Prune {
|
||||||
repo_path: String,
|
repo_path: String,
|
||||||
|
@ -318,6 +319,7 @@ pub fn parse() -> Result<(LogLevel, Arguments), ErrorCode> {
|
||||||
.arg(Arg::from_usage("<DST> 'Destination path for backup'")
|
.arg(Arg::from_usage("<DST> 'Destination path for backup'")
|
||||||
.validator(validate_existing_path)))
|
.validator(validate_existing_path)))
|
||||||
.subcommand(SubCommand::with_name("remove").aliases(&["rm", "delete", "del"]).about("Remove a backup or a subtree")
|
.subcommand(SubCommand::with_name("remove").aliases(&["rm", "delete", "del"]).about("Remove a backup or a subtree")
|
||||||
|
.arg(Arg::from_usage("-f --force 'Remove multiple backups in a backup folder'"))
|
||||||
.arg(Arg::from_usage("<BACKUP> 'The backup/subtree path, [repository]::backup[::subtree]'")
|
.arg(Arg::from_usage("<BACKUP> 'The backup/subtree path, [repository]::backup[::subtree]'")
|
||||||
.validator(|val| validate_repo_path(val, true, Some(true), None))))
|
.validator(|val| validate_repo_path(val, true, Some(true), None))))
|
||||||
.subcommand(SubCommand::with_name("prune").about("Remove backups based on age")
|
.subcommand(SubCommand::with_name("prune").about("Remove backups based on age")
|
||||||
|
@ -468,7 +470,8 @@ pub fn parse() -> Result<(LogLevel, Arguments), ErrorCode> {
|
||||||
Arguments::Remove {
|
Arguments::Remove {
|
||||||
repo_path: repository.to_string(),
|
repo_path: repository.to_string(),
|
||||||
backup_name: backup.unwrap().to_string(),
|
backup_name: backup.unwrap().to_string(),
|
||||||
inode: inode.map(|v| v.to_string())
|
inode: inode.map(|v| v.to_string()),
|
||||||
|
force: args.is_present("force")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
("prune", Some(args)) => {
|
("prune", Some(args)) => {
|
||||||
|
|
|
@ -386,13 +386,25 @@ pub fn run() -> Result<(), ErrorCode> {
|
||||||
}
|
}
|
||||||
info!("Restore finished");
|
info!("Restore finished");
|
||||||
},
|
},
|
||||||
Arguments::Remove{repo_path, backup_name, inode} => {
|
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 {
|
||||||
let mut backup = try!(get_backup(&repo, &backup_name));
|
let mut backup = try!(get_backup(&repo, &backup_name));
|
||||||
checked!(repo.remove_backup_path(&mut backup, inode), "remove backup subpath", ErrorCode::RemoveRun);
|
checked!(repo.remove_backup_path(&mut backup, inode), "remove backup subpath", ErrorCode::RemoveRun);
|
||||||
checked!(repo.save_backup(&backup, &backup_name), "save backup file", ErrorCode::SaveBackup);
|
checked!(repo.save_backup(&backup, &backup_name), "save backup file", ErrorCode::SaveBackup);
|
||||||
info!("The backup subpath has been deleted, run vacuum to reclaim space");
|
info!("The backup subpath has been deleted, run vacuum to reclaim space");
|
||||||
|
} else if repo.layout.backups_path().join(&backup_name).is_dir() {
|
||||||
|
let backups = checked!(repo.get_backups(&backup_name), "retrieve backups", ErrorCode::RemoveRun);
|
||||||
|
if force {
|
||||||
|
for name in backups.keys() {
|
||||||
|
checked!(repo.delete_backup(&format!("{}/{}", &backup_name, name)), "delete backup", ErrorCode::RemoveRun);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
error!("Denying to remove multiple backups (use --force):");
|
||||||
|
for name in backups.keys() {
|
||||||
|
println!(" - {}/{}", backup_name, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
checked!(repo.delete_backup(&backup_name), "delete backup", ErrorCode::RemoveRun);
|
checked!(repo.delete_backup(&backup_name), "delete backup", ErrorCode::RemoveRun);
|
||||||
info!("The backup has been deleted, run vacuum to reclaim space");
|
info!("The backup has been deleted, run vacuum to reclaim space");
|
||||||
|
|
Loading…
Reference in New Issue