13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
"""Transport is an abstraction layer to handle file access.
273
272
from/to a storage location.
275
274
Most functions have a _multi variant, which allows you to queue up
276
multiple requests. They generally have a dumb base implementation
275
multiple requests. They generally have a dumb base implementation
277
276
which just iterates over the arguments, but smart Transport
278
277
implementations can do pipelining.
279
278
In general implementations should support having a generator or a list
325
324
def clone(self, offset=None):
326
325
"""Return a new Transport object, cloned from the current location,
327
using a subdirectory or parent directory. This allows connections
326
using a subdirectory or parent directory. This allows connections
328
327
to be pooled, rather than a new one needed for each subdir.
330
329
raise NotImplementedError(self.clone)
368
367
raise NotImplementedError(self.external_url)
370
369
def _pump(self, from_file, to_file):
371
"""Most children will need to copy from one file-like
370
"""Most children will need to copy from one file-like
372
371
object or string to another one.
373
372
This just gives them something easy to call.
452
451
t._combine_paths('/home/sarah', '/etc')
455
:param base_path: urlencoded path for the transport root; typically a
454
:param base_path: urlencoded path for the transport root; typically a
456
455
URL but need not contain scheme/host/etc.
457
456
:param relpath: relative url string for relative part of remote path.
458
457
:return: urlencoded string for final path.
485
484
"""Return the recommended page size for this transport.
487
486
This is potentially different for every path in a given namespace.
488
For example, local transports might use an operating system call to
487
For example, local transports might use an operating system call to
489
488
get the block size for a given path, which can vary due to mount
497
496
"""Return the local path portion from a given absolute path.
499
498
This default implementation is not suitable for filesystems with
500
aliasing, such as that given by symlinks, where a path may not
501
start with our base, but still be a relpath once aliasing is
499
aliasing, such as that given by symlinks, where a path may not
500
start with our base, but still be a relpath once aliasing is
504
503
# TODO: This might want to use bzrlib.osutils.relpath
520
519
def has(self, relpath):
521
520
"""Does the file relpath exist?
523
522
Note that some transports MAY allow querying on directories, but this
524
is not part of the protocol. In other words, the results of
523
is not part of the protocol. In other words, the results of
525
524
t.has("a_directory_name") are undefined.
590
@deprecated_method(one_four)
591
def get_smart_client(self):
592
"""Return a smart client for this transport if possible.
594
A smart client doesn't imply the presence of a smart server: it implies
595
that the smart protocol can be tunnelled via this transport.
597
:raises NoSmartServer: if no smart server client is available.
599
raise errors.NoSmartServer(self.base)
601
589
def get_smart_medium(self):
602
590
"""Return a smart client medium for this transport if possible.
609
597
raise errors.NoSmartMedium(self)
611
@deprecated_method(one_four)
612
def get_shared_medium(self):
613
"""Return a smart client shared medium for this transport if possible.
615
A smart medium doesn't imply the presence of a smart server: it implies
616
that the smart protocol can be tunnelled via this transport.
618
:raises NoSmartMedium: if no smart server medium is available.
620
raise errors.NoSmartMedium(self)
622
599
def readv(self, relpath, offsets, adjust_for_latency=False,
623
600
upper_limit=None):
624
601
"""Get parts of the file at the given relative path.
965
942
be synchronised with any internal buffering that may be present.
967
944
:param relpath: The relative path to the file.
968
:param mode: The mode for the newly created file,
945
:param mode: The mode for the newly created file,
969
946
None means just use the default
970
947
:return: A FileStream. FileStream objects have two methods, write() and
971
948
close(). There is no guarantee that data is committed to the file
1021
998
def copy(self, rel_from, rel_to):
1022
999
"""Copy the item at rel_from to the location at rel_to.
1024
Override this for efficiency if a specific transport can do it
1001
Override this for efficiency if a specific transport can do it
1025
1002
faster than this default implementation.
1027
1004
self.put_file(rel_to, self.get(rel_from))
1029
1006
def copy_multi(self, relpaths, pb=None):
1030
1007
"""Copy a bunch of entries.
1032
1009
:param relpaths: A list of tuples of the form [(from, to), (from, to),...]
1034
1011
# This is the non-pipelined implementation, so that
1052
1029
def copy_tree(self, from_relpath, to_relpath):
1053
1030
"""Copy a subtree from one relpath to another.
1055
If a faster implementation is available, specific transports should
1032
If a faster implementation is available, specific transports should
1058
1035
source = self.clone(from_relpath)
1120
1097
def move_multi(self, relpaths, pb=None):
1121
1098
"""Move a bunch of entries.
1123
1100
:param relpaths: A list of tuples of the form [(from1, to1), (from2, to2),...]
1125
1102
return self._iterate_over(relpaths, self.move, pb, 'move', expand=True)
1178
1155
NOTE: This returns an object with fields such as 'st_size'. It MAY
1179
1156
or MAY NOT return the literal result of an os.stat() call, so all
1180
1157
access should be via named fields.
1181
ALSO NOTE: Stats of directories may not be supported on some
1158
ALSO NOTE: Stats of directories may not be supported on some
1184
1161
raise NotImplementedError(self.stat)
1248
1225
"""Return true if this transport can store and retrieve unix modebits.
1250
1227
(For example, 0700 to make a directory owner-private.)
1252
Note: most callers will not want to switch on this, but should rather
1229
Note: most callers will not want to switch on this, but should rather
1253
1230
just try and set permissions and let them be either stored or not.
1254
1231
This is intended mainly for the use of the test suite.
1256
Warning: this is not guaranteed to be accurate as sometimes we can't
1233
Warning: this is not guaranteed to be accurate as sometimes we can't
1257
1234
be sure: for example with vfat mounted on unix, or a windows sftp
1259
1236
# TODO: Perhaps return a e.g. TransportCharacteristics that can answer
1593
1570
def convert_path_to_url(base, error_str):
1594
1571
m = _urlRE.match(base)
1596
# This looks like a URL, but we weren't able to
1573
# This looks like a URL, but we weren't able to
1597
1574
# instantiate it as such raise an appropriate error
1598
1575
# FIXME: we have a 'error_str' unused and we use last_err below
1599
1576
raise errors.UnsupportedProtocol(base, last_err)
1665
1642
:param action: A callable, what the caller want to do while catching
1667
1644
:param transport: The initial transport used.
1668
:param redirected: A callable receiving the redirected transport and the
1645
:param redirected: A callable receiving the redirected transport and the
1669
1646
RedirectRequested exception.
1671
1648
:return: Whatever 'action' returns
1699
1676
class Server(object):
1700
1677
"""A Transport Server.
1702
1679
The Server interface provides a server for a given transport. We use
1703
1680
these servers as loopback testing tools. For any given transport the
1704
1681
Servers it provides must either allow writing, or serve the contents
1705
1682
of os.getcwdu() at the time setUp is called.
1707
1684
Note that these are real servers - they must implement all the things
1708
1685
that we want bzr transports to take advantage of.
1717
1694
def get_url(self):
1718
1695
"""Return a url for this server.
1720
If the transport does not represent a disk directory (i.e. it is
1697
If the transport does not represent a disk directory (i.e. it is
1721
1698
a database like svn, or a memory only transport, it should return
1722
1699
a connection to a newly established resource for this Server.
1723
1700
Otherwise it should return a url that will provide access to the path
1724
1701
that was os.getcwdu() when setUp() was called.
1726
1703
Subsequent calls will return the same resource.
1728
1705
raise NotImplementedError
1730
1707
def get_bogus_url(self):
1731
1708
"""Return a url for this protocol, that will fail to connect.
1733
1710
This may raise NotImplementedError to indicate that this server cannot
1734
1711
provide bogus urls.
1787
1764
register_transport_proto('aftp://', help="Access using active FTP.")
1788
1765
register_lazy_transport('aftp://', 'bzrlib.transport.ftp', 'FtpTransport')
1790
# Default to trying GSSAPI authentication (if the kerberos module is available)
1791
register_transport_proto('ftp+gssapi://', register_netloc=True)
1792
register_lazy_transport('ftp+gssapi://', 'bzrlib.transport.ftp._gssapi',
1793
'GSSAPIFtpTransport')
1794
register_transport_proto('aftp+gssapi://', register_netloc=True)
1795
register_lazy_transport('aftp+gssapi://', 'bzrlib.transport.ftp._gssapi',
1796
'GSSAPIFtpTransport')
1797
register_transport_proto('ftp+nogssapi://', register_netloc=True)
1798
register_transport_proto('aftp+nogssapi://', register_netloc=True)
1800
register_lazy_transport('ftp://', 'bzrlib.transport.ftp._gssapi',
1801
'GSSAPIFtpTransport')
1802
register_lazy_transport('aftp://', 'bzrlib.transport.ftp._gssapi',
1803
'GSSAPIFtpTransport')
1804
register_lazy_transport('ftp+nogssapi://', 'bzrlib.transport.ftp',
1806
register_lazy_transport('aftp+nogssapi://', 'bzrlib.transport.ftp',
1769
kerberos_available = True
1771
kerberos_available = False
1773
if kerberos_available:
1774
# Default to trying GSSAPI authentication (if the kerberos module is
1776
register_transport_proto('ftp+gssapi://', register_netloc=True)
1777
register_lazy_transport('ftp+gssapi://', 'bzrlib.transport.ftp._gssapi',
1778
'GSSAPIFtpTransport')
1779
register_transport_proto('aftp+gssapi://', register_netloc=True)
1780
register_lazy_transport('aftp+gssapi://', 'bzrlib.transport.ftp._gssapi',
1781
'GSSAPIFtpTransport')
1782
register_transport_proto('ftp+nogssapi://', register_netloc=True)
1783
register_transport_proto('aftp+nogssapi://', register_netloc=True)
1785
register_lazy_transport('ftp://', 'bzrlib.transport.ftp._gssapi',
1786
'GSSAPIFtpTransport')
1787
register_lazy_transport('aftp://', 'bzrlib.transport.ftp._gssapi',
1788
'GSSAPIFtpTransport')
1789
register_lazy_transport('ftp+nogssapi://', 'bzrlib.transport.ftp',
1791
register_lazy_transport('aftp+nogssapi://', 'bzrlib.transport.ftp',
1809
1794
register_transport_proto('memory://')
1810
1795
register_lazy_transport('memory://', 'bzrlib.transport.memory',