Skip to content

Commit

Permalink
major change: we now always filter all properties that start with "au…
Browse files Browse the repository at this point in the history
…tobackup:". fixes #150 and #221
  • Loading branch information
psy0rz committed Sep 24, 2024
1 parent 85819a9 commit c9cbe42
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 16 deletions.
29 changes: 25 additions & 4 deletions tests/test_zfsautobackup31.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,23 +55,44 @@ def test_re_replication(self):
shelltest("zfs create test_target1/b")

with mocktime("20101111000000"):
self.assertFalse(ZfsAutobackup("test test_target1/a --no-progress --verbose --debug".split(" ")).run())
self.assertFalse(ZfsAutobackup("test test_target1/a --no-progress --verbose --debug --allow-empty".split(" ")).run())

#NOTE: since v3.4 this changed. autobackup: properties are filtered. So its up to the admin to reset this property on the other side:
shelltest("zfs set autobackup:test=true test_target1/a")

with mocktime("20101111000001"):
self.assertFalse(ZfsAutobackup("test test_target1/b --no-progress --verbose".split(" ")).run())
self.assertFalse(ZfsAutobackup("test test_target1/b --no-progress --verbose --allow-empty".split(" ")).run())

r=shelltest("zfs list -H -o name -r -t snapshot test_target1")
#NOTE: it wont backup test_target1/a/test_source2/fs2/sub to test_target1/b since it doesnt have the zfs_autobackup property anymore.
self.assertMultiLineEqual(r,"""
self.assertMultiLineEqual("""
test_target1/a@test-20101111000001
test_target1/a/test_source1@test-20101111000001
test_target1/a/test_source1/fs1@test-20101111000000
test_target1/a/test_source1/fs1@test-20101111000001
test_target1/a/test_source1/fs1/sub@test-20101111000000
test_target1/a/test_source1/fs1/sub@test-20101111000001
test_target1/a/test_source2@test-20101111000001
test_target1/a/test_source2/fs2@test-20101111000001
test_target1/a/test_source2/fs2/sub@test-20101111000000
test_target1/a/test_source2/fs2/sub@test-20101111000001
test_target1/b/test_source1/fs1@test-20101111000000
test_target1/b/test_source1/fs1@test-20101111000001
test_target1/b/test_source1/fs1/sub@test-20101111000000
test_target1/b/test_source1/fs1/sub@test-20101111000001
test_target1/b/test_source2/fs2/sub@test-20101111000000
test_target1/b/test_source2/fs2/sub@test-20101111000001
test_target1/b/test_target1/a@test-20101111000001
test_target1/b/test_target1/a/test_source1@test-20101111000001
test_target1/b/test_target1/a/test_source1/fs1@test-20101111000000
test_target1/b/test_target1/a/test_source1/fs1@test-20101111000001
test_target1/b/test_target1/a/test_source1/fs1/sub@test-20101111000000
""")
test_target1/b/test_target1/a/test_source1/fs1/sub@test-20101111000001
test_target1/b/test_target1/a/test_source2@test-20101111000001
test_target1/b/test_target1/a/test_source2/fs2@test-20101111000001
test_target1/b/test_target1/a/test_source2/fs2/sub@test-20101111000000
test_target1/b/test_target1/a/test_source2/fs2/sub@test-20101111000001
""",r)

def test_zfs_compressed(self):

Expand Down
19 changes: 7 additions & 12 deletions zfs_autobackup/ZfsAuto.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,14 @@ def parse_args(self, argv):
# may still need to be used to explicitly exclude a backup with the 'received' source property to avoid accidental
# recursive replication of a zvol that is currently being received in another session (as it will have changes).

# Follow up note: This isnt a problem anymore since v3.4, we now filter the autobackup-property by default to prevent these difficult issues.

self.exclude_paths = []
if args.ssh_source == args.ssh_target:
if args.target_path:
# target and source are the same, make sure to exclude target_path
self.verbose("NOTE: Source and target are on the same host, excluding target-path from selection.")
self.exclude_paths.append(args.target_path)
else:
if not args.exclude_received and not args.include_received:
self.verbose(
"NOTE: Source and target are on the same host, adding --exclude-received to commandline. (use --include-received to overrule)")
args.exclude_received = True

if args.test:
self.warning("TEST MODE - SIMULATING WITHOUT MAKING ANY CHANGES")
Expand Down Expand Up @@ -107,10 +104,9 @@ def get_parser(self):
group.add_argument('--exclude-unchanged', metavar='BYTES', default=0, type=int,
help='Exclude datasets that have less than BYTES data changed since any last snapshot. (Use with proxmox HA replication)')
group.add_argument('--exclude-received', action='store_true',
help='Exclude datasets that have the origin of their autobackup: property as "received". '
'This can avoid recursive replication between two backup partners.')
group.add_argument('--include-received', action='store_true',
help=argparse.SUPPRESS)
help='Exclude datasets that have the origin of their autobackup: property as "received".' , )
# group.add_argument('--include-received', action='store_true',
# help=argparse.SUPPRESS)

def regex_argument_type(input_line):
"""Parses regex arguments into re.Pattern objects"""
Expand All @@ -126,9 +122,8 @@ def regex_argument_type(input_line):

def print_error_sources(self):
self.error(
"No source filesystems selected, please do a 'zfs set autobackup:{0}=true' on the source datasets "
"you want to select.".format(
self.args.backup_name))
"No source filesystems selected, please do a 'zfs set {}=true' on the source datasets "
"you want to select.".format(self.property_name))

def make_target_name(self, source_dataset):
"""make target_name from a source_dataset"""
Expand Down
4 changes: 4 additions & 0 deletions zfs_autobackup/ZfsAutobackup.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ def parse_args(self, argv):
if args.decrypt:
self.warning("Properties will not be sent over for datasets that will be decrypted. (zfs bug https://github.com/openzfs/zfs/issues/16275)")



return args

def get_parser(self):
Expand Down Expand Up @@ -93,6 +95,7 @@ def get_parser(self):
group.add_argument('--set-properties', metavar='PROPERTY=VALUE,...', type=str,
help='List of propererties to override when receiving filesystems. (you can still restore '
'them with zfs inherit -S)')

group.add_argument('--rollback', action='store_true',
help='Rollback changes to the latest target snapshot before starting. (normally you can '
'prevent changes by setting the readonly property on the target_path to on)')
Expand Down Expand Up @@ -439,6 +442,7 @@ def filter_properties_list(self):
if self.args.clear_refreservation:
filter_properties.append("refreservation")


return filter_properties

def set_properties_list(self):
Expand Down
5 changes: 5 additions & 0 deletions zfs_autobackup/ZfsDataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -1188,6 +1188,11 @@ def sync_snapshots(self, target_dataset, features, show_progress, filter_propert
(active_filter_properties, active_set_properties) = self.get_allowed_properties(filter_properties,
set_properties)

# always filter properties that start with 'autobackup:' (https://github.com/psy0rz/zfs_autobackup/issues/221)
for property in self.properties:
if property.startswith('autobackup:'):
active_filter_properties.append(property)

# encrypt at target?
if encrypt and not raw:
# filter out encryption properties to let encryption on the target take place
Expand Down

0 comments on commit c9cbe42

Please sign in to comment.