2019-01-04 18:24:03 +00:00
|
|
|
package restic
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2023-05-13 20:34:02 +00:00
|
|
|
"fmt"
|
2019-01-04 18:24:03 +00:00
|
|
|
"sort"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
2022-12-10 14:29:20 +00:00
|
|
|
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:
|
2023-05-13 20:34:02 +00:00
|
|
|
return SnapshotGroupByOptions{}, fmt.Errorf("unknown grouping option: %q", option)
|
2022-12-10 14:29:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
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"
|
|
|
|
}
|
|
|
|
|
2019-01-04 18:24:03 +00:00
|
|
|
// 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
|
2023-03-04 03:07:57 +00:00
|
|
|
// a grouped list of snapshots.
|
2022-12-10 14:29:20 +00:00
|
|
|
func GroupSnapshots(snapshots Snapshots, groupBy SnapshotGroupByOptions) (map[string]Snapshots, bool, error) {
|
2019-01-04 18:24:03 +00:00
|
|
|
// 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
|
|
|
|
|
2022-12-10 14:29:20 +00:00
|
|
|
if groupBy.Tag {
|
2019-01-04 18:24:03 +00:00
|
|
|
tags = sn.Tags
|
2020-03-06 22:22:10 +00:00
|
|
|
sort.Strings(tags)
|
2019-01-04 18:24:03 +00:00
|
|
|
}
|
2022-12-10 14:29:20 +00:00
|
|
|
if groupBy.Host {
|
2019-01-04 18:24:03 +00:00
|
|
|
hostname = sn.Hostname
|
|
|
|
}
|
2022-12-10 14:29:20 +00:00
|
|
|
if groupBy.Path {
|
2019-01-04 18:24:03 +00:00
|
|
|
paths = sn.Paths
|
|
|
|
}
|
|
|
|
|
2020-03-06 22:22:10 +00:00
|
|
|
sort.Strings(sn.Paths)
|
2019-01-04 18:24:03 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2022-12-10 14:29:20 +00:00
|
|
|
return snapshotGroups, groupBy.Tag || groupBy.Host || groupBy.Path, nil
|
2019-01-04 18:24:03 +00:00
|
|
|
}
|