From 685f5ebbd1ad5de0335dc3e8cbd6c2595da76a15 Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Tue, 21 Feb 2017 10:58:30 +0100 Subject: [PATCH] Add `--prune` switch to `forget` --- doc/Manual.md | 40 +++++++++++++++++++++++++++++++++-- src/cmds/restic/cmd_forget.go | 12 +++++++++++ src/cmds/restic/cmd_prune.go | 6 +++++- 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/doc/Manual.md b/doc/Manual.md index 0fc37143a..b7feb7b1f 100644 --- a/doc/Manual.md +++ b/doc/Manual.md @@ -545,7 +545,8 @@ be done either manually (by specifying a snapshot ID to remove) or by using a policy that describes which snapshots to forget. For all remove operations, two commands need to be called in sequence: `forget` to remove a snapshot and `prune` to actually remove the data that was referenced by the snapshot from -the repository. +the repository. This can be automated with the `--prune` option of the `forget` +command, which runs `prune` automatically if snapshots have been removed. ## Remove a single snapshot @@ -610,6 +611,41 @@ done Afterwards the repository is smaller. +You can automate this two-step process by using the `--prune` switch to +`forget`: + +```console +$ restic forget --keep-last 1 --prune +snapshots for host mopped, directories /home/user/work: + +keep 1 snapshots: +ID Date Host Tags Directory +---------------------------------------------------------------------- +4bba301e 2017-02-21 10:49:18 mopped /home/user/work + +remove 1 snapshots: +ID Date Host Tags Directory +---------------------------------------------------------------------- +8c02b94b 2017-02-21 10:48:33 mopped /home/user/work + +1 snapshots have been removed, running prune +counting files in repo +building new index for repo +[0:00] 100.00% 37 / 37 packs +repository contains 37 packs (5521 blobs) with 151.012 MiB bytes +processed 5521 blobs: 0 duplicate blobs, 0B duplicate +load all snapshots +find data that is still in use for 1 snapshots +[0:00] 100.00% 1 / 1 snapshots +found 5323 of 5521 data blobs still in use, removing 198 blobs +will delete 0 packs and rewrite 27 packs, this frees 22.106 MiB +creating new index +[0:00] 100.00% 30 / 30 packs +saved new index as b49f3e68 +done +``` + + ## Removing snapshots according to a policy Removing snapshots manually is tedious and error-prone, therefore restic allows @@ -747,4 +783,4 @@ enter password for repository: Restic supports the output of some commands in JSON format. The JSON flag ```--json``` is currently supported only by ```restic snapshots```. ```console -$ restic -r /tmp/backup snapshots --json``` \ No newline at end of file +$ restic -r /tmp/backup snapshots --json``` diff --git a/src/cmds/restic/cmd_forget.go b/src/cmds/restic/cmd_forget.go index a28ae6f62..deaf999aa 100644 --- a/src/cmds/restic/cmd_forget.go +++ b/src/cmds/restic/cmd_forget.go @@ -38,6 +38,7 @@ type ForgetOptions struct { Tags []string DryRun bool + Prune bool } var forgetOptions ForgetOptions @@ -58,6 +59,7 @@ func init() { f.StringSliceVar(&forgetOptions.Tags, "tag", []string{}, "only forget snapshots with the `tag` (can be specified multiple times)") f.BoolVarP(&forgetOptions.DryRun, "dry-run", "n", false, "do not delete anything, just print what would be done") + f.BoolVar(&forgetOptions.Prune, "prune", false, "automatically run the 'prune' command if snapshots have been removed") } func printSnapshots(w io.Writer, snapshots restic.Snapshots) { @@ -188,6 +190,7 @@ func runForget(opts ForgetOptions, gopts GlobalOptions, args []string) error { snapshotGroups[k] = list } + removeSnapshots := 0 for key, snapshotGroup := range snapshotGroups { Printf("snapshots for host %v, directories %v:\n\n", key.Hostname, key.Dirs) keep, remove := restic.ApplyPolicy(snapshotGroup, policy) @@ -200,6 +203,8 @@ func runForget(opts ForgetOptions, gopts GlobalOptions, args []string) error { printSnapshots(globalOptions.stdout, remove) Printf("\n") + removeSnapshots += len(remove) + if !opts.DryRun { for _, sn := range remove { h := restic.Handle{Type: restic.SnapshotFile, Name: sn.ID().String()} @@ -211,5 +216,12 @@ func runForget(opts ForgetOptions, gopts GlobalOptions, args []string) error { } } + if removeSnapshots > 0 && opts.Prune { + Printf("%d snapshots have been removed, running prune\n", removeSnapshots) + if !opts.DryRun { + return pruneRepository(gopts, repo) + } + } + return nil } diff --git a/src/cmds/restic/cmd_prune.go b/src/cmds/restic/cmd_prune.go index f43c99f00..1922f35ce 100644 --- a/src/cmds/restic/cmd_prune.go +++ b/src/cmds/restic/cmd_prune.go @@ -75,7 +75,11 @@ func runPrune(gopts GlobalOptions) error { return err } - err = repo.LoadIndex() + return pruneRepository(gopts, repo) +} + +func pruneRepository(gopts GlobalOptions, repo restic.Repository) error { + err := repo.LoadIndex() if err != nil { return err }