Rev 4809: (Martin <gzlist>) Allow specifying path in 'BZR_SSH' rather than just in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Wed Nov 18 19:04:51 GMT 2009


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 4809 [merge]
revision-id: pqm at pqm.ubuntu.com-20091118190447-5ey1wyx4v5c962uk
parent: pqm at pqm.ubuntu.com-20091118173251-z5gh93fnn18bw4on
parent: john at arbash-meinel.com-20091118175426-vvxie9nvsim8cv71
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Wed 2009-11-18 19:04:47 +0000
message:
  (Martin <gzlist>) Allow specifying path in 'BZR_SSH' rather than just
  	vendors.
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/help_topics/__init__.py help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
  bzrlib/tests/test_ssh_transport.py test_ssh_transport.p-20070105153201-f7iq2bosvgjbdgc3-1
  bzrlib/transport/ssh.py        ssh.py-20060824042150-0s9787kng6zv1nwq-1
=== modified file 'NEWS'
--- a/NEWS	2009-11-17 04:03:45 +0000
+++ b/NEWS	2009-11-18 17:54:26 +0000
@@ -14,6 +14,12 @@
 Compatibility Breaks
 ********************
 
+* The BZR_SSH environmental variable may now be set to the path of a secure
+  shell client. If currently set to the value ``ssh`` it will now guess the
+  vendor of the program with that name, to restore the old behaviour that
+  indicated the SSH Corporation client use ``sshcorp`` instead as the magic
+  string. (Martin <gzlist at googlemail.com>, #176292)
+
 New Features
 ************
 

=== modified file 'bzrlib/help_topics/__init__.py'
--- a/bzrlib/help_topics/__init__.py	2009-10-29 21:13:16 +0000
+++ b/bzrlib/help_topics/__init__.py	2009-11-07 08:02:13 +0000
@@ -561,7 +561,7 @@
 BZR_HOME         Directory holding .bazaar config dir. Overrides HOME.
 BZR_HOME (Win32) Directory holding bazaar config dir. Overrides APPDATA and HOME.
 BZR_REMOTE_PATH  Full name of remote 'bzr' command (for bzr+ssh:// URLs).
-BZR_SSH          SSH client: paramiko (default), openssh, ssh, plink.
+BZR_SSH          Path to SSH client, or one of paramiko, openssh, sshcorp, plink.
 BZR_LOG          Location of .bzr.log (use '/dev/null' to suppress log).
 BZR_LOG (Win32)  Location of .bzr.log (use 'NUL' to suppress log).
 ================ =================================================================

=== modified file 'bzrlib/tests/test_ssh_transport.py'
--- a/bzrlib/tests/test_ssh_transport.py	2009-08-28 05:00:33 +0000
+++ b/bzrlib/tests/test_ssh_transport.py	2009-11-07 08:02:13 +0000
@@ -132,6 +132,25 @@
         # Last cached value always checked first
         self.assertIs(manager.get_vendor({}), vendor)
 
+    def test_get_vendor_from_path_win32_plink(self):
+        manager = TestSSHVendorManager()
+        manager.set_ssh_version_string("plink: Release 0.60")
+        plink_path = "C:/Program Files/PuTTY/plink.exe"
+        vendor = manager.get_vendor({"BZR_SSH": plink_path})
+        self.assertIsInstance(vendor, PLinkSubprocessVendor)
+        args = vendor._get_vendor_specific_argv("user", "host", 22, ["bzr"])
+        self.assertEqual(args[0], plink_path)
+
+    def test_get_vendor_from_path_nix_openssh(self):
+        manager = TestSSHVendorManager()
+        manager.set_ssh_version_string(
+            "OpenSSH_5.1p1 Debian-5, OpenSSL, 0.9.8g 19 Oct 2007")
+        openssh_path = "/usr/bin/ssh"
+        vendor = manager.get_vendor({"BZR_SSH": openssh_path})
+        self.assertIsInstance(vendor, OpenSSHSubprocessVendor)
+        args = vendor._get_vendor_specific_argv("user", "host", 22, ["bzr"])
+        self.assertEqual(args[0], openssh_path)
+
 
 class SubprocessVendorsTests(TestCase):
 

=== modified file 'bzrlib/transport/ssh.py'
--- a/bzrlib/transport/ssh.py	2009-10-02 05:43:41 +0000
+++ b/bzrlib/transport/ssh.py	2009-11-07 08:02:13 +0000
@@ -94,7 +94,10 @@
             try:
                 vendor = self._ssh_vendors[vendor_name]
             except KeyError:
-                raise errors.UnknownSSH(vendor_name)
+                vendor = self._get_vendor_from_path(vendor_name)
+                if vendor is None:
+                    raise errors.UnknownSSH(vendor_name)
+                vendor.executable_path = vendor_name
             return vendor
         return None
 
@@ -110,7 +113,7 @@
             stdout = stderr = ''
         return stdout + stderr
 
-    def _get_vendor_by_version_string(self, version, args):
+    def _get_vendor_by_version_string(self, version, progname):
         """Return the vendor or None based on output from the subprocess.
 
         :param version: The output of 'ssh -V' like command.
@@ -123,25 +126,27 @@
         elif 'SSH Secure Shell' in version:
             trace.mutter('ssh implementation is SSH Corp.')
             vendor = SSHCorpSubprocessVendor()
-        # Auto-detect of plink vendor disabled, on Windows recommended
-        # default ssh-client is paramiko
-        # see https://bugs.launchpad.net/bugs/414743
-        #~elif 'plink' in version and args[0] == 'plink':
-        #~    # Checking if "plink" was the executed argument as Windows
-        #~    # sometimes reports 'ssh -V' incorrectly with 'plink' in it's
-        #~    # version.  See https://bugs.launchpad.net/bzr/+bug/107155
-        #~    trace.mutter("ssh implementation is Putty's plink.")
-        #~    vendor = PLinkSubprocessVendor()
+        # As plink user prompts are not handled currently, don't auto-detect
+        # it by inspection below, but keep this vendor detection for if a path
+        # is given in BZR_SSH. See https://bugs.launchpad.net/bugs/414743
+        elif 'plink' in version and progname == 'plink':
+            # Checking if "plink" was the executed argument as Windows
+            # sometimes reports 'ssh -V' incorrectly with 'plink' in it's
+            # version.  See https://bugs.launchpad.net/bzr/+bug/107155
+            trace.mutter("ssh implementation is Putty's plink.")
+            vendor = PLinkSubprocessVendor()
         return vendor
 
     def _get_vendor_by_inspection(self):
         """Return the vendor or None by checking for known SSH implementations."""
-        for args in (['ssh', '-V'], ['plink', '-V']):
-            version = self._get_ssh_version_string(args)
-            vendor = self._get_vendor_by_version_string(version, args)
-            if vendor is not None:
-                return vendor
-        return None
+        version = self._get_ssh_version_string(['ssh', '-V'])
+        return self._get_vendor_by_version_string(version, "ssh")
+
+    def _get_vendor_from_path(self, path):
+        """Return the vendor or None using the program at the given path"""
+        version = self._get_ssh_version_string([path, '-V'])
+        return self._get_vendor_by_version_string(version, 
+            os.path.splitext(os.path.basename(path))[0])
 
     def get_vendor(self, environment=None):
         """Find out what version of SSH is on the system.
@@ -404,9 +409,11 @@
 class OpenSSHSubprocessVendor(SubprocessVendor):
     """SSH vendor that uses the 'ssh' executable from OpenSSH."""
 
+    executable_path = 'ssh'
+
     def _get_vendor_specific_argv(self, username, host, port, subsystem=None,
                                   command=None):
-        args = ['ssh',
+        args = [self.executable_path,
                 '-oForwardX11=no', '-oForwardAgent=no',
                 '-oClearAllForwardings=yes', '-oProtocol=2',
                 '-oNoHostAuthenticationForLocalhost=yes']
@@ -426,9 +433,11 @@
 class SSHCorpSubprocessVendor(SubprocessVendor):
     """SSH vendor that uses the 'ssh' executable from SSH Corporation."""
 
+    executable_path = 'ssh'
+
     def _get_vendor_specific_argv(self, username, host, port, subsystem=None,
                                   command=None):
-        args = ['ssh', '-x']
+        args = [self.executable_path, '-x']
         if port is not None:
             args.extend(['-p', str(port)])
         if username is not None:
@@ -439,15 +448,17 @@
             args.extend([host] + command)
         return args
 
-register_ssh_vendor('ssh', SSHCorpSubprocessVendor())
+register_ssh_vendor('sshcorp', SSHCorpSubprocessVendor())
 
 
 class PLinkSubprocessVendor(SubprocessVendor):
     """SSH vendor that uses the 'plink' executable from Putty."""
 
+    executable_path = 'plink'
+
     def _get_vendor_specific_argv(self, username, host, port, subsystem=None,
                                   command=None):
-        args = ['plink', '-x', '-a', '-ssh', '-2', '-batch']
+        args = [self.executable_path, '-x', '-a', '-ssh', '-2', '-batch']
         if port is not None:
             args.extend(['-P', str(port)])
         if username is not None:




More information about the bazaar-commits mailing list