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
}
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

View File

@ -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")

View File

@ -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.