mirror of
https://github.com/octoleo/restic.git
synced 2024-11-22 12:55:18 +00:00
Merge pull request #1196 from mungomat/forget_groupByTagsOnly
forget: group-by-tags-only
This commit is contained in:
commit
b6aeea425b
@ -6,6 +6,7 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/restic/restic/internal/errors"
|
||||||
"github.com/restic/restic/internal/restic"
|
"github.com/restic/restic/internal/restic"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
@ -38,9 +39,10 @@ type ForgetOptions struct {
|
|||||||
Tags restic.TagLists
|
Tags restic.TagLists
|
||||||
Paths []string
|
Paths []string
|
||||||
|
|
||||||
GroupByTags bool
|
// Grouping
|
||||||
DryRun bool
|
GroupBy string
|
||||||
Prune bool
|
DryRun bool
|
||||||
|
Prune bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var forgetOptions ForgetOptions
|
var forgetOptions ForgetOptions
|
||||||
@ -57,7 +59,6 @@ func init() {
|
|||||||
f.IntVarP(&forgetOptions.Yearly, "keep-yearly", "y", 0, "keep the last `n` yearly snapshots")
|
f.IntVarP(&forgetOptions.Yearly, "keep-yearly", "y", 0, "keep the last `n` yearly snapshots")
|
||||||
|
|
||||||
f.Var(&forgetOptions.KeepTags, "keep-tag", "keep snapshots with this `taglist` (can be specified multiple times)")
|
f.Var(&forgetOptions.KeepTags, "keep-tag", "keep snapshots with this `taglist` (can be specified multiple times)")
|
||||||
f.BoolVarP(&forgetOptions.GroupByTags, "group-by-tags", "G", false, "Group by host,paths,tags instead of just host,paths")
|
|
||||||
// Sadly the commonly used shortcut `H` is already used.
|
// Sadly the commonly used shortcut `H` is already used.
|
||||||
f.StringVar(&forgetOptions.Host, "host", "", "only consider snapshots with the given `host`")
|
f.StringVar(&forgetOptions.Host, "host", "", "only consider snapshots with the given `host`")
|
||||||
// Deprecated since 2017-03-07.
|
// Deprecated since 2017-03-07.
|
||||||
@ -65,6 +66,7 @@ func init() {
|
|||||||
f.Var(&forgetOptions.Tags, "tag", "only consider snapshots which include this `taglist` in the format `tag[,tag,...]` (can be specified multiple times)")
|
f.Var(&forgetOptions.Tags, "tag", "only consider snapshots which include this `taglist` in the format `tag[,tag,...]` (can be specified multiple times)")
|
||||||
f.StringArrayVar(&forgetOptions.Paths, "path", nil, "only consider snapshots which include this (absolute) `path` (can be specified multiple times)")
|
f.StringArrayVar(&forgetOptions.Paths, "path", nil, "only consider snapshots which include this (absolute) `path` (can be specified multiple times)")
|
||||||
|
|
||||||
|
f.StringVarP(&forgetOptions.GroupBy, "group-by", "g", "host,paths", "string for grouping snapshots by host,paths,tags")
|
||||||
f.BoolVarP(&forgetOptions.DryRun, "dry-run", "n", false, "do not delete anything, just print what would be done")
|
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")
|
f.BoolVar(&forgetOptions.Prune, "prune", false, "automatically run the 'prune' command if snapshots have been removed")
|
||||||
|
|
||||||
@ -91,6 +93,27 @@ func runForget(opts ForgetOptions, gopts GlobalOptions, args []string) error {
|
|||||||
}
|
}
|
||||||
snapshotGroups := make(map[string]restic.Snapshots)
|
snapshotGroups := make(map[string]restic.Snapshots)
|
||||||
|
|
||||||
|
var GroupByTag bool
|
||||||
|
var GroupByHost bool
|
||||||
|
var GroupByPath bool
|
||||||
|
var GroupOptionList []string
|
||||||
|
|
||||||
|
GroupOptionList = strings.Split(opts.GroupBy, ",")
|
||||||
|
|
||||||
|
for _, option := range GroupOptionList {
|
||||||
|
switch option {
|
||||||
|
case "host":
|
||||||
|
GroupByHost = true
|
||||||
|
case "paths":
|
||||||
|
GroupByPath = true
|
||||||
|
case "tags":
|
||||||
|
GroupByTag = true
|
||||||
|
case "":
|
||||||
|
default:
|
||||||
|
return errors.Fatal("unknown grouping option: '" + option + "'")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(gopts.ctx)
|
ctx, cancel := context.WithCancel(gopts.ctx)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
for sn := range FindFilteredSnapshots(ctx, repo, opts.Host, opts.Tags, opts.Paths, args) {
|
for sn := range FindFilteredSnapshots(ctx, repo, opts.Host, opts.Tags, opts.Paths, args) {
|
||||||
@ -106,13 +129,28 @@ func runForget(opts ForgetOptions, gopts GlobalOptions, args []string) error {
|
|||||||
Verbosef("would have removed snapshot %v\n", sn.ID().Str())
|
Verbosef("would have removed snapshot %v\n", sn.ID().Str())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Determing grouping-keys
|
||||||
var tags []string
|
var tags []string
|
||||||
if opts.GroupByTags {
|
var hostname string
|
||||||
|
var paths []string
|
||||||
|
|
||||||
|
if GroupByTag {
|
||||||
tags = sn.Tags
|
tags = sn.Tags
|
||||||
sort.StringSlice(tags).Sort()
|
sort.StringSlice(tags).Sort()
|
||||||
}
|
}
|
||||||
|
if GroupByHost {
|
||||||
|
hostname = sn.Hostname
|
||||||
|
}
|
||||||
|
if GroupByPath {
|
||||||
|
paths = sn.Paths
|
||||||
|
}
|
||||||
|
|
||||||
sort.StringSlice(sn.Paths).Sort()
|
sort.StringSlice(sn.Paths).Sort()
|
||||||
k, err := json.Marshal(key{Hostname: sn.Hostname, Tags: tags, Paths: sn.Paths})
|
var k []byte
|
||||||
|
var err error
|
||||||
|
|
||||||
|
k, err = json.Marshal(key{Tags: tags, Hostname: hostname, Paths: paths})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -144,11 +182,24 @@ func runForget(opts ForgetOptions, gopts GlobalOptions, args []string) error {
|
|||||||
if json.Unmarshal([]byte(k), &key) != nil {
|
if json.Unmarshal([]byte(k), &key) != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if opts.GroupByTags {
|
|
||||||
Verbosef("snapshots for host %v, tags [%v], paths: [%v]:\n\n", key.Hostname, strings.Join(key.Tags, ", "), strings.Join(key.Paths, ", "))
|
// Info
|
||||||
} else {
|
Verbosef("snapshots")
|
||||||
Verbosef("snapshots for host %v, paths: [%v]:\n\n", key.Hostname, strings.Join(key.Paths, ", "))
|
var infoStrings []string
|
||||||
|
if GroupByTag {
|
||||||
|
infoStrings = append(infoStrings, "tags ["+strings.Join(key.Tags, ", ")+"]")
|
||||||
}
|
}
|
||||||
|
if GroupByHost {
|
||||||
|
infoStrings = append(infoStrings, "host ["+key.Hostname+"]")
|
||||||
|
}
|
||||||
|
if GroupByPath {
|
||||||
|
infoStrings = append(infoStrings, "paths ["+strings.Join(key.Paths, ", ")+"]")
|
||||||
|
}
|
||||||
|
if infoStrings != nil {
|
||||||
|
Verbosef(" for (" + strings.Join(infoStrings, ", ") + ")")
|
||||||
|
}
|
||||||
|
Verbosef(":\n\n")
|
||||||
|
|
||||||
keep, remove := restic.ApplyPolicy(snapshotGroup, policy)
|
keep, remove := restic.ApplyPolicy(snapshotGroup, policy)
|
||||||
|
|
||||||
if len(keep) != 0 && !gopts.Quiet {
|
if len(keep) != 0 && !gopts.Quiet {
|
||||||
|
@ -50,10 +50,6 @@ data after 'forget' was run successfully, see the 'prune' command.
|
|||||||
\fB\-\-keep\-tag\fP=[]
|
\fB\-\-keep\-tag\fP=[]
|
||||||
keep snapshots with this \fB\fCtaglist\fR (can be specified multiple times)
|
keep snapshots with this \fB\fCtaglist\fR (can be specified multiple times)
|
||||||
|
|
||||||
.PP
|
|
||||||
\fB\-G\fP, \fB\-\-group\-by\-tags\fP[=false]
|
|
||||||
Group by host,paths,tags instead of just host,paths
|
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
\fB\-\-host\fP=""
|
\fB\-\-host\fP=""
|
||||||
only consider snapshots with the given \fB\fChost\fR
|
only consider snapshots with the given \fB\fChost\fR
|
||||||
@ -70,6 +66,10 @@ data after 'forget' was run successfully, see the 'prune' command.
|
|||||||
\fB\-\-path\fP=[]
|
\fB\-\-path\fP=[]
|
||||||
only consider snapshots which include this (absolute) \fB\fCpath\fR (can be specified multiple times)
|
only consider snapshots which include this (absolute) \fB\fCpath\fR (can be specified multiple times)
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-g\fP, \fB\-\-group\-by\fP="host,paths"
|
||||||
|
string for grouping snapshots by host,paths,tags
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
\fB\-n\fP, \fB\-\-dry\-run\fP[=false]
|
\fB\-n\fP, \fB\-\-dry\-run\fP[=false]
|
||||||
do not delete anything, just print what would be done
|
do not delete anything, just print what would be done
|
||||||
|
Loading…
Reference in New Issue
Block a user