~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/sftp.py

  • Committer: Alexander Belchenko
  • Date: 2007-08-10 09:04:38 UTC
  • mto: This revision was merged to the branch mainline in revision 2694.
  • Revision ID: bialix@ukr.net-20070810090438-0835xdz0rl8825qv
fixes after Ian's review

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
import time
35
35
import urllib
36
36
import urlparse
37
 
import warnings
38
37
 
39
38
from bzrlib import (
40
39
    errors,
50
49
from bzrlib.osutils import pathjoin, fancy_rename, getcwd
51
50
from bzrlib.symbol_versioning import (
52
51
        deprecated_function,
53
 
        zero_ninety,
 
52
        zero_nineteen,
54
53
        )
55
54
from bzrlib.trace import mutter, warning
56
55
from bzrlib.transport import (
57
 
    FileFileStream,
58
 
    _file_streams,
59
56
    local,
 
57
    register_urlparse_netloc_protocol,
60
58
    Server,
61
59
    ssh,
62
60
    ConnectedTransport,
63
61
    )
64
62
 
65
 
# Disable one particular warning that comes from paramiko in Python2.5; if
66
 
# this is emitted at the wrong time it tends to cause spurious test failures
67
 
# or at least noise in the test case::
68
 
#
69
 
# [1770/7639 in 86s, 1 known failures, 50 skipped, 2 missing features]
70
 
# test_permissions.TestSftpPermissions.test_new_files
71
 
# /var/lib/python-support/python2.5/paramiko/message.py:226: DeprecationWarning: integer argument expected, got float
72
 
#  self.packet.write(struct.pack('>I', n))
73
 
warnings.filterwarnings('ignore',
74
 
        'integer argument expected, got float',
75
 
        category=DeprecationWarning,
76
 
        module='paramiko.message')
77
 
 
78
63
try:
79
64
    import paramiko
80
65
except ImportError, e:
87
72
    from paramiko.sftp_file import SFTPFile
88
73
 
89
74
 
 
75
register_urlparse_netloc_protocol('sftp')
 
76
 
 
77
 
90
78
_paramiko_version = getattr(paramiko, '__version_info__', (0, 0, 0))
91
79
# don't use prefetch unless paramiko version >= 1.5.5 (there were bugs earlier)
92
80
_default_do_prefetch = (_paramiko_version >= (1, 5, 5))
93
81
 
94
82
 
95
 
@deprecated_function(zero_ninety)
 
83
@deprecated_function(zero_nineteen)
96
84
def clear_connection_cache():
97
85
    """Remove all hosts from the SFTP connection cache.
98
86
 
217
205
            self._set_connection(connection, credentials)
218
206
        return connection
219
207
 
 
208
 
 
209
    def should_cache(self):
 
210
        """
 
211
        Return True if the data pulled across should be cached locally.
 
212
        """
 
213
        return True
 
214
 
220
215
    def has(self, relpath):
221
216
        """
222
217
        Does the target location exist?
243
238
            self._translate_io_exception(e, path, ': error retrieving',
244
239
                failure_exc=errors.ReadError)
245
240
 
246
 
    def _readv(self, relpath, offsets):
 
241
    def readv(self, relpath, offsets):
247
242
        """See Transport.readv()"""
248
243
        # We overload the default readv() because we want to use a file
249
244
        # that does not have prefetch enabled.
262
257
        except (IOError, paramiko.SSHException), e:
263
258
            self._translate_io_exception(e, path, ': error retrieving')
264
259
 
265
 
    def recommended_page_size(self):
266
 
        """See Transport.recommended_page_size().
267
 
 
268
 
        For SFTP we suggest a large page size to reduce the overhead
269
 
        introduced by latency.
270
 
        """
271
 
        return 64 * 1024
272
 
 
273
260
    def _sftp_readv(self, fp, offsets, relpath='<unknown>'):
274
261
        """Use the readv() member of fp to do async readv.
275
262
 
382
369
        :param mode: The final mode for the file
383
370
        """
384
371
        final_path = self._remote_path(relpath)
385
 
        return self._put(final_path, f, mode=mode)
 
372
        self._put(final_path, f, mode=mode)
386
373
 
387
374
    def _put(self, abspath, f, mode=None):
388
375
        """Helper function so both put() and copy_abspaths can reuse the code"""
393
380
        try:
394
381
            try:
395
382
                fout.set_pipelined(True)
396
 
                length = self._pump(f, fout)
 
383
                self._pump(f, fout)
397
384
            except (IOError, paramiko.SSHException), e:
398
385
                self._translate_io_exception(e, tmp_abspath)
399
386
            # XXX: This doesn't truly help like we would like it to.
414
401
            fout.close()
415
402
            closed = True
416
403
            self._rename_and_overwrite(tmp_abspath, abspath)
417
 
            return length
418
404
        except Exception, e:
419
405
            # If we fail, try to clean up the temporary file
420
406
            # before we throw the exception
539
525
        """Create a directory at the given path."""
540
526
        self._mkdir(self._remote_path(relpath), mode=mode)
541
527
 
542
 
    def open_write_stream(self, relpath, mode=None):
543
 
        """See Transport.open_write_stream."""
544
 
        # initialise the file to zero-length
545
 
        # this is three round trips, but we don't use this 
546
 
        # api more than once per write_group at the moment so 
547
 
        # it is a tolerable overhead. Better would be to truncate
548
 
        # the file after opening. RBC 20070805
549
 
        self.put_bytes_non_atomic(relpath, "", mode)
550
 
        abspath = self._remote_path(relpath)
551
 
        # TODO: jam 20060816 paramiko doesn't publicly expose a way to
552
 
        #       set the file mode at create time. If it does, use it.
553
 
        #       But for now, we just chmod later anyway.
554
 
        handle = None
555
 
        try:
556
 
            handle = self._get_sftp().file(abspath, mode='wb')
557
 
            handle.set_pipelined(True)
558
 
        except (paramiko.SSHException, IOError), e:
559
 
            self._translate_io_exception(e, abspath,
560
 
                                         ': unable to open')
561
 
        _file_streams[self.abspath(relpath)] = handle
562
 
        return FileFileStream(self, relpath, handle)
563
 
 
564
528
    def _translate_io_exception(self, e, path, more_info='',
565
529
                                failure_exc=PathError):
566
530
        """Translate a paramiko or IOError into a friendlier exception.