~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/ssh.py

  • Committer: John Arbash Meinel
  • Date: 2006-10-11 00:23:23 UTC
  • mfrom: (2070 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2071.
  • Revision ID: john@arbash-meinel.com-20061011002323-82ba88c293d7caff
[merge] bzr.dev 2070

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
from bzrlib.config import config_dir, ensure_config_dir_exists
28
28
from bzrlib.errors import (ConnectionError,
29
29
                           ParamikoNotPresent,
30
 
                           SocketConnectionError,
31
30
                           TransportError,
32
31
                           UnknownSSH,
33
32
                           )
39
38
try:
40
39
    import paramiko
41
40
except ImportError, e:
42
 
    # If we have an ssh subprocess, we don't strictly need paramiko for all ssh
43
 
    # access
44
 
    paramiko = None
 
41
    raise ParamikoNotPresent(e)
45
42
else:
46
43
    from paramiko.sftp_client import SFTPClient
47
44
 
109
106
    return _ssh_vendor
110
107
 
111
108
 
 
109
 
112
110
def _ignore_sigint():
113
111
    # TODO: This should possibly ignore SIGHUP as well, but bzr currently
114
112
    # doesn't handle it itself.
163
161
        """
164
162
        raise NotImplementedError(self.connect_ssh)
165
163
        
166
 
    def _raise_connection_error(self, host, port=None, orig_error=None,
167
 
                                msg='Unable to connect to SSH host'):
168
 
        """Raise a SocketConnectionError with properly formatted host.
169
 
 
170
 
        This just unifies all the locations that try to raise ConnectionError,
171
 
        so that they format things properly.
172
 
        """
173
 
        raise SocketConnectionError(host=host, port=port, msg=msg,
174
 
                                    orig_error=orig_error)
175
 
 
176
164
 
177
165
class LoopbackVendor(SSHVendor):
178
166
    """SSH "vendor" that connects over a plain TCP socket, not SSH."""
182
170
        try:
183
171
            sock.connect((host, port))
184
172
        except socket.error, e:
185
 
            self._raise_connection_error(host, port=port, orig_error=e)
 
173
            raise ConnectionError('Unable to connect to SSH host %s:%s: %s'
 
174
                                  % (host, port, e))
186
175
        return SFTPClient(LoopbackSFTP(sock))
187
176
 
188
177
register_ssh_vendor('loopback', LoopbackVendor())
212
201
            t.set_log_channel('bzr.paramiko')
213
202
            t.start_client()
214
203
        except (paramiko.SSHException, socket.error), e:
215
 
            self._raise_connection_error(host, port=port, orig_error=e)
 
204
            raise ConnectionError('Unable to reach SSH host %s:%s: %s' 
 
205
                                  % (host, port, e))
216
206
            
217
207
        server_key = t.get_remote_server_key()
218
208
        server_key_hex = paramiko.util.hexify(server_key.get_fingerprint())
225
215
            our_server_key_hex = paramiko.util.hexify(our_server_key.get_fingerprint())
226
216
        else:
227
217
            warning('Adding %s host key for %s: %s' % (keytype, host, server_key_hex))
228
 
            add = getattr(BZR_HOSTKEYS, 'add', None)
229
 
            if add is not None: # paramiko >= 1.X.X
230
 
                BZR_HOSTKEYS.add(host, keytype, server_key)
231
 
            else:
232
 
                BZR_HOSTKEYS.setdefault(host, {})[keytype] = server_key
 
218
            if host not in BZR_HOSTKEYS:
 
219
                BZR_HOSTKEYS[host] = {}
 
220
            BZR_HOSTKEYS[host][keytype] = server_key
233
221
            our_server_key = server_key
234
222
            our_server_key_hex = paramiko.util.hexify(our_server_key.get_fingerprint())
235
223
            save_host_keys()
248
236
        try:
249
237
            return t.open_sftp_client()
250
238
        except paramiko.SSHException, e:
251
 
            self._raise_connection_error(host, port=port, orig_error=e,
252
 
                                         msg='Unable to start sftp client')
 
239
            raise ConnectionError('Unable to start sftp client %s:%d' %
 
240
                                  (host, port), e)
253
241
 
254
242
    def connect_ssh(self, username, password, host, port, command):
255
243
        t = self._connect(username, password, host, port)
259
247
            channel.exec_command(cmdline)
260
248
            return _ParamikoSSHConnection(channel)
261
249
        except paramiko.SSHException, e:
262
 
            self._raise_connection_error(host, port=port, orig_error=e,
263
 
                                         msg='Unable to invoke remote bzr')
 
250
            raise ConnectionError('Unable to invoke remote bzr %s:%d' %
 
251
                                  (host, port), e)
264
252
 
265
 
if paramiko is not None:
266
 
    register_ssh_vendor('paramiko', ParamikoVendor())
 
253
register_ssh_vendor('paramiko', ParamikoVendor())
267
254
 
268
255
 
269
256
class SubprocessVendor(SSHVendor):
283
270
            sock = self._connect(argv)
284
271
            return SFTPClient(sock)
285
272
        except (EOFError, paramiko.SSHException), e:
286
 
            self._raise_connection_error(host, port=port, orig_error=e)
 
273
            raise ConnectionError('Unable to connect to SSH host %s:%s: %s'
 
274
                                  % (host, port, e))
287
275
        except (OSError, IOError), e:
288
276
            # If the machine is fast enough, ssh can actually exit
289
277
            # before we try and send it the sftp request, which
290
278
            # raises a Broken Pipe
291
279
            if e.errno not in (errno.EPIPE,):
292
280
                raise
293
 
            self._raise_connection_error(host, port=port, orig_error=e)
 
281
            raise ConnectionError('Unable to connect to SSH host %s:%s: %s'
 
282
                                  % (host, port, e))
294
283
 
295
284
    def connect_ssh(self, username, password, host, port, command):
296
285
        try:
298
287
                                                  command=command)
299
288
            return self._connect(argv)
300
289
        except (EOFError), e:
301
 
            self._raise_connection_error(host, port=port, orig_error=e)
 
290
            raise ConnectionError('Unable to connect to SSH host %s:%s: %s'
 
291
                                  % (host, port, e))
302
292
        except (OSError, IOError), e:
303
293
            # If the machine is fast enough, ssh can actually exit
304
294
            # before we try and send it the sftp request, which
305
295
            # raises a Broken Pipe
306
296
            if e.errno not in (errno.EPIPE,):
307
297
                raise
308
 
            self._raise_connection_error(host, port=port, orig_error=e)
 
298
            raise ConnectionError('Unable to connect to SSH host %s:%s: %s'
 
299
                                  % (host, port, e))
309
300
 
310
301
    def _get_vendor_specific_argv(self, username, host, port, subsystem=None,
311
302
                                  command=None):