mirror of
https://github.com/zrepl/zrepl.git
synced 2024-11-24 17:35:01 +01:00
pruning: add 'Negate' option to KeepRegex and expose it in config
This commit is contained in:
parent
2db3977408
commit
5e1ea21f85
@ -250,6 +250,7 @@ type PruneKeepLastN struct {
|
||||
type PruneKeepRegex struct { // FIXME rename to KeepRegex
|
||||
Type string `yaml:"type"`
|
||||
Regex string `yaml:"regex"`
|
||||
Negate bool `yaml:"negate,optional,default=false"`
|
||||
}
|
||||
|
||||
type LoggingOutletEnum struct {
|
||||
|
@ -179,7 +179,7 @@ func TestPruner_Prune(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
keepRules := []pruning.KeepRule{pruning.MustKeepRegex("^keep")}
|
||||
keepRules := []pruning.KeepRule{pruning.MustKeepRegex("^keep", false)}
|
||||
|
||||
p := Pruner{
|
||||
args: args{
|
||||
|
@ -146,12 +146,22 @@ Policy ``regex``
|
||||
- type: push
|
||||
pruning:
|
||||
keep_receiver:
|
||||
# keep all snapshots with prefix zrepl_ or manual_
|
||||
- type: regex
|
||||
regex: "^(zrepl|manual)_.*"
|
||||
...
|
||||
|
||||
- type: push
|
||||
snapshotting:
|
||||
prefix: zrepl_
|
||||
pruning:
|
||||
keep_sender:
|
||||
# keep all snapshots that were not created by zrepl
|
||||
- type: regex
|
||||
negate: true
|
||||
regex: "^zrepl_.*"
|
||||
|
||||
``regex`` keeps all snapshots whose names are matched by the regular expressionin ``regex``.
|
||||
Like all other regular expression fields in prune policies, zrepl uses Go's `regexp.Regexp <https://golang.org/pkg/regexp/#Compile>`_ Perl-compatible regular expressions (`Syntax <https://golang.org/pkg/regexp/syntax>`_).
|
||||
|
||||
The optional `negate` boolean field inverts the semantics: Use it if you want to keep all snapshots that *do not* match the given regex.
|
||||
|
||||
|
||||
|
@ -6,20 +6,21 @@ import (
|
||||
|
||||
type KeepRegex struct {
|
||||
expr *regexp.Regexp
|
||||
negate bool
|
||||
}
|
||||
|
||||
var _ KeepRule = &KeepRegex{}
|
||||
|
||||
func NewKeepRegex(expr string) (*KeepRegex, error) {
|
||||
func NewKeepRegex(expr string, negate bool) (*KeepRegex, error) {
|
||||
re, err := regexp.Compile(expr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &KeepRegex{re}, nil
|
||||
return &KeepRegex{re, negate}, nil
|
||||
}
|
||||
|
||||
func MustKeepRegex(expr string) *KeepRegex {
|
||||
k, err := NewKeepRegex(expr)
|
||||
func MustKeepRegex(expr string, negate bool) *KeepRegex {
|
||||
k, err := NewKeepRegex(expr, negate)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -28,6 +29,10 @@ func MustKeepRegex(expr string) *KeepRegex {
|
||||
|
||||
func (k *KeepRegex) KeepRule(snaps []Snapshot) []Snapshot {
|
||||
return filterSnapList(snaps, func(s Snapshot) bool {
|
||||
if k.negate {
|
||||
return k.expr.FindStringIndex(s.Name()) != nil
|
||||
} else {
|
||||
return k.expr.FindStringIndex(s.Name()) == nil
|
||||
}
|
||||
})
|
||||
}
|
||||
|
32
pruning/keep_regex_test.go
Normal file
32
pruning/keep_regex_test.go
Normal file
@ -0,0 +1,32 @@
|
||||
package pruning
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestKeepRegexNegation(t *testing.T) {
|
||||
|
||||
noneg := MustKeepRegex("^zrepl_", false)
|
||||
neg := MustKeepRegex("^zrepl_", true)
|
||||
|
||||
snaps := []Snapshot{
|
||||
stubSnap{name: "zrepl_foobar"},
|
||||
stubSnap{name: "zrepl"},
|
||||
stubSnap{name: "barfoo"},
|
||||
}
|
||||
|
||||
destroyNonNeg := snapshotList(noneg.KeepRule(snaps))
|
||||
t.Logf("non-negated rule destroys: %#v", destroyNonNeg.NameList())
|
||||
assert.True(t, destroyNonNeg.ContainsName("zrepl"))
|
||||
assert.True(t, destroyNonNeg.ContainsName("barfoo"))
|
||||
assert.False(t, destroyNonNeg.ContainsName("zrepl_foobar"))
|
||||
|
||||
destroyNeg := snapshotList(neg.KeepRule(snaps))
|
||||
t.Logf("negated rule destroys: %#v", destroyNeg.NameList())
|
||||
assert.False(t, destroyNeg.ContainsName("zrepl"))
|
||||
assert.False(t, destroyNeg.ContainsName("barfoo"))
|
||||
assert.True(t, destroyNeg.ContainsName("zrepl_foobar"))
|
||||
|
||||
}
|
@ -60,7 +60,7 @@ func RuleFromConfig(in config.PruningEnum) (KeepRule, error) {
|
||||
case *config.PruneKeepLastN:
|
||||
return NewKeepLastN(v.Count)
|
||||
case *config.PruneKeepRegex:
|
||||
return NewKeepRegex(v.Regex)
|
||||
return NewKeepRegex(v.Regex, v.Negate)
|
||||
case *config.PruneGrid:
|
||||
return NewKeepGrid(v)
|
||||
default:
|
||||
|
@ -24,6 +24,25 @@ type testCase struct {
|
||||
expDestroyAlternatives []map[string]bool
|
||||
}
|
||||
|
||||
type snapshotList []Snapshot
|
||||
|
||||
func (l snapshotList) ContainsName(n string) bool {
|
||||
for _, s := range l {
|
||||
if s.Name() == n {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (l snapshotList) NameList() []string {
|
||||
res := make([]string, len(l))
|
||||
for i, s := range l {
|
||||
res[i] = s.Name()
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func testTable(tcs map[string]testCase, t *testing.T) {
|
||||
mapEqual := func(a, b map[string]bool) bool {
|
||||
if len(a) != len(b) {
|
||||
@ -79,7 +98,7 @@ func TestPruneSnapshots(t *testing.T) {
|
||||
"simple": {
|
||||
inputs: inputs["s1"],
|
||||
rules: []KeepRule{
|
||||
MustKeepRegex("foo_"),
|
||||
MustKeepRegex("foo_", false),
|
||||
},
|
||||
expDestroy: map[string]bool{
|
||||
"bar_123": true,
|
||||
@ -88,16 +107,16 @@ func TestPruneSnapshots(t *testing.T) {
|
||||
"multipleRules": {
|
||||
inputs: inputs["s1"],
|
||||
rules: []KeepRule{
|
||||
MustKeepRegex("foo_"),
|
||||
MustKeepRegex("bar_"),
|
||||
MustKeepRegex("foo_", false),
|
||||
MustKeepRegex("bar_", false),
|
||||
},
|
||||
expDestroy: map[string]bool{},
|
||||
},
|
||||
"onlyThoseRemovedByAllAreRemoved": {
|
||||
inputs: inputs["s1"],
|
||||
rules: []KeepRule{
|
||||
MustKeepRegex("notInS1"), // would remove all
|
||||
MustKeepRegex("bar_"), // would remove all but bar_, i.e. foo_.*
|
||||
MustKeepRegex("notInS1", false), // would remove all
|
||||
MustKeepRegex("bar_", false), // would remove all but bar_, i.e. foo_.*
|
||||
},
|
||||
expDestroy: map[string]bool{
|
||||
"foo_123": true,
|
||||
@ -117,7 +136,7 @@ func TestPruneSnapshots(t *testing.T) {
|
||||
"noSnaps": {
|
||||
inputs: []Snapshot{},
|
||||
rules: []KeepRule{
|
||||
MustKeepRegex("foo_"),
|
||||
MustKeepRegex("foo_", false),
|
||||
},
|
||||
expDestroy: map[string]bool{},
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user