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
This commit is contained in:
Christian Schwarz 2017-10-05 19:58:43 +02:00
parent b5d46e2ec3
commit 72d288567e
3 changed files with 8 additions and 14 deletions

View File

@ -125,14 +125,9 @@ func (m DatasetMapFilter) Map(source *zfs.DatasetPath) (target *zfs.DatasetPath,
return return
} }
if me.subtreeMatch { if me.subtreeMatch {
// strip common prefix // strip common prefix ('<' wildcards are no special case here)
extendComps := source.Copy() extendComps := source.Copy()
if me.path.Empty() { extendComps.TrimPrefix(me.path)
// special case: trying to map the root => strip first component
extendComps.TrimNPrefixComps(1)
} else {
extendComps.TrimPrefix(me.path)
}
target.Extend(extendComps) target.Extend(extendComps)
} }
return return

View File

@ -129,8 +129,8 @@ func TestDatasetMapFilter(t *testing.T) {
expectMapping(map1, "a/b/c/d/e", "") expectMapping(map1, "a/b/c/d/e", "")
expectMapping(map1, "a/b/e", "root2/e") expectMapping(map1, "a/b/e", "root2/e")
expectMapping(map1, "a/b", "root2") expectMapping(map1, "a/b", "root2")
expectMapping(map1, "x", "root3/b/c") expectMapping(map1, "x", "root3/b/c/x")
expectMapping(map1, "x/y", "root3/b/c/y") expectMapping(map1, "x/y", "root3/b/c/x/y")
expectMapping(map1, "q", "root4/1/2") expectMapping(map1, "q", "root4/1/2")
expectMapping(map1, "b", "") expectMapping(map1, "b", "")
expectMapping(map1, "q/r", "root4/1/2/r") expectMapping(map1, "q/r", "root4/1/2/r")

View File

@ -45,15 +45,14 @@ tank/var/log => 1
#### Mappings #### 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. 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 no pattern matches, there exists no target filesystem (`NO MATCH`).
* If the result is a `"!"`, 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 non-wildcard pattern, the source path is mapped to the target path 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. * 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.
Note that paths are never appended - a mapping represents a correspondence between a path on the left and a path on the right.
The example is from the {{< sampleconflink "localbackup/host1.yml" >}} example config. The example is from the {{< sampleconflink "localbackup/host1.yml" >}} example config.