/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/transport/ssh.py

  • Committer: John Arbash Meinel
  • Date: 2009-07-31 17:42:29 UTC
  • mto: This revision was merged to the branch mainline in revision 4611.
  • Revision ID: john@arbash-meinel.com-20090731174229-w2zdsdlfpeddk8gl
Now we got to the per-workingtree tests, etc.

The main causes seem to break down into:
  bzrdir.clone() is known to be broken wrt locking, this effects
  everything that tries to 'push'

  shelf code is not compatible with strict locking

  merge code seems to have an issue. This might actually be the
  root cause of the clone() problems.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Robey Pointer <robey@lag.net>
 
1
# Copyright (C) 2005 Robey Pointer <robey@lag.net>
2
2
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
3
3
#
4
4
# This program is free software; you can redistribute it and/or modify
94
94
            try:
95
95
                vendor = self._ssh_vendors[vendor_name]
96
96
            except KeyError:
97
 
                vendor = self._get_vendor_from_path(vendor_name)
98
 
                if vendor is None:
99
 
                    raise errors.UnknownSSH(vendor_name)
100
 
                vendor.executable_path = vendor_name
 
97
                raise errors.UnknownSSH(vendor_name)
101
98
            return vendor
102
99
        return None
103
100
 
113
110
            stdout = stderr = ''
114
111
        return stdout + stderr
115
112
 
116
 
    def _get_vendor_by_version_string(self, version, progname):
 
113
    def _get_vendor_by_version_string(self, version, args):
117
114
        """Return the vendor or None based on output from the subprocess.
118
115
 
119
116
        :param version: The output of 'ssh -V' like command.
126
123
        elif 'SSH Secure Shell' in version:
127
124
            trace.mutter('ssh implementation is SSH Corp.')
128
125
            vendor = SSHCorpSubprocessVendor()
129
 
        # As plink user prompts are not handled currently, don't auto-detect
130
 
        # it by inspection below, but keep this vendor detection for if a path
131
 
        # is given in BZR_SSH. See https://bugs.launchpad.net/bugs/414743
132
 
        elif 'plink' in version and progname == 'plink':
 
126
        elif 'plink' in version and args[0] == 'plink':
133
127
            # Checking if "plink" was the executed argument as Windows
134
128
            # sometimes reports 'ssh -V' incorrectly with 'plink' in it's
135
129
            # version.  See https://bugs.launchpad.net/bzr/+bug/107155
139
133
 
140
134
    def _get_vendor_by_inspection(self):
141
135
        """Return the vendor or None by checking for known SSH implementations."""
142
 
        version = self._get_ssh_version_string(['ssh', '-V'])
143
 
        return self._get_vendor_by_version_string(version, "ssh")
144
 
 
145
 
    def _get_vendor_from_path(self, path):
146
 
        """Return the vendor or None using the program at the given path"""
147
 
        version = self._get_ssh_version_string([path, '-V'])
148
 
        return self._get_vendor_by_version_string(version, 
149
 
            os.path.splitext(os.path.basename(path))[0])
 
136
        for args in (['ssh', '-V'], ['plink', '-V']):
 
137
            version = self._get_ssh_version_string(args)
 
138
            vendor = self._get_vendor_by_version_string(version, args)
 
139
            if vendor is not None:
 
140
                return vendor
 
141
        return None
150
142
 
151
143
    def get_vendor(self, environment=None):
152
144
        """Find out what version of SSH is on the system.
173
165
register_ssh_vendor = _ssh_vendor_manager.register_vendor
174
166
 
175
167
 
176
 
def _ignore_signals():
 
168
def _ignore_sigint():
177
169
    # TODO: This should possibly ignore SIGHUP as well, but bzr currently
178
170
    # doesn't handle it itself.
179
171
    # <https://launchpad.net/products/bzr/+bug/41433/+index>
180
172
    import signal
181
173
    signal.signal(signal.SIGINT, signal.SIG_IGN)
182
 
    # GZ 2010-02-19: Perhaps make this check if breakin is installed instead
183
 
    if signal.getsignal(signal.SIGQUIT) != signal.SIG_DFL:
184
 
        signal.signal(signal.SIGQUIT, signal.SIG_IGN)
185
174
 
186
175
 
187
176
class SocketAsChannelAdapter(object):
412
401
class OpenSSHSubprocessVendor(SubprocessVendor):
413
402
    """SSH vendor that uses the 'ssh' executable from OpenSSH."""
414
403
 
415
 
    executable_path = 'ssh'
416
 
 
417
404
    def _get_vendor_specific_argv(self, username, host, port, subsystem=None,
418
405
                                  command=None):
419
 
        args = [self.executable_path,
 
406
        args = ['ssh',
420
407
                '-oForwardX11=no', '-oForwardAgent=no',
421
408
                '-oClearAllForwardings=yes', '-oProtocol=2',
422
409
                '-oNoHostAuthenticationForLocalhost=yes']
436
423
class SSHCorpSubprocessVendor(SubprocessVendor):
437
424
    """SSH vendor that uses the 'ssh' executable from SSH Corporation."""
438
425
 
439
 
    executable_path = 'ssh'
440
 
 
441
426
    def _get_vendor_specific_argv(self, username, host, port, subsystem=None,
442
427
                                  command=None):
443
 
        args = [self.executable_path, '-x']
 
428
        args = ['ssh', '-x']
444
429
        if port is not None:
445
430
            args.extend(['-p', str(port)])
446
431
        if username is not None:
451
436
            args.extend([host] + command)
452
437
        return args
453
438
 
454
 
register_ssh_vendor('sshcorp', SSHCorpSubprocessVendor())
 
439
register_ssh_vendor('ssh', SSHCorpSubprocessVendor())
455
440
 
456
441
 
457
442
class PLinkSubprocessVendor(SubprocessVendor):
458
443
    """SSH vendor that uses the 'plink' executable from Putty."""
459
444
 
460
 
    executable_path = 'plink'
461
 
 
462
445
    def _get_vendor_specific_argv(self, username, host, port, subsystem=None,
463
446
                                  command=None):
464
 
        args = [self.executable_path, '-x', '-a', '-ssh', '-2', '-batch']
 
447
        args = ['plink', '-x', '-a', '-ssh', '-2', '-batch']
465
448
        if port is not None:
466
449
            args.extend(['-P', str(port)])
467
450
        if username is not None:
518
501
    except paramiko.SSHException, e:
519
502
        # Don't know what happened, but just ignore it
520
503
        pass
521
 
    # We treat 'keyboard-interactive' and 'password' auth methods identically,
522
 
    # because Paramiko's auth_password method will automatically try
523
 
    # 'keyboard-interactive' auth (using the password as the response) if
524
 
    # 'password' auth is not available.  Apparently some Debian and Gentoo
525
 
    # OpenSSH servers require this.
526
 
    # XXX: It's possible for a server to require keyboard-interactive auth that
527
 
    # requires something other than a single password, but we currently don't
528
 
    # support that.
529
 
    if ('password' not in supported_auth_types and
530
 
        'keyboard-interactive' not in supported_auth_types):
 
504
    if 'password' not in supported_auth_types:
531
505
        raise errors.ConnectionError('Unable to authenticate to SSH host as'
532
506
            '\n  %s@%s\nsupported auth types: %s'
533
507
            % (username, host, supported_auth_types))
637
611
        # Running it in a separate process group is not good because then it
638
612
        # can't get non-echoed input of a password or passphrase.
639
613
        # <https://launchpad.net/products/bzr/+bug/40508>
640
 
        return {'preexec_fn': _ignore_signals,
 
614
        return {'preexec_fn': _ignore_sigint,
641
615
                'close_fds': True,
642
616
                }
643
617
 
644
 
import weakref
645
 
_subproc_weakrefs = set()
646
 
 
647
 
def _close_ssh_proc(proc):
648
 
    for func in [proc.stdin.close, proc.stdout.close, proc.wait]:
649
 
        try:
650
 
            func()
651
 
        except OSError:
652
 
            pass
653
 
 
654
618
 
655
619
class SSHSubprocess(object):
656
620
    """A socket-like object that talks to an ssh subprocess via pipes."""
657
621
 
658
622
    def __init__(self, proc):
659
623
        self.proc = proc
660
 
        # Add a weakref to proc that will attempt to do the same as self.close
661
 
        # to avoid leaving processes lingering indefinitely.
662
 
        def terminate(ref):
663
 
            _subproc_weakrefs.remove(ref)
664
 
            _close_ssh_proc(proc)
665
 
        _subproc_weakrefs.add(weakref.ref(self, terminate))
666
624
 
667
625
    def send(self, data):
668
626
        return os.write(self.proc.stdin.fileno(), data)
671
629
        return os.read(self.proc.stdout.fileno(), count)
672
630
 
673
631
    def close(self):
674
 
        _close_ssh_proc(self.proc)
 
632
        self.proc.stdin.close()
 
633
        self.proc.stdout.close()
 
634
        self.proc.wait()
675
635
 
676
636
    def get_filelike_channels(self):
677
637
        return (self.proc.stdout, self.proc.stdin)