fix #219
This commit is contained in:
@ -191,3 +191,36 @@ test_target1/test_source2/fs2 encryptionroot -
|
|||||||
test_target1/test_source2/fs2/sub encryptionroot - -
|
test_target1/test_source2/fs2/sub encryptionroot - -
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_raw_invalid_snapshot(self):
|
||||||
|
"""in raw mode, its not allowed to have any newer snaphots on target, #219"""
|
||||||
|
|
||||||
|
self.prepare_encrypted_dataset("11111111", "test_source1/fs1/encryptedsource")
|
||||||
|
|
||||||
|
with patch('time.strftime', return_value="test-20101111000000"):
|
||||||
|
self.assertFalse(ZfsAutobackup("test test_target1 --verbose --no-progress".split(" ")).run())
|
||||||
|
|
||||||
|
#this is invalid in raw mode
|
||||||
|
shelltest("zfs snapshot test_target1/test_source1/fs1/encryptedsource@incompatible")
|
||||||
|
|
||||||
|
with patch('time.strftime', return_value="test-20101111000001"):
|
||||||
|
#should fail because of incompatble snapshot
|
||||||
|
self.assertEqual(ZfsAutobackup("test test_target1 --verbose --no-progress --allow-empty".split(" ")).run(),1)
|
||||||
|
#should destroy incompatible and continue
|
||||||
|
self.assertFalse(ZfsAutobackup("test test_target1 --verbose --no-progress --no-snapshot --destroy-incompatible".split(" ")).run())
|
||||||
|
|
||||||
|
|
||||||
|
r = shelltest("zfs get -r -t filesystem encryptionroot test_target1")
|
||||||
|
self.assertMultiLineEqual(r,"""
|
||||||
|
NAME PROPERTY VALUE SOURCE
|
||||||
|
test_target1 encryptionroot - -
|
||||||
|
test_target1/test_source1 encryptionroot - -
|
||||||
|
test_target1/test_source1/fs1 encryptionroot - -
|
||||||
|
test_target1/test_source1/fs1/encryptedsource encryptionroot test_target1/test_source1/fs1/encryptedsource -
|
||||||
|
test_target1/test_source1/fs1/sub encryptionroot - -
|
||||||
|
test_target1/test_source2 encryptionroot - -
|
||||||
|
test_target1/test_source2/fs2 encryptionroot - -
|
||||||
|
test_target1/test_source2/fs2/sub encryptionroot - -
|
||||||
|
""")
|
||||||
|
|||||||
@ -105,3 +105,4 @@ test_target1/test_source2/fs2/sub@test-20101111000000
|
|||||||
test_target1/test_source2/fs2/sub@test-20101111000001
|
test_target1/test_source2/fs2/sub@test-20101111000001
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -866,13 +866,16 @@ class ZfsDataset:
|
|||||||
|
|
||||||
return start_snapshot
|
return start_snapshot
|
||||||
|
|
||||||
def find_incompatible_snapshots(self, common_snapshot):
|
def find_incompatible_snapshots(self, common_snapshot, raw):
|
||||||
"""returns a list of snapshots that is incompatible for a zfs recv onto
|
"""returns a list of snapshots that is incompatible for a zfs recv onto
|
||||||
the common_snapshot. all direct followup snapshots with written=0 are
|
the common_snapshot. all direct followup snapshots with written=0 are
|
||||||
compatible.
|
compatible.
|
||||||
|
|
||||||
|
in raw-mode nothing is compatible. issue #219
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
:type common_snapshot: ZfsDataset
|
:type common_snapshot: ZfsDataset
|
||||||
|
:type raw: bool
|
||||||
"""
|
"""
|
||||||
|
|
||||||
ret = []
|
ret = []
|
||||||
@ -880,7 +883,7 @@ class ZfsDataset:
|
|||||||
if common_snapshot and self.snapshots:
|
if common_snapshot and self.snapshots:
|
||||||
followup = True
|
followup = True
|
||||||
for snapshot in self.snapshots[self.find_snapshot_index(common_snapshot) + 1:]:
|
for snapshot in self.snapshots[self.find_snapshot_index(common_snapshot) + 1:]:
|
||||||
if not followup or int(snapshot.properties['written']) != 0:
|
if raw or not followup or int(snapshot.properties['written']) != 0:
|
||||||
followup = False
|
followup = False
|
||||||
ret.append(snapshot)
|
ret.append(snapshot)
|
||||||
|
|
||||||
@ -983,7 +986,7 @@ class ZfsDataset:
|
|||||||
else:
|
else:
|
||||||
return resume_token
|
return resume_token
|
||||||
|
|
||||||
def _plan_sync(self, target_dataset, also_other_snapshots, guid_check):
|
def _plan_sync(self, target_dataset, also_other_snapshots, guid_check, raw):
|
||||||
"""plan where to start syncing and what to sync and what to keep
|
"""plan where to start syncing and what to sync and what to keep
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -991,13 +994,14 @@ class ZfsDataset:
|
|||||||
:type target_dataset: ZfsDataset
|
:type target_dataset: ZfsDataset
|
||||||
:type also_other_snapshots: bool
|
:type also_other_snapshots: bool
|
||||||
:type guid_check: bool
|
:type guid_check: bool
|
||||||
|
:type raw: bool
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# determine common and start snapshot
|
# determine common and start snapshot
|
||||||
target_dataset.debug("Determining start snapshot")
|
target_dataset.debug("Determining start snapshot")
|
||||||
common_snapshot = self.find_common_snapshot(target_dataset, guid_check=guid_check)
|
common_snapshot = self.find_common_snapshot(target_dataset, guid_check=guid_check)
|
||||||
start_snapshot = self.find_start_snapshot(common_snapshot, also_other_snapshots)
|
start_snapshot = self.find_start_snapshot(common_snapshot, also_other_snapshots)
|
||||||
incompatible_target_snapshots = target_dataset.find_incompatible_snapshots(common_snapshot)
|
incompatible_target_snapshots = target_dataset.find_incompatible_snapshots(common_snapshot, raw)
|
||||||
|
|
||||||
# let thinner decide whats obsolete on source
|
# let thinner decide whats obsolete on source
|
||||||
source_obsoletes = []
|
source_obsoletes = []
|
||||||
@ -1058,11 +1062,26 @@ class ZfsDataset:
|
|||||||
:type guid_check: bool
|
:type guid_check: bool
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.verbose("sending to {}".format(target_dataset))
|
# self.verbose("-> {}".format(target_dataset))
|
||||||
|
|
||||||
|
#defaults for these settings if there is no encryption stuff going on:
|
||||||
|
send_properties = True
|
||||||
|
raw = False
|
||||||
|
write_embedded = True
|
||||||
|
|
||||||
|
# source dataset encrypted?
|
||||||
|
if self.properties.get('encryption', 'off')!='off':
|
||||||
|
# user wants to send it over decrypted?
|
||||||
|
if decrypt:
|
||||||
|
# when decrypting, zfs cant send properties
|
||||||
|
send_properties=False
|
||||||
|
else:
|
||||||
|
# keep data encrypted by sending it raw (including properties)
|
||||||
|
raw=True
|
||||||
|
|
||||||
(common_snapshot, start_snapshot, source_obsoletes, target_obsoletes, target_keeps,
|
(common_snapshot, start_snapshot, source_obsoletes, target_obsoletes, target_keeps,
|
||||||
incompatible_target_snapshots) = \
|
incompatible_target_snapshots) = \
|
||||||
self._plan_sync(target_dataset=target_dataset, also_other_snapshots=also_other_snapshots, guid_check=guid_check)
|
self._plan_sync(target_dataset=target_dataset, also_other_snapshots=also_other_snapshots, guid_check=guid_check, raw=raw)
|
||||||
|
|
||||||
# NOTE: we do this because we dont want filesystems to fillup when backups keep failing.
|
# NOTE: we do this because we dont want filesystems to fillup when backups keep failing.
|
||||||
# Also usefull with no_send to still cleanup stuff.
|
# Also usefull with no_send to still cleanup stuff.
|
||||||
@ -1084,23 +1103,9 @@ class ZfsDataset:
|
|||||||
if rollback:
|
if rollback:
|
||||||
target_dataset.rollback()
|
target_dataset.rollback()
|
||||||
|
|
||||||
#defaults for these settings if there is no encryption stuff going on:
|
|
||||||
send_properties = True
|
|
||||||
raw = False
|
|
||||||
write_embedded = True
|
|
||||||
|
|
||||||
(active_filter_properties, active_set_properties) = self.get_allowed_properties(filter_properties, set_properties)
|
(active_filter_properties, active_set_properties) = self.get_allowed_properties(filter_properties, set_properties)
|
||||||
|
|
||||||
# source dataset encrypted?
|
|
||||||
if self.properties.get('encryption', 'off')!='off':
|
|
||||||
# user wants to send it over decrypted?
|
|
||||||
if decrypt:
|
|
||||||
# when decrypting, zfs cant send properties
|
|
||||||
send_properties=False
|
|
||||||
else:
|
|
||||||
# keep data encrypted by sending it raw (including properties)
|
|
||||||
raw=True
|
|
||||||
|
|
||||||
# encrypt at target?
|
# encrypt at target?
|
||||||
if encrypt and not raw:
|
if encrypt and not raw:
|
||||||
# filter out encryption properties to let encryption on the target take place
|
# filter out encryption properties to let encryption on the target take place
|
||||||
|
|||||||
Reference in New Issue
Block a user