~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/remote.py

(jam) Switch from Transport.get() to .get_bytes(),
        close open file handles.

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
)
34
34
from bzrlib.branch import BranchReferenceFormat
35
35
from bzrlib.bzrdir import BzrDir, RemoteBzrDirFormat
36
 
from bzrlib.decorators import needs_read_lock, needs_write_lock
 
36
from bzrlib.decorators import needs_read_lock, needs_write_lock, only_raises
37
37
from bzrlib.errors import (
38
38
    NoSuchRevision,
39
39
    SmartProtocolError,
89
89
class RemoteBzrDir(BzrDir, _RpcHelper):
90
90
    """Control directory on a remote server, accessed via bzr:// or similar."""
91
91
 
92
 
    def __init__(self, transport, format, _client=None):
 
92
    def __init__(self, transport, format, _client=None, _force_probe=False):
93
93
        """Construct a RemoteBzrDir.
94
94
 
95
95
        :param _client: Private parameter for testing. Disables probing and the
99
99
        # this object holds a delegated bzrdir that uses file-level operations
100
100
        # to talk to the other side
101
101
        self._real_bzrdir = None
 
102
        self._has_working_tree = None
102
103
        # 1-shot cache for the call pattern 'create_branch; open_branch' - see
103
104
        # create_branch for details.
104
105
        self._next_open_branch_result = None
108
109
            self._client = client._SmartClient(medium)
109
110
        else:
110
111
            self._client = _client
111
 
            return
112
 
 
 
112
            if not _force_probe:
 
113
                return
 
114
 
 
115
        self._probe_bzrdir()
 
116
 
 
117
    def _probe_bzrdir(self):
 
118
        medium = self._client._medium
113
119
        path = self._path_for_remote_call(self._client)
 
120
        if medium._is_remote_before((2, 1)):
 
121
            self._rpc_open(path)
 
122
            return
 
123
        try:
 
124
            self._rpc_open_2_1(path)
 
125
            return
 
126
        except errors.UnknownSmartMethod:
 
127
            medium._remember_remote_is_before((2, 1))
 
128
            self._rpc_open(path)
 
129
 
 
130
    def _rpc_open_2_1(self, path):
 
131
        response = self._call('BzrDir.open_2.1', path)
 
132
        if response == ('no',):
 
133
            raise errors.NotBranchError(path=self.root_transport.base)
 
134
        elif response[0] == 'yes':
 
135
            if response[1] == 'yes':
 
136
                self._has_working_tree = True
 
137
            elif response[1] == 'no':
 
138
                self._has_working_tree = False
 
139
            else:
 
140
                raise errors.UnexpectedSmartServerResponse(response)
 
141
        else:
 
142
            raise errors.UnexpectedSmartServerResponse(response)
 
143
 
 
144
    def _rpc_open(self, path):
114
145
        response = self._call('BzrDir.open', path)
115
146
        if response not in [('yes',), ('no',)]:
116
147
            raise errors.UnexpectedSmartServerResponse(response)
117
148
        if response == ('no',):
118
 
            raise errors.NotBranchError(path=transport.base)
 
149
            raise errors.NotBranchError(path=self.root_transport.base)
119
150
 
120
151
    def _ensure_real(self):
121
152
        """Ensure that there is a _real_bzrdir set.
123
154
        Used before calls to self._real_bzrdir.
124
155
        """
125
156
        if not self._real_bzrdir:
 
157
            if 'hpssvfs' in debug.debug_flags:
 
158
                import traceback
 
159
                warning('VFS BzrDir access triggered\n%s',
 
160
                    ''.join(traceback.format_stack()))
126
161
            self._real_bzrdir = BzrDir.open_from_transport(
127
162
                self.root_transport, _server_formats=False)
128
163
            self._format._network_name = \
355
390
        else:
356
391
            raise errors.NoRepositoryPresent(self)
357
392
 
 
393
    def has_workingtree(self):
 
394
        if self._has_working_tree is None:
 
395
            self._ensure_real()
 
396
            self._has_working_tree = self._real_bzrdir.has_workingtree()
 
397
        return self._has_working_tree
 
398
 
358
399
    def open_workingtree(self, recommend_upgrade=True):
359
 
        self._ensure_real()
360
 
        if self._real_bzrdir.has_workingtree():
 
400
        if self.has_workingtree():
361
401
            raise errors.NotLocalUrl(self.root_transport)
362
402
        else:
363
403
            raise errors.NoWorkingTree(self.root_transport.base)
561
601
        return self._custom_format._fetch_reconcile
562
602
 
563
603
    def get_format_description(self):
564
 
        return 'bzr remote repository'
 
604
        self._ensure_real()
 
605
        return 'Remote: ' + self._custom_format.get_format_description()
565
606
 
566
607
    def __eq__(self, other):
567
608
        return self.__class__ is other.__class__
583
624
        return self._custom_format._serializer
584
625
 
585
626
 
586
 
class RemoteRepository(_RpcHelper):
 
627
class RemoteRepository(_RpcHelper, lock._RelockDebugMixin):
587
628
    """Repository accessed over rpc.
588
629
 
589
630
    For the moment most operations are performed using local transport-backed
913
954
    def lock_read(self):
914
955
        # wrong eventually - want a local lock cache context
915
956
        if not self._lock_mode:
 
957
            self._note_lock('r')
916
958
            self._lock_mode = 'r'
917
959
            self._lock_count = 1
918
960
            self._unstacked_provider.enable_cache(cache_misses=True)
938
980
 
939
981
    def lock_write(self, token=None, _skip_rpc=False):
940
982
        if not self._lock_mode:
 
983
            self._note_lock('w')
941
984
            if _skip_rpc:
942
985
                if self._lock_token is not None:
943
986
                    if token != self._lock_token:
1046
1089
        else:
1047
1090
            raise errors.UnexpectedSmartServerResponse(response)
1048
1091
 
 
1092
    @only_raises(errors.LockNotHeld, errors.LockBroken)
1049
1093
    def unlock(self):
1050
1094
        if not self._lock_count:
1051
1095
            return lock.cant_unlock_not_held(self)
1956
2000
                self._network_name)
1957
2001
 
1958
2002
    def get_format_description(self):
1959
 
        return 'Remote BZR Branch'
 
2003
        self._ensure_real()
 
2004
        return 'Remote: ' + self._custom_format.get_format_description()
1960
2005
 
1961
2006
    def network_name(self):
1962
2007
        return self._network_name
2045
2090
        return self._custom_format.supports_set_append_revisions_only()
2046
2091
 
2047
2092
 
2048
 
class RemoteBranch(branch.Branch, _RpcHelper):
 
2093
class RemoteBranch(branch.Branch, _RpcHelper, lock._RelockDebugMixin):
2049
2094
    """Branch stored on a server accessed by HPSS RPC.
2050
2095
 
2051
2096
    At the moment most operations are mapped down to simple file operations.
2282
2327
    def lock_read(self):
2283
2328
        self.repository.lock_read()
2284
2329
        if not self._lock_mode:
 
2330
            self._note_lock('r')
2285
2331
            self._lock_mode = 'r'
2286
2332
            self._lock_count = 1
2287
2333
            if self._real_branch is not None:
2307
2353
 
2308
2354
    def lock_write(self, token=None):
2309
2355
        if not self._lock_mode:
 
2356
            self._note_lock('w')
2310
2357
            # Lock the branch and repo in one remote call.
2311
2358
            remote_tokens = self._remote_lock_write(token)
2312
2359
            self._lock_token, self._repo_lock_token = remote_tokens
2347
2394
            return
2348
2395
        raise errors.UnexpectedSmartServerResponse(response)
2349
2396
 
 
2397
    @only_raises(errors.LockNotHeld, errors.LockBroken)
2350
2398
    def unlock(self):
2351
2399
        try:
2352
2400
            self._lock_count -= 1