/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
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
1752.2.39 by Martin Pool
[broken] implement upgrade apis on remote bzrdirs
17
# TODO: At some point, handle upgrades by just passing the whole request
18
# across to run on the server.
19
2018.5.26 by Andrew Bennetts
Extract a simple SmartClient class from RemoteTransport, and a hack to avoid VFS operations when probing for a bzrdir over a smart transport.
20
from urlparse import urlparse
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
21
2018.5.25 by Andrew Bennetts
Make sure RemoteBzrDirFormat is always registered (John Arbash Meinel, Robert Collins, Andrew Bennetts).
22
from bzrlib import branch, errors, repository
23
from bzrlib.bzrdir import BzrDir, BzrDirFormat, RemoteBzrDirFormat
2018.5.36 by Andrew Bennetts
Fix typo, and clean up some ununsed import warnings from pyflakes at the same time.
24
from bzrlib.branch import BranchReferenceFormat
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
25
from bzrlib.smart import client, vfs
2018.5.32 by Robert Collins
Unescape urls before handing over the wire to the smart server for the probe_transport method.
26
from bzrlib.urlutils import unescape
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
27
2018.5.25 by Andrew Bennetts
Make sure RemoteBzrDirFormat is always registered (John Arbash Meinel, Robert Collins, Andrew Bennetts).
28
# Note: RemoteBzrDirFormat is in bzrdir.py
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
29
30
class RemoteBzrDir(BzrDir):
31
    """Control directory on a remote server, accessed by HPSS."""
32
33
    def __init__(self, transport):
1752.2.39 by Martin Pool
[broken] implement upgrade apis on remote bzrdirs
34
        BzrDir.__init__(self, transport, RemoteBzrDirFormat())
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
35
        self.client = transport.get_smart_client()
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
36
        # this object holds a delegated bzrdir that uses file-level operations
37
        # to talk to the other side
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
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
        
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
41
        # THIS IS A COMPLETE AND UTTER LIE.
42
        # XXX: XXX: XXX: must be removed before merging to mainline
43
        # SMART_SERVER_MERGE_BLOCKER
1752.2.72 by Andrew Bennetts
Make Remote* classes in remote.py more consistent and remove some dead code.
44
        default_format = BzrDirFormat.get_default_format()
45
        self._real_bzrdir = default_format.open(transport, _found=True)
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
46
        smartclient = client.SmartClient(self.client)
47
        path = self._path_for_remote_call(smartclient)
2018.5.26 by Andrew Bennetts
Extract a simple SmartClient class from RemoteTransport, and a hack to avoid VFS operations when probing for a bzrdir over a smart transport.
48
        #self._real_bzrdir._format.probe_transport(transport)
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
49
        response = smartclient.call('probe_dont_use', path)
2018.5.26 by Andrew Bennetts
Extract a simple SmartClient class from RemoteTransport, and a hack to avoid VFS operations when probing for a bzrdir over a smart transport.
50
        if response == ('no',):
51
            raise errors.NotBranchError(path=transport.base)
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
52
        self._branch = None
53
1752.2.39 by Martin Pool
[broken] implement upgrade apis on remote bzrdirs
54
    def create_repository(self, shared=False):
1752.2.72 by Andrew Bennetts
Make Remote* classes in remote.py more consistent and remove some dead code.
55
        return RemoteRepository(
56
            self, self._real_bzrdir.create_repository(shared=shared))
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
57
58
    def create_branch(self):
1752.2.72 by Andrew Bennetts
Make Remote* classes in remote.py more consistent and remove some dead code.
59
        real_branch = self._real_bzrdir.create_branch()
60
        real_repository = real_branch.repository
61
        remote_repository = RemoteRepository(self, real_repository)
62
        return RemoteBranch(self, remote_repository, real_branch)
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
63
64
    def create_workingtree(self, revision_id=None):
1752.2.72 by Andrew Bennetts
Make Remote* classes in remote.py more consistent and remove some dead code.
65
        real_workingtree = self._real_bzrdir.create_workingtree(revision_id=revision_id)
66
        return RemoteWorkingTree(self, real_workingtree)
1752.2.39 by Martin Pool
[broken] implement upgrade apis on remote bzrdirs
67
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
68
    def open_branch(self, _unsupported=False):
69
        assert _unsupported == False, 'unsupported flag support not implemented yet.'
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
70
        smartclient = client.SmartClient(self.client)
71
        path = self._path_for_remote_call(smartclient)
72
        response = smartclient.call('BzrDir.open_branch', path)
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
73
        assert response[0] == 'ok', 'unexpected response code %s' % response[0]
74
        if response[0] != 'ok':
75
            # this should probably be a regular translate no ?
76
            raise errors.NotBranchError(path=self.root_transport.base)
77
        if response[1] == '':
78
            # branch at this location.
79
            if vfs.vfs_enabled():
80
                # if the VFS is enabled, create a local object using the VFS.
81
                real_branch = self._real_bzrdir.open_branch(unsupported=_unsupported)
82
                # This branch accessed through the smart server, so wrap the
83
                # file-level objects.
84
                real_repository = real_branch.repository
85
                remote_repository = RemoteRepository(self, real_repository)
86
                return RemoteBranch(self, remote_repository, real_branch)
87
            else:
88
                # otherwise just create a proxy for the branch.
89
                return RemoteBranch(self, self.find_repository())
90
        else:
91
            # a branch reference, use the existing BranchReference logic.
92
            format = BranchReferenceFormat()
93
            return format.open(self, _found=True, location=response[1])
94
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
95
    def open_repository(self):
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
96
        smartclient = client.SmartClient(self.client)
97
        path = self._path_for_remote_call(smartclient)
98
        response = smartclient.call('BzrDir.find_repository', path)
99
        assert response[0] in ('ok', 'norepository'), \
100
            'unexpected response code %s' % response[0]
101
        if response[0] == 'norepository':
102
            raise errors.NoRepositoryPresent(self)
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
103
        if response[1] == '':
104
            if vfs.vfs_enabled():
105
                return RemoteRepository(self, self._real_bzrdir.open_repository())
106
            else:
107
                return RemoteRepository(self)
108
        else:
109
            raise errors.NoRepositoryPresent(self)
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
110
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
111
    def open_workingtree(self):
1752.2.72 by Andrew Bennetts
Make Remote* classes in remote.py more consistent and remove some dead code.
112
        return RemoteWorkingTree(self, self._real_bzrdir.open_workingtree())
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
113
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
114
    def _path_for_remote_call(self, client):
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
115
        """Return the path to be used for this bzrdir in a remote call."""
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
116
        return client.remote_path_from_transport(self.root_transport)
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
117
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
118
    def get_branch_transport(self, branch_format):
119
        return self._real_bzrdir.get_branch_transport(branch_format)
120
1752.2.43 by Andrew Bennetts
Fix get_{branch,repository,workingtree}_transport.
121
    def get_repository_transport(self, repository_format):
122
        return self._real_bzrdir.get_repository_transport(repository_format)
123
124
    def get_workingtree_transport(self, workingtree_format):
125
        return self._real_bzrdir.get_workingtree_transport(workingtree_format)
126
1752.2.39 by Martin Pool
[broken] implement upgrade apis on remote bzrdirs
127
    def can_convert_format(self):
128
        """Upgrading of remote bzrdirs is not supported yet."""
129
        return False
130
131
    def needs_format_conversion(self, format=None):
132
        """Upgrading of remote bzrdirs is not supported yet."""
133
        return False
134
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
135
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
136
class RemoteRepositoryFormat(repository.RepositoryFormat):
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
137
    """Format for repositories accessed over rpc.
138
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
139
    Instances of this repository are represented by RemoteRepository
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
140
    instances.
141
    """
142
143
    _matchingbzrdir = RemoteBzrDirFormat
144
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
145
    def initialize(self, a_bzrdir, shared=False):
1752.2.72 by Andrew Bennetts
Make Remote* classes in remote.py more consistent and remove some dead code.
146
        assert isinstance(a_bzrdir, RemoteBzrDir)
147
        return a_bzrdir.create_repository(shared=shared)
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
148
    
149
    def open(self, a_bzrdir):
1752.2.72 by Andrew Bennetts
Make Remote* classes in remote.py more consistent and remove some dead code.
150
        assert isinstance(a_bzrdir, RemoteBzrDir)
151
        return a_bzrdir.open_repository()
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
152
153
    def get_format_description(self):
154
        return 'bzr remote repository'
155
156
    def __eq__(self, other):
1752.2.87 by Andrew Bennetts
Make tests pass.
157
        return self.__class__ == other.__class__
158
159
    rich_root_data = False
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
160
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
161
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
162
class RemoteRepository(object):
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
163
    """Repository accessed over rpc.
164
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
165
    For the moment everything is delegated to IO-like operations over
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
166
    the transport.
167
    """
168
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
169
    def __init__(self, remote_bzrdir, real_repository=None):
170
        """Create a RemoteRepository instance.
171
        
172
        :param remote_bzrdir: The bzrdir hosting this repository.
173
        :param real_repository: If not None, a local implementation of the
174
            repository logic for the repository, usually accessing the data
175
            via the VFS.
176
        """
177
        if real_repository:
2018.5.36 by Andrew Bennetts
Fix typo, and clean up some ununsed import warnings from pyflakes at the same time.
178
            self._real_repository = real_repository
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
179
        self.bzrdir = remote_bzrdir
2018.5.40 by Robert Collins
Implement a remote Repository.has_revision method.
180
        self._client = client.SmartClient(self.bzrdir.client)
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
181
        self._format = RemoteRepositoryFormat()
182
2018.5.40 by Robert Collins
Implement a remote Repository.has_revision method.
183
    def has_revision(self, revision_id):
184
        """See Repository.has_revision()."""
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
185
        path = self.bzrdir._path_for_remote_call(self._client)
2018.5.40 by Robert Collins
Implement a remote Repository.has_revision method.
186
        response = self._client.call('Repository.has_revision', path, revision_id.encode('utf8'))
187
        assert response[0] in ('ok', 'no'), 'unexpected response code %s' % response[0]
188
        return response[0] == 'ok'
189
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
190
191
class RemoteBranchFormat(branch.BranchFormat):
192
193
    def open(self, a_bzrdir):
1752.2.72 by Andrew Bennetts
Make Remote* classes in remote.py more consistent and remove some dead code.
194
        assert isinstance(a_bzrdir, RemoteBzrDir)
195
        return a_bzrdir.open_branch()
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
196
197
    def initialize(self, a_bzrdir):
198
        assert isinstance(a_bzrdir, RemoteBzrDir)
199
        return a_bzrdir.create_branch()
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
200
201
202
class RemoteBranch(branch.Branch):
203
    """Branch stored on a server accessed by HPSS RPC.
204
205
    At the moment most operations are mapped down to simple file operations.
206
    """
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
207
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
208
    def __init__(self, remote_bzrdir, remote_repository, real_branch=None):
209
        """Create a RemoteBranch instance.
210
211
        :param real_branch: An optional local implementation of the branch
212
            format, usually accessing the data via the VFS.
213
        """
1752.2.64 by Andrew Bennetts
Improve how RemoteBzrDir.open_branch works to handle references and not double-open repositories.
214
        self.bzrdir = remote_bzrdir
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
215
        self._client = client.SmartClient(self.bzrdir.client)
1752.2.64 by Andrew Bennetts
Improve how RemoteBzrDir.open_branch works to handle references and not double-open repositories.
216
        self.repository = remote_repository
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
217
        if real_branch is not None:
218
            self._real_branch = real_branch
1752.2.64 by Andrew Bennetts
Improve how RemoteBzrDir.open_branch works to handle references and not double-open repositories.
219
        self._format = RemoteBranchFormat()
220
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
221
    def lock_read(self):
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
222
        return self._real_branch.lock_read()
223
224
    def lock_write(self):
225
        return self._real_branch.lock_write()
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
226
227
    def unlock(self):
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
228
        return self._real_branch.unlock()
229
230
    def break_lock(self):
231
        return self._real_branch.break_lock()
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
232
233
    def revision_history(self):
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
234
        """See Branch.revision_history()."""
235
        # XXX: TODO: this does not cache the revision history for the duration
236
        # of a lock, which is a bug - see the code for regular branches
237
        # for details.
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
238
        path = self.bzrdir._path_for_remote_call(self._client)
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
239
        response = self._client.call2('Branch.revision_history', path)
240
        assert response[0][0] == 'ok', 'unexpected response code %s' % response[0]
241
        result = response[1].read_body_bytes().decode('utf8').split('\x00')
242
        if result == ['']:
243
            return []
244
        return result
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
245
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
246
    def set_revision_history(self, rev_history):
247
        return self._real_branch.set_revision_history(rev_history)
248
249
    def get_parent(self):
250
        return self._real_branch.get_parent()
251
        
1752.2.63 by Andrew Bennetts
Delegate set_parent.
252
    def set_parent(self, url):
253
        return self._real_branch.set_parent(url)
254
        
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
255
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
256
class RemoteWorkingTree(object):
257
1752.2.72 by Andrew Bennetts
Make Remote* classes in remote.py more consistent and remove some dead code.
258
    def __init__(self, remote_bzrdir, real_workingtree):
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
259
        self.real_workingtree = real_workingtree
260
        self.bzrdir = remote_bzrdir
261
262
    def __getattr__(self, name):
263
        # XXX: temporary way to lazily delegate everything to the real
264
        # workingtree
265
        return getattr(self.real_workingtree, name)
266
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
267