diff --git a/bin/zfs-autobackup b/bin/zfs-autobackup index 6fe0d65..04e46e4 100755 --- a/bin/zfs-autobackup +++ b/bin/zfs-autobackup @@ -305,12 +305,14 @@ class ExecuteNode: """an endpoint to execute local or remote commands via ssh""" - def __init__(self, ssh_to=None, readonly=False, debug_output=False): - """ssh_to: server you want to ssh to. none means local + def __init__(self, ssh_config=None, ssh_to=None, readonly=False, debug_output=False): + """ssh_config: custom ssh config + ssh_to: server you want to ssh to. none means local readonly: only execute commands that dont make any changes (usefull for testing-runs) debug_output: show output and exit codes of commands in debugging output. """ + self.ssh_config=ssh_config self.ssh_to=ssh_to self.readonly=readonly self.debug_output=debug_output @@ -355,7 +357,12 @@ class ExecuteNode: #use ssh? if self.ssh_to != None: - encoded_cmd.extend(["ssh".encode('utf-8'), self.ssh_to.encode('utf-8')]) + encoded_cmd.append("ssh".encode('utf-8')) + + if self.ssh_config != None: + encoded_cmd.extend(["-F".encode('utf-8'), self.ssh_config.encode('utf-8')]) + + encoded_cmd.append(self.ssh_to.encode('utf-8')) #make sure the command gets all the data in utf8 format: #(this is neccesary if LC_ALL=en_US.utf8 is not set in the environment) @@ -1163,7 +1170,7 @@ class ZfsDataset(): class ZfsNode(ExecuteNode): """a node that contains zfs datasets. implements global (systemwide/pool wide) zfs commands""" - def __init__(self, backup_name, zfs_autobackup, ssh_to=None, readonly=False, description="", debug_output=False, thinner=Thinner()): + def __init__(self, backup_name, zfs_autobackup, ssh_config=None, ssh_to=None, readonly=False, description="", debug_output=False, thinner=Thinner()): self.backup_name=backup_name if not description: self.description=ssh_to @@ -1172,6 +1179,9 @@ class ZfsNode(ExecuteNode): self.zfs_autobackup=zfs_autobackup #for logging + if ssh_config: + self.verbose("Using custom SSH config: {}".format(ssh_config)) + if ssh_to: self.verbose("Datasets on: {}".format(ssh_to)) else: @@ -1187,7 +1197,7 @@ class ZfsNode(ExecuteNode): self.thinner=thinner - ExecuteNode.__init__(self, ssh_to=ssh_to, readonly=readonly, debug_output=debug_output) + ExecuteNode.__init__(self, ssh_config=ssh_config, ssh_to=ssh_to, readonly=readonly, debug_output=debug_output) def reset_progress(self): @@ -1349,6 +1359,7 @@ class ZfsAutobackup: parser = argparse.ArgumentParser( description=HEADER, epilog='When a filesystem fails, zfs_backup will continue and report the number of failures at that end. Also the exit code will indicate the number of failures.') + parser.add_argument('--ssh-config', default=None, help='Custom ssh client config') parser.add_argument('--ssh-source', default=None, help='Source host to get backup from. (user@hostname) Default %(default)s.') parser.add_argument('--ssh-target', default=None, help='Target host to push backup to. (user@hostname) Default %(default)s.') parser.add_argument('--keep-source', type=str, default="10,1d1w,1w1m,1m1y", help='Thinning schedule for old source snapshots. Default: %(default)s') @@ -1426,14 +1437,14 @@ class ZfsAutobackup: description="[Source]" source_thinner=Thinner(self.args.keep_source) - source_node=ZfsNode(self.args.backup_name, self, ssh_to=self.args.ssh_source, readonly=self.args.test, debug_output=self.args.debug_output, description=description, thinner=source_thinner) + source_node=ZfsNode(self.args.backup_name, 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) source_node.verbose("Send all datasets that have 'autobackup:{}=true' or 'autobackup:{}=child'".format(self.args.backup_name, self.args.backup_name)) self.verbose("") description="[Target]" target_thinner=Thinner(self.args.keep_target) - target_node=ZfsNode(self.args.backup_name, self, ssh_to=self.args.ssh_target, readonly=self.args.test, debug_output=self.args.debug_output, description=description, thinner=target_thinner) + target_node=ZfsNode(self.args.backup_name, self, ssh_config=self.args.ssh_config, ssh_to=self.args.ssh_target, readonly=self.args.test, debug_output=self.args.debug_output, description=description, thinner=target_thinner) target_node.verbose("Receive datasets under: {}".format(self.args.target_path)) self.set_title("Selecting")