mirror of
https://github.com/zrepl/zrepl.git
synced 2024-11-22 00:13:52 +01:00
cmd: automatic inverting of DatasetMapFilter
This commit is contained in:
parent
1deaa459c8
commit
e2149de840
@ -4,8 +4,9 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/zrepl/zrepl/zfs"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zrepl/zrepl/zfs"
|
||||
)
|
||||
|
||||
type DatasetMapFilter struct {
|
||||
@ -144,14 +145,46 @@ func (m DatasetMapFilter) Filter(p *zfs.DatasetPath) (pass bool, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// Construct a new filter-only DatasetMapFilter from a mapping
|
||||
// The new filter allows excactly those paths that were not forbidden by the mapping.
|
||||
func (m DatasetMapFilter) InvertedFilter() (inv *DatasetMapFilter, err error) {
|
||||
|
||||
if m.filterOnly {
|
||||
err = errors.Errorf("can only invert mappings")
|
||||
return
|
||||
}
|
||||
|
||||
inv = &DatasetMapFilter{
|
||||
make([]datasetMapFilterEntry, len(m.entries)),
|
||||
true,
|
||||
}
|
||||
|
||||
for i, e := range m.entries {
|
||||
inv.entries[i].path, err = zfs.NewDatasetPath(e.mapping)
|
||||
if err != nil {
|
||||
err = errors.Wrapf(err, "mapping cannot be inverted: '%s' is not a dataset path: %s", e.mapping)
|
||||
return
|
||||
}
|
||||
inv.entries[i].mapping = MapFilterResultOk
|
||||
inv.entries[i].subtreeMatch = e.subtreeMatch
|
||||
}
|
||||
|
||||
return inv, nil
|
||||
}
|
||||
|
||||
const (
|
||||
MapFilterResultOk string = "ok"
|
||||
MapFilterResultOmit string = "omit"
|
||||
)
|
||||
|
||||
// Parse a dataset filter result
|
||||
func parseDatasetFilterResult(result string) (pass bool, err error) {
|
||||
l := strings.ToLower(result)
|
||||
switch strings.ToLower(l) {
|
||||
case "ok":
|
||||
case MapFilterResultOk:
|
||||
pass = true
|
||||
return
|
||||
case "omit":
|
||||
case MapFilterResultOmit:
|
||||
return
|
||||
default:
|
||||
err = fmt.Errorf("'%s' is not a valid filter result", result)
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/kr/pretty"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/zrepl/zrepl/util"
|
||||
"github.com/zrepl/zrepl/zfs"
|
||||
@ -135,3 +136,36 @@ func TestDatasetMapFilter(t *testing.T) {
|
||||
expectFilter(filter2, "foo", false) // default to omit
|
||||
|
||||
}
|
||||
|
||||
func TestDatasetMapFilter_InvertedFilter(t *testing.T) {
|
||||
mapspec := map[string]string{
|
||||
"a/b": "1/2",
|
||||
"a/b/c<": "3",
|
||||
"a/b/c/d<": "1/2/a",
|
||||
}
|
||||
|
||||
m, err := parseDatasetMapFilter(mapspec, false)
|
||||
assert.Nil(t, err)
|
||||
|
||||
inv, err := m.InvertedFilter()
|
||||
assert.Nil(t, err)
|
||||
|
||||
t.Log(pretty.Sprint(inv))
|
||||
|
||||
expectMapping := func(m *DatasetMapFilter, ps string, expRes bool) {
|
||||
p, err := zfs.NewDatasetPath(ps)
|
||||
assert.Nil(t, err)
|
||||
r, err := m.Filter(p)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, expRes, r)
|
||||
}
|
||||
|
||||
expectMapping(inv, "4", false)
|
||||
expectMapping(inv, "3", true)
|
||||
expectMapping(inv, "3/x", true)
|
||||
expectMapping(inv, "1", false)
|
||||
expectMapping(inv, "1/2", true)
|
||||
expectMapping(inv, "1/2/3", false)
|
||||
expectMapping(inv, "1/2/a/b", true)
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user