diff --git a/src/restic/snapshot_filter.go b/src/restic/snapshot_filter.go index 589b4bd4e..3753e2646 100644 --- a/src/restic/snapshot_filter.go +++ b/src/restic/snapshot_filter.go @@ -57,6 +57,7 @@ func FilterSnapshots(s Snapshots, f SnapshotFilter) (result Snapshots) { // ExpirePolicy configures which snapshots should be automatically removed. type ExpirePolicy struct { Last int // keep the last n snapshots + Hourly int // keep the last n hourly snapshots Daily int // keep the last n daily snapshots Weekly int // keep the last n weekly snapshots Monthly int // keep the last n monthly snapshots @@ -81,6 +82,11 @@ func (f filter) String() string { return fmt.Sprintf("", len(f.Unprocessed), len(f.Keep), len(f.Remove)) } +// ymdh returns an integer in the form YYYYMMDDHH. +func ymdh(d time.Time) int { + return d.Year()*1000000 + int(d.Month())*10000 + d.Day()*100 + d.Hour() +} + // ymd returns an integer in the form YYYYMMDD. func ymd(d time.Time) int { return d.Year()*10000 + int(d.Month())*100 + d.Day() @@ -185,6 +191,7 @@ func ApplyPolicy(list Snapshots, p ExpirePolicy) (keep, remove Snapshots) { } f.keepLast(p.Last) + f.apply(ymdh, p.Hourly) f.apply(ymd, p.Daily) f.apply(yw, p.Weekly) f.apply(ym, p.Monthly) diff --git a/src/restic/snapshot_filter_test.go b/src/restic/snapshot_filter_test.go index 6bf65b9be..7a902a687 100644 --- a/src/restic/snapshot_filter_test.go +++ b/src/restic/snapshot_filter_test.go @@ -194,6 +194,7 @@ var expireTests = []ExpirePolicy{ {Last: 15}, {Last: 99}, {Last: 200}, + {Hourly: 20}, {Daily: 3}, {Daily: 10}, {Daily: 30}, diff --git a/src/restic/testdata/expired_snapshots_10 b/src/restic/testdata/expired_snapshots_10 index 853fdce73..63fbd8b09 100644 --- a/src/restic/testdata/expired_snapshots_10 +++ b/src/restic/testdata/expired_snapshots_10 @@ -8,5 +8,55 @@ "time": "2016-01-12T21:08:03+01:00", "tree": null, "paths": null + }, + { + "time": "2016-01-12T21:02:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-09T21:02:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-08T20:02:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-07T10:02:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-06T08:02:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-05T09:02:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-04T16:23:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-03T07:02:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-01T07:08:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2015-11-22T10:20:30+01:00", + "tree": null, + "paths": null } ] \ No newline at end of file diff --git a/src/restic/testdata/expired_snapshots_11 b/src/restic/testdata/expired_snapshots_11 index c89b120a9..853fdce73 100644 --- a/src/restic/testdata/expired_snapshots_11 +++ b/src/restic/testdata/expired_snapshots_11 @@ -8,15 +8,5 @@ "time": "2016-01-12T21:08:03+01:00", "tree": null, "paths": null - }, - { - "time": "2016-01-09T21:02:03+01:00", - "tree": null, - "paths": null - }, - { - "time": "2016-01-03T07:02:03+01:00", - "tree": null, - "paths": null } ] \ No newline at end of file diff --git a/src/restic/testdata/expired_snapshots_12 b/src/restic/testdata/expired_snapshots_12 index 240906b19..c89b120a9 100644 --- a/src/restic/testdata/expired_snapshots_12 +++ b/src/restic/testdata/expired_snapshots_12 @@ -14,24 +14,9 @@ "tree": null, "paths": null }, - { - "time": "2016-01-08T20:02:03+01:00", - "tree": null, - "paths": null - }, { "time": "2016-01-03T07:02:03+01:00", "tree": null, "paths": null - }, - { - "time": "2015-11-22T10:20:30+01:00", - "tree": null, - "paths": null - }, - { - "time": "2015-11-15T10:20:30+01:00", - "tree": null, - "paths": null } ] \ No newline at end of file diff --git a/src/restic/testdata/expired_snapshots_13 b/src/restic/testdata/expired_snapshots_13 index 938a85271..240906b19 100644 --- a/src/restic/testdata/expired_snapshots_13 +++ b/src/restic/testdata/expired_snapshots_13 @@ -4,28 +4,33 @@ "tree": null, "paths": null }, + { + "time": "2016-01-12T21:08:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-09T21:02:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-08T20:02:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-03T07:02:03+01:00", + "tree": null, + "paths": null + }, { "time": "2015-11-22T10:20:30+01:00", "tree": null, "paths": null }, { - "time": "2015-10-22T11:20:30+02:00", - "tree": null, - "paths": null - }, - { - "time": "2015-09-22T11:20:30+02:00", - "tree": null, - "paths": null - }, - { - "time": "2015-08-22T11:20:30+02:00", - "tree": null, - "paths": null - }, - { - "time": "2014-11-22T10:20:30+01:00", + "time": "2015-11-15T10:20:30+01:00", "tree": null, "paths": null } diff --git a/src/restic/testdata/expired_snapshots_14 b/src/restic/testdata/expired_snapshots_14 index 52f6b1aa1..938a85271 100644 --- a/src/restic/testdata/expired_snapshots_14 +++ b/src/restic/testdata/expired_snapshots_14 @@ -4,21 +4,6 @@ "tree": null, "paths": null }, - { - "time": "2016-01-12T21:08:03+01:00", - "tree": null, - "paths": null - }, - { - "time": "2016-01-09T21:02:03+01:00", - "tree": null, - "paths": null - }, - { - "time": "2016-01-03T07:02:03+01:00", - "tree": null, - "paths": null - }, { "time": "2015-11-22T10:20:30+01:00", "tree": null, @@ -43,10 +28,5 @@ "time": "2014-11-22T10:20:30+01:00", "tree": null, "paths": null - }, - { - "time": "2014-10-22T11:20:30+02:00", - "tree": null, - "paths": null } ] \ No newline at end of file diff --git a/src/restic/testdata/expired_snapshots_15 b/src/restic/testdata/expired_snapshots_15 index aaf743f09..52f6b1aa1 100644 --- a/src/restic/testdata/expired_snapshots_15 +++ b/src/restic/testdata/expired_snapshots_15 @@ -4,14 +4,49 @@ "tree": null, "paths": null }, + { + "time": "2016-01-12T21:08:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-09T21:02:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-03T07:02:03+01:00", + "tree": null, + "paths": null + }, { "time": "2015-11-22T10:20:30+01:00", "tree": null, "paths": null }, + { + "time": "2015-10-22T11:20:30+02:00", + "tree": null, + "paths": null + }, + { + "time": "2015-09-22T11:20:30+02:00", + "tree": null, + "paths": null + }, + { + "time": "2015-08-22T11:20:30+02:00", + "tree": null, + "paths": null + }, { "time": "2014-11-22T10:20:30+01:00", "tree": null, "paths": null + }, + { + "time": "2014-10-22T11:20:30+02:00", + "tree": null, + "paths": null } ] \ No newline at end of file diff --git a/src/restic/testdata/expired_snapshots_16 b/src/restic/testdata/expired_snapshots_16 index eddb2c833..aaf743f09 100644 --- a/src/restic/testdata/expired_snapshots_16 +++ b/src/restic/testdata/expired_snapshots_16 @@ -4,66 +4,11 @@ "tree": null, "paths": null }, - { - "time": "2016-01-12T21:08:03+01:00", - "tree": null, - "paths": null - }, - { - "time": "2016-01-09T21:02:03+01:00", - "tree": null, - "paths": null - }, - { - "time": "2016-01-08T20:02:03+01:00", - "tree": null, - "paths": null - }, - { - "time": "2016-01-07T10:02:03+01:00", - "tree": null, - "paths": null - }, - { - "time": "2016-01-06T08:02:03+01:00", - "tree": null, - "paths": null - }, - { - "time": "2016-01-05T09:02:03+01:00", - "tree": null, - "paths": null - }, - { - "time": "2016-01-04T16:23:03+01:00", - "tree": null, - "paths": null - }, - { - "time": "2016-01-03T07:02:03+01:00", - "tree": null, - "paths": null - }, { "time": "2015-11-22T10:20:30+01:00", "tree": null, "paths": null }, - { - "time": "2015-10-22T11:20:30+02:00", - "tree": null, - "paths": null - }, - { - "time": "2015-09-22T11:20:30+02:00", - "tree": null, - "paths": null - }, - { - "time": "2015-08-22T11:20:30+02:00", - "tree": null, - "paths": null - }, { "time": "2014-11-22T10:20:30+01:00", "tree": null, diff --git a/src/restic/testdata/expired_snapshots_17 b/src/restic/testdata/expired_snapshots_17 new file mode 100644 index 000000000..eddb2c833 --- /dev/null +++ b/src/restic/testdata/expired_snapshots_17 @@ -0,0 +1,72 @@ +[ + { + "time": "2016-01-18T12:02:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-12T21:08:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-09T21:02:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-08T20:02:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-07T10:02:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-06T08:02:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-05T09:02:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-04T16:23:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-03T07:02:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2015-11-22T10:20:30+01:00", + "tree": null, + "paths": null + }, + { + "time": "2015-10-22T11:20:30+02:00", + "tree": null, + "paths": null + }, + { + "time": "2015-09-22T11:20:30+02:00", + "tree": null, + "paths": null + }, + { + "time": "2015-08-22T11:20:30+02:00", + "tree": null, + "paths": null + }, + { + "time": "2014-11-22T10:20:30+01:00", + "tree": null, + "paths": null + } +] \ No newline at end of file diff --git a/src/restic/testdata/expired_snapshots_5 b/src/restic/testdata/expired_snapshots_5 index e862779c0..f84efb1f5 100644 --- a/src/restic/testdata/expired_snapshots_5 +++ b/src/restic/testdata/expired_snapshots_5 @@ -13,5 +13,90 @@ "time": "2016-01-09T21:02:03+01:00", "tree": null, "paths": null + }, + { + "time": "2016-01-08T20:02:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-07T10:02:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-06T08:02:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-05T09:02:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-04T16:23:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-04T12:30:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-04T11:23:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-04T10:23:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-03T07:02:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-01T07:08:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2016-01-01T01:03:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2015-11-22T10:20:30+01:00", + "tree": null, + "paths": null + }, + { + "time": "2015-11-21T10:20:30+01:00", + "tree": null, + "paths": null + }, + { + "time": "2015-11-20T10:20:30+01:00", + "tree": null, + "paths": null + }, + { + "time": "2015-11-18T10:20:30+01:00", + "tree": null, + "paths": null + }, + { + "time": "2015-11-15T10:20:30+01:00", + "tree": null, + "paths": null + }, + { + "time": "2015-11-13T10:20:30+01:00", + "tree": null, + "paths": null } ] \ No newline at end of file diff --git a/src/restic/testdata/expired_snapshots_6 b/src/restic/testdata/expired_snapshots_6 index 6f53af139..e862779c0 100644 --- a/src/restic/testdata/expired_snapshots_6 +++ b/src/restic/testdata/expired_snapshots_6 @@ -13,40 +13,5 @@ "time": "2016-01-09T21:02:03+01:00", "tree": null, "paths": null - }, - { - "time": "2016-01-08T20:02:03+01:00", - "tree": null, - "paths": null - }, - { - "time": "2016-01-07T10:02:03+01:00", - "tree": null, - "paths": null - }, - { - "time": "2016-01-06T08:02:03+01:00", - "tree": null, - "paths": null - }, - { - "time": "2016-01-05T09:02:03+01:00", - "tree": null, - "paths": null - }, - { - "time": "2016-01-04T16:23:03+01:00", - "tree": null, - "paths": null - }, - { - "time": "2016-01-03T07:02:03+01:00", - "tree": null, - "paths": null - }, - { - "time": "2016-01-01T07:08:03+01:00", - "tree": null, - "paths": null } ] \ No newline at end of file diff --git a/src/restic/testdata/expired_snapshots_7 b/src/restic/testdata/expired_snapshots_7 index 750da193f..6f53af139 100644 --- a/src/restic/testdata/expired_snapshots_7 +++ b/src/restic/testdata/expired_snapshots_7 @@ -48,105 +48,5 @@ "time": "2016-01-01T07:08:03+01:00", "tree": null, "paths": null - }, - { - "time": "2015-11-22T10:20:30+01:00", - "tree": null, - "paths": null - }, - { - "time": "2015-11-21T10:20:30+01:00", - "tree": null, - "paths": null - }, - { - "time": "2015-11-20T10:20:30+01:00", - "tree": null, - "paths": null - }, - { - "time": "2015-11-18T10:20:30+01:00", - "tree": null, - "paths": null - }, - { - "time": "2015-11-15T10:20:30+01:00", - "tree": null, - "paths": null - }, - { - "time": "2015-11-13T10:20:30+01:00", - "tree": null, - "paths": null - }, - { - "time": "2015-11-12T10:20:30+01:00", - "tree": null, - "paths": null - }, - { - "time": "2015-11-10T10:20:30+01:00", - "tree": null, - "paths": null - }, - { - "time": "2015-11-08T10:20:30+01:00", - "tree": null, - "paths": null - }, - { - "time": "2015-10-22T11:20:30+02:00", - "tree": null, - "paths": null - }, - { - "time": "2015-10-20T11:20:30+02:00", - "tree": null, - "paths": null - }, - { - "time": "2015-10-11T11:20:30+02:00", - "tree": null, - "paths": null - }, - { - "time": "2015-10-10T11:20:30+02:00", - "tree": null, - "paths": null - }, - { - "time": "2015-10-09T11:20:30+02:00", - "tree": null, - "paths": null - }, - { - "time": "2015-10-08T11:20:30+02:00", - "tree": null, - "paths": null - }, - { - "time": "2015-10-06T11:20:30+02:00", - "tree": null, - "paths": null - }, - { - "time": "2015-10-05T11:20:30+02:00", - "tree": null, - "paths": null - }, - { - "time": "2015-10-02T11:20:30+02:00", - "tree": null, - "paths": null - }, - { - "time": "2015-10-01T11:20:30+02:00", - "tree": null, - "paths": null - }, - { - "time": "2015-09-22T11:20:30+02:00", - "tree": null, - "paths": null } ] \ No newline at end of file diff --git a/src/restic/testdata/expired_snapshots_8 b/src/restic/testdata/expired_snapshots_8 index fd72ec6a5..750da193f 100644 --- a/src/restic/testdata/expired_snapshots_8 +++ b/src/restic/testdata/expired_snapshots_8 @@ -9,11 +9,6 @@ "tree": null, "paths": null }, - { - "time": "2016-01-12T21:02:03+01:00", - "tree": null, - "paths": null - }, { "time": "2016-01-09T21:02:03+01:00", "tree": null, @@ -48,5 +43,110 @@ "time": "2016-01-03T07:02:03+01:00", "tree": null, "paths": null + }, + { + "time": "2016-01-01T07:08:03+01:00", + "tree": null, + "paths": null + }, + { + "time": "2015-11-22T10:20:30+01:00", + "tree": null, + "paths": null + }, + { + "time": "2015-11-21T10:20:30+01:00", + "tree": null, + "paths": null + }, + { + "time": "2015-11-20T10:20:30+01:00", + "tree": null, + "paths": null + }, + { + "time": "2015-11-18T10:20:30+01:00", + "tree": null, + "paths": null + }, + { + "time": "2015-11-15T10:20:30+01:00", + "tree": null, + "paths": null + }, + { + "time": "2015-11-13T10:20:30+01:00", + "tree": null, + "paths": null + }, + { + "time": "2015-11-12T10:20:30+01:00", + "tree": null, + "paths": null + }, + { + "time": "2015-11-10T10:20:30+01:00", + "tree": null, + "paths": null + }, + { + "time": "2015-11-08T10:20:30+01:00", + "tree": null, + "paths": null + }, + { + "time": "2015-10-22T11:20:30+02:00", + "tree": null, + "paths": null + }, + { + "time": "2015-10-20T11:20:30+02:00", + "tree": null, + "paths": null + }, + { + "time": "2015-10-11T11:20:30+02:00", + "tree": null, + "paths": null + }, + { + "time": "2015-10-10T11:20:30+02:00", + "tree": null, + "paths": null + }, + { + "time": "2015-10-09T11:20:30+02:00", + "tree": null, + "paths": null + }, + { + "time": "2015-10-08T11:20:30+02:00", + "tree": null, + "paths": null + }, + { + "time": "2015-10-06T11:20:30+02:00", + "tree": null, + "paths": null + }, + { + "time": "2015-10-05T11:20:30+02:00", + "tree": null, + "paths": null + }, + { + "time": "2015-10-02T11:20:30+02:00", + "tree": null, + "paths": null + }, + { + "time": "2015-10-01T11:20:30+02:00", + "tree": null, + "paths": null + }, + { + "time": "2015-09-22T11:20:30+02:00", + "tree": null, + "paths": null } ] \ No newline at end of file diff --git a/src/restic/testdata/expired_snapshots_9 b/src/restic/testdata/expired_snapshots_9 index 63fbd8b09..fd72ec6a5 100644 --- a/src/restic/testdata/expired_snapshots_9 +++ b/src/restic/testdata/expired_snapshots_9 @@ -48,15 +48,5 @@ "time": "2016-01-03T07:02:03+01:00", "tree": null, "paths": null - }, - { - "time": "2016-01-01T07:08:03+01:00", - "tree": null, - "paths": null - }, - { - "time": "2015-11-22T10:20:30+01:00", - "tree": null, - "paths": null } ] \ No newline at end of file