From b2bf11382c641db944666cd25cd8f56c7c8ef518 Mon Sep 17 00:00:00 2001 From: Phil Krylov Date: Wed, 16 Jun 2021 16:12:20 +0300 Subject: [PATCH] Add --pre-snapshot-cmd and --post-snapshot-cmd options --- zfs_autobackup/ZfsAutobackup.py | 8 +++++++- zfs_autobackup/ZfsNode.py | 10 +++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/zfs_autobackup/ZfsAutobackup.py b/zfs_autobackup/ZfsAutobackup.py index 8c95f45..9e97fb1 100644 --- a/zfs_autobackup/ZfsAutobackup.py +++ b/zfs_autobackup/ZfsAutobackup.py @@ -45,6 +45,10 @@ class ZfsAutobackup: help='Target ZFS filesystem (optional: if not specified, zfs-autobackup will only operate ' 'as snapshot-tool on source)') + parser.add_argument('--pre-snapshot-cmd', metavar="COMMAND", type=str, + help='Run COMMAND before snapshotting.') + parser.add_argument('--post-snapshot-cmd', metavar="COMMAND", type=str, + help='Run COMMAND after snapshotting.') parser.add_argument('--other-snapshots', action='store_true', help='Send over other snapshots as well, not just the ones created by this tool.') parser.add_argument('--no-snapshot', action='store_true', @@ -506,7 +510,9 @@ class ZfsAutobackup: if not self.args.no_snapshot: self.set_title("Snapshotting") source_node.consistent_snapshot(source_datasets, source_node.new_snapshotname(), - min_changed_bytes=self.args.min_change) + min_changed_bytes=self.args.min_change, + pre_snapshot_cmd=self.args.pre_snapshot_cmd, + post_snapshot_cmd=self.args.post_snapshot_cmd) ################# sync # if target is specified, we sync the datasets, otherwise we just thin the source. (e.g. snapshot mode) diff --git a/zfs_autobackup/ZfsNode.py b/zfs_autobackup/ZfsNode.py index da37349..28a7f5b 100644 --- a/zfs_autobackup/ZfsNode.py +++ b/zfs_autobackup/ZfsNode.py @@ -161,7 +161,7 @@ class ZfsNode(ExecuteNode): """determine uniq new snapshotname""" return self.backup_name + "-" + time.strftime("%Y%m%d%H%M%S") - def consistent_snapshot(self, datasets, snapshot_name, min_changed_bytes): + def consistent_snapshot(self, datasets, snapshot_name, min_changed_bytes, pre_snapshot_cmd=None, post_snapshot_cmd=None): """create a consistent (atomic) snapshot of specified datasets, per pool. """ @@ -191,6 +191,10 @@ class ZfsNode(ExecuteNode): self.verbose("No changes anywhere: not creating snapshots.") return + if pre_snapshot_cmd: + self.verbose("Running pre-snapshot-cmd:\n\t{}".format(pre_snapshot_cmd)) + self.run(cmd=pre_snapshot_cmd.split(" "), readonly=False) + # create consistent snapshot per pool for (pool_name, snapshots) in pools.items(): cmd = ["zfs", "snapshot"] @@ -200,6 +204,10 @@ class ZfsNode(ExecuteNode): self.verbose("Creating snapshots {} in pool {}".format(snapshot_name, pool_name)) self.run(cmd, readonly=False) + if post_snapshot_cmd: + self.verbose("Running post-snapshot-cmd:\n\t{}".format(post_snapshot_cmd)) + self.run(cmd=post_snapshot_cmd.split(" "), readonly=False) + def selected_datasets(self, exclude_received, exclude_paths): """determine filesystems that should be backupped by looking at the special autobackup-property, systemwide