/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/remote.py

Make sure all the request handlers in bzrlib/smart/vfs.py have consistent names.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2006 Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
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
 
16
 
 
17
# TODO: At some point, handle upgrades by just passing the whole request
 
18
# across to run on the server.
 
19
 
 
20
from urlparse import urlparse
 
21
 
 
22
from bzrlib import branch, errors, repository
 
23
from bzrlib.bzrdir import BzrDir, BzrDirFormat, RemoteBzrDirFormat
 
24
from bzrlib.branch import BranchReferenceFormat
 
25
from bzrlib.smart import client, vfs
 
26
from bzrlib.urlutils import unescape
 
27
 
 
28
# Note: RemoteBzrDirFormat is in bzrdir.py
 
29
 
 
30
class RemoteBzrDir(BzrDir):
 
31
    """Control directory on a remote server, accessed by HPSS."""
 
32
 
 
33
    def __init__(self, transport):
 
34
        BzrDir.__init__(self, transport, RemoteBzrDirFormat())
 
35
        self.client = transport.get_smart_client()
 
36
        # this object holds a delegated bzrdir that uses file-level operations
 
37
        # to talk to the other side
 
38
        # XXX: We should go into find_format, but not allow it to find
 
39
        # RemoteBzrDirFormat and make sure it finds the real underlying format.
 
40
        
 
41
        # THIS IS A COMPLETE AND UTTER LIE.
 
42
        # XXX: XXX: XXX: must be removed before merging to mainline
 
43
        # SMART_SERVER_MERGE_BLOCKER
 
44
        default_format = BzrDirFormat.get_default_format()
 
45
        self._real_bzrdir = default_format.open(transport, _found=True)
 
46
        path = self._path_for_remote_call()
 
47
        #self._real_bzrdir._format.probe_transport(transport)
 
48
        response = client.SmartClient(self.client).call('probe_dont_use', path)
 
49
        if response == ('no',):
 
50
            raise errors.NotBranchError(path=transport.base)
 
51
        self._branch = None
 
52
 
 
53
    def create_repository(self, shared=False):
 
54
        return RemoteRepository(
 
55
            self, self._real_bzrdir.create_repository(shared=shared))
 
56
 
 
57
    def create_branch(self):
 
58
        real_branch = self._real_bzrdir.create_branch()
 
59
        real_repository = real_branch.repository
 
60
        remote_repository = RemoteRepository(self, real_repository)
 
61
        return RemoteBranch(self, remote_repository, real_branch)
 
62
 
 
63
    def create_workingtree(self, revision_id=None):
 
64
        real_workingtree = self._real_bzrdir.create_workingtree(revision_id=revision_id)
 
65
        return RemoteWorkingTree(self, real_workingtree)
 
66
 
 
67
    def open_branch(self, _unsupported=False):
 
68
        assert _unsupported == False, 'unsupported flag support not implemented yet.'
 
69
        path = self._path_for_remote_call()
 
70
        response = client.SmartClient(self.client).call('BzrDir.open_branch', path)
 
71
        assert response[0] == 'ok', 'unexpected response code %s' % response[0]
 
72
        if response[0] != 'ok':
 
73
            # this should probably be a regular translate no ?
 
74
            raise errors.NotBranchError(path=self.root_transport.base)
 
75
        if response[1] == '':
 
76
            # branch at this location.
 
77
            if vfs.vfs_enabled():
 
78
                # if the VFS is enabled, create a local object using the VFS.
 
79
                real_branch = self._real_bzrdir.open_branch(unsupported=_unsupported)
 
80
                # This branch accessed through the smart server, so wrap the
 
81
                # file-level objects.
 
82
                real_repository = real_branch.repository
 
83
                remote_repository = RemoteRepository(self, real_repository)
 
84
                return RemoteBranch(self, remote_repository, real_branch)
 
85
            else:
 
86
                # otherwise just create a proxy for the branch.
 
87
                return RemoteBranch(self, self.find_repository())
 
88
        else:
 
89
            # a branch reference, use the existing BranchReference logic.
 
90
            format = BranchReferenceFormat()
 
91
            return format.open(self, _found=True, location=response[1])
 
92
 
 
93
    def open_repository(self):
 
94
        path = self._path_for_remote_call()
 
95
        response = client.SmartClient(self.client).call('BzrDir.find_repository', path)
 
96
        assert response[0] == 'ok', 'unexpected response code %s' % response[0]
 
97
        if response[1] == '':
 
98
            if vfs.vfs_enabled():
 
99
                return RemoteRepository(self, self._real_bzrdir.open_repository())
 
100
            else:
 
101
                return RemoteRepository(self)
 
102
        else:
 
103
            raise errors.NoRepositoryPresent(self)
 
104
 
 
105
    def open_workingtree(self):
 
106
        return RemoteWorkingTree(self, self._real_bzrdir.open_workingtree())
 
107
 
 
108
    def _path_for_remote_call(self):
 
109
        """Return the path to be used for this bzrdir in a remote call."""
 
110
        return unescape(urlparse(self.root_transport.base)[2])
 
111
 
 
112
    def get_branch_transport(self, branch_format):
 
113
        return self._real_bzrdir.get_branch_transport(branch_format)
 
114
 
 
115
    def get_repository_transport(self, repository_format):
 
116
        return self._real_bzrdir.get_repository_transport(repository_format)
 
117
 
 
118
    def get_workingtree_transport(self, workingtree_format):
 
119
        return self._real_bzrdir.get_workingtree_transport(workingtree_format)
 
120
 
 
121
    def can_convert_format(self):
 
122
        """Upgrading of remote bzrdirs is not supported yet."""
 
123
        return False
 
124
 
 
125
    def needs_format_conversion(self, format=None):
 
126
        """Upgrading of remote bzrdirs is not supported yet."""
 
127
        return False
 
128
 
 
129
 
 
130
class RemoteRepositoryFormat(repository.RepositoryFormat):
 
131
    """Format for repositories accessed over rpc.
 
132
 
 
133
    Instances of this repository are represented by RemoteRepository
 
134
    instances.
 
135
    """
 
136
 
 
137
    _matchingbzrdir = RemoteBzrDirFormat
 
138
 
 
139
    def initialize(self, a_bzrdir, shared=False):
 
140
        assert isinstance(a_bzrdir, RemoteBzrDir)
 
141
        return a_bzrdir.create_repository(shared=shared)
 
142
    
 
143
    def open(self, a_bzrdir):
 
144
        assert isinstance(a_bzrdir, RemoteBzrDir)
 
145
        return a_bzrdir.open_repository()
 
146
 
 
147
    def get_format_description(self):
 
148
        return 'bzr remote repository'
 
149
 
 
150
    def __eq__(self, other):
 
151
        return self.__class__ == other.__class__
 
152
 
 
153
    rich_root_data = False
 
154
 
 
155
 
 
156
class RemoteRepository(object):
 
157
    """Repository accessed over rpc.
 
158
 
 
159
    For the moment everything is delegated to IO-like operations over
 
160
    the transport.
 
161
    """
 
162
 
 
163
    def __init__(self, remote_bzrdir, real_repository=None):
 
164
        """Create a RemoteRepository instance.
 
165
        
 
166
        :param remote_bzrdir: The bzrdir hosting this repository.
 
167
        :param real_repository: If not None, a local implementation of the
 
168
            repository logic for the repository, usually accessing the data
 
169
            via the VFS.
 
170
        """
 
171
        if real_repository:
 
172
            self._real_repository = real_repository
 
173
        self.bzrdir = remote_bzrdir
 
174
        self._format = RemoteRepositoryFormat()
 
175
 
 
176
 
 
177
class RemoteBranchFormat(branch.BranchFormat):
 
178
 
 
179
    def open(self, a_bzrdir):
 
180
        assert isinstance(a_bzrdir, RemoteBzrDir)
 
181
        return a_bzrdir.open_branch()
 
182
 
 
183
    def initialize(self, a_bzrdir):
 
184
        assert isinstance(a_bzrdir, RemoteBzrDir)
 
185
        return a_bzrdir.create_branch()
 
186
 
 
187
 
 
188
class RemoteBranch(branch.Branch):
 
189
    """Branch stored on a server accessed by HPSS RPC.
 
190
 
 
191
    At the moment most operations are mapped down to simple file operations.
 
192
    """
 
193
 
 
194
    def __init__(self, remote_bzrdir, remote_repository, real_branch=None):
 
195
        """Create a RemoteBranch instance.
 
196
 
 
197
        :param real_branch: An optional local implementation of the branch
 
198
            format, usually accessing the data via the VFS.
 
199
        """
 
200
        self.bzrdir = remote_bzrdir
 
201
        self.repository = remote_repository
 
202
        if real_branch is not None:
 
203
            self._real_branch = real_branch
 
204
        self._format = RemoteBranchFormat()
 
205
 
 
206
    def lock_read(self):
 
207
        return self._real_branch.lock_read()
 
208
 
 
209
    def lock_write(self):
 
210
        return self._real_branch.lock_write()
 
211
 
 
212
    def unlock(self):
 
213
        return self._real_branch.unlock()
 
214
 
 
215
    def break_lock(self):
 
216
        return self._real_branch.break_lock()
 
217
 
 
218
    def revision_history(self):
 
219
        return self._real_branch.revision_history()
 
220
 
 
221
    def set_revision_history(self, rev_history):
 
222
        return self._real_branch.set_revision_history(rev_history)
 
223
 
 
224
    def get_parent(self):
 
225
        return self._real_branch.get_parent()
 
226
        
 
227
    def set_parent(self, url):
 
228
        return self._real_branch.set_parent(url)
 
229
        
 
230
 
 
231
class RemoteWorkingTree(object):
 
232
 
 
233
    def __init__(self, remote_bzrdir, real_workingtree):
 
234
        self.real_workingtree = real_workingtree
 
235
        self.bzrdir = remote_bzrdir
 
236
 
 
237
    def __getattr__(self, name):
 
238
        # XXX: temporary way to lazily delegate everything to the real
 
239
        # workingtree
 
240
        return getattr(self.real_workingtree, name)
 
241
 
 
242