From 62178e424ed0d64dc5161830b9c46c4871433dc6 Mon Sep 17 00:00:00 2001 From: Marius van Witzenburg Date: Thu, 5 Apr 2018 09:23:08 +0200 Subject: [PATCH 1/6] Added argument to return exit code --- zfs_autobackup | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/zfs_autobackup b/zfs_autobackup index 5bfc012..44663ab 100755 --- a/zfs_autobackup +++ b/zfs_autobackup @@ -31,7 +31,7 @@ def debug(txt): """run a command. specifiy ssh user@host to run remotely""" -def run(cmd, input=None, ssh_to="local", tab_split=False, valid_exitcodes=[ 0 ], test=False): +def run(cmd, input=None, ssh_to="local", tab_split=False, valid_exitcodes=[ 0 ], test=False, return_exitcode=False): encoded_cmd=[] @@ -80,6 +80,9 @@ def run(cmd, input=None, ssh_to="local", tab_split=False, valid_exitcodes=[ 0 ], if p.returncode not in valid_exitcodes: raise(subprocess.CalledProcessError(p.returncode, encoded_cmd)) + if return_exitcode: + return(p.returncode) + lines=output.splitlines() if not tab_split: return(lines) From ba89dc8bb28a6b4ccc35ce832932c18bcc69cd85 Mon Sep 17 00:00:00 2001 From: Marius van Witzenburg Date: Thu, 5 Apr 2018 09:23:39 +0200 Subject: [PATCH 2/6] Use persistent connections for 600 seconds (10min) --- zfs_autobackup | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zfs_autobackup b/zfs_autobackup index 44663ab..17eb8f1 100755 --- a/zfs_autobackup +++ b/zfs_autobackup @@ -38,7 +38,7 @@ def run(cmd, input=None, ssh_to="local", tab_split=False, valid_exitcodes=[ 0 ], #use ssh? if ssh_to != "local": - encoded_cmd.extend(["ssh", ssh_to]) + encoded_cmd.extend([ "ssh", "-o", "ControlMaster=auto", "-o", "ControlPersist=600s", "-o", "ControlPath=~/.ssh/control-master-%r@%h:%p", ssh_to ]) if args.ssh_cipher: encoded_cmd.extend(["-c", args.ssh_cipher]) if args.compress: @@ -263,7 +263,7 @@ def zfs_transfer(ssh_source, source_filesystem, first_snapshot, second_snapshot, source_cmd=[] if ssh_source != "local": - source_cmd.extend([ "ssh", ssh_source ]) + source_cmd.extend([ "ssh", "-o", "ControlMaster=auto", "-o", "ControlPersist=600s", "-o", "ControlPath=~/.ssh/control-master-%r@%h:%p", ssh_source ]) if args.ssh_cipher: source_cmd.extend(["-c", args.ssh_cipher]) if args.compress: @@ -302,7 +302,7 @@ def zfs_transfer(ssh_source, source_filesystem, first_snapshot, second_snapshot, target_cmd=[] if ssh_target != "local": - target_cmd.extend([ "ssh", ssh_target ]) + target_cmd.extend([ "ssh", "-o", "ControlMaster=auto", "-o", "ControlPersist=600s", "-o", "ControlPath=~/.ssh/control-master-%r@%h:%p", ssh_target ]) if args.ssh_cipher: target_cmd.extend(["-c", args.ssh_cipher]) if args.compress: From 84d44a267a709a5034a297d6c0be1fb6636f67e1 Mon Sep 17 00:00:00 2001 From: Marius van Witzenburg Date: Thu, 5 Apr 2018 09:23:59 +0200 Subject: [PATCH 3/6] Exit persistent connection when everything is finished --- zfs_autobackup | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/zfs_autobackup b/zfs_autobackup index 17eb8f1..f981f86 100755 --- a/zfs_autobackup +++ b/zfs_autobackup @@ -611,6 +611,17 @@ def zfs_autobackup(): verbose("Destroying old snapshots on target {0}:\n{1}".format(args.ssh_target, "\n".join(target_destroys))) zfs_destroy_snapshots(ssh_to=args.ssh_target, snapshots=target_destroys) + if args.ssh_source != "local": + verbose("Disconnect ssh_source") + code=run(test=args.test, valid_exitcodes=[0, 255], return_exitcode=True, cmd=[ "ssh", "-o", "ControlPath=~/.ssh/control-master-%r@%h:%p", "-O", "check", args.ssh_source ]) + if code == 0: + code=run(test=args.test, valid_exitcodes=[0, 255], cmd=[ "ssh", "-o", "ControlPath=~/.ssh/control-master-%r@%h:%p", "-O", "exit", args.ssh_source ]) + + if args.ssh_target != "local": + verbose("Disconnect ssh_target") + code=run(test=args.test, valid_exitcodes=[0, 255], return_exitcode=True, cmd=[ "ssh", "-o", "ControlPath=~/.ssh/control-master-%r@%h:%p", "-O", "check", args.ssh_target ]) + if code == 0: + run(test=args.test, valid_exitcodes=[0, 255], cmd=[ "ssh", "-o", "ControlPath=~/.ssh/control-master-%r@%h:%p", "-O", "exit", args.ssh_target ]) verbose("All done") From 42b71bbc74ddc46583bdf930ccaee6609f5c837d Mon Sep 17 00:00:00 2001 From: Marius van Witzenburg Date: Thu, 5 Apr 2018 10:00:53 +0200 Subject: [PATCH 4/6] Write STDERR to STDOUT --- zfs_autobackup | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zfs_autobackup b/zfs_autobackup index f981f86..271beac 100755 --- a/zfs_autobackup +++ b/zfs_autobackup @@ -75,7 +75,7 @@ def run(cmd, input=None, ssh_to="local", tab_split=False, valid_exitcodes=[ 0 ], if test: return - p=subprocess.Popen(encoded_cmd, env=os.environ, stdout=subprocess.PIPE, stdin=stdin) + p=subprocess.Popen(encoded_cmd, env=os.environ, stdout=subprocess.PIPE, stdin=stdin, stderr=subprocess.STDOUT) output=p.communicate(input=input)[0] if p.returncode not in valid_exitcodes: raise(subprocess.CalledProcessError(p.returncode, encoded_cmd)) From cc1725e3be23a0de82f6c547bb65b9751a2ae981 Mon Sep 17 00:00:00 2001 From: Marius van Witzenburg Date: Thu, 5 Apr 2018 10:01:23 +0200 Subject: [PATCH 5/6] Compacted code bit into a function --- zfs_autobackup | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/zfs_autobackup b/zfs_autobackup index 271beac..177cb3d 100755 --- a/zfs_autobackup +++ b/zfs_autobackup @@ -93,6 +93,15 @@ def run(cmd, input=None, ssh_to="local", tab_split=False, valid_exitcodes=[ 0 ], return(ret) + +"""Close open SSH connections""" +def run_ssh_close(ssh_host, test=False): + code=run(test=test, valid_exitcodes=[0, 255], return_exitcode=True, cmd=[ "ssh", "-o", "ControlPath=~/.ssh/control-master-%r@%h:%p", "-O", "check", ssh_host ]) + if code == 0: + code=run(test=test, valid_exitcodes=[0, 255], cmd=[ "ssh", "-o", "ControlPath=~/.ssh/control-master-%r@%h:%p", "-O", "exit", ssh_host ]) + + + """determine filesystems that should be backupped by looking at the special autobackup-property""" def zfs_get_selected_filesystems(ssh_to, backup_name): #get all source filesystems that have the backup property @@ -613,15 +622,11 @@ def zfs_autobackup(): if args.ssh_source != "local": verbose("Disconnect ssh_source") - code=run(test=args.test, valid_exitcodes=[0, 255], return_exitcode=True, cmd=[ "ssh", "-o", "ControlPath=~/.ssh/control-master-%r@%h:%p", "-O", "check", args.ssh_source ]) - if code == 0: - code=run(test=args.test, valid_exitcodes=[0, 255], cmd=[ "ssh", "-o", "ControlPath=~/.ssh/control-master-%r@%h:%p", "-O", "exit", args.ssh_source ]) + run_ssh_close(ssh_host=args.ssh_source, test=args.test) if args.ssh_target != "local": verbose("Disconnect ssh_target") - code=run(test=args.test, valid_exitcodes=[0, 255], return_exitcode=True, cmd=[ "ssh", "-o", "ControlPath=~/.ssh/control-master-%r@%h:%p", "-O", "check", args.ssh_target ]) - if code == 0: - run(test=args.test, valid_exitcodes=[0, 255], cmd=[ "ssh", "-o", "ControlPath=~/.ssh/control-master-%r@%h:%p", "-O", "exit", args.ssh_target ]) + run_ssh_close(ssh_host=args.ssh_target, test=args.test) verbose("All done") From a8d0ff9f377462e4a5cd1bd962c3dd4f115d24ab Mon Sep 17 00:00:00 2001 From: Marius van Witzenburg Date: Thu, 5 Apr 2018 18:05:10 +0200 Subject: [PATCH 6/6] Restored stderr handing to previous state --- zfs_autobackup | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zfs_autobackup b/zfs_autobackup index 177cb3d..a16bd2e 100755 --- a/zfs_autobackup +++ b/zfs_autobackup @@ -75,7 +75,7 @@ def run(cmd, input=None, ssh_to="local", tab_split=False, valid_exitcodes=[ 0 ], if test: return - p=subprocess.Popen(encoded_cmd, env=os.environ, stdout=subprocess.PIPE, stdin=stdin, stderr=subprocess.STDOUT) + p=subprocess.Popen(encoded_cmd, env=os.environ, stdout=subprocess.PIPE, stdin=stdin) output=p.communicate(input=input)[0] if p.returncode not in valid_exitcodes: raise(subprocess.CalledProcessError(p.returncode, encoded_cmd))