import os.path import pprint import subprocess import sys import transfer.protocol class RsyncOverSsh(transfer.protocol.Protocol): def __init__(self, options, config): super(RsyncOverSsh, self).__init__(options, config) self.ssh_config = config.get_value("ssh") def build_rsync_command(self, transfer_spec, dry_run): dest_path = os.path.join( self.ssh_config["root_dir"], transfer_spec.dest_path) flags = "-avz" if dry_run: flags += "n" cmd = [ "rsync", flags, "-e", "ssh -p {}".format(self.ssh_config["port"]), "--rsync-path", # The following command needs to know the right way to do # this on the dest platform - ensures the target dir exists. "mkdir -p {} && rsync".format(dest_path) ] # Add source dir exclusions if transfer_spec.exclude_paths: for exclude_path in transfer_spec.exclude_paths: cmd.append("--exclude") cmd.append(exclude_path) cmd.extend([ "--delete", transfer_spec.source_path + "/", "{}@{}:{}".format( self.ssh_config["user"], self.ssh_config["dest_host"], dest_path)]) return cmd def transfer(self, transfer_specs, dry_run): if self.options.verbose: printer = pprint.PrettyPrinter() for spec in transfer_specs: printer.pprint(spec) for spec in transfer_specs: cmd = self.build_rsync_command(spec, dry_run) if self.options.verbose: print "executing the following command:\n{}".format(cmd) result = subprocess.call( cmd, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr) if result != 0: return result