From 72d288567eb6a76947cc176ff67fcc8771a760e1 Mon Sep 17 00:00:00 2001 From: Christian Schwarz Date: Thu, 5 Oct 2017 19:58:43 +0200 Subject: [PATCH] mappings: fix aliasing bug with '<' wildcards In contrast to any 'something<' mapping, a '<' mapping cannot be unique Thus, '<' mappings are thus just an append to target, which is exactly what we get when trimming empty prefix ''. Otherwise, given mapping { "<": "storage/backups/app-srv" } Before (clearly a conflict) zroot => storage/backups/app-srv storage => storage/backups/app-srv After: zroot => storage/backups/app-srv/zroot storage => storage/backups/app-srv/storage However, mapping directly with subtree wildcard is still possible, just not with the root wildcard { "<" "storage/backups/app-srv" "zroot/var/db<": "storage/db_replication/app-srv" } fixes #22 --- cmd/config_mapfilter.go | 9 ++------- cmd/config_test.go | 4 ++-- docs/content/configuration/map_filter_syntax.md | 9 ++++----- 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/cmd/config_mapfilter.go b/cmd/config_mapfilter.go index ac7a24f..c625fc8 100644 --- a/cmd/config_mapfilter.go +++ b/cmd/config_mapfilter.go @@ -125,14 +125,9 @@ func (m DatasetMapFilter) Map(source *zfs.DatasetPath) (target *zfs.DatasetPath, return } if me.subtreeMatch { - // strip common prefix + // strip common prefix ('<' wildcards are no special case here) extendComps := source.Copy() - if me.path.Empty() { - // special case: trying to map the root => strip first component - extendComps.TrimNPrefixComps(1) - } else { - extendComps.TrimPrefix(me.path) - } + extendComps.TrimPrefix(me.path) target.Extend(extendComps) } return diff --git a/cmd/config_test.go b/cmd/config_test.go index d0d3c91..dbbf439 100644 --- a/cmd/config_test.go +++ b/cmd/config_test.go @@ -129,8 +129,8 @@ func TestDatasetMapFilter(t *testing.T) { expectMapping(map1, "a/b/c/d/e", "") expectMapping(map1, "a/b/e", "root2/e") expectMapping(map1, "a/b", "root2") - expectMapping(map1, "x", "root3/b/c") - expectMapping(map1, "x/y", "root3/b/c/y") + expectMapping(map1, "x", "root3/b/c/x") + expectMapping(map1, "x/y", "root3/b/c/x/y") expectMapping(map1, "q", "root4/1/2") expectMapping(map1, "b", "") expectMapping(map1, "q/r", "root4/1/2/r") diff --git a/docs/content/configuration/map_filter_syntax.md b/docs/content/configuration/map_filter_syntax.md index 6013dda..9eb6aaa 100644 --- a/docs/content/configuration/map_filter_syntax.md +++ b/docs/content/configuration/map_filter_syntax.md @@ -45,15 +45,14 @@ tank/var/log => 1 #### Mappings -Mappings map a *filesystem path* to a *target filesystem*. +Mappings map a *source filesystem path* to a *target filesystem path*. Per pattern, either a target filesystem path or `"!"` is specified as a result. * If no pattern matches, there exists no target filesystem (`NO MATCH`). * If the result is a `"!"`, there exists no target filesystem (`NO MATCH`). -* If the pattern is a non-wildcard pattern, the filesystem specified on the left is mapped to the target filesystem on the right. -* If the pattern is a *subtree wildcard* pattern, the root of the subtree specified in the pattern is mapped to the target filesystem on the right and all children are mapped bewlow it. - -Note that paths are never appended - a mapping represents a correspondence between a path on the left and a path on the right. +* If the pattern is a non-wildcard pattern, the source path is mapped to the target path on the right. +* If the pattern ends with a *subtree wildcard* (`<`), the source path is **prefix-trimmed** with the path specified left of `<`. + * Note: this means that only for *wildcard-only* patterns (pattern=`<`) is the source path simply appended to the target path. The example is from the {{< sampleconflink "localbackup/host1.yml" >}} example config.