/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: Robert Collins
  • Date: 2006-11-22 02:49:26 UTC
  • mto: (2018.5.34 hpss)
  • mto: This revision was merged to the branch mainline in revision 2435.
  • Revision ID: robertc@robertcollins.net-20061122024926-41ba3a48a35200ee
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.

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 Branch, BranchFormat, BranchReferenceFormat
 
25
from bzrlib.smart import client, vfs
 
26
from bzrlib.trace import mutter
 
27
from bzrlib.urlutils import unescape
 
28
 
 
29
# Note: RemoteBzrDirFormat is in bzrdir.py
 
30
 
 
31
class RemoteBzrDir(BzrDir):
 
32
    """Control directory on a remote server, accessed by HPSS."""
 
33
 
 
34
    def __init__(self, transport):
 
35
        BzrDir.__init__(self, transport, RemoteBzrDirFormat())
 
36
        self.client = transport.get_smart_client()
 
37
        # this object holds a delegated bzrdir that uses file-level operations
 
38
        # to talk to the other side
 
39
        # XXX: We should go into find_format, but not allow it to find
 
40
        # RemoteBzrDirFormat and make sure it finds the real underlying format.
 
41
        
 
42
        # THIS IS A COMPLETE AND UTTER LIE.
 
43
        # XXX: XXX: XXX: must be removed before merging to mainline
 
44
        # SMART_SERVER_MERGE_BLOCKER
 
45
        default_format = BzrDirFormat.get_default_format()
 
46
        self._real_bzrdir = default_format.open(transport, _found=True)
 
47
        path = self._path_for_remote_call()
 
48
        #self._real_bzrdir._format.probe_transport(transport)
 
49
        response = client.SmartClient(self.client).call('probe_dont_use', path)
 
50
        if response == ('no',):
 
51
            raise errors.NotBranchError(path=transport.base)
 
52
        self._branch = None
 
53
 
 
54
    def create_repository(self, shared=False):
 
55
        return RemoteRepository(
 
56
            self, self._real_bzrdir.create_repository(shared=shared))
 
57
 
 
58
    def create_branch(self):
 
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)
 
63
 
 
64
    def create_workingtree(self, revision_id=None):
 
65
        real_workingtree = self._real_bzrdir.create_workingtree(revision_id=revision_id)
 
66
        return RemoteWorkingTree(self, real_workingtree)
 
67
 
 
68
    def open_branch(self, _unsupported=False):
 
69
        assert _unsupported == False, 'unsupported flag support not implemented yet.'
 
70
        path = self._path_for_remote_call()
 
71
        response = client.SmartClient(self.client).call('BzrDir.open_branch', path)
 
72
        assert response[0] == 'ok', 'unexpected response code %s' % response[0]
 
73
        if response[0] != 'ok':
 
74
            # this should probably be a regular translate no ?
 
75
            raise errors.NotBranchError(path=self.root_transport.base)
 
76
        if response[1] == '':
 
77
            # branch at this location.
 
78
            if vfs.vfs_enabled():
 
79
                # if the VFS is enabled, create a local object using the VFS.
 
80
                real_branch = self._real_bzrdir.open_branch(unsupported=_unsupported)
 
81
                # This branch accessed through the smart server, so wrap the
 
82
                # file-level objects.
 
83
                real_repository = real_branch.repository
 
84
                remote_repository = RemoteRepository(self, real_repository)
 
85
                return RemoteBranch(self, remote_repository, real_branch)
 
86
            else:
 
87
                # otherwise just create a proxy for the branch.
 
88
                return RemoteBranch(self, self.find_repository())
 
89
        else:
 
90
            # a branch reference, use the existing BranchReference logic.
 
91
            format = BranchReferenceFormat()
 
92
            return format.open(self, _found=True, location=response[1])
 
93
 
 
94
    def open_repository(self):
 
95
        return RemoteRepository(self, self._real_bzrdir.open_repository())
 
96
 
 
97
    def open_workingtree(self):
 
98
        return RemoteWorkingTree(self, self._real_bzrdir.open_workingtree())
 
99
 
 
100
    def _path_for_remote_call(self):
 
101
        """Return the path to be used for this bzrdir in a remote call."""
 
102
        return unescape(urlparse(self.root_transport.base)[2])
 
103
 
 
104
    def get_branch_transport(self, branch_format):
 
105
        return self._real_bzrdir.get_branch_transport(branch_format)
 
106
 
 
107
    def get_repository_transport(self, repository_format):
 
108
        return self._real_bzrdir.get_repository_transport(repository_format)
 
109
 
 
110
    def get_workingtree_transport(self, workingtree_format):
 
111
        return self._real_bzrdir.get_workingtree_transport(workingtree_format)
 
112
 
 
113
    def can_convert_format(self):
 
114
        """Upgrading of remote bzrdirs is not supported yet."""
 
115
        return False
 
116
 
 
117
    def needs_format_conversion(self, format=None):
 
118
        """Upgrading of remote bzrdirs is not supported yet."""
 
119
        return False
 
120
 
 
121
 
 
122
class RemoteRepositoryFormat(repository.RepositoryFormat):
 
123
    """Format for repositories accessed over rpc.
 
124
 
 
125
    Instances of this repository are represented by RemoteRepository
 
126
    instances.
 
127
    """
 
128
 
 
129
    _matchingbzrdir = RemoteBzrDirFormat
 
130
 
 
131
    def initialize(self, a_bzrdir, shared=False):
 
132
        assert isinstance(a_bzrdir, RemoteBzrDir)
 
133
        return a_bzrdir.create_repository(shared=shared)
 
134
    
 
135
    def open(self, a_bzrdir):
 
136
        assert isinstance(a_bzrdir, RemoteBzrDir)
 
137
        return a_bzrdir.open_repository()
 
138
 
 
139
    def get_format_description(self):
 
140
        return 'bzr remote repository'
 
141
 
 
142
    def __eq__(self, other):
 
143
        return self.__class__ == other.__class__
 
144
 
 
145
    rich_root_data = False
 
146
 
 
147
 
 
148
class RemoteRepository(object):
 
149
    """Repository accessed over rpc.
 
150
 
 
151
    For the moment everything is delegated to IO-like operations over
 
152
    the transport.
 
153
    """
 
154
 
 
155
    def __init__(self, remote_bzrdir, real_repository):
 
156
        self.real_repository = real_repository
 
157
        self.bzrdir = remote_bzrdir
 
158
        self._format = RemoteRepositoryFormat()
 
159
 
 
160
    def __getattr__(self, name):
 
161
        # XXX: temporary way to lazily delegate everything to the real
 
162
        # repository
 
163
        return getattr(self.real_repository, name)
 
164
 
 
165
 
 
166
class RemoteBranchFormat(branch.BranchFormat):
 
167
 
 
168
    def open(self, a_bzrdir):
 
169
        assert isinstance(a_bzrdir, RemoteBzrDir)
 
170
        return a_bzrdir.open_branch()
 
171
 
 
172
    def initialize(self, a_bzrdir):
 
173
        assert isinstance(a_bzrdir, RemoteBzrDir)
 
174
        return a_bzrdir.create_branch()
 
175
 
 
176
 
 
177
class RemoteBranch(branch.Branch):
 
178
    """Branch stored on a server accessed by HPSS RPC.
 
179
 
 
180
    At the moment most operations are mapped down to simple file operations.
 
181
    """
 
182
 
 
183
    def __init__(self, remote_bzrdir, remote_repository, real_branch):
 
184
        self.bzrdir = remote_bzrdir
 
185
        self.transport = remote_bzrdir.transport
 
186
        self.repository = remote_repository
 
187
        self._real_branch = real_branch
 
188
        self._format = RemoteBranchFormat()
 
189
 
 
190
    def lock_read(self):
 
191
        return self._real_branch.lock_read()
 
192
 
 
193
    def lock_write(self):
 
194
        return self._real_branch.lock_write()
 
195
 
 
196
    def unlock(self):
 
197
        return self._real_branch.unlock()
 
198
 
 
199
    def break_lock(self):
 
200
        return self._real_branch.break_lock()
 
201
 
 
202
    def revision_history(self):
 
203
        return self._real_branch.revision_history()
 
204
 
 
205
    def set_revision_history(self, rev_history):
 
206
        return self._real_branch.set_revision_history(rev_history)
 
207
 
 
208
    def get_parent(self):
 
209
        return self._real_branch.get_parent()
 
210
        
 
211
    def set_parent(self, url):
 
212
        return self._real_branch.set_parent(url)
 
213
        
 
214
 
 
215
class RemoteWorkingTree(object):
 
216
 
 
217
    def __init__(self, remote_bzrdir, real_workingtree):
 
218
        self.real_workingtree = real_workingtree
 
219
        self.bzrdir = remote_bzrdir
 
220
 
 
221
    def __getattr__(self, name):
 
222
        # XXX: temporary way to lazily delegate everything to the real
 
223
        # workingtree
 
224
        return getattr(self.real_workingtree, name)
 
225
 
 
226