forked from TrueCloudLab/restic
Move snapshot grouping code into own function to deduplicate code
This commit moves the code which is used to group snapshots in the snapshots command into an own function to deduplicate code shared by the snapshots command and forget command.
This commit is contained in:
parent
c9fd9b5275
commit
c4475ac58f
1 changed files with 82 additions and 66 deletions
|
@ -70,60 +70,16 @@ func runSnapshots(opts SnapshotOptions, gopts GlobalOptions, args []string) erro
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// group by hostname and dirs
|
|
||||||
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()
|
||||||
|
|
||||||
|
var snapshots restic.Snapshots
|
||||||
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) {
|
||||||
// Determining grouping-keys
|
snapshots = append(snapshots, sn)
|
||||||
var tags []string
|
}
|
||||||
var hostname string
|
snapshotGroups, grouped, err := GroupSnapshots(snapshots, opts.GroupBy)
|
||||||
var paths []string
|
if err != nil {
|
||||||
|
return err
|
||||||
if GroupByTag {
|
|
||||||
tags = sn.Tags
|
|
||||||
sort.StringSlice(tags).Sort()
|
|
||||||
}
|
|
||||||
if GroupByHost {
|
|
||||||
hostname = sn.Hostname
|
|
||||||
}
|
|
||||||
if GroupByPath {
|
|
||||||
paths = sn.Paths
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.StringSlice(sn.Paths).Sort()
|
|
||||||
var k []byte
|
|
||||||
var err error
|
|
||||||
|
|
||||||
k, err = json.Marshal(groupKey{Tags: tags, Hostname: hostname, Paths: paths})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
snapshotGroups[string(k)] = append(snapshotGroups[string(k)], sn)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, list := range snapshotGroups {
|
for k, list := range snapshotGroups {
|
||||||
|
@ -135,7 +91,7 @@ func runSnapshots(opts SnapshotOptions, gopts GlobalOptions, args []string) erro
|
||||||
}
|
}
|
||||||
|
|
||||||
if gopts.JSON {
|
if gopts.JSON {
|
||||||
err := printSnapshotGroupJSON(gopts.stdout, snapshotGroups, GroupByTag || GroupByHost || GroupByPath)
|
err := printSnapshotGroupJSON(gopts.stdout, snapshotGroups, grouped)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Warnf("error printing snapshots: %v\n", err)
|
Warnf("error printing snapshots: %v\n", err)
|
||||||
}
|
}
|
||||||
|
@ -143,12 +99,13 @@ func runSnapshots(opts SnapshotOptions, gopts GlobalOptions, args []string) erro
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, list := range snapshotGroups {
|
for k, list := range snapshotGroups {
|
||||||
err := PrintSnapshotGroupHeader(gopts.stdout, k, GroupByTag, GroupByHost, GroupByPath)
|
if grouped {
|
||||||
if err != nil {
|
err := PrintSnapshotGroupHeader(gopts.stdout, k)
|
||||||
Warnf("error printing snapshots: %v\n", err)
|
if err != nil {
|
||||||
return nil
|
Warnf("error printing snapshots: %v\n", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintSnapshots(gopts.stdout, list, nil, opts.Compact)
|
PrintSnapshots(gopts.stdout, list, nil, opts.Compact)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,6 +148,65 @@ func FilterLastSnapshots(list restic.Snapshots) restic.Snapshots {
|
||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GroupSnapshots takes a list of snapshots and a grouping criteria and creates
|
||||||
|
// a group list of snapshots.
|
||||||
|
func GroupSnapshots(snapshots restic.Snapshots, options string) (map[string]restic.Snapshots, bool, error) {
|
||||||
|
// group by hostname and dirs
|
||||||
|
snapshotGroups := make(map[string]restic.Snapshots)
|
||||||
|
|
||||||
|
var GroupByTag bool
|
||||||
|
var GroupByHost bool
|
||||||
|
var GroupByPath bool
|
||||||
|
var GroupOptionList []string
|
||||||
|
|
||||||
|
GroupOptionList = strings.Split(options, ",")
|
||||||
|
|
||||||
|
for _, option := range GroupOptionList {
|
||||||
|
switch option {
|
||||||
|
case "host":
|
||||||
|
GroupByHost = true
|
||||||
|
case "paths":
|
||||||
|
GroupByPath = true
|
||||||
|
case "tags":
|
||||||
|
GroupByTag = true
|
||||||
|
case "":
|
||||||
|
default:
|
||||||
|
return nil, false, errors.Fatal("unknown grouping option: '" + option + "'")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, sn := range snapshots {
|
||||||
|
// Determining grouping-keys
|
||||||
|
var tags []string
|
||||||
|
var hostname string
|
||||||
|
var paths []string
|
||||||
|
|
||||||
|
if GroupByTag {
|
||||||
|
tags = sn.Tags
|
||||||
|
sort.StringSlice(tags).Sort()
|
||||||
|
}
|
||||||
|
if GroupByHost {
|
||||||
|
hostname = sn.Hostname
|
||||||
|
}
|
||||||
|
if GroupByPath {
|
||||||
|
paths = sn.Paths
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.StringSlice(sn.Paths).Sort()
|
||||||
|
var k []byte
|
||||||
|
var err error
|
||||||
|
|
||||||
|
k, err = json.Marshal(groupKey{Tags: tags, Hostname: hostname, Paths: paths})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
snapshotGroups[string(k)] = append(snapshotGroups[string(k)], sn)
|
||||||
|
}
|
||||||
|
|
||||||
|
return snapshotGroups, GroupByTag || GroupByHost || GroupByPath, nil
|
||||||
|
}
|
||||||
|
|
||||||
// PrintSnapshots prints a text table of the snapshots in list to stdout.
|
// PrintSnapshots prints a text table of the snapshots in list to stdout.
|
||||||
func PrintSnapshots(stdout io.Writer, list restic.Snapshots, reasons []restic.KeepReason, compact bool) {
|
func PrintSnapshots(stdout io.Writer, list restic.Snapshots, reasons []restic.KeepReason, compact bool) {
|
||||||
// keep the reasons a snasphot is being kept in a map, so that it doesn't
|
// keep the reasons a snasphot is being kept in a map, so that it doesn't
|
||||||
|
@ -294,10 +310,7 @@ func PrintSnapshots(stdout io.Writer, list restic.Snapshots, reasons []restic.Ke
|
||||||
// PrintSnapshotGroupHeader prints which group of the group-by option the
|
// PrintSnapshotGroupHeader prints which group of the group-by option the
|
||||||
// following snapshots belong to.
|
// following snapshots belong to.
|
||||||
// Prints nothing, if we did not group at all.
|
// Prints nothing, if we did not group at all.
|
||||||
func PrintSnapshotGroupHeader(stdout io.Writer, groupKeyJSON string, GroupByTag bool, GroupByHost bool, GroupByPath bool) error {
|
func PrintSnapshotGroupHeader(stdout io.Writer, groupKeyJSON string) error {
|
||||||
if !GroupByTag && !GroupByHost && !GroupByPath {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
var key groupKey
|
var key groupKey
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
@ -306,16 +319,20 @@ func PrintSnapshotGroupHeader(stdout io.Writer, groupKeyJSON string, GroupByTag
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if key.Hostname == "" && key.Tags == nil && key.Paths == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Info
|
// Info
|
||||||
fmt.Fprintf(stdout, "snapshots")
|
fmt.Fprintf(stdout, "snapshots")
|
||||||
var infoStrings []string
|
var infoStrings []string
|
||||||
if GroupByTag {
|
if key.Hostname != "" {
|
||||||
infoStrings = append(infoStrings, "tags ["+strings.Join(key.Tags, ", ")+"]")
|
|
||||||
}
|
|
||||||
if GroupByHost {
|
|
||||||
infoStrings = append(infoStrings, "host ["+key.Hostname+"]")
|
infoStrings = append(infoStrings, "host ["+key.Hostname+"]")
|
||||||
}
|
}
|
||||||
if GroupByPath {
|
if key.Tags != nil {
|
||||||
|
infoStrings = append(infoStrings, "tags ["+strings.Join(key.Tags, ", ")+"]")
|
||||||
|
}
|
||||||
|
if key.Paths != nil {
|
||||||
infoStrings = append(infoStrings, "paths ["+strings.Join(key.Paths, ", ")+"]")
|
infoStrings = append(infoStrings, "paths ["+strings.Join(key.Paths, ", ")+"]")
|
||||||
}
|
}
|
||||||
if infoStrings != nil {
|
if infoStrings != nil {
|
||||||
|
@ -342,7 +359,6 @@ type SnapshotGroup struct {
|
||||||
|
|
||||||
// printSnapshotsJSON writes the JSON representation of list to stdout.
|
// printSnapshotsJSON writes the JSON representation of list to stdout.
|
||||||
func printSnapshotGroupJSON(stdout io.Writer, snGroups map[string]restic.Snapshots, grouped bool) error {
|
func printSnapshotGroupJSON(stdout io.Writer, snGroups map[string]restic.Snapshots, grouped bool) error {
|
||||||
|
|
||||||
if grouped {
|
if grouped {
|
||||||
var snapshotGroups []SnapshotGroup
|
var snapshotGroups []SnapshotGroup
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue