/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

MergeĀ fromĀ remote-transport

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
 
 
21
from bzrlib import bzrdir, branch, errors, repository
 
22
from bzrlib.bzrdir import BzrDir, BzrDirFormat
 
23
from bzrlib.branch import Branch, BranchFormat
 
24
from bzrlib.trace import mutter
 
25
from bzrlib.transport.smart import SmartTransport
 
26
 
 
27
 
 
28
class RemoteBzrDirFormat(bzrdir.BzrDirMetaFormat1):
 
29
    """Format representing bzrdirs accessed via a smart server"""
 
30
 
 
31
    def get_format_description(self):
 
32
        return 'bzr remote bzrdir'
 
33
    
 
34
    def probe_transport(self, transport):
 
35
        ## mutter("%r probe for bzrdir in %r" % (self, transport))
 
36
        try:
 
37
            transport.get_smart_client()
 
38
        except (NotImplementedError, AttributeError,
 
39
                errors.TransportNotPossible):
 
40
            raise errors.NoSmartServer(transport.base)
 
41
        else:
 
42
            return self
 
43
 
 
44
    def _open(self, transport):
 
45
        return RemoteBzrDir(transport)
 
46
 
 
47
    def __eq__(self, other):
 
48
        if not isinstance(other, RemoteBzrDirFormat):
 
49
            return False
 
50
        return self.get_format_description() == other.get_format_description()
 
51
 
 
52
 
 
53
class RemoteBzrDir(BzrDir):
 
54
    """Control directory on a remote server, accessed by HPSS."""
 
55
 
 
56
    def __init__(self, transport):
 
57
        BzrDir.__init__(self, transport, RemoteBzrDirFormat())
 
58
        self.client = transport.get_smart_client()
 
59
        # this object holds a delegated bzrdir that uses file-level operations
 
60
        # to talk to the other side
 
61
        # XXX: We should go into find_format, but not allow it to find
 
62
        # RemoteBzrDirFormat and make sure it finds the real underlying format.
 
63
        
 
64
        default_format = BzrDirFormat.get_default_format()
 
65
        self._real_bzrdir = default_format.open(transport, _found=True)
 
66
        self._real_bzrdir._format.probe_transport(transport)
 
67
        self._branch = None
 
68
 
 
69
    def create_repository(self, shared=False):
 
70
        return RemoteRepository(
 
71
            self, self._real_bzrdir.create_repository(shared=shared))
 
72
 
 
73
    def create_branch(self):
 
74
        real_branch = self._real_bzrdir.create_branch()
 
75
        real_repository = real_branch.repository
 
76
        remote_repository = RemoteRepository(self, real_repository)
 
77
        return RemoteBranch(self, remote_repository, real_branch)
 
78
 
 
79
    def create_workingtree(self, revision_id=None):
 
80
        real_workingtree = self._real_bzrdir.create_workingtree(revision_id=revision_id)
 
81
        return RemoteWorkingTree(self, real_workingtree)
 
82
 
 
83
    def open_repository(self):
 
84
        return RemoteRepository(self, self._real_bzrdir.open_repository())
 
85
 
 
86
    def open_branch(self, _unsupported=False):
 
87
        real_branch = self._real_bzrdir.open_branch(unsupported=_unsupported)
 
88
        if real_branch.bzrdir is self._real_bzrdir:
 
89
            # This branch accessed through the smart server, so wrap the
 
90
            # file-level objects.
 
91
            real_repository = real_branch.repository
 
92
            remote_repository = RemoteRepository(self, real_repository)
 
93
            return RemoteBranch(self, remote_repository, real_branch)
 
94
        else:
 
95
            # We were redirected to somewhere else, so don't wrap.
 
96
            return real_branch
 
97
 
 
98
    def open_workingtree(self):
 
99
        return RemoteWorkingTree(self, self._real_bzrdir.open_workingtree())
 
100
 
 
101
    def get_branch_transport(self, branch_format):
 
102
        return self._real_bzrdir.get_branch_transport(branch_format)
 
103
 
 
104
    def get_repository_transport(self, repository_format):
 
105
        return self._real_bzrdir.get_repository_transport(repository_format)
 
106
 
 
107
    def get_workingtree_transport(self, workingtree_format):
 
108
        return self._real_bzrdir.get_workingtree_transport(workingtree_format)
 
109
 
 
110
    def can_convert_format(self):
 
111
        """Upgrading of remote bzrdirs is not supported yet."""
 
112
        return False
 
113
 
 
114
    def needs_format_conversion(self, format=None):
 
115
        """Upgrading of remote bzrdirs is not supported yet."""
 
116
        return False
 
117
 
 
118
 
 
119
class RemoteRepositoryFormat(repository.RepositoryFormat):
 
120
    """Format for repositories accessed over rpc.
 
121
 
 
122
    Instances of this repository are represented by RemoteRepository
 
123
    instances.
 
124
    """
 
125
 
 
126
    _matchingbzrdir = RemoteBzrDirFormat
 
127
 
 
128
    def initialize(self, a_bzrdir, shared=False):
 
129
        assert isinstance(a_bzrdir, RemoteBzrDir)
 
130
        return a_bzrdir.create_repository(shared=shared)
 
131
    
 
132
    def open(self, a_bzrdir):
 
133
        assert isinstance(a_bzrdir, RemoteBzrDir)
 
134
        return a_bzrdir.open_repository()
 
135
 
 
136
    def get_format_description(self):
 
137
        return 'bzr remote repository'
 
138
 
 
139
    def __eq__(self, other):
 
140
        return self.__class__ == other.__class__
 
141
 
 
142
    rich_root_data = False
 
143
 
 
144
 
 
145
class RemoteRepository(object):
 
146
    """Repository accessed over rpc.
 
147
 
 
148
    For the moment everything is delegated to IO-like operations over
 
149
    the transport.
 
150
    """
 
151
 
 
152
    def __init__(self, remote_bzrdir, real_repository):
 
153
        self.real_repository = real_repository
 
154
        self.bzrdir = remote_bzrdir
 
155
        self._format = RemoteRepositoryFormat()
 
156
 
 
157
    def __getattr__(self, name):
 
158
        # XXX: temporary way to lazily delegate everything to the real
 
159
        # repository
 
160
        return getattr(self.real_repository, name)
 
161
 
 
162
 
 
163
class RemoteBranchFormat(branch.BranchFormat):
 
164
 
 
165
    def open(self, a_bzrdir):
 
166
        assert isinstance(a_bzrdir, RemoteBzrDir)
 
167
        return a_bzrdir.open_branch()
 
168
 
 
169
    def initialize(self, a_bzrdir):
 
170
        assert isinstance(a_bzrdir, RemoteBzrDir)
 
171
        return a_bzrdir.create_branch()
 
172
 
 
173
 
 
174
class RemoteBranch(branch.Branch):
 
175
    """Branch stored on a server accessed by HPSS RPC.
 
176
 
 
177
    At the moment most operations are mapped down to simple file operations.
 
178
    """
 
179
 
 
180
    def __init__(self, remote_bzrdir, remote_repository, real_branch):
 
181
        self.bzrdir = remote_bzrdir
 
182
        self.transport = remote_bzrdir.transport
 
183
        self.repository = remote_repository
 
184
        self._real_branch = real_branch
 
185
        self._format = RemoteBranchFormat()
 
186
 
 
187
    def lock_read(self):
 
188
        return self._real_branch.lock_read()
 
189
 
 
190
    def lock_write(self):
 
191
        return self._real_branch.lock_write()
 
192
 
 
193
    def unlock(self):
 
194
        return self._real_branch.unlock()
 
195
 
 
196
    def break_lock(self):
 
197
        return self._real_branch.break_lock()
 
198
 
 
199
    def revision_history(self):
 
200
        return self._real_branch.revision_history()
 
201
 
 
202
    def set_revision_history(self, rev_history):
 
203
        return self._real_branch.set_revision_history(rev_history)
 
204
 
 
205
    def get_parent(self):
 
206
        return self._real_branch.get_parent()
 
207
        
 
208
    def set_parent(self, url):
 
209
        return self._real_branch.set_parent(url)
 
210
        
 
211
 
 
212
class RemoteWorkingTree(object):
 
213
 
 
214
    def __init__(self, remote_bzrdir, real_workingtree):
 
215
        self.real_workingtree = real_workingtree
 
216
        self.bzrdir = remote_bzrdir
 
217
 
 
218
    def __getattr__(self, name):
 
219
        # XXX: temporary way to lazily delegate everything to the real
 
220
        # workingtree
 
221
        return getattr(self.real_workingtree, name)
 
222
 
 
223
 
 
224
# when first loaded, register this format.
 
225
#
 
226
# TODO: Actually this needs to be done earlier; we can hold off on loading
 
227
# this code until it's needed though.
 
228
 
 
229
# We can't use register_control_format because it adds it at a lower priority
 
230
# than the existing branches, whereas this should take priority.
 
231
BzrDirFormat._control_formats.insert(0, RemoteBzrDirFormat())