Add --keep-tag to forget command

This commit is contained in:
Alexander Neumann 2016-09-13 20:37:11 +02:00
parent 0f9fb37c78
commit cfdf4c92f7
8 changed files with 333 additions and 67 deletions

View file

@ -9,13 +9,15 @@ import (
// CmdForget implements the 'forget' command.
type CmdForget struct {
Last int `short:"l" long:"keep-last" description:"keep the last n snapshots"`
Last int `short:"l" long:"keep-last" description:"keep the last n snapshots"`
Hourly int `short:"H" long:"keep-hourly" description:"keep the last n hourly snapshots"`
Daily int `short:"d" long:"keep-daily" description:"keep the last n daily snapshots"`
Daily int `short:"d" long:"keep-daily" description:"keep the last n daily snapshots"`
Weekly int `short:"w" long:"keep-weekly" description:"keep the last n weekly snapshots"`
Monthly int `short:"m" long:"keep-monthly" description:"keep the last n monthly snapshots"`
Monthly int `short:"m" long:"keep-monthly"description:"keep the last n monthly snapshots"`
Yearly int `short:"y" long:"keep-yearly" description:"keep the last n yearly snapshots"`
KeepTags []string `long:"keep-tag" description:"alwaps keep snapshots with this tag (can be specified multiple times)"`
Hostname string `long:"hostname" description:"only forget snapshots for the given hostname"`
Tags []string `long:"tag" description:"only forget snapshots with the tag (can be specified multiple times)"`
@ -111,6 +113,7 @@ func (cmd CmdForget) Execute(args []string) error {
Weekly: cmd.Weekly,
Monthly: cmd.Monthly,
Yearly: cmd.Yearly,
Tags: cmd.KeepTags,
}
if policy.Empty() {

View file

@ -61,12 +61,13 @@ 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
Yearly int // keep the last n yearly snapshots
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
Yearly int // keep the last n yearly snapshots
Tags []string // keep all snapshots with these tags
}
// Sum returns the maximum number of snapshots to be kept according to this
@ -77,8 +78,12 @@ func (e ExpirePolicy) Sum() int {
// Empty returns true iff no policy has been configured (all values zero).
func (e ExpirePolicy) Empty() bool {
if len(e.Tags) != 0 {
return false
}
empty := ExpirePolicy{}
return e == empty
return reflect.DeepEqual(e, empty)
}
// filter is used to split a list of snapshots into those to keep and those to
@ -166,6 +171,19 @@ func (f *filter) apply(fn func(time.Time) int, max int) {
}
}
// keepTags marks the snapshots which have all tags as to be kept.
func (f *filter) keepTags(tags []string) {
if len(tags) == 0 {
return
}
for _, sn := range f.Unprocessed {
if sn.HasTags(tags) {
f.Keep = append(f.Keep, sn)
}
}
}
// keepLast marks the last n snapshots as to be kept.
func (f *filter) keepLast(n int) {
if n > len(f.Unprocessed) {
@ -200,6 +218,7 @@ func ApplyPolicy(list Snapshots, p ExpirePolicy) (keep, remove Snapshots) {
Keep: Snapshots{},
}
f.keepTags(p.Tags)
f.keepLast(p.Last)
f.apply(ymdh, p.Hourly)
f.apply(ymd, p.Daily)

View file

@ -112,20 +112,20 @@ var testExpireSnapshots = restic.Snapshots{
{Time: parseTimeUTC("2014-08-20 10:20:30")},
{Time: parseTimeUTC("2014-08-21 10:20:30")},
{Time: parseTimeUTC("2014-08-22 10:20:30")},
{Time: parseTimeUTC("2014-10-01 10:20:30")},
{Time: parseTimeUTC("2014-10-02 10:20:30")},
{Time: parseTimeUTC("2014-10-05 10:20:30")},
{Time: parseTimeUTC("2014-10-06 10:20:30")},
{Time: parseTimeUTC("2014-10-08 10:20:30")},
{Time: parseTimeUTC("2014-10-09 10:20:30")},
{Time: parseTimeUTC("2014-10-10 10:20:30")},
{Time: parseTimeUTC("2014-10-11 10:20:30")},
{Time: parseTimeUTC("2014-10-20 10:20:30")},
{Time: parseTimeUTC("2014-10-22 10:20:30")},
{Time: parseTimeUTC("2014-11-08 10:20:30")},
{Time: parseTimeUTC("2014-11-10 10:20:30")},
{Time: parseTimeUTC("2014-11-12 10:20:30")},
{Time: parseTimeUTC("2014-11-13 10:20:30")},
{Time: parseTimeUTC("2014-10-01 10:20:30"), Tags: []string{"foo"}},
{Time: parseTimeUTC("2014-10-02 10:20:30"), Tags: []string{"foo"}},
{Time: parseTimeUTC("2014-10-05 10:20:30"), Tags: []string{"foo"}},
{Time: parseTimeUTC("2014-10-06 10:20:30"), Tags: []string{"foo"}},
{Time: parseTimeUTC("2014-10-08 10:20:30"), Tags: []string{"foo"}},
{Time: parseTimeUTC("2014-10-09 10:20:30"), Tags: []string{"foo"}},
{Time: parseTimeUTC("2014-10-10 10:20:30"), Tags: []string{"foo"}},
{Time: parseTimeUTC("2014-10-11 10:20:30"), Tags: []string{"foo"}},
{Time: parseTimeUTC("2014-10-20 10:20:30"), Tags: []string{"foo"}},
{Time: parseTimeUTC("2014-10-22 10:20:30"), Tags: []string{"foo"}},
{Time: parseTimeUTC("2014-11-08 10:20:30"), Tags: []string{"foo"}},
{Time: parseTimeUTC("2014-11-10 10:20:30"), Tags: []string{"foo"}},
{Time: parseTimeUTC("2014-11-12 10:20:30"), Tags: []string{"foo"}},
{Time: parseTimeUTC("2014-11-13 10:20:30"), Tags: []string{"foo"}},
{Time: parseTimeUTC("2014-11-13 10:20:30")},
{Time: parseTimeUTC("2014-11-15 10:20:30")},
{Time: parseTimeUTC("2014-11-18 10:20:30")},
@ -212,6 +212,7 @@ var expireTests = []restic.ExpirePolicy{
{Daily: 2, Weekly: 2, Monthly: 6},
{Yearly: 10},
{Daily: 7, Weekly: 2, Monthly: 3, Yearly: 10},
{Tags: []string{"foo"}},
}
func TestApplyPolicy(t *testing.T) {

View file

@ -327,72 +327,114 @@
{
"time": "2014-11-13T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-11-12T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-11-10T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-11-08T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-22T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-20T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-11T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-10T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-09T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-08T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-06T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-05T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-02T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-01T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-09-22T10:20:30Z",

View file

@ -47,6 +47,9 @@
{
"time": "2014-10-22T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
}
]

114
src/restic/testdata/expired_snapshots_18 vendored Normal file
View file

@ -0,0 +1,114 @@
[
{
"time": "2014-11-13T10:20:30Z",
"tree": null,
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-11-12T10:20:30Z",
"tree": null,
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-11-10T10:20:30Z",
"tree": null,
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-11-08T10:20:30Z",
"tree": null,
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-22T10:20:30Z",
"tree": null,
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-20T10:20:30Z",
"tree": null,
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-11T10:20:30Z",
"tree": null,
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-10T10:20:30Z",
"tree": null,
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-09T10:20:30Z",
"tree": null,
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-08T10:20:30Z",
"tree": null,
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-06T10:20:30Z",
"tree": null,
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-05T10:20:30Z",
"tree": null,
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-02T10:20:30Z",
"tree": null,
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-01T10:20:30Z",
"tree": null,
"paths": null,
"tags": [
"foo"
]
}
]

View file

@ -327,72 +327,114 @@
{
"time": "2014-11-13T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-11-12T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-11-10T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-11-08T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-22T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-20T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-11T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-10T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-09T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-08T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-06T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-05T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-02T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-01T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-09-22T10:20:30Z",

View file

@ -327,72 +327,114 @@
{
"time": "2014-11-13T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-11-12T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-11-10T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-11-08T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-22T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-20T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-11T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-10T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-09T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-08T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-06T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-05T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-02T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-10-01T10:20:30Z",
"tree": null,
"paths": null
"paths": null,
"tags": [
"foo"
]
},
{
"time": "2014-09-22T10:20:30Z",