edso has proposed merging lp:~ed.so/duplicity/backend_fixes into lp:duplicity.
Requested reviews: duplicity-team (duplicity-team) For more details, see: https://code.launchpad.net/~ed.so/duplicity/backend_fixes/+merge/105956 - fixed ssh/gio backend import warnings + ssh paramiko backend imports paramiko lazily now + gio backend is not imported automatically but on request when --gio option is used - added a warning when --ssh-backend is used with an incorrect value -- https://code.launchpad.net/~ed.so/duplicity/backend_fixes/+merge/105956 Your team duplicity-team is requested to review the proposed merge of lp:~ed.so/duplicity/backend_fixes into lp:duplicity.
=== modified file 'duplicity/backend.py' --- duplicity/backend.py 2012-02-29 16:40:41 +0000 +++ duplicity/backend.py 2012-05-16 11:17:18 +0000 @@ -74,6 +74,8 @@ if fn.endswith("backend.py"): fn = fn[:-3] imp = "duplicity.backends.%s" % (fn,) + # ignore gio as it is explicitly loaded in commandline.parse_cmdline_options() + if fn == "giobackend": continue try: __import__(imp) res = "Succeeded" @@ -155,7 +157,10 @@ elif not pu.scheme in _backends: raise UnsupportedBackendScheme(url_string) else: - return _backends[pu.scheme](pu) + try: + return _backends[pu.scheme](pu) + except ImportError: + raise BackendException(_("Could not initialize backend: %s") % str(sys.exc_info()[1])) _urlparser_initialized = False === modified file 'duplicity/backends/_ssh_paramiko.py' --- duplicity/backends/_ssh_paramiko.py 2012-05-15 11:34:57 +0000 +++ duplicity/backends/_ssh_paramiko.py 2012-05-16 11:17:18 +0000 @@ -32,13 +32,6 @@ import getpass from binascii import hexlify -# debian squeeze's paramiko is a bit old, so we silence randompool depreciation warning -# note also: passphrased private keys work with squeeze's paramiko only if done with DES, not AES -import warnings -warnings.simplefilter("ignore") -import paramiko -warnings.resetwarnings() - import duplicity.backend from duplicity import globals from duplicity import log @@ -73,6 +66,42 @@ else: self.remote_dir = '.' + # lazily import paramiko when we need it + # debian squeeze's paramiko is a bit old, so we silence randompool depreciation warning + # note also: passphrased private keys work with squeeze's paramiko only if done with DES, not AES + import warnings + warnings.simplefilter("ignore") + import paramiko + warnings.resetwarnings() + + class AgreedAddPolicy (paramiko.AutoAddPolicy): + """ + Policy for showing a yes/no prompt and adding the hostname and new + host key to the known host file accordingly. + + This class simply extends the AutoAddPolicy class with a yes/no prompt. + """ + def missing_host_key(self, client, hostname, key): + fp = hexlify(key.get_fingerprint()) + fingerprint = ':'.join(a+b for a,b in zip(fp[::2], fp[1::2])) + question = """The authenticity of host '%s' can't be established. +%s key fingerprint is %s. +Are you sure you want to continue connecting (yes/no)? """ % (hostname, key.get_name().upper(), fingerprint) + while True: + sys.stdout.write(question) + choice = raw_input().lower() + if choice in ['yes','y']: + super(AgreedAddPolicy, self).missing_host_key(client, hostname, key) + return + elif choice in ['no','n']: + raise AuthenticityException( hostname ) + else: + question = "Please type 'yes' or 'no': " + + class AuthenticityException (paramiko.SSHException): + def __init__(self, hostname): + paramiko.SSHException.__init__(self, 'Host key verification for server %s failed.' % hostname) + self.client = paramiko.SSHClient() self.client.set_missing_host_key_policy(AgreedAddPolicy()) # load known_hosts files @@ -358,6 +387,8 @@ return output def gethostconfig(self, file, host): + import paramiko + file = os.path.expanduser(file) if not os.path.isfile(file): return {} @@ -370,35 +401,6 @@ return sshconfig.lookup(host) -class AgreedAddPolicy (paramiko.AutoAddPolicy): - """ - Policy for showing a yes/no prompt and adding the hostname and new - host key to the known host file accordingly. - - This class simply extends the AutoAddPolicy class with a yes/no prompt. - """ - def missing_host_key(self, client, hostname, key): - fp = hexlify(key.get_fingerprint()) - fingerprint = ':'.join(a+b for a,b in zip(fp[::2], fp[1::2])) - question = """The authenticity of host '%s' can't be established. -%s key fingerprint is %s. -Are you sure you want to continue connecting (yes/no)? """ % (hostname, key.get_name().upper(), fingerprint) - while True: - sys.stdout.write(question) - choice = raw_input().lower() - if choice in ['yes','y']: - super(AgreedAddPolicy, self).missing_host_key(client, hostname, key) - return - elif choice in ['no','n']: - raise AuthenticityException( hostname ) - else: - question = "Please type 'yes' or 'no': " - -class AuthenticityException (paramiko.SSHException): - def __init__(self, hostname): - paramiko.SSHException.__init__(self, 'Host key verification for server %s failed.' % hostname) - - duplicity.backend.register_backend("sftp", SSHParamikoBackend) duplicity.backend.register_backend("scp", SSHParamikoBackend) duplicity.backend.register_backend("ssh", SSHParamikoBackend) === modified file 'duplicity/backends/sshbackend.py' --- duplicity/backends/sshbackend.py 2012-05-15 13:08:14 +0000 +++ duplicity/backends/sshbackend.py 2012-05-16 11:17:18 +0000 @@ -22,12 +22,15 @@ def warn_option(option, optionvar): if optionvar: - log.Warn("Warning: Option %s is supported by ssh pexpect backend only and will be ignored. " % option) + log.Warn(_("Warning: Option %s is supported by ssh pexpect backend only and will be ignored.") % option) if (globals.ssh_backend and globals.ssh_backend.lower().strip() == 'pexpect'): import _ssh_pexpect else: + # take user by the hand to prevent typo driven bug reports + if globals.ssh_backend.lower().strip() != 'paramiko': + log.Warn(_("Warning: Selected ssh backend '%s' is neither 'paramiko nor 'pexpect'. Will use default paramiko instead.") % globals.ssh_backend) warn_option("--scp-command", globals.scp_command) warn_option("--sftp-command", globals.sftp_command) import _ssh_paramiko === modified file 'duplicity/commandline.py' --- duplicity/commandline.py 2012-03-13 20:53:35 +0000 +++ duplicity/commandline.py 2012-05-16 11:17:18 +0000 @@ -207,7 +207,7 @@ import duplicity.backends.giobackend backend.force_backend(duplicity.backends.giobackend.GIOBackend) except ImportError: - log.FatalError(_("Unable to load gio module"), log.ErrorCode.gio_not_available) + log.FatalError(_("Unable to load gio backend: %s") % str(sys.exc_info()[1]), log.ErrorCode.gio_not_available) def set_log_fd(fd): if fd < 1:
_______________________________________________ Mailing list: https://launchpad.net/~duplicity-team Post to : duplicity-team@lists.launchpad.net Unsubscribe : https://launchpad.net/~duplicity-team More help : https://help.launchpad.net/ListHelp