mirror of
https://github.com/octoleo/restic.git
synced 2024-12-22 10:58:55 +00:00
Merge pull request 2090 from plumbeo/within-hours
Increase the granularity of the "keep within" snapshot retention policy
This commit is contained in:
commit
1f246c5309
9
changelog/unreleased/issue-2089
Normal file
9
changelog/unreleased/issue-2089
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
Enhancement: increase granularity of the "keep within" retention policy
|
||||||
|
|
||||||
|
The `keep-within` option of the `forget` command now accepts time ranges with
|
||||||
|
an hourly granularity. For example, running `restic forget --keep-within 3d12h`
|
||||||
|
will keep all the snapshots made within three days and twelve hours from the
|
||||||
|
time of the latest snapshot.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2089
|
||||||
|
https://github.com/restic/restic/pull/2090
|
@ -59,7 +59,7 @@ func init() {
|
|||||||
f.IntVarP(&forgetOptions.Weekly, "keep-weekly", "w", 0, "keep the last `n` weekly snapshots")
|
f.IntVarP(&forgetOptions.Weekly, "keep-weekly", "w", 0, "keep the last `n` weekly snapshots")
|
||||||
f.IntVarP(&forgetOptions.Monthly, "keep-monthly", "m", 0, "keep the last `n` monthly snapshots")
|
f.IntVarP(&forgetOptions.Monthly, "keep-monthly", "m", 0, "keep the last `n` monthly snapshots")
|
||||||
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.VarP(&forgetOptions.Within, "keep-within", "", "keep snapshots that are older than `duration` (eg. 1y5m7d) relative to the latest snapshot")
|
f.VarP(&forgetOptions.Within, "keep-within", "", "keep snapshots that are newer than `duration` (eg. 1y5m7d2h) relative to the latest snapshot")
|
||||||
|
|
||||||
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.StringVar(&forgetOptions.Host, "host", "", "only consider snapshots with the given `host`")
|
f.StringVar(&forgetOptions.Host, "host", "", "only consider snapshots with the given `host`")
|
||||||
|
@ -168,8 +168,9 @@ The ``forget`` command accepts the following parameters:
|
|||||||
this option (can be specified multiple times).
|
this option (can be specified multiple times).
|
||||||
- ``--keep-within duration`` keep all snapshots which have been made within
|
- ``--keep-within duration`` keep all snapshots which have been made within
|
||||||
the duration of the latest snapshot. ``duration`` needs to be a number of
|
the duration of the latest snapshot. ``duration`` needs to be a number of
|
||||||
years, months, and days, e.g. ``2y5m7d`` will keep all snapshots made in the
|
years, months, days, and hours, e.g. ``2y5m7d3h`` will keep all snapshots
|
||||||
two years, five months, and seven days before the latest snapshot.
|
made in the two years, five months, seven days, and three hours before the
|
||||||
|
latest snapshot.
|
||||||
|
|
||||||
Multiple policies will be ORed together so as to be as inclusive as possible
|
Multiple policies will be ORed together so as to be as inclusive as possible
|
||||||
for keeping snapshots.
|
for keeping snapshots.
|
||||||
|
@ -10,9 +10,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Duration is similar to time.Duration, except it only supports larger ranges
|
// Duration is similar to time.Duration, except it only supports larger ranges
|
||||||
// like days, months, and years.
|
// like hours, days, months, and years.
|
||||||
type Duration struct {
|
type Duration struct {
|
||||||
Days, Months, Years int
|
Hours, Days, Months, Years int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d Duration) String() string {
|
func (d Duration) String() string {
|
||||||
@ -29,6 +29,10 @@ func (d Duration) String() string {
|
|||||||
s += fmt.Sprintf("%dd", d.Days)
|
s += fmt.Sprintf("%dd", d.Days)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if d.Hours != 0 {
|
||||||
|
s += fmt.Sprintf("%dh", d.Hours)
|
||||||
|
}
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +77,7 @@ func nextNumber(input string) (num int, rest string, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ParseDuration parses a duration from a string. The format is:
|
// ParseDuration parses a duration from a string. The format is:
|
||||||
// 6y5m234d
|
// 6y5m234d37h
|
||||||
func ParseDuration(s string) (Duration, error) {
|
func ParseDuration(s string) (Duration, error) {
|
||||||
var (
|
var (
|
||||||
d Duration
|
d Duration
|
||||||
@ -100,6 +104,8 @@ func ParseDuration(s string) (Duration, error) {
|
|||||||
d.Months = num
|
d.Months = num
|
||||||
case 'd':
|
case 'd':
|
||||||
d.Days = num
|
d.Days = num
|
||||||
|
case 'h':
|
||||||
|
d.Hours = num
|
||||||
}
|
}
|
||||||
|
|
||||||
s = s[1:]
|
s = s[1:]
|
||||||
@ -127,5 +133,5 @@ func (d Duration) Type() string {
|
|||||||
|
|
||||||
// Zero returns true if the duration is empty (all values are set to zero).
|
// Zero returns true if the duration is empty (all values are set to zero).
|
||||||
func (d Duration) Zero() bool {
|
func (d Duration) Zero() bool {
|
||||||
return d.Years == 0 && d.Months == 0 && d.Days == 0
|
return d.Years == 0 && d.Months == 0 && d.Days == 0 && d.Hours == 0
|
||||||
}
|
}
|
||||||
|
@ -13,15 +13,24 @@ func TestNextNumber(t *testing.T) {
|
|||||||
rest string
|
rest string
|
||||||
err bool
|
err bool
|
||||||
}{
|
}{
|
||||||
|
{
|
||||||
|
input: "12h", num: 12, rest: "h",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
input: "3d", num: 3, rest: "d",
|
input: "3d", num: 3, rest: "d",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
input: "4d9h", num: 4, rest: "d9h",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
input: "7m5d", num: 7, rest: "m5d",
|
input: "7m5d", num: 7, rest: "m5d",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: "-23y7m5d", num: -23, rest: "y7m5d",
|
input: "-23y7m5d", num: -23, rest: "y7m5d",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
input: "-13y5m11d12h", num: -13, rest: "y5m11d12h",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
input: " 5d", num: 0, rest: " 5d", err: true,
|
input: " 5d", num: 0, rest: " 5d", err: true,
|
||||||
},
|
},
|
||||||
@ -55,10 +64,15 @@ func TestParseDuration(t *testing.T) {
|
|||||||
d Duration
|
d Duration
|
||||||
output string
|
output string
|
||||||
}{
|
}{
|
||||||
|
{"9h", Duration{Hours: 9}, "9h"},
|
||||||
{"3d", Duration{Days: 3}, "3d"},
|
{"3d", Duration{Days: 3}, "3d"},
|
||||||
|
{"4d2h", Duration{Days: 4, Hours: 2}, "4d2h"},
|
||||||
{"7m5d", Duration{Months: 7, Days: 5}, "7m5d"},
|
{"7m5d", Duration{Months: 7, Days: 5}, "7m5d"},
|
||||||
|
{"6m4d8h", Duration{Months: 6, Days: 4, Hours: 8}, "6m4d8h"},
|
||||||
{"5d7m", Duration{Months: 7, Days: 5}, "7m5d"},
|
{"5d7m", Duration{Months: 7, Days: 5}, "7m5d"},
|
||||||
|
{"4h3d9m", Duration{Months: 9, Days: 3, Hours: 4}, "9m3d4h"},
|
||||||
{"-7m5d", Duration{Months: -7, Days: 5}, "-7m5d"},
|
{"-7m5d", Duration{Months: -7, Days: 5}, "-7m5d"},
|
||||||
|
{"1y4m-5d-3h", Duration{Years: 1, Months: 4, Days: -5, Hours: -3}, "1y4m-5d-3h"},
|
||||||
{"2y7m-5d", Duration{Years: 2, Months: 7, Days: -5}, "2y7m-5d"},
|
{"2y7m-5d", Duration{Years: 2, Months: 7, Days: -5}, "2y7m-5d"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +196,7 @@ func ApplyPolicy(list Snapshots, p ExpirePolicy) (keep, remove Snapshots, reason
|
|||||||
|
|
||||||
// If the timestamp of the snapshot is within the range, then keep it.
|
// If the timestamp of the snapshot is within the range, then keep it.
|
||||||
if !p.Within.Zero() {
|
if !p.Within.Zero() {
|
||||||
t := latest.AddDate(-p.Within.Years, -p.Within.Months, -p.Within.Days)
|
t := latest.AddDate(-p.Within.Years, -p.Within.Months, -p.Within.Days).Add(time.Hour * time.Duration(-p.Within.Hours))
|
||||||
if cur.Time.After(t) {
|
if cur.Time.After(t) {
|
||||||
keepSnap = true
|
keepSnap = true
|
||||||
keepSnapReasons = append(keepSnapReasons, fmt.Sprintf("within %v", p.Within))
|
keepSnapReasons = append(keepSnapReasons, fmt.Sprintf("within %v", p.Within))
|
||||||
|
@ -225,6 +225,9 @@ func TestApplyPolicy(t *testing.T) {
|
|||||||
{Within: parseDuration("1m")},
|
{Within: parseDuration("1m")},
|
||||||
{Within: parseDuration("1m14d")},
|
{Within: parseDuration("1m14d")},
|
||||||
{Within: parseDuration("1y1d1m")},
|
{Within: parseDuration("1y1d1m")},
|
||||||
|
{Within: parseDuration("13d23h")},
|
||||||
|
{Within: parseDuration("2m2h")},
|
||||||
|
{Within: parseDuration("1y2m3d3h")},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, p := range tests {
|
for i, p := range tests {
|
||||||
|
150
internal/restic/testdata/policy_keep_snapshots_27
vendored
Normal file
150
internal/restic/testdata/policy_keep_snapshots_27
vendored
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
{
|
||||||
|
"keep": [
|
||||||
|
{
|
||||||
|
"time": "2016-01-18T12:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2016-01-12T21:08:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2016-01-12T21:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2016-01-09T21:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2016-01-08T20:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2016-01-07T10:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2016-01-06T08:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2016-01-05T09:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2016-01-04T16:23:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"reasons": [
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-18T12:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 13d23h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-12T21:08:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 13d23h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-12T21:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 13d23h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-09T21:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 13d23h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-08T20:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 13d23h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-07T10:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 13d23h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-06T08:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 13d23h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-05T09:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 13d23h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-04T16:23:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 13d23h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
374
internal/restic/testdata/policy_keep_snapshots_28
vendored
Normal file
374
internal/restic/testdata/policy_keep_snapshots_28
vendored
Normal file
@ -0,0 +1,374 @@
|
|||||||
|
{
|
||||||
|
"keep": [
|
||||||
|
{
|
||||||
|
"time": "2016-01-18T12:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2016-01-12T21:08:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2016-01-12T21:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2016-01-09T21:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2016-01-08T20:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2016-01-07T10:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2016-01-06T08:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2016-01-05T09:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2016-01-04T16:23:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2016-01-04T12:30:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2016-01-04T12:28:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2016-01-04T12:24:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2016-01-04T12:23:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2016-01-04T11:23:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2016-01-04T10:23:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2016-01-03T07:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2016-01-01T07:08:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2016-01-01T01:03:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2016-01-01T01:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2015-11-22T10:20:30Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2015-11-21T10:20:30Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2015-11-20T10:20:30Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "2015-11-18T10:20:30Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"reasons": [
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-18T12:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 2m2h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-12T21:08:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 2m2h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-12T21:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 2m2h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-09T21:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 2m2h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-08T20:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 2m2h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-07T10:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 2m2h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-06T08:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 2m2h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-05T09:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 2m2h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-04T16:23:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 2m2h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-04T12:30:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 2m2h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-04T12:28:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 2m2h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-04T12:24:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 2m2h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-04T12:23:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 2m2h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-04T11:23:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 2m2h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-04T10:23:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 2m2h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-03T07:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 2m2h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-01T07:08:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 2m2h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-01T01:03:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 2m2h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2016-01-01T01:02:03Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 2m2h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2015-11-22T10:20:30Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 2m2h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2015-11-21T10:20:30Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 2m2h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2015-11-20T10:20:30Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 2m2h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"snapshot": {
|
||||||
|
"time": "2015-11-18T10:20:30Z",
|
||||||
|
"tree": null,
|
||||||
|
"paths": null
|
||||||
|
},
|
||||||
|
"matches": [
|
||||||
|
"within 2m2h"
|
||||||
|
],
|
||||||
|
"counters": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
1132
internal/restic/testdata/policy_keep_snapshots_29
vendored
Normal file
1132
internal/restic/testdata/policy_keep_snapshots_29
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user