321
321
if self._do_prefetch and hasattr(f, 'prefetch'):
324
except (IOError, paramiko.SSHException), x:
325
raise NoSuchFile('Error retrieving %s: %s' % (path, str(x)), x)
324
except (IOError, paramiko.SSHException), e:
325
self._translate_io_exception(e, path, ': error retrieving')
327
327
def get_partial(self, relpath, start, length=None):
395
395
path = self._abspath(relpath)
396
396
self._sftp.mkdir(path)
397
397
except (paramiko.SSHException, IOError), e:
398
self._translate_io_exception(e, relpath, ': unable to mkdir')
400
def _translate_io_exception(self, e, relpath, more_info=''):
398
self._translate_io_exception(e, relpath, ': unable to mkdir',
399
failure_exc=FileExists)
401
def _translate_io_exception(self, e, path, more_info='', failure_exc=NoSuchFile):
402
"""Translate a paramiko or IOError into a friendlier exception.
404
:param e: The original exception
405
:param path: The path in question when the error is raised
406
:param more_info: Extra information that can be included,
407
such as what was going on
408
:param failure_exc: Paramiko has the super fun ability to raise completely
409
opaque errors that just set "e.args = ('Failure',)" with
411
This sometimes means FileExists, but it also sometimes
401
414
# paramiko seems to generate detailless errors.
402
self._translate_error(e, relpath, raise_generic=False)
415
self._translate_error(e, path, raise_generic=False)
403
416
if hasattr(e, 'args'):
404
417
if (e.args == ('No such file or directory',) or
405
418
e.args == ('No such file',)):
406
raise NoSuchFile(relpath, str(e) + more_info)
419
raise NoSuchFile(path, str(e) + more_info)
407
420
if (e.args == ('mkdir failed',)):
408
raise FileExists(relpath, str(e) + more_info)
421
raise FileExists(path, str(e) + more_info)
409
422
# strange but true, for the paramiko server.
410
423
if (e.args == ('Failure',)):
411
raise FileExists(relpath, str(e) + more_info)
424
raise failure_exc(path, str(e) + more_info)
414
427
def append(self, relpath, f):
420
433
path = self._abspath(relpath)
421
434
fout = self._sftp.file(path, 'ab')
422
435
self._pump(f, fout)
423
except (IOError, paramiko.SSHException), x:
424
raise TransportError('Unable to append file %r' % (path,), x)
436
except (IOError, paramiko.SSHException), e:
437
self._translate_io_exception(e, relpath, ': unable to append')
426
439
def copy(self, rel_from, rel_to):
427
440
"""Copy the item at rel_from to the location at rel_to"""
455
except (IOError, paramiko.SSHException), x:
456
raise TransportError('Unable to copy %r to %r' % (path_from, path_to), x)
468
except (IOError, paramiko.SSHException), e:
469
self._translate_io_exception(e, path_from, ': unable copy to: %r' % path_to)
458
471
def copy_to(self, relpaths, other, pb=None):
459
472
"""Copy a set of entries from self into another Transport.
505
518
path = self._abspath(relpath)
507
520
self._sftp.remove(path)
508
except (IOError, paramiko.SSHException), x:
509
raise TransportError('Unable to delete %r' % (path,), x)
521
except (IOError, paramiko.SSHException), e:
522
self._translate_io_exception(e, path, ': unable to delete')
511
524
def listable(self):
512
525
"""Return True if this store supports listing."""
520
533
path = self._abspath(relpath)
522
535
return self._sftp.listdir(path)
523
except (IOError, paramiko.SSHException), x:
524
raise TransportError('Unable to list folder %r' % (path,), x)
536
except (IOError, paramiko.SSHException), e:
537
self._translate_io_exception(e, path, ': failed to list_dir')
526
539
def stat(self, relpath):
527
540
"""Return the stat information for a file."""
528
541
path = self._abspath(relpath)
530
543
return self._sftp.stat(path)
531
except (IOError, paramiko.SSHException), x:
532
raise TransportError('Unable to stat %r' % (path,), x)
544
except (IOError, paramiko.SSHException), e:
545
self._translate_io_exception(e, path, ': unable to stat')
534
547
def lock_read(self, relpath):
647
t = paramiko.Transport((self._host, self._port))
661
t = paramiko.Transport((self._host, self._port or 22))
649
except paramiko.SSHException:
650
raise TransportError('Unable to reach SSH host %s:%d' % (self._host, self._port))
663
except paramiko.SSHException, e:
664
raise ConnectionError('Unable to reach SSH host %s:%d' %
665
(self._host, self._port), e)
652
667
server_key = t.get_remote_server_key()
653
668
server_key_hex = paramiko.util.hexify(server_key.get_fingerprint())
679
694
self._sftp = t.open_sftp_client()
680
except paramiko.SSHException:
681
raise BzrError('Unable to find path %s on SFTP server %s' % \
682
(self._path, self._host))
695
except paramiko.SSHException, e:
696
raise ConnectionError('Unable to start sftp client %s:%d' %
697
(self._host, self._port), e)
684
699
def _sftp_auth(self, transport):
685
700
# paramiko requires a username, but it might be none if nothing was supplied
727
742
user=username, host=self._host)
729
744
transport.auth_password(username, password)
730
except paramiko.SSHException:
731
raise TransportError('Unable to authenticate to SSH host as %s@%s' % \
732
(username, self._host))
745
except paramiko.SSHException, e:
746
raise ConnectionError('Unable to authenticate to SSH host as %s@%s' %
747
(username, self._host), e)
734
749
def _try_pkey_auth(self, transport, pkey_class, username, filename):
735
750
filename = os.path.expanduser('~/.ssh/' + filename)
777
792
handle = msg.get_string()
778
793
return SFTPFile(self._sftp, handle, 'wb', -1)
779
794
except (paramiko.SSHException, IOError), e:
780
self._translate_io_exception(e, relpath, ': unable to open')
795
self._translate_io_exception(e, relpath, ': unable to open',
796
failure_exc=FileExists)