-
Notifications
You must be signed in to change notification settings - Fork 0
/
snapshot_group.go
105 lines (91 loc) · 2.17 KB
/
snapshot_group.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package restic
import (
"encoding/json"
"fmt"
"sort"
"strings"
)
type SnapshotGroupByOptions struct {
Tag bool
Host bool
Path bool
}
func splitSnapshotGroupBy(s string) (SnapshotGroupByOptions, error) {
var l SnapshotGroupByOptions
for _, option := range strings.Split(s, ",") {
switch option {
case "host", "hosts":
l.Host = true
case "path", "paths":
l.Path = true
case "tag", "tags":
l.Tag = true
case "":
default:
return SnapshotGroupByOptions{}, fmt.Errorf("unknown grouping option: %q", option)
}
}
return l, nil
}
func (l SnapshotGroupByOptions) String() string {
var parts []string
if l.Host {
parts = append(parts, "host")
}
if l.Path {
parts = append(parts, "paths")
}
if l.Tag {
parts = append(parts, "tags")
}
return strings.Join(parts, ",")
}
func (l *SnapshotGroupByOptions) Set(s string) error {
parts, err := splitSnapshotGroupBy(s)
if err != nil {
return err
}
*l = parts
return nil
}
func (l *SnapshotGroupByOptions) Type() string {
return "group"
}
// SnapshotGroupKey is the structure for identifying groups in a grouped
// snapshot list. This is used by GroupSnapshots()
type SnapshotGroupKey struct {
Hostname string `json:"hostname"`
Paths []string `json:"paths"`
Tags []string `json:"tags"`
}
// GroupSnapshots takes a list of snapshots and a grouping criteria and creates
// a grouped list of snapshots.
func GroupSnapshots(snapshots Snapshots, groupBy SnapshotGroupByOptions) (map[string]Snapshots, bool, error) {
// group by hostname and dirs
snapshotGroups := make(map[string]Snapshots)
for _, sn := range snapshots {
// Determining grouping-keys
var tags []string
var hostname string
var paths []string
if groupBy.Tag {
tags = sn.Tags
sort.Strings(tags)
}
if groupBy.Host {
hostname = sn.Hostname
}
if groupBy.Path {
paths = sn.Paths
}
sort.Strings(sn.Paths)
var k []byte
var err error
k, err = json.Marshal(SnapshotGroupKey{Tags: tags, Hostname: hostname, Paths: paths})
if err != nil {
return nil, false, err
}
snapshotGroups[string(k)] = append(snapshotGroups[string(k)], sn)
}
return snapshotGroups, groupBy.Tag || groupBy.Host || groupBy.Path, nil
}