Skip to content

Commit

Permalink
added tag support (needed for bookmarks). implements #151
Browse files Browse the repository at this point in the history
  • Loading branch information
psy0rz committed Oct 2, 2024
1 parent 88a4e52 commit ec9ca29
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 54 deletions.
29 changes: 28 additions & 1 deletion zfs_autobackup/ZfsAuto.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ def parse_args(self, argv):
self.property_name = args.property_format.format(args.backup_name)
self.snapshot_time_format = args.snapshot_format.format(args.backup_name)
self.hold_name = args.hold_format.format(args.backup_name)
self.tag_seperator = args.tag_seperator

dt = datetime_now(args.utc)

Expand All @@ -68,6 +69,27 @@ def parse_args(self, argv):
self.verbose("Snapshot format : {}".format(self.snapshot_time_format))
self.verbose("Timezone : {}".format("UTC" if args.utc else "Local"))

seperator_test = datetime_now(False).strftime(self.snapshot_time_format)

# according to man 8 zfs:
valid_tags = "_.: -"
if self.tag_seperator not in valid_tags or self.tag_seperator == '':
self.log.error("Invalid tag seperator. Allowed: '{}'".format(valid_tags))
sys.exit(255)

if self.tag_seperator in seperator_test:
self.log.error("Tag seperator '{}' may not be used in snapshot format: {}".format(self.tag_seperator,
self.snapshot_time_format))
sys.exit(255)

if args.tag and self.tag_seperator in args.tag:
self.log.error(
"Tag '{}' may not contain tag seperator '{}'".format(args.tag, self.tag_seperator))
sys.exit(255)

if args.tag:
self.verbose("Tag : {}".format(self.tag_seperator + args.tag))

return args

def get_parser(self):
Expand Down Expand Up @@ -98,13 +120,18 @@ def get_parser(self):
help='ZFS hold string format. Default: %(default)s')
group.add_argument('--strip-path', metavar='N', default=0, type=int,
help='Number of directories to strip from target path.')
group.add_argument('--tag-seperator', metavar='CHAR', default="_",
help="Tag seperator for snapshots and bookmarks. Default: %(default)s")
group.add_argument('--tag', metavar='TAG', default=None,
help='Backup tag to add to snapshots names. (For administrative purposes)')

group = parser.add_argument_group("Selection options")
group.add_argument('--ignore-replicated', action='store_true', help=argparse.SUPPRESS)
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".' , )
help='Exclude datasets that have the origin of their autobackup: property as "received".', )

# group.add_argument('--include-received', action='store_true',
# help=argparse.SUPPRESS)

Expand Down
25 changes: 14 additions & 11 deletions zfs_autobackup/ZfsAutobackup.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,8 @@ def parse_args(self, argv):
self.warning("Using --compress with --zfs-compressed, might be inefficient.")

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


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

Expand Down Expand Up @@ -127,8 +126,8 @@ def get_parser(self):
help='Limit data transfer rate in Bytes/sec (e.g. 128K. requires mbuffer.)')
group.add_argument('--buffer', metavar='SIZE', default=None,
help='Add zfs send and recv buffers to smooth out IO bursts. (e.g. 128M. requires mbuffer)')
parser.add_argument('--buffer-chunk-size', metavar="BUFFERCHUNKSIZE", default=None,
help='Tune chunk size when mbuffer is used. (requires mbuffer.)')
group.add_argument('--buffer-chunk-size', metavar="BUFFERCHUNKSIZE", default=None,
help='Tune chunk size when mbuffer is used. (requires mbuffer.)')
group.add_argument('--send-pipe', metavar="COMMAND", default=[], action='append',
help='pipe zfs send output through COMMAND (can be used multiple times)')
group.add_argument('--recv-pipe', metavar="COMMAND", default=[], action='append',
Expand Down Expand Up @@ -399,14 +398,14 @@ def sync_datasets(self, source_node, source_datasets, target_node):
common_features = source_features and target_features

if self.args.no_bookmarks:
use_bookmarks=False
use_bookmarks = False
else:
# NOTE: bookmark_written seems to be needed. (only 'bookmarks' was not enough on ubuntu 20)
if not 'bookmark_written' in common_features:
source_dataset.warning("Disabling bookmarks, not supported on both pools.")
use_bookmarks=False
use_bookmarks = False
else:
use_bookmarks=True
use_bookmarks = True

# sync the snapshots of this dataset
source_dataset.sync_snapshots(target_dataset, show_progress=self.args.progress,
Expand Down Expand Up @@ -455,7 +454,6 @@ def filter_properties_list(self):
if self.args.clear_refreservation:
filter_properties.append("refreservation")


return filter_properties

def set_properties_list(self):
Expand Down Expand Up @@ -496,7 +494,8 @@ def run(self):
ssh_config=self.args.ssh_config,
ssh_to=self.args.ssh_source, readonly=self.args.test,
debug_output=self.args.debug_output, description=description, thinner=source_thinner,
exclude_snapshot_patterns=self.args.exclude_snapshot_pattern)
exclude_snapshot_patterns=self.args.exclude_snapshot_pattern,
tag_seperator=self.tag_seperator)

################# select source datasets
self.set_title("Selecting")
Expand All @@ -512,6 +511,9 @@ def run(self):
if not self.args.no_snapshot:
self.set_title("Snapshotting")
snapshot_name = datetime_now(self.args.utc).strftime(self.snapshot_time_format)
if self.args.tag:
snapshot_name = snapshot_name + self.tag_seperator + self.args.tag

source_node.consistent_snapshot(source_datasets, snapshot_name,
min_changed_bytes=self.args.min_change,
pre_snapshot_cmds=self.args.pre_snapshot_cmd,
Expand All @@ -534,7 +536,8 @@ def run(self):
ssh_to=self.args.ssh_target,
readonly=self.args.test, debug_output=self.args.debug_output,
description="[Target]",
thinner=target_thinner)
exclude_snapshot_patterns=self.args.exclude_snapshot_pattern,
thinner=target_thinner, tag_seperator=self.tag_seperator)
target_node.verbose("Receive datasets under: {}".format(self.args.target_path))

self.set_title("Synchronising")
Expand Down
Loading

0 comments on commit ec9ca29

Please sign in to comment.