mirror of
https://github.com/psy0rz/zfs_autobackup.git
synced 2025-04-11 22:40:01 +03:00
fix #219
This commit is contained in:
parent
a7d05a7064
commit
6e5a6764c5
@ -191,3 +191,36 @@ test_target1/test_source2/fs2 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
|
||||
""")
|
||||
|
||||
|
||||
|
@ -866,13 +866,16 @@ class ZfsDataset:
|
||||
|
||||
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
|
||||
the common_snapshot. all direct followup snapshots with written=0 are
|
||||
compatible.
|
||||
|
||||
in raw-mode nothing is compatible. issue #219
|
||||
|
||||
Args:
|
||||
:type common_snapshot: ZfsDataset
|
||||
:type raw: bool
|
||||
"""
|
||||
|
||||
ret = []
|
||||
@ -880,7 +883,7 @@ class ZfsDataset:
|
||||
if common_snapshot and self.snapshots:
|
||||
followup = True
|
||||
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
|
||||
ret.append(snapshot)
|
||||
|
||||
@ -983,7 +986,7 @@ class ZfsDataset:
|
||||
else:
|
||||
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
|
||||
|
||||
Args:
|
||||
@ -991,13 +994,14 @@ class ZfsDataset:
|
||||
:type target_dataset: ZfsDataset
|
||||
:type also_other_snapshots: bool
|
||||
:type guid_check: bool
|
||||
:type raw: bool
|
||||
"""
|
||||
|
||||
# determine common and start snapshot
|
||||
target_dataset.debug("Determining start snapshot")
|
||||
common_snapshot = self.find_common_snapshot(target_dataset, guid_check=guid_check)
|
||||
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
|
||||
source_obsoletes = []
|
||||
@ -1058,11 +1062,26 @@ class ZfsDataset:
|
||||
: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,
|
||||
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.
|
||||
# Also usefull with no_send to still cleanup stuff.
|
||||
@ -1084,23 +1103,9 @@ class ZfsDataset:
|
||||
if 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)
|
||||
|
||||
# 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?
|
||||
if encrypt and not raw:
|
||||
# filter out encryption properties to let encryption on the target take place
|
||||
|
Loading…
x
Reference in New Issue
Block a user