/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

Extract a simple SmartClient class from RemoteTransport, and a hack to avoid VFS operations when probing for a bzrdir over a smart 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
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
 
25
from bzrlib.trace import mutter
 
26
from bzrlib.smart import client
 
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
        default_format = BzrDirFormat.get_default_format()
 
42
        self._real_bzrdir = default_format.open(transport, _found=True)
 
43
        path = urlparse(transport.base)[2]
 
44
        #self._real_bzrdir._format.probe_transport(transport)
 
45
        response = client.SmartClient(self.client).call('probe_dont_use', path)
 
46
        if response == ('no',):
 
47
            raise errors.NotBranchError(path=transport.base)
 
48
        self._branch = None
 
49
 
 
50
    def create_repository(self, shared=False):
 
51
        return RemoteRepository(
 
52
            self, self._real_bzrdir.create_repository(shared=shared))
 
53
 
 
54
    def create_branch(self):
 
55
        real_branch = self._real_bzrdir.create_branch()
 
56
        real_repository = real_branch.repository
 
57
        remote_repository = RemoteRepository(self, real_repository)
 
58
        return RemoteBranch(self, remote_repository, real_branch)
 
59
 
 
60
    def create_workingtree(self, revision_id=None):
 
61
        real_workingtree = self._real_bzrdir.create_workingtree(revision_id=revision_id)
 
62
        return RemoteWorkingTree(self, real_workingtree)
 
63
 
 
64
    def open_repository(self):
 
65
        return RemoteRepository(self, self._real_bzrdir.open_repository())
 
66
 
 
67
    def open_branch(self, _unsupported=False):
 
68
        real_branch = self._real_bzrdir.open_branch(unsupported=_unsupported)
 
69
        if real_branch.bzrdir is self._real_bzrdir:
 
70
            # This branch accessed through the smart server, so wrap the
 
71
            # file-level objects.
 
72
            real_repository = real_branch.repository
 
73
            remote_repository = RemoteRepository(self, real_repository)
 
74
            return RemoteBranch(self, remote_repository, real_branch)
 
75
        else:
 
76
            # We were redirected to somewhere else, so don't wrap.
 
77
            return real_branch
 
78
 
 
79
    def open_workingtree(self):
 
80
        return RemoteWorkingTree(self, self._real_bzrdir.open_workingtree())
 
81
 
 
82
    def get_branch_transport(self, branch_format):
 
83
        return self._real_bzrdir.get_branch_transport(branch_format)
 
84
 
 
85
    def get_repository_transport(self, repository_format):
 
86
        return self._real_bzrdir.get_repository_transport(repository_format)
 
87
 
 
88
    def get_workingtree_transport(self, workingtree_format):
 
89
        return self._real_bzrdir.get_workingtree_transport(workingtree_format)
 
90
 
 
91
    def can_convert_format(self):
 
92
        """Upgrading of remote bzrdirs is not supported yet."""
 
93
        return False
 
94
 
 
95
    def needs_format_conversion(self, format=None):
 
96
        """Upgrading of remote bzrdirs is not supported yet."""
 
97
        return False
 
98
 
 
99
 
 
100
class RemoteRepositoryFormat(repository.RepositoryFormat):
 
101
    """Format for repositories accessed over rpc.
 
102
 
 
103
    Instances of this repository are represented by RemoteRepository
 
104
    instances.
 
105
    """
 
106
 
 
107
    _matchingbzrdir = RemoteBzrDirFormat
 
108
 
 
109
    def initialize(self, a_bzrdir, shared=False):
 
110
        assert isinstance(a_bzrdir, RemoteBzrDir)
 
111
        return a_bzrdir.create_repository(shared=shared)
 
112
    
 
113
    def open(self, a_bzrdir):
 
114
        assert isinstance(a_bzrdir, RemoteBzrDir)
 
115
        return a_bzrdir.open_repository()
 
116
 
 
117
    def get_format_description(self):
 
118
        return 'bzr remote repository'
 
119
 
 
120
    def __eq__(self, other):
 
121
        return self.__class__ == other.__class__
 
122
 
 
123
    rich_root_data = False
 
124
 
 
125
 
 
126
class RemoteRepository(object):
 
127
    """Repository accessed over rpc.
 
128
 
 
129
    For the moment everything is delegated to IO-like operations over
 
130
    the transport.
 
131
    """
 
132
 
 
133
    def __init__(self, remote_bzrdir, real_repository):
 
134
        self.real_repository = real_repository
 
135
        self.bzrdir = remote_bzrdir
 
136
        self._format = RemoteRepositoryFormat()
 
137
 
 
138
    def __getattr__(self, name):
 
139
        # XXX: temporary way to lazily delegate everything to the real
 
140
        # repository
 
141
        return getattr(self.real_repository, name)
 
142
 
 
143
 
 
144
class RemoteBranchFormat(branch.BranchFormat):
 
145
 
 
146
    def open(self, a_bzrdir):
 
147
        assert isinstance(a_bzrdir, RemoteBzrDir)
 
148
        return a_bzrdir.open_branch()
 
149
 
 
150
    def initialize(self, a_bzrdir):
 
151
        assert isinstance(a_bzrdir, RemoteBzrDir)
 
152
        return a_bzrdir.create_branch()
 
153
 
 
154
 
 
155
class RemoteBranch(branch.Branch):
 
156
    """Branch stored on a server accessed by HPSS RPC.
 
157
 
 
158
    At the moment most operations are mapped down to simple file operations.
 
159
    """
 
160
 
 
161
    def __init__(self, remote_bzrdir, remote_repository, real_branch):
 
162
        self.bzrdir = remote_bzrdir
 
163
        self.transport = remote_bzrdir.transport
 
164
        self.repository = remote_repository
 
165
        self._real_branch = real_branch
 
166
        self._format = RemoteBranchFormat()
 
167
 
 
168
    def lock_read(self):
 
169
        return self._real_branch.lock_read()
 
170
 
 
171
    def lock_write(self):
 
172
        return self._real_branch.lock_write()
 
173
 
 
174
    def unlock(self):
 
175
        return self._real_branch.unlock()
 
176
 
 
177
    def break_lock(self):
 
178
        return self._real_branch.break_lock()
 
179
 
 
180
    def revision_history(self):
 
181
        return self._real_branch.revision_history()
 
182
 
 
183
    def set_revision_history(self, rev_history):
 
184
        return self._real_branch.set_revision_history(rev_history)
 
185
 
 
186
    def get_parent(self):
 
187
        return self._real_branch.get_parent()
 
188
        
 
189
    def set_parent(self, url):
 
190
        return self._real_branch.set_parent(url)
 
191
        
 
192
 
 
193
class RemoteWorkingTree(object):
 
194
 
 
195
    def __init__(self, remote_bzrdir, real_workingtree):
 
196
        self.real_workingtree = real_workingtree
 
197
        self.bzrdir = remote_bzrdir
 
198
 
 
199
    def __getattr__(self, name):
 
200
        # XXX: temporary way to lazily delegate everything to the real
 
201
        # workingtree
 
202
        return getattr(self.real_workingtree, name)
 
203
 
 
204