/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

  • Committer: Andrew Bennetts
  • Date: 2006-10-20 04:02:48 UTC
  • mfrom: (2091 +trunk)
  • mto: (2018.5.1 split-smart)
  • mto: This revision was merged to the branch mainline in revision 2435.
  • Revision ID: andrew.bennetts@canonical.com-20061020040248-80ca63c7e0a13298
Merge from bzr.dev.

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):
 
87
        real_branch = self._real_bzrdir.open_branch()
 
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.get_format_description() == other.get_format_description()
 
141
 
 
142
 
 
143
class RemoteRepository(object):
 
144
    """Repository accessed over rpc.
 
145
 
 
146
    For the moment everything is delegated to IO-like operations over
 
147
    the transport.
 
148
    """
 
149
 
 
150
    def __init__(self, remote_bzrdir, real_repository):
 
151
        self.real_repository = real_repository
 
152
        self.bzrdir = remote_bzrdir
 
153
        self._format = RemoteRepositoryFormat()
 
154
 
 
155
    def __getattr__(self, name):
 
156
        # XXX: temporary way to lazily delegate everything to the real
 
157
        # repository
 
158
        return getattr(self.real_repository, name)
 
159
 
 
160
 
 
161
class RemoteBranchFormat(branch.BranchFormat):
 
162
 
 
163
    def open(self, a_bzrdir):
 
164
        assert isinstance(a_bzrdir, RemoteBzrDir)
 
165
        return a_bzrdir.open_branch()
 
166
 
 
167
    def initialize(self, a_bzrdir):
 
168
        assert isinstance(a_bzrdir, RemoteBzrDir)
 
169
        return a_bzrdir.create_branch()
 
170
 
 
171
 
 
172
class RemoteBranch(branch.Branch):
 
173
    """Branch stored on a server accessed by HPSS RPC.
 
174
 
 
175
    At the moment most operations are mapped down to simple file operations.
 
176
    """
 
177
 
 
178
    def __init__(self, remote_bzrdir, remote_repository, real_branch):
 
179
        self.bzrdir = remote_bzrdir
 
180
        self.transport = remote_bzrdir.transport
 
181
        self.repository = remote_repository
 
182
        self._real_branch = real_branch
 
183
        self._format = RemoteBranchFormat()
 
184
 
 
185
    def lock_read(self):
 
186
        return self._real_branch.lock_read()
 
187
 
 
188
    def lock_write(self):
 
189
        return self._real_branch.lock_write()
 
190
 
 
191
    def unlock(self):
 
192
        return self._real_branch.unlock()
 
193
 
 
194
    def break_lock(self):
 
195
        return self._real_branch.break_lock()
 
196
 
 
197
    def revision_history(self):
 
198
        return self._real_branch.revision_history()
 
199
 
 
200
    def set_revision_history(self, rev_history):
 
201
        return self._real_branch.set_revision_history(rev_history)
 
202
 
 
203
    def get_parent(self):
 
204
        return self._real_branch.get_parent()
 
205
        
 
206
    def set_parent(self, url):
 
207
        return self._real_branch.set_parent(url)
 
208
        
 
209
 
 
210
class RemoteWorkingTree(object):
 
211
 
 
212
    def __init__(self, remote_bzrdir, real_workingtree):
 
213
        self.real_workingtree = real_workingtree
 
214
        self.bzrdir = remote_bzrdir
 
215
 
 
216
    def __getattr__(self, name):
 
217
        # XXX: temporary way to lazily delegate everything to the real
 
218
        # workingtree
 
219
        return getattr(self.real_workingtree, name)
 
220
 
 
221
 
 
222
# when first loaded, register this format.
 
223
#
 
224
# TODO: Actually this needs to be done earlier; we can hold off on loading
 
225
# this code until it's needed though.
 
226
 
 
227
# We can't use register_control_format because it adds it at a lower priority
 
228
# than the existing branches, whereas this should take priority.
 
229
BzrDirFormat._control_formats.insert(0, RemoteBzrDirFormat())