make initial replication policy configurable (most_recent, all, fail)

Config:

```
- type: push
  ...
  conflict_resolution:
    initial_replication: most_recent | all | fali
```

The ``initial_replication`` option determines which snapshots zrepl
replicates if the filesystem has not been replicated before.
If ``most_recent`` (the default), the initial replication will only
transfer the most recent snapshot, while ignoring previous snapshots.
If all snapshots should be replicated, specify ``all``.
Use ``fail`` to make replication of the filesystem fail in case
there is no corresponding fileystem on the receiver.

Code-Level Changes, apart from the obvious:
- Rework IncrementalPath()'s return signature.
  Now returns an error for initial replications as well.
- Rename & rework it's consumer, resolveConflict().

Co-authored-by: Graham Christensen <graham@grahamc.com>

Fixes https://github.com/zrepl/zrepl/issues/550
Fixes https://github.com/zrepl/zrepl/issues/187
Closes https://github.com/zrepl/zrepl/pull/592
This commit is contained in:
Christian Schwarz
2022-05-01 14:46:38 +02:00
parent 1acafabb5b
commit 2642c64303
12 changed files with 394 additions and 61 deletions
+30 -5
View File
@@ -96,12 +96,37 @@ func TestIncrementalPath_SnapshotsOnly(t *testing.T) {
assert.Equal(t, l("@c,3", "@d,4"), path)
})
// sender with earlier but also current version as sender is not a conflict
// nothing to do if fully shared history
doTest(l("@a,1", "@b,2"), l("@a,1", "@b,2"), func(incpath []*FilesystemVersion, conflict error) {
assert.Nil(t, incpath)
assert.NotNil(t, conflict)
_, ok := conflict.(*ConflictMostRecentSnapshotAlreadyPresent)
assert.True(t, ok)
})
// ...but it's sufficient if the most recent snapshot is present
doTest(l("@c,3"), l("@a,1", "@b,2", "@c,3"), func(path []*FilesystemVersion, conflict error) {
t.Logf("path: %#v", path)
t.Logf("conflict: %#v", conflict)
assert.Empty(t, path)
assert.Nil(t, conflict)
assert.Nil(t, path)
_, ok := conflict.(*ConflictMostRecentSnapshotAlreadyPresent)
assert.True(t, ok)
})
// no sender snapshots errors: empty receiver
doTest(l(), l(), func(incpath []*FilesystemVersion, conflict error) {
assert.Nil(t, incpath)
assert.NotNil(t, conflict)
t.Logf("%T", conflict)
_, ok := conflict.(*ConflictNoSenderSnapshots)
assert.True(t, ok)
})
// no sender snapshots errors: snapshots on receiver
doTest(l("@a,1"), l(), func(incpath []*FilesystemVersion, conflict error) {
assert.Nil(t, incpath)
assert.NotNil(t, conflict)
t.Logf("%T", conflict)
_, ok := conflict.(*ConflictNoSenderSnapshots)
assert.True(t, ok)
})
}