320
320
if self._do_prefetch and hasattr(f, 'prefetch'):
323
except (IOError, paramiko.SSHException), x:
324
raise NoSuchFile('Error retrieving %s: %s' % (path, str(x)), x)
323
except (IOError, paramiko.SSHException), e:
324
self._translate_io_exception(e, path, ': error retrieving')
326
326
def get_partial(self, relpath, start, length=None):
412
412
path = self._abspath(relpath)
413
413
self._sftp.mkdir(path)
414
414
except (paramiko.SSHException, IOError), e:
415
self._translate_io_exception(e, relpath, ': unable to mkdir')
417
def _translate_io_exception(self, e, relpath, more_info=''):
415
self._translate_io_exception(e, relpath, ': unable to mkdir',
416
failure_exc=FileExists)
418
def _translate_io_exception(self, e, path, more_info='', failure_exc=NoSuchFile):
419
"""Translate a paramiko or IOError into a friendlier exception.
421
:param e: The original exception
422
:param path: The path in question when the error is raised
423
:param more_info: Extra information that can be included,
424
such as what was going on
425
:param failure_exc: Paramiko has the super fun ability to raise completely
426
opaque errors that just set "e.args = ('Failure',)" with
428
This sometimes means FileExists, but it also sometimes
418
431
# paramiko seems to generate detailless errors.
419
self._translate_error(e, relpath, raise_generic=False)
432
self._translate_error(e, path, raise_generic=False)
420
433
if hasattr(e, 'args'):
421
434
if (e.args == ('No such file or directory',) or
422
435
e.args == ('No such file',)):
423
raise NoSuchFile(relpath, str(e) + more_info)
436
raise NoSuchFile(path, str(e) + more_info)
424
437
if (e.args == ('mkdir failed',)):
425
raise FileExists(relpath, str(e) + more_info)
438
raise FileExists(path, str(e) + more_info)
426
439
# strange but true, for the paramiko server.
427
440
if (e.args == ('Failure',)):
428
raise FileExists(relpath, str(e) + more_info)
441
raise failure_exc(path, str(e) + more_info)
431
444
def append(self, relpath, f):
437
450
path = self._abspath(relpath)
438
451
fout = self._sftp.file(path, 'ab')
439
452
self._pump(f, fout)
440
except (IOError, paramiko.SSHException), x:
441
raise TransportError('Unable to append file %r' % (path,), x)
453
except (IOError, paramiko.SSHException), e:
454
self._translate_io_exception(e, relpath, ': unable to append')
443
456
def copy(self, rel_from, rel_to):
444
457
"""Copy the item at rel_from to the location at rel_to"""
472
except (IOError, paramiko.SSHException), x:
473
raise TransportError('Unable to copy %r to %r' % (path_from, path_to), x)
485
except (IOError, paramiko.SSHException), e:
486
self._translate_io_exception(e, path_from, ': unable copy to: %r' % path_to)
475
488
def copy_to(self, relpaths, other, pb=None):
476
489
"""Copy a set of entries from self into another Transport.
505
518
path_to = self._abspath(rel_to)
507
520
self._sftp.rename(path_from, path_to)
508
except (IOError, paramiko.SSHException), x:
509
raise TransportError('Unable to move %r to %r' % (path_from, path_to), x)
521
except (IOError, paramiko.SSHException), e:
522
self._translate_io_exception(e, path_from, ': unable to move to: %r' % path_to)
511
524
def delete(self, relpath):
512
525
"""Delete the item at relpath"""
513
526
path = self._abspath(relpath)
515
528
self._sftp.remove(path)
516
except (IOError, paramiko.SSHException), x:
517
raise TransportError('Unable to delete %r' % (path,), x)
529
except (IOError, paramiko.SSHException), e:
530
self._translate_io_exception(e, path, ': unable to delete')
519
532
def listable(self):
520
533
"""Return True if this store supports listing."""
528
541
path = self._abspath(relpath)
530
543
return self._sftp.listdir(path)
531
except (IOError, paramiko.SSHException), x:
532
raise TransportError('Unable to list folder %r' % (path,), x)
544
except (IOError, paramiko.SSHException), e:
545
self._translate_io_exception(e, path, ': failed to list_dir')
534
547
def stat(self, relpath):
535
548
"""Return the stat information for a file."""
536
549
path = self._abspath(relpath)
538
551
return self._sftp.stat(path)
539
except (IOError, paramiko.SSHException), x:
540
raise TransportError('Unable to stat %r' % (path,), x)
552
except (IOError, paramiko.SSHException), e:
553
self._translate_io_exception(e, path, ': unable to stat')
542
555
def lock_read(self, relpath):
655
669
t = paramiko.Transport((self._host, self._port or 22))
657
except paramiko.SSHException:
658
raise TransportError('Unable to reach SSH host %s:%d' % (self._host, self._port))
671
except paramiko.SSHException, e:
672
raise ConnectionError('Unable to reach SSH host %s:%d' %
673
(self._host, self._port), e)
660
675
server_key = t.get_remote_server_key()
661
676
server_key_hex = paramiko.util.hexify(server_key.get_fingerprint())
687
702
self._sftp = t.open_sftp_client()
688
except paramiko.SSHException:
689
raise BzrError('Unable to find path %s on SFTP server %s' % \
690
(self._path, self._host))
703
except paramiko.SSHException, e:
704
raise ConnectionError('Unable to start sftp client %s:%d' %
705
(self._host, self._port), e)
692
707
def _sftp_auth(self, transport):
693
708
# paramiko requires a username, but it might be none if nothing was supplied
735
750
user=username, host=self._host)
737
752
transport.auth_password(username, password)
738
except paramiko.SSHException:
739
raise TransportError('Unable to authenticate to SSH host as %s@%s' % \
740
(username, self._host))
753
except paramiko.SSHException, e:
754
raise ConnectionError('Unable to authenticate to SSH host as %s@%s' %
755
(username, self._host), e)
742
757
def _try_pkey_auth(self, transport, pkey_class, username, filename):
743
758
filename = os.path.expanduser('~/.ssh/' + filename)
785
800
handle = msg.get_string()
786
801
return SFTPFile(self._sftp, handle, 'w', -1)
787
802
except (paramiko.SSHException, IOError), e:
788
self._translate_io_exception(e, relpath, ': unable to open')
803
self._translate_io_exception(e, relpath, ': unable to open',
804
failure_exc=FileExists)