~bzr-pqm/bzr/bzr.dev

5050.78.5 by John Arbash Meinel
Merge the 2.1-client-read-reconnect-819604 (bug #819604) to bzr-2.2
1
# Copyright (C) 2006-2011 Canonical Ltd
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
16
4160.2.14 by Andrew Bennetts
Merge bzr.dev, improve NEWS entry and bzrlib.smart.request docs.
17
"""Infrastructure for server-side request handlers.
18
19
Interesting module attributes:
20
    * The request_handlers registry maps verb names to SmartServerRequest
21
      classes.
22
    * The jail_info threading.local() object is used to prevent accidental
23
      opening of BzrDirs outside of the backing transport, or any other
24
      transports placed in jail_info.transports.  The jail_info is reset on
25
      every call into a request handler (which can happen an arbitrary number
26
      of times during a request).
3195.3.4 by Andrew Bennetts
Make the general request handler dispatch version 3 events to the specific request handler (i.e. to the SmartServerRequest instance).
27
"""
2018.5.19 by Andrew Bennetts
Add docstrings to all the new modules, and a few other places.
28
6379.6.1 by Jelmer Vernooij
Import absolute_import in a few places.
29
from __future__ import absolute_import
30
4160.2.14 by Andrew Bennetts
Merge bzr.dev, improve NEWS entry and bzrlib.smart.request docs.
31
# XXX: The class names are a little confusing: the protocol will instantiate a
32
# SmartServerRequestHandler, whose dispatch_command method creates an instance
33
# of a SmartServerRequest subclass.
34
35
4160.2.2 by Andrew Bennetts
Add setup_jail and teardown_jail to SmartServerRequest.
36
import threading
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
37
2402.1.2 by Andrew Bennetts
Deal with review comments.
38
from bzrlib import (
4889.2.1 by John Arbash Meinel
Make -Dhpss log debug information for the server process.
39
    debug,
2402.1.2 by Andrew Bennetts
Deal with review comments.
40
    errors,
4889.2.1 by John Arbash Meinel
Make -Dhpss log debug information for the server process.
41
    osutils,
2402.1.2 by Andrew Bennetts
Deal with review comments.
42
    registry,
43
    revision,
4064.1.2 by Andrew Bennetts
Refactor server-side error translation, improve tests.
44
    trace,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
45
    urlutils,
2402.1.2 by Andrew Bennetts
Deal with review comments.
46
    )
3224.5.6 by Andrew Bennetts
Don't import bzrlib.bundle in bzrlib.smart.request until it's needed.
47
from bzrlib.lazy_import import lazy_import
48
lazy_import(globals(), """
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
49
from bzrlib import bzrdir
3224.5.6 by Andrew Bennetts
Don't import bzrlib.bundle in bzrlib.smart.request until it's needed.
50
from bzrlib.bundle import serializer
5816.1.4 by Jelmer Vernooij
Add import tariff test for the smart server.
51
52
import tempfile
53
import thread
3224.5.6 by Andrew Bennetts
Don't import bzrlib.bundle in bzrlib.smart.request until it's needed.
54
""")
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
55
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
56
4160.2.2 by Andrew Bennetts
Add setup_jail and teardown_jail to SmartServerRequest.
57
jail_info = threading.local()
58
jail_info.transports = None
59
60
4160.2.4 by Andrew Bennetts
Use BzrDir pre_open hook to jail request code from accessing transports other than the backing transport.
61
def _install_hook():
62
    bzrdir.BzrDir.hooks.install_named_hook(
63
        'pre_open', _pre_open_hook, 'checking server jail')
64
65
66
def _pre_open_hook(transport):
4205.2.1 by Andrew Bennetts
Fix BzrDir.open in non-main (and non-server-request) thread when bzrlib.smart.request's _pre_open_hook is installed.
67
    allowed_transports = getattr(jail_info, 'transports', None)
4160.2.4 by Andrew Bennetts
Use BzrDir pre_open hook to jail request code from accessing transports other than the backing transport.
68
    if allowed_transports is None:
69
        return
70
    abspath = transport.base
71
    for allowed_transport in allowed_transports:
72
        try:
73
            allowed_transport.relpath(abspath)
74
        except errors.PathNotChild:
75
            continue
76
        else:
77
            return
4294.2.8 by Robert Collins
Reduce round trips pushing new branches substantially.
78
    raise errors.JailBreak(abspath)
4160.2.4 by Andrew Bennetts
Use BzrDir pre_open hook to jail request code from accessing transports other than the backing transport.
79
80
81
_install_hook()
82
83
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
84
class SmartServerRequest(object):
2692.1.10 by Andrew Bennetts
More docstring polish
85
    """Base class for request handlers.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
86
2692.1.10 by Andrew Bennetts
More docstring polish
87
    To define a new request, subclass this class and override the `do` method
88
    (and if appropriate, `do_body` as well).  Request implementors should take
89
    care to call `translate_client_path` and `transport_from_client_path` as
90
    appropriate when dealing with paths received from the client.
91
    """
3195.3.2 by Andrew Bennetts
Checkpoint first rough cut of SmartServerRequestProtocolThree, this implementation reuses the _StatefulDecoder class. Plus some attempts to start tidying the smart protocol tests.
92
    # XXX: rename this class to BaseSmartServerRequestHandler ?  A request
93
    # *handler* is a different concept to the request.
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
94
4760.1.1 by Andrew Bennetts
Add optional jail_root argument to SmartServerRequest and friends, and use it in the WSGI glue. Allows opening branches in shared repos via bzr+http (assuming the repo should be accessible).
95
    def __init__(self, backing_transport, root_client_path='/', jail_root=None):
2402.1.2 by Andrew Bennetts
Deal with review comments.
96
        """Constructor.
97
98
        :param backing_transport: the base transport to be used when performing
99
            this request.
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
100
        :param root_client_path: the client path that maps to the root of
2692.1.9 by Andrew Bennetts
Docstrings for translate_client_path and transport_from_client_path.
101
            backing_transport.  This is used to interpret relpaths received
102
            from the client.  Clients will not be able to refer to paths above
2692.1.16 by Andrew Bennetts
Improve comments.
103
            this root.  If root_client_path is None, then no translation will
104
            be performed on client paths.  Default is '/'.
4760.1.1 by Andrew Bennetts
Add optional jail_root argument to SmartServerRequest and friends, and use it in the WSGI glue. Allows opening branches in shared repos via bzr+http (assuming the repo should be accessible).
105
        :param jail_root: if specified, the root of the BzrDir.open jail to use
106
            instead of backing_transport.
2402.1.2 by Andrew Bennetts
Deal with review comments.
107
        """
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
108
        self._backing_transport = backing_transport
4760.1.1 by Andrew Bennetts
Add optional jail_root argument to SmartServerRequest and friends, and use it in the WSGI glue. Allows opening branches in shared repos via bzr+http (assuming the repo should be accessible).
109
        if jail_root is None:
110
            jail_root = backing_transport
111
        self._jail_root = jail_root
2692.1.14 by Andrew Bennetts
All WSGI tests passing, and manual testing works too.
112
        if root_client_path is not None:
113
            if not root_client_path.startswith('/'):
114
                root_client_path = '/' + root_client_path
115
            if not root_client_path.endswith('/'):
116
                root_client_path += '/'
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
117
        self._root_client_path = root_client_path
3842.3.19 by Andrew Bennetts
Tweaks suggested by review.
118
        self._body_chunks = []
2018.5.5 by Andrew Bennetts
Pass body_bytes directly to SmartServerRequest.do_body
119
2018.5.24 by Andrew Bennetts
Setting NO_SMART_VFS in environment will disable VFS methods in the smart server. (Robert Collins, John Arbash Meinel, Andrew Bennetts)
120
    def _check_enabled(self):
121
        """Raises DisabledMethod if this method is disabled."""
122
        pass
123
2018.5.19 by Andrew Bennetts
Add docstrings to all the new modules, and a few other places.
124
    def do(self, *args):
2018.5.24 by Andrew Bennetts
Setting NO_SMART_VFS in environment will disable VFS methods in the smart server. (Robert Collins, John Arbash Meinel, Andrew Bennetts)
125
        """Mandatory extension point for SmartServerRequest subclasses.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
126
2018.5.24 by Andrew Bennetts
Setting NO_SMART_VFS in environment will disable VFS methods in the smart server. (Robert Collins, John Arbash Meinel, Andrew Bennetts)
127
        Subclasses must implement this.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
128
2018.5.19 by Andrew Bennetts
Add docstrings to all the new modules, and a few other places.
129
        This should return a SmartServerResponse if this command expects to
130
        receive no body.
131
        """
2018.5.5 by Andrew Bennetts
Pass body_bytes directly to SmartServerRequest.do_body
132
        raise NotImplementedError(self.do)
133
2018.5.24 by Andrew Bennetts
Setting NO_SMART_VFS in environment will disable VFS methods in the smart server. (Robert Collins, John Arbash Meinel, Andrew Bennetts)
134
    def execute(self, *args):
135
        """Public entry point to execute this request.
136
137
        It will return a SmartServerResponse if the command does not expect a
138
        body.
139
5891.1.3 by Andrew Bennetts
Move docstring formatting fixes.
140
        :param args: the arguments of the request.
2018.5.24 by Andrew Bennetts
Setting NO_SMART_VFS in environment will disable VFS methods in the smart server. (Robert Collins, John Arbash Meinel, Andrew Bennetts)
141
        """
142
        self._check_enabled()
143
        return self.do(*args)
144
2018.5.5 by Andrew Bennetts
Pass body_bytes directly to SmartServerRequest.do_body
145
    def do_body(self, body_bytes):
2018.5.19 by Andrew Bennetts
Add docstrings to all the new modules, and a few other places.
146
        """Called if the client sends a body with the request.
3184.1.10 by Robert Collins
Change the smart server verb for Repository.stream_revisions_chunked to use SearchResults as the request mechanism for downloads.
147
148
        The do() method is still called, and must have returned None.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
149
2018.5.19 by Andrew Bennetts
Add docstrings to all the new modules, and a few other places.
150
        Must return a SmartServerResponse.
151
        """
3990.3.2 by Andrew Bennetts
Fix the do_body NotImplementedError log spam.
152
        if body_bytes != '':
3990.3.3 by Andrew Bennetts
Add a test that unexpected request bodies trigger a SmartProtocolError from request implementations.
153
            raise errors.SmartProtocolError('Request does not expect a body')
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
154
3195.3.4 by Andrew Bennetts
Make the general request handler dispatch version 3 events to the specific request handler (i.e. to the SmartServerRequest instance).
155
    def do_chunk(self, chunk_bytes):
156
        """Called with each body chunk if the request has a streamed body.
157
158
        The do() method is still called, and must have returned None.
159
        """
3842.3.19 by Andrew Bennetts
Tweaks suggested by review.
160
        self._body_chunks.append(chunk_bytes)
3195.3.4 by Andrew Bennetts
Make the general request handler dispatch version 3 events to the specific request handler (i.e. to the SmartServerRequest instance).
161
162
    def do_end(self):
163
        """Called when the end of the request has been received."""
3842.3.19 by Andrew Bennetts
Tweaks suggested by review.
164
        body_bytes = ''.join(self._body_chunks)
165
        self._body_chunks = None
3923.5.2 by Andrew Bennetts
Completely delegate handling of request body chunks to the command object. The default implementation accumulates, like the existing behaviour.
166
        return self.do_body(body_bytes)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
167
4160.2.2 by Andrew Bennetts
Add setup_jail and teardown_jail to SmartServerRequest.
168
    def setup_jail(self):
4760.1.1 by Andrew Bennetts
Add optional jail_root argument to SmartServerRequest and friends, and use it in the WSGI glue. Allows opening branches in shared repos via bzr+http (assuming the repo should be accessible).
169
        jail_info.transports = [self._jail_root]
4160.2.2 by Andrew Bennetts
Add setup_jail and teardown_jail to SmartServerRequest.
170
171
    def teardown_jail(self):
172
        jail_info.transports = None
173
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
174
    def translate_client_path(self, client_path):
2692.1.9 by Andrew Bennetts
Docstrings for translate_client_path and transport_from_client_path.
175
        """Translate a path received from a network client into a local
176
        relpath.
177
178
        All paths received from the client *must* be translated.
179
2692.1.14 by Andrew Bennetts
All WSGI tests passing, and manual testing works too.
180
        :param client_path: the path from the client.
2692.1.9 by Andrew Bennetts
Docstrings for translate_client_path and transport_from_client_path.
181
        :returns: a relpath that may be used with self._backing_transport
2692.1.14 by Andrew Bennetts
All WSGI tests passing, and manual testing works too.
182
            (unlike the untranslated client_path, which must not be used with
183
            the backing transport).
2692.1.9 by Andrew Bennetts
Docstrings for translate_client_path and transport_from_client_path.
184
        """
2692.1.14 by Andrew Bennetts
All WSGI tests passing, and manual testing works too.
185
        if self._root_client_path is None:
186
            # no translation necessary!
187
            return client_path
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
188
        if not client_path.startswith('/'):
189
            client_path = '/' + client_path
4294.2.1 by Robert Collins
Move directory checking for bzr push options into Branch.create_clone_on_transport.
190
        if client_path + '/' == self._root_client_path:
191
            return '.'
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
192
        if client_path.startswith(self._root_client_path):
193
            path = client_path[len(self._root_client_path):]
194
            relpath = urlutils.joinpath('/', path)
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
195
            if not relpath.startswith('/'):
196
                raise ValueError(relpath)
4760.2.1 by Michael Hudson
very simple fix
197
            return urlutils.escape('.' + relpath)
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
198
        else:
199
            raise errors.PathNotChild(client_path, self._root_client_path)
200
201
    def transport_from_client_path(self, client_path):
2692.1.9 by Andrew Bennetts
Docstrings for translate_client_path and transport_from_client_path.
202
        """Get a backing transport corresponding to the location referred to by
203
        a network client.
204
205
        :seealso: translate_client_path
206
        :returns: a transport cloned from self._backing_transport
207
        """
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
208
        relpath = self.translate_client_path(client_path)
2692.1.16 by Andrew Bennetts
Improve comments.
209
        return self._backing_transport.clone(relpath)
3195.3.4 by Andrew Bennetts
Make the general request handler dispatch version 3 events to the specific request handler (i.e. to the SmartServerRequest instance).
210
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
211
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
212
class SmartServerResponse(object):
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
213
    """A response to a client request.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
214
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
215
    This base class should not be used. Instead use
216
    SuccessfulSmartServerResponse and FailedSmartServerResponse as appropriate.
217
    """
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
218
2748.4.2 by Andrew Bennetts
Add protocol (version two) support for streaming bodies (using chunking) in responses.
219
    def __init__(self, args, body=None, body_stream=None):
220
        """Constructor.
221
222
        :param args: tuple of response arguments.
223
        :param body: string of a response body.
224
        :param body_stream: iterable of bytestrings to be streamed to the
225
            client.
226
        """
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
227
        self.args = args
2748.4.2 by Andrew Bennetts
Add protocol (version two) support for streaming bodies (using chunking) in responses.
228
        if body is not None and body_stream is not None:
229
            raise errors.BzrError(
230
                "'body' and 'body_stream' are mutually exclusive.")
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
231
        self.body = body
2748.4.2 by Andrew Bennetts
Add protocol (version two) support for streaming bodies (using chunking) in responses.
232
        self.body_stream = body_stream
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
233
2402.1.1 by Andrew Bennetts
Use the Command pattern for handling smart server commands.
234
    def __eq__(self, other):
235
        if other is None:
236
            return False
2748.4.2 by Andrew Bennetts
Add protocol (version two) support for streaming bodies (using chunking) in responses.
237
        return (other.args == self.args and
238
                other.body == self.body and
239
                other.body_stream is self.body_stream)
2402.1.1 by Andrew Bennetts
Use the Command pattern for handling smart server commands.
240
241
    def __repr__(self):
3691.2.6 by Martin Pool
Disable RemoteBranch stacking, but get get_stacked_on_url working, and passing back exceptions
242
        return "<%s args=%r body=%r>" % (self.__class__.__name__,
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
243
            self.args, self.body)
2402.1.1 by Andrew Bennetts
Use the Command pattern for handling smart server commands.
244
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
245
2432.4.2 by Robert Collins
Add FailedSmartServerResponse.
246
class FailedSmartServerResponse(SmartServerResponse):
247
    """A SmartServerResponse for a request which failed."""
248
249
    def is_successful(self):
250
        """FailedSmartServerResponse are not successful."""
251
        return False
252
253
2432.4.1 by Robert Collins
Add SuccessfulSmartServerResponse.
254
class SuccessfulSmartServerResponse(SmartServerResponse):
255
    """A SmartServerResponse for a successfully completed request."""
256
257
    def is_successful(self):
258
        """SuccessfulSmartServerResponse are successful."""
259
        return True
260
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
261
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
262
class SmartServerRequestHandler(object):
263
    """Protocol logic for smart server.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
264
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
265
    This doesn't handle serialization at all, it just processes requests and
266
    creates responses.
267
    """
268
269
    # IMPORTANT FOR IMPLEMENTORS: It is important that SmartServerRequestHandler
270
    # not contain encoding or decoding logic to allow the wire protocol to vary
271
    # from the object protocol: we will want to tweak the wire protocol separate
272
    # from the object model, and ideally we will be able to do that without
273
    # having a SmartServerRequestHandler subclass for each wire protocol, rather
274
    # just a Protocol subclass.
275
276
    # TODO: Better way of representing the body for commands that take it,
277
    # and allow it to be streamed into the server.
278
4760.1.1 by Andrew Bennetts
Add optional jail_root argument to SmartServerRequest and friends, and use it in the WSGI glue. Allows opening branches in shared repos via bzr+http (assuming the repo should be accessible).
279
    def __init__(self, backing_transport, commands, root_client_path,
4760.1.4 by Andrew Bennetts
Make jail_root param of SmartServerRequestHandler optional for convenience of tests.
280
        jail_root=None):
2018.5.17 by Andrew Bennetts
Paramaterise the commands handled by SmartServerRequestHandler.
281
        """Constructor.
282
283
        :param backing_transport: a Transport to handle requests for.
2018.5.23 by Andrew Bennetts
Use a Registry for smart server command handlers.
284
        :param commands: a registry mapping command names to SmartServerRequest
2018.5.17 by Andrew Bennetts
Paramaterise the commands handled by SmartServerRequestHandler.
285
            subclasses. e.g. bzrlib.transport.smart.vfs.vfs_commands.
286
        """
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
287
        self._backing_transport = backing_transport
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
288
        self._root_client_path = root_client_path
2018.5.17 by Andrew Bennetts
Paramaterise the commands handled by SmartServerRequestHandler.
289
        self._commands = commands
4760.1.4 by Andrew Bennetts
Make jail_root param of SmartServerRequestHandler optional for convenience of tests.
290
        if jail_root is None:
291
            jail_root = backing_transport
4760.1.1 by Andrew Bennetts
Add optional jail_root argument to SmartServerRequest and friends, and use it in the WSGI glue. Allows opening branches in shared repos via bzr+http (assuming the repo should be accessible).
292
        self._jail_root = jail_root
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
293
        self.response = None
294
        self.finished_reading = False
295
        self._command = None
4889.2.1 by John Arbash Meinel
Make -Dhpss log debug information for the server process.
296
        if 'hpss' in debug.debug_flags:
297
            self._request_start_time = osutils.timer_func()
4913.1.1 by John Arbash Meinel
Switch to using thread.get_ident() which is available on all python versions.
298
            self._thread_id = thread.get_ident()
4889.2.1 by John Arbash Meinel
Make -Dhpss log debug information for the server process.
299
4889.2.4 by John Arbash Meinel
Clean up some bits, we don't really need the time reported except for end time.
300
    def _trace(self, action, message, extra_bytes=None, include_time=False):
4889.2.3 by John Arbash Meinel
Get rid of -Dhpssthread, just always include it.
301
        # It is a bit of a shame that this functionality overlaps with that of 
302
        # ProtocolThreeRequester._trace. However, there is enough difference
303
        # that just putting it in a helper doesn't help a lot. And some state
304
        # is taken from the instance.
4889.2.4 by John Arbash Meinel
Clean up some bits, we don't really need the time reported except for end time.
305
        if include_time:
306
            t = '%5.3fs ' % (osutils.timer_func() - self._request_start_time)
307
        else:
4889.2.1 by John Arbash Meinel
Make -Dhpss log debug information for the server process.
308
            t = ''
309
        if extra_bytes is None:
310
            extra = ''
311
        else:
312
            extra = ' ' + repr(extra_bytes[:40])
313
            if len(extra) > 33:
314
                extra = extra[:29] + extra[-1] + '...'
4889.2.3 by John Arbash Meinel
Get rid of -Dhpssthread, just always include it.
315
        trace.mutter('%12s: [%s] %s%s%s'
316
                     % (action, self._thread_id, t, message, extra))
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
317
318
    def accept_body(self, bytes):
319
        """Accept body data."""
4475.2.2 by Andrew Bennetts
Don't try call do_chunk or do_end if there's no active command (e.g. while consuming a request for an unknown method)
320
        if self._command is None:
321
            # no active command object, so ignore the event.
322
            return
3923.5.2 by Andrew Bennetts
Completely delegate handling of request body chunks to the command object. The default implementation accumulates, like the existing behaviour.
323
        self._run_handler_code(self._command.do_chunk, (bytes,), {})
4889.2.1 by John Arbash Meinel
Make -Dhpss log debug information for the server process.
324
        if 'hpss' in debug.debug_flags:
325
            self._trace('accept body',
326
                        '%d bytes' % (len(bytes),), bytes)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
327
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
328
    def end_of_body(self):
329
        """No more body data will be received."""
3923.5.2 by Andrew Bennetts
Completely delegate handling of request body chunks to the command object. The default implementation accumulates, like the existing behaviour.
330
        self._run_handler_code(self._command.do_end, (), {})
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
331
        # cannot read after this.
332
        self.finished_reading = True
4889.2.1 by John Arbash Meinel
Make -Dhpss log debug information for the server process.
333
        if 'hpss' in debug.debug_flags:
4889.2.4 by John Arbash Meinel
Clean up some bits, we don't really need the time reported except for end time.
334
            self._trace('end of body', '', include_time=True)
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
335
336
    def _run_handler_code(self, callable, args, kwargs):
337
        """Run some handler specific code 'callable'.
338
339
        If a result is returned, it is considered to be the commands response,
340
        and finished_reading is set true, and its assigned to self.response.
341
342
        Any exceptions caught are translated and a response object created
343
        from them.
344
        """
345
        result = self._call_converting_errors(callable, args, kwargs)
2018.5.19 by Andrew Bennetts
Add docstrings to all the new modules, and a few other places.
346
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
347
        if result is not None:
348
            self.response = result
349
            self.finished_reading = True
350
351
    def _call_converting_errors(self, callable, args, kwargs):
352
        """Call callable converting errors to Response objects."""
353
        # XXX: most of this error conversion is VFS-related, and thus ought to
354
        # be in SmartServerVFSRequestHandler somewhere.
355
        try:
4160.2.2 by Andrew Bennetts
Add setup_jail and teardown_jail to SmartServerRequest.
356
            self._command.setup_jail()
357
            try:
358
                return callable(*args, **kwargs)
359
            finally:
360
                self._command.teardown_jail()
4064.1.2 by Andrew Bennetts
Refactor server-side error translation, improve tests.
361
        except (KeyboardInterrupt, SystemExit):
362
            raise
363
        except Exception, err:
364
            err_struct = _translate_error(err)
365
            return FailedSmartServerResponse(err_struct)
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
366
3195.3.2 by Andrew Bennetts
Checkpoint first rough cut of SmartServerRequestProtocolThree, this implementation reuses the _StatefulDecoder class. Plus some attempts to start tidying the smart protocol tests.
367
    def headers_received(self, headers):
3245.4.33 by Andrew Bennetts
Remove unused no_body_received method on SmartServerRequestHandler.
368
        # Just a no-op at the moment.
4889.2.1 by John Arbash Meinel
Make -Dhpss log debug information for the server process.
369
        if 'hpss' in debug.debug_flags:
370
            self._trace('headers', repr(headers))
3195.3.2 by Andrew Bennetts
Checkpoint first rough cut of SmartServerRequestProtocolThree, this implementation reuses the _StatefulDecoder class. Plus some attempts to start tidying the smart protocol tests.
371
372
    def args_received(self, args):
3195.3.4 by Andrew Bennetts
Make the general request handler dispatch version 3 events to the specific request handler (i.e. to the SmartServerRequest instance).
373
        cmd = args[0]
374
        args = args[1:]
375
        try:
376
            command = self._commands.get(cmd)
377
        except LookupError:
4889.2.1 by John Arbash Meinel
Make -Dhpss log debug information for the server process.
378
            if 'hpss' in debug.debug_flags:
379
                self._trace('hpss unknown request', 
4889.2.4 by John Arbash Meinel
Clean up some bits, we don't really need the time reported except for end time.
380
                            cmd, repr(args)[1:-1])
3245.4.48 by Andrew Bennetts
raise UnknownSmartMethod from dispatch_command.
381
            raise errors.UnknownSmartMethod(cmd)
4889.2.1 by John Arbash Meinel
Make -Dhpss log debug information for the server process.
382
        if 'hpss' in debug.debug_flags:
383
            from bzrlib.smart import vfs
384
            if issubclass(command, vfs.VfsRequest):
385
                action = 'hpss vfs req'
386
            else:
387
                action = 'hpss request'
388
            self._trace(action, 
4889.2.4 by John Arbash Meinel
Clean up some bits, we don't really need the time reported except for end time.
389
                        '%s %s' % (cmd, repr(args)[1:-1]))
4634.6.30 by Andrew Bennetts
Remove SmartServerRequest.dispatch_command, fix SmartServerRequest.args_received.
390
        self._command = command(
4760.1.1 by Andrew Bennetts
Add optional jail_root argument to SmartServerRequest and friends, and use it in the WSGI glue. Allows opening branches in shared repos via bzr+http (assuming the repo should be accessible).
391
            self._backing_transport, self._root_client_path, self._jail_root)
3195.3.4 by Andrew Bennetts
Make the general request handler dispatch version 3 events to the specific request handler (i.e. to the SmartServerRequest instance).
392
        self._run_handler_code(self._command.execute, args, {})
3195.3.2 by Andrew Bennetts
Checkpoint first rough cut of SmartServerRequestProtocolThree, this implementation reuses the _StatefulDecoder class. Plus some attempts to start tidying the smart protocol tests.
393
3195.3.4 by Andrew Bennetts
Make the general request handler dispatch version 3 events to the specific request handler (i.e. to the SmartServerRequest instance).
394
    def end_received(self):
4475.2.2 by Andrew Bennetts
Don't try call do_chunk or do_end if there's no active command (e.g. while consuming a request for an unknown method)
395
        if self._command is None:
396
            # no active command object, so ignore the event.
397
            return
3195.3.4 by Andrew Bennetts
Make the general request handler dispatch version 3 events to the specific request handler (i.e. to the SmartServerRequest instance).
398
        self._run_handler_code(self._command.do_end, (), {})
4889.2.1 by John Arbash Meinel
Make -Dhpss log debug information for the server process.
399
        if 'hpss' in debug.debug_flags:
4889.2.4 by John Arbash Meinel
Clean up some bits, we don't really need the time reported except for end time.
400
            self._trace('end', '', include_time=True)
3195.3.2 by Andrew Bennetts
Checkpoint first rough cut of SmartServerRequestProtocolThree, this implementation reuses the _StatefulDecoder class. Plus some attempts to start tidying the smart protocol tests.
401
3923.5.4 by Andrew Bennetts
Allow a request's body part(s) to be followed by an error.
402
    def post_body_error_received(self, error_args):
403
        # Just a no-op at the moment.
404
        pass
405
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
406
4064.1.2 by Andrew Bennetts
Refactor server-side error translation, improve tests.
407
def _translate_error(err):
408
    if isinstance(err, errors.NoSuchFile):
409
        return ('NoSuchFile', err.path)
410
    elif isinstance(err, errors.FileExists):
411
        return ('FileExists', err.path)
412
    elif isinstance(err, errors.DirectoryNotEmpty):
413
        return ('DirectoryNotEmpty', err.path)
4650.2.2 by Robert Collins
Serialize IncompatibleRepositories from the server too.
414
    elif isinstance(err, errors.IncompatibleRepositories):
415
        return ('IncompatibleRepositories', str(err.source), str(err.target),
416
            str(err.details))
4064.1.2 by Andrew Bennetts
Refactor server-side error translation, improve tests.
417
    elif isinstance(err, errors.ShortReadvError):
418
        return ('ShortReadvError', err.path, str(err.offset), str(err.length),
419
                str(err.actual))
6280.10.2 by Jelmer Vernooij
Add Repository.iter_file_bytes.
420
    elif isinstance(err, errors.RevisionNotPresent):
421
        return ('RevisionNotPresent', err.revision_id, err.file_id)
4064.1.2 by Andrew Bennetts
Refactor server-side error translation, improve tests.
422
    elif isinstance(err, errors.UnstackableRepositoryFormat):
423
        return (('UnstackableRepositoryFormat', str(err.format), err.url))
424
    elif isinstance(err, errors.UnstackableBranchFormat):
425
        return ('UnstackableBranchFormat', str(err.format), err.url)
426
    elif isinstance(err, errors.NotStacked):
427
        return ('NotStacked',)
6280.7.5 by Jelmer Vernooij
Bunch of test fixes.
428
    elif isinstance(err, errors.BzrCheckError):
429
        return ('BzrCheckError', err.msg)
4064.1.2 by Andrew Bennetts
Refactor server-side error translation, improve tests.
430
    elif isinstance(err, UnicodeError):
431
        # If it is a DecodeError, than most likely we are starting
432
        # with a plain string
433
        str_or_unicode = err.object
434
        if isinstance(str_or_unicode, unicode):
435
            # XXX: UTF-8 might have \x01 (our protocol v1 and v2 seperator
436
            # byte) in it, so this encoding could cause broken responses.
437
            # Newer clients use protocol v3, so will be fine.
438
            val = 'u:' + str_or_unicode.encode('utf-8')
439
        else:
440
            val = 's:' + str_or_unicode.encode('base64')
441
        # This handles UnicodeEncodeError or UnicodeDecodeError
442
        return (err.__class__.__name__, err.encoding, val, str(err.start),
443
                str(err.end), err.reason)
444
    elif isinstance(err, errors.TransportNotPossible):
445
        if err.msg == "readonly transport":
446
            return ('ReadOnlyError', )
447
    elif isinstance(err, errors.ReadError):
448
        # cannot read the file
449
        return ('ReadError', err.path)
450
    elif isinstance(err, errors.PermissionDenied):
451
        return ('PermissionDenied', err.path, err.extra)
4144.3.1 by Andrew Bennetts
Add Repository.insert_stream_locked server-side implementation, plus tests for server-side _translate_error.
452
    elif isinstance(err, errors.TokenMismatch):
453
        return ('TokenMismatch', err.given_token, err.lock_token)
454
    elif isinstance(err, errors.LockContention):
4556.2.6 by Andrew Bennetts
More conservative fix for LockContention serialisation.
455
        return ('LockContention',)
5677.2.1 by Martin
Detect and report MemoryError during a smart server request
456
    elif isinstance(err, MemoryError):
457
        # GZ 2011-02-24: Copy bzrlib.trace -Dmem_dump functionality here?
458
        return ('MemoryError',)
4064.1.2 by Andrew Bennetts
Refactor server-side error translation, improve tests.
459
    # Unserialisable error.  Log it, and return a generic error
460
    trace.log_exception_quietly()
5677.2.7 by Martin
Store exception name after initial 'error' slot as suggested in review
461
    return ('error', trace._qualified_exception_name(err.__class__, True),
462
        str(err))
4064.1.2 by Andrew Bennetts
Refactor server-side error translation, improve tests.
463
464
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
465
class HelloRequest(SmartServerRequest):
2432.2.6 by Andrew Bennetts
Improve HelloRequest's docstring.
466
    """Answer a version request with the highest protocol version this server
467
    supports.
468
    """
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
469
470
    def do(self):
3245.4.59 by Andrew Bennetts
Various tweaks in response to Martin's review.
471
        return SuccessfulSmartServerResponse(('ok', '2'))
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
472
473
474
class GetBundleRequest(SmartServerRequest):
2402.1.2 by Andrew Bennetts
Deal with review comments.
475
    """Get a bundle of from the null revision to the specified revision."""
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
476
477
    def do(self, path, revision_id):
478
        # open transport relative to our base
2692.1.7 by Andrew Bennetts
Translate path in GetBundleRequest too.
479
        t = self.transport_from_client_path(path)
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
480
        control, extra_path = bzrdir.BzrDir.open_containing_from_transport(t)
481
        repo = control.open_repository()
482
        tmpf = tempfile.TemporaryFile()
483
        base_revision = revision.NULL_REVISION
3224.5.6 by Andrew Bennetts
Don't import bzrlib.bundle in bzrlib.smart.request until it's needed.
484
        serializer.write_bundle(repo, revision_id, base_revision, tmpf)
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
485
        tmpf.seek(0)
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
486
        return SuccessfulSmartServerResponse((), tmpf.read())
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
487
488
2018.5.95 by Andrew Bennetts
Add a Transport.is_readonly remote call, let {Branch,Repository}.lock_write remote call return UnlockableTransport, and miscellaneous test fixes.
489
class SmartServerIsReadonly(SmartServerRequest):
490
    # XXX: this request method belongs somewhere else.
491
492
    def do(self):
493
        if self._backing_transport.is_readonly():
494
            answer = 'yes'
495
        else:
496
            answer = 'no'
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
497
        return SuccessfulSmartServerResponse((answer,))
2018.5.95 by Andrew Bennetts
Add a Transport.is_readonly remote call, let {Branch,Repository}.lock_write remote call return UnlockableTransport, and miscellaneous test fixes.
498
499
4797.85.31 by John Arbash Meinel
Categorize all of the requests as safe/unsafe/semi/stream for retrying purposes.
500
# In the 'info' attribute, we store whether this request is 'safe' to retry if
501
# we get a disconnect while reading the response. It can have the values:
4797.85.32 by John Arbash Meinel
Per request, change
502
#   read    This is purely a read request, so retrying it is perfectly ok.
503
#   idem    An idempotent write request. Something like 'put' where if you put
504
#           the same bytes twice you end up with the same final bytes.
4797.85.31 by John Arbash Meinel
Categorize all of the requests as safe/unsafe/semi/stream for retrying purposes.
505
#   semi    This is a request that isn't strictly idempotent, but doesn't
506
#           result in corruption if it is retried. This is for things like
507
#           'lock' and 'unlock'. If you call lock, it updates the disk
508
#           structure. If you fail to read the response, you won't be able to
509
#           use the lock, because you don't have the lock token. Calling lock
510
#           again will fail, because the lock is already taken. However, we
511
#           can't tell if the server received our request or not. If it didn't,
512
#           then retrying the request is fine, as it will actually do what we
513
#           want. If it did, we will interrupt the current operation, but we
514
#           are no worse off than interrupting the current operation because of
515
#           a ConnectionReset.
4797.85.32 by John Arbash Meinel
Per request, change
516
#   semivfs Similar to semi, but specific to a Virtual FileSystem request.
4797.85.31 by John Arbash Meinel
Categorize all of the requests as safe/unsafe/semi/stream for retrying purposes.
517
#   stream  This is a request that takes a stream that cannot be restarted if
518
#           consumed. This request is 'safe' in that if we determine the
519
#           connection is closed before we consume the stream, we can try
520
#           again.
4797.92.1 by John Arbash Meinel
Move mutate to the end, because it is the most obviously not retry-able.
521
#   mutate  State is updated in a way that replaying that request results in a
522
#           different state. For example 'append' writes more bytes to a given
523
#           file. If append succeeds, it moves the file pointer.
2018.5.23 by Andrew Bennetts
Use a Registry for smart server command handlers.
524
request_handlers = registry.Registry()
525
request_handlers.register_lazy(
4797.85.32 by John Arbash Meinel
Per request, change
526
    'append', 'bzrlib.smart.vfs', 'AppendRequest', info='mutate')
2018.5.23 by Andrew Bennetts
Use a Registry for smart server command handlers.
527
request_handlers.register_lazy(
6280.4.4 by Jelmer Vernooij
Add Branch.break_lock.
528
    'Branch.break_lock', 'bzrlib.smart.branch',
6206.1.2 by Jelmer Vernooij
Merge bzr.dev.
529
    'SmartServerBranchBreakLock', info='idem')
6280.4.4 by Jelmer Vernooij
Add Branch.break_lock.
530
request_handlers.register_lazy(
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
531
    'Branch.get_config_file', 'bzrlib.smart.branch',
4797.85.32 by John Arbash Meinel
Per request, change
532
    'SmartServerBranchGetConfigFile', info='read')
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
533
request_handlers.register_lazy(
4797.85.31 by John Arbash Meinel
Categorize all of the requests as safe/unsafe/semi/stream for retrying purposes.
534
    'Branch.get_parent', 'bzrlib.smart.branch', 'SmartServerBranchGetParent',
4797.85.32 by John Arbash Meinel
Per request, change
535
    info='read')
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
536
request_handlers.register_lazy(
6270.1.17 by Jelmer Vernooij
s/set_config_file/put_config_file.
537
    'Branch.put_config_file', 'bzrlib.smart.branch',
6206.1.2 by Jelmer Vernooij
Merge bzr.dev.
538
    'SmartServerBranchPutConfigFile', info='idem')
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
539
request_handlers.register_lazy(
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
540
    'Branch.get_tags_bytes', 'bzrlib.smart.branch',
4797.85.32 by John Arbash Meinel
Per request, change
541
    'SmartServerBranchGetTagsBytes', info='read')
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
542
request_handlers.register_lazy(
4556.2.1 by Andrew Bennetts
Add Branch.set_tags_bytes RPC, with HPSS call count acceptance test. Also fixes serialisation of LockDir, and uses external_url() in LockDir's repr and contention message.
543
    'Branch.set_tags_bytes', 'bzrlib.smart.branch',
4797.85.32 by John Arbash Meinel
Per request, change
544
    'SmartServerBranchSetTagsBytes', info='idem')
4797.85.31 by John Arbash Meinel
Categorize all of the requests as safe/unsafe/semi/stream for retrying purposes.
545
request_handlers.register_lazy(
5672.1.4 by Andrew Bennetts
Fix final bzr-loom test by adding RemoteBranch.heads_to_fetch that can ask the remote branch for the heads to fetch (but uses the cheaper default logic if it knows the remote format has an identical heads_to_fetch as Branch.heads_to_fetch).
546
    'Branch.heads_to_fetch', 'bzrlib.smart.branch',
6015.49.1 by John Arbash Meinel
Merge the bug #819604 client reconnect code into the bzr-2.4 series.
547
    'SmartServerBranchHeadsToFetch', info='read')
548
request_handlers.register_lazy(
4797.85.31 by John Arbash Meinel
Categorize all of the requests as safe/unsafe/semi/stream for retrying purposes.
549
    'Branch.get_stacked_on_url', 'bzrlib.smart.branch',
4797.85.32 by John Arbash Meinel
Per request, change
550
    'SmartServerBranchRequestGetStackedOnURL', info='read')
6280.6.2 by Jelmer Vernooij
Add HPSS calls Repository.get_physical_lock_status and Branch.get_physical_lock_status.
551
request_handlers.register_lazy(
552
    'Branch.get_physical_lock_status', 'bzrlib.smart.branch',
6206.1.2 by Jelmer Vernooij
Merge bzr.dev.
553
    'SmartServerBranchRequestGetPhysicalLockStatus', info='read')
554
request_handlers.register_lazy(
4797.85.31 by John Arbash Meinel
Categorize all of the requests as safe/unsafe/semi/stream for retrying purposes.
555
    'Branch.last_revision_info', 'bzrlib.smart.branch',
4797.85.32 by John Arbash Meinel
Per request, change
556
    'SmartServerBranchRequestLastRevisionInfo', info='read')
4797.85.31 by John Arbash Meinel
Categorize all of the requests as safe/unsafe/semi/stream for retrying purposes.
557
request_handlers.register_lazy(
558
    'Branch.lock_write', 'bzrlib.smart.branch',
559
    'SmartServerBranchRequestLockWrite', info='semi')
5050.78.5 by John Arbash Meinel
Merge the 2.1-client-read-reconnect-819604 (bug #819604) to bzr-2.2
560
request_handlers.register_lazy(
561
    'Branch.revision_history', 'bzrlib.smart.branch',
562
    'SmartServerRequestRevisionHistory', info='read')
4797.85.32 by John Arbash Meinel
Per request, change
563
request_handlers.register_lazy(
564
    'Branch.set_config_option', 'bzrlib.smart.branch',
565
    'SmartServerBranchRequestSetConfigOption', info='idem')
566
request_handlers.register_lazy(
5050.78.5 by John Arbash Meinel
Merge the 2.1-client-read-reconnect-819604 (bug #819604) to bzr-2.2
567
    'Branch.set_config_option_dict', 'bzrlib.smart.branch',
568
    'SmartServerBranchRequestSetConfigOptionDict', info='idem')
569
request_handlers.register_lazy(
4797.85.32 by John Arbash Meinel
Per request, change
570
    'Branch.set_last_revision', 'bzrlib.smart.branch',
571
    'SmartServerBranchRequestSetLastRevision', info='idem')
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
572
request_handlers.register_lazy(
2892.2.1 by Andrew Bennetts
Add Branch.set_last_revision_info smart method, and make the RemoteBranch client use it.
573
    'Branch.set_last_revision_info', 'bzrlib.smart.branch',
4797.85.32 by John Arbash Meinel
Per request, change
574
    'SmartServerBranchRequestSetLastRevisionInfo', info='idem')
2892.2.1 by Andrew Bennetts
Add Branch.set_last_revision_info smart method, and make the RemoteBranch client use it.
575
request_handlers.register_lazy(
3441.5.25 by Andrew Bennetts
Rename Branch.set_last_revision_descendant verb to Branch.set_last_revision_ex. It's a cop out, but at least it's not misleading.
576
    'Branch.set_last_revision_ex', 'bzrlib.smart.branch',
4797.85.32 by John Arbash Meinel
Per request, change
577
    'SmartServerBranchRequestSetLastRevisionEx', info='idem')
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
578
request_handlers.register_lazy(
4288.1.7 by Robert Collins
Add new remote server verb Branch.set_parent_location, dropping roundtrips further on push operations.
579
    'Branch.set_parent_location', 'bzrlib.smart.branch',
4797.85.32 by John Arbash Meinel
Per request, change
580
    'SmartServerBranchRequestSetParentLocation', info='idem')
4288.1.7 by Robert Collins
Add new remote server verb Branch.set_parent_location, dropping roundtrips further on push operations.
581
request_handlers.register_lazy(
6206.1.2 by Jelmer Vernooij
Merge bzr.dev.
582
    'Branch.unlock', 'bzrlib.smart.branch',
583
    'SmartServerBranchRequestUnlock', info='semi')
584
request_handlers.register_lazy(
585
    'Branch.revision_id_to_revno', 'bzrlib.smart.branch',
586
    'SmartServerBranchRequestRevisionIdToRevno', info='read')
6263.1.2 by Jelmer Vernooij
Add ``Branch.revision_id_to_revno`` smart verb.
587
request_handlers.register_lazy(
6305.5.10 by Jelmer Vernooij
Move to BzrDir.checkout_metadir.
588
    'BzrDir.checkout_metadir', 'bzrlib.smart.bzrdir',
589
    'SmartServerBzrDirRequestCheckoutMetaDir', info='read')
590
request_handlers.register_lazy(
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
591
    'BzrDir.cloning_metadir', 'bzrlib.smart.bzrdir',
4797.85.32 by John Arbash Meinel
Per request, change
592
    'SmartServerBzrDirRequestCloningMetaDir', info='read')
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
593
request_handlers.register_lazy(
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
594
    'BzrDir.create_branch', 'bzrlib.smart.bzrdir',
4797.85.31 by John Arbash Meinel
Categorize all of the requests as safe/unsafe/semi/stream for retrying purposes.
595
    'SmartServerRequestCreateBranch', info='semi')
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
596
request_handlers.register_lazy(
597
    'BzrDir.create_repository', 'bzrlib.smart.bzrdir',
4797.85.31 by John Arbash Meinel
Categorize all of the requests as safe/unsafe/semi/stream for retrying purposes.
598
    'SmartServerRequestCreateRepository', info='semi')
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
599
request_handlers.register_lazy(
600
    'BzrDir.find_repository', 'bzrlib.smart.bzrdir',
4797.85.32 by John Arbash Meinel
Per request, change
601
    'SmartServerRequestFindRepositoryV1', info='read')
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
602
request_handlers.register_lazy(
603
    'BzrDir.find_repositoryV2', 'bzrlib.smart.bzrdir',
4797.85.32 by John Arbash Meinel
Per request, change
604
    'SmartServerRequestFindRepositoryV2', info='read')
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
605
request_handlers.register_lazy(
606
    'BzrDir.find_repositoryV3', 'bzrlib.smart.bzrdir',
4797.85.32 by John Arbash Meinel
Per request, change
607
    'SmartServerRequestFindRepositoryV3', info='read')
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
608
request_handlers.register_lazy(
6436.3.2 by Jelmer Vernooij
Add HPSS call for BzrDir.get_branches.
609
    'BzrDir.get_branches', 'bzrlib.smart.bzrdir',
610
    'SmartServerBzrDirRequestGetBranches', info='read')
611
request_handlers.register_lazy(
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
612
    'BzrDir.get_config_file', 'bzrlib.smart.bzrdir',
4797.85.32 by John Arbash Meinel
Per request, change
613
    'SmartServerBzrDirRequestConfigFile', info='read')
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
614
request_handlers.register_lazy(
6266.4.1 by Jelmer Vernooij
HPSS call 'BzrDir.destroy_branch'.
615
    'BzrDir.destroy_branch', 'bzrlib.smart.bzrdir',
6206.1.2 by Jelmer Vernooij
Merge bzr.dev.
616
    'SmartServerBzrDirRequestDestroyBranch', info='semi')
6266.4.1 by Jelmer Vernooij
HPSS call 'BzrDir.destroy_branch'.
617
request_handlers.register_lazy(
6266.4.4 by Jelmer Vernooij
merge bzr.dev.
618
    'BzrDir.destroy_repository', 'bzrlib.smart.bzrdir',
6206.1.2 by Jelmer Vernooij
Merge bzr.dev.
619
    'SmartServerBzrDirRequestDestroyRepository', info='semi')
6266.4.4 by Jelmer Vernooij
merge bzr.dev.
620
request_handlers.register_lazy(
6266.3.2 by Jelmer Vernooij
merge bzr.dev.
621
    'BzrDir.has_workingtree', 'bzrlib.smart.bzrdir',
6206.1.2 by Jelmer Vernooij
Merge bzr.dev.
622
    'SmartServerBzrDirRequestHasWorkingTree', info='read')
6266.3.2 by Jelmer Vernooij
merge bzr.dev.
623
request_handlers.register_lazy(
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
624
    'BzrDirFormat.initialize', 'bzrlib.smart.bzrdir',
4797.85.31 by John Arbash Meinel
Categorize all of the requests as safe/unsafe/semi/stream for retrying purposes.
625
    'SmartServerRequestInitializeBzrDir', info='semi')
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
626
request_handlers.register_lazy(
4436.1.1 by Andrew Bennetts
Rename BzrDirFormat.initialize_ex verb to BzrDirFormat.initialize_ex_1.16.
627
    'BzrDirFormat.initialize_ex_1.16', 'bzrlib.smart.bzrdir',
4797.85.31 by John Arbash Meinel
Categorize all of the requests as safe/unsafe/semi/stream for retrying purposes.
628
    'SmartServerRequestBzrDirInitializeEx', info='semi')
629
request_handlers.register_lazy(
630
    'BzrDir.open', 'bzrlib.smart.bzrdir', 'SmartServerRequestOpenBzrDir',
4797.85.32 by John Arbash Meinel
Per request, change
631
    info='read')
4797.85.31 by John Arbash Meinel
Categorize all of the requests as safe/unsafe/semi/stream for retrying purposes.
632
request_handlers.register_lazy(
633
    'BzrDir.open_2.1', 'bzrlib.smart.bzrdir',
4797.85.32 by John Arbash Meinel
Per request, change
634
    'SmartServerRequestOpenBzrDir_2_1', info='read')
4634.47.3 by Andrew Bennetts
Add a BzrDir.open_2.1 verb that indicates if there is a workingtree present. Removes the last 2 VFS calls from incremental pushes.
635
request_handlers.register_lazy(
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
636
    'BzrDir.open_branch', 'bzrlib.smart.bzrdir',
4797.85.32 by John Arbash Meinel
Per request, change
637
    'SmartServerRequestOpenBranch', info='read')
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
638
request_handlers.register_lazy(
639
    'BzrDir.open_branchV2', 'bzrlib.smart.bzrdir',
4797.85.32 by John Arbash Meinel
Per request, change
640
    'SmartServerRequestOpenBranchV2', info='read')
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
641
request_handlers.register_lazy(
4734.4.8 by Andrew Bennetts
Fix HPSS tests; pass 'location is a repository' message via smart server when possible (adds BzrDir.open_branchV3 verb).
642
    'BzrDir.open_branchV3', 'bzrlib.smart.bzrdir',
4797.85.32 by John Arbash Meinel
Per request, change
643
    'SmartServerRequestOpenBranchV3', info='read')
644
request_handlers.register_lazy(
645
    'delete', 'bzrlib.smart.vfs', 'DeleteRequest', info='semivfs')
646
request_handlers.register_lazy(
647
    'get', 'bzrlib.smart.vfs', 'GetRequest', info='read')
648
request_handlers.register_lazy(
649
    'get_bundle', 'bzrlib.smart.request', 'GetBundleRequest', info='read')
650
request_handlers.register_lazy(
651
    'has', 'bzrlib.smart.vfs', 'HasRequest', info='read')
652
request_handlers.register_lazy(
653
    'hello', 'bzrlib.smart.request', 'HelloRequest', info='read')
4797.85.31 by John Arbash Meinel
Categorize all of the requests as safe/unsafe/semi/stream for retrying purposes.
654
request_handlers.register_lazy(
655
    'iter_files_recursive', 'bzrlib.smart.vfs', 'IterFilesRecursiveRequest',
4797.85.32 by John Arbash Meinel
Per request, change
656
    info='read')
657
request_handlers.register_lazy(
658
    'list_dir', 'bzrlib.smart.vfs', 'ListDirRequest', info='read')
659
request_handlers.register_lazy(
660
    'mkdir', 'bzrlib.smart.vfs', 'MkdirRequest', info='semivfs')
661
request_handlers.register_lazy(
662
    'move', 'bzrlib.smart.vfs', 'MoveRequest', info='semivfs')
663
request_handlers.register_lazy(
664
    'put', 'bzrlib.smart.vfs', 'PutRequest', info='idem')
665
request_handlers.register_lazy(
666
    'put_non_atomic', 'bzrlib.smart.vfs', 'PutNonAtomicRequest', info='idem')
667
request_handlers.register_lazy(
668
    'readv', 'bzrlib.smart.vfs', 'ReadvRequest', info='read')
669
request_handlers.register_lazy(
670
    'rename', 'bzrlib.smart.vfs', 'RenameRequest', info='semivfs')
3452.2.2 by Andrew Bennetts
Experimental PackRepository.{check_references,autopack} RPCs.
671
request_handlers.register_lazy(
6206.1.8 by Jelmer Vernooij
Merge bzr.dev.
672
    'Repository.add_signature_text', 'bzrlib.smart.repository',
673
    'SmartServerRepositoryAddSignatureText', info='idem')
674
request_handlers.register_lazy(
6206.1.2 by Jelmer Vernooij
Merge bzr.dev.
675
    'Repository.all_revision_ids', 'bzrlib.smart.repository',
676
    'SmartServerRepositoryAllRevisionIds', info='read')
3452.2.2 by Andrew Bennetts
Experimental PackRepository.{check_references,autopack} RPCs.
677
request_handlers.register_lazy(
678
    'PackRepository.autopack', 'bzrlib.smart.packrepository',
4797.85.32 by John Arbash Meinel
Per request, change
679
    'SmartServerPackRepositoryAutopack', info='idem')
4797.85.31 by John Arbash Meinel
Categorize all of the requests as safe/unsafe/semi/stream for retrying purposes.
680
request_handlers.register_lazy(
6206.1.2 by Jelmer Vernooij
Merge bzr.dev.
681
    'Repository.break_lock', 'bzrlib.smart.repository',
682
    'SmartServerRepositoryBreakLock', info='idem')
683
request_handlers.register_lazy(
4797.85.31 by John Arbash Meinel
Categorize all of the requests as safe/unsafe/semi/stream for retrying purposes.
684
    'Repository.gather_stats', 'bzrlib.smart.repository',
4797.85.32 by John Arbash Meinel
Per request, change
685
    'SmartServerRepositoryGatherStats', info='read')
4797.85.31 by John Arbash Meinel
Categorize all of the requests as safe/unsafe/semi/stream for retrying purposes.
686
request_handlers.register_lazy(
687
    'Repository.get_parent_map', 'bzrlib.smart.repository',
4797.85.32 by John Arbash Meinel
Per request, change
688
    'SmartServerRepositoryGetParentMap', info='read')
4797.85.31 by John Arbash Meinel
Categorize all of the requests as safe/unsafe/semi/stream for retrying purposes.
689
request_handlers.register_lazy(
690
    'Repository.get_revision_graph', 'bzrlib.smart.repository',
4797.85.32 by John Arbash Meinel
Per request, change
691
    'SmartServerRepositoryGetRevisionGraph', info='read')
4797.85.31 by John Arbash Meinel
Categorize all of the requests as safe/unsafe/semi/stream for retrying purposes.
692
request_handlers.register_lazy(
6263.3.2 by Jelmer Vernooij
Add new HPSS call 'Repository.get_revision_signature_text'.
693
    'Repository.get_revision_signature_text', 'bzrlib.smart.repository',
6206.1.12 by Jelmer Vernooij
merge bzr.dev.
694
    'SmartServerRepositoryGetRevisionSignatureText', info='read')
6263.3.2 by Jelmer Vernooij
Add new HPSS call 'Repository.get_revision_signature_text'.
695
request_handlers.register_lazy(
4797.85.31 by John Arbash Meinel
Categorize all of the requests as safe/unsafe/semi/stream for retrying purposes.
696
    'Repository.has_revision', 'bzrlib.smart.repository',
4797.85.32 by John Arbash Meinel
Per request, change
697
    'SmartServerRequestHasRevision', info='read')
4797.85.31 by John Arbash Meinel
Categorize all of the requests as safe/unsafe/semi/stream for retrying purposes.
698
request_handlers.register_lazy(
6265.1.1 by Jelmer Vernooij
Add new HPSS call ``Repository.has_signature_for_revision_id``.
699
    'Repository.has_signature_for_revision_id', 'bzrlib.smart.repository',
6206.1.2 by Jelmer Vernooij
Merge bzr.dev.
700
    'SmartServerRequestHasSignatureForRevisionId', info='read')
701
request_handlers.register_lazy(
4797.85.31 by John Arbash Meinel
Categorize all of the requests as safe/unsafe/semi/stream for retrying purposes.
702
    'Repository.insert_stream', 'bzrlib.smart.repository',
703
    'SmartServerRepositoryInsertStream', info='stream')
704
request_handlers.register_lazy(
705
    'Repository.insert_stream_1.19', 'bzrlib.smart.repository',
706
    'SmartServerRepositoryInsertStream_1_19', info='stream')
707
request_handlers.register_lazy(
708
    'Repository.insert_stream_locked', 'bzrlib.smart.repository',
709
    'SmartServerRepositoryInsertStreamLocked', info='stream')
710
request_handlers.register_lazy(
711
    'Repository.is_shared', 'bzrlib.smart.repository',
4797.85.32 by John Arbash Meinel
Per request, change
712
    'SmartServerRepositoryIsShared', info='read')
4797.85.31 by John Arbash Meinel
Categorize all of the requests as safe/unsafe/semi/stream for retrying purposes.
713
request_handlers.register_lazy(
6280.10.20 by Jelmer Vernooij
Convert smart to zlib.
714
    'Repository.iter_files_bytes', 'bzrlib.smart.repository',
6206.1.12 by Jelmer Vernooij
merge bzr.dev.
715
    'SmartServerRepositoryIterFilesBytes', info='read')
716
request_handlers.register_lazy(
4797.85.31 by John Arbash Meinel
Categorize all of the requests as safe/unsafe/semi/stream for retrying purposes.
717
    'Repository.lock_write', 'bzrlib.smart.repository',
718
    'SmartServerRepositoryLockWrite', info='semi')
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
719
request_handlers.register_lazy(
6206.1.2 by Jelmer Vernooij
Merge bzr.dev.
720
    'Repository.make_working_trees', 'bzrlib.smart.repository',
721
    'SmartServerRepositoryMakeWorkingTrees', info='read')
6263.2.1 by Jelmer Vernooij
Add hpss call ``Repository.make_working_trees``
722
request_handlers.register_lazy(
4017.3.4 by Robert Collins
Create a verb for Repository.set_make_working_trees.
723
    'Repository.set_make_working_trees', 'bzrlib.smart.repository',
4797.85.32 by John Arbash Meinel
Per request, change
724
    'SmartServerRepositorySetMakeWorkingTrees', info='idem')
4017.3.4 by Robert Collins
Create a verb for Repository.set_make_working_trees.
725
request_handlers.register_lazy(
4797.85.31 by John Arbash Meinel
Categorize all of the requests as safe/unsafe/semi/stream for retrying purposes.
726
    'Repository.unlock', 'bzrlib.smart.repository',
727
    'SmartServerRepositoryUnlock', info='semi')
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
728
request_handlers.register_lazy(
6280.6.2 by Jelmer Vernooij
Add HPSS calls Repository.get_physical_lock_status and Branch.get_physical_lock_status.
729
    'Repository.get_physical_lock_status', 'bzrlib.smart.repository',
6206.1.2 by Jelmer Vernooij
Merge bzr.dev.
730
    'SmartServerRepositoryGetPhysicalLockStatus', info='read')
6280.6.2 by Jelmer Vernooij
Add HPSS calls Repository.get_physical_lock_status and Branch.get_physical_lock_status.
731
request_handlers.register_lazy(
4419.2.4 by Andrew Bennetts
Add Repository.get_rev_id_for_revno RPC, removes VFS calls from 'pull -r 123' case.
732
    'Repository.get_rev_id_for_revno', 'bzrlib.smart.repository',
4797.85.32 by John Arbash Meinel
Per request, change
733
    'SmartServerRepositoryGetRevIdForRevno', info='read')
4419.2.4 by Andrew Bennetts
Add Repository.get_rev_id_for_revno RPC, removes VFS calls from 'pull -r 123' case.
734
request_handlers.register_lazy(
4060.1.5 by Robert Collins
Verb change name requested by Andrew.
735
    'Repository.get_stream', 'bzrlib.smart.repository',
4797.85.32 by John Arbash Meinel
Per request, change
736
    'SmartServerRepositoryGetStream', info='read')
4060.1.4 by Robert Collins
Streaming fetch from remote servers.
737
request_handlers.register_lazy(
4476.3.82 by Andrew Bennetts
Mention another bug fix in NEWS, and update verb name, comments, and NEWS additions for landing on 1.19 rather than 1.18.
738
    'Repository.get_stream_1.19', 'bzrlib.smart.repository',
4797.85.32 by John Arbash Meinel
Per request, change
739
    'SmartServerRepositoryGetStream_1_19', info='read')
4476.3.29 by Andrew Bennetts
Add Repository.get_stream_1.18 verb.
740
request_handlers.register_lazy(
6280.9.2 by Jelmer Vernooij
Add smart side.
741
    'Repository.iter_revisions', 'bzrlib.smart.repository',
6206.1.14 by Martin Pool
Add retry info for Repository.iter_revisions
742
    'SmartServerRepositoryIterRevisions', info='read')
6280.9.2 by Jelmer Vernooij
Add smart side.
743
request_handlers.register_lazy(
6305.2.2 by Jelmer Vernooij
Add smart side of pack.
744
    'Repository.pack', 'bzrlib.smart.repository',
6206.1.8 by Jelmer Vernooij
Merge bzr.dev.
745
    'SmartServerRepositoryPack', info='idem')
2018.18.1 by Martin Pool
Add stub Repository.tarball smart method
746
request_handlers.register_lazy(
6280.7.2 by Jelmer Vernooij
Add HPSS calls ``Repository.start_write_group``, ``Repository.abort_write_group`` and ``Repository.commit_write_group``.
747
    'Repository.start_write_group', 'bzrlib.smart.repository',
6206.1.2 by Jelmer Vernooij
Merge bzr.dev.
748
    'SmartServerRepositoryStartWriteGroup', info='semi')
6280.7.2 by Jelmer Vernooij
Add HPSS calls ``Repository.start_write_group``, ``Repository.abort_write_group`` and ``Repository.commit_write_group``.
749
request_handlers.register_lazy(
750
    'Repository.commit_write_group', 'bzrlib.smart.repository',
6206.1.2 by Jelmer Vernooij
Merge bzr.dev.
751
    'SmartServerRepositoryCommitWriteGroup', info='semi')
6280.7.2 by Jelmer Vernooij
Add HPSS calls ``Repository.start_write_group``, ``Repository.abort_write_group`` and ``Repository.commit_write_group``.
752
request_handlers.register_lazy(
753
    'Repository.abort_write_group', 'bzrlib.smart.repository',
6206.1.8 by Jelmer Vernooij
Merge bzr.dev.
754
    'SmartServerRepositoryAbortWriteGroup', info='semi')
6280.7.2 by Jelmer Vernooij
Add HPSS calls ``Repository.start_write_group``, ``Repository.abort_write_group`` and ``Repository.commit_write_group``.
755
request_handlers.register_lazy(
6280.7.6 by Jelmer Vernooij
Fix remaining tests.
756
    'Repository.check_write_group', 'bzrlib.smart.repository',
6206.1.2 by Jelmer Vernooij
Merge bzr.dev.
757
    'SmartServerRepositoryCheckWriteGroup', info='read')
6280.7.6 by Jelmer Vernooij
Fix remaining tests.
758
request_handlers.register_lazy(
6282.6.41 by Jelmer Vernooij
Merge bzr.dev.
759
    'Repository.reconcile', 'bzrlib.smart.repository',
760
    'SmartServerRepositoryReconcile', info='idem')
761
request_handlers.register_lazy(
2018.18.1 by Martin Pool
Add stub Repository.tarball smart method
762
    'Repository.tarball', 'bzrlib.smart.repository',
4797.85.32 by John Arbash Meinel
Per request, change
763
    'SmartServerRepositoryTarball', info='read')
764
request_handlers.register_lazy(
6280.5.2 by Jelmer Vernooij
New HPSS call VersionedFileRepository.get_serializer_format.
765
    'VersionedFileRepository.get_serializer_format', 'bzrlib.smart.repository',
6206.1.2 by Jelmer Vernooij
Merge bzr.dev.
766
    'SmartServerRepositoryGetSerializerFormat', info='read')
767
request_handlers.register_lazy(
6282.6.28 by Jelmer Vernooij
Rename VersionedFileRepository.iter_inventories to VersionedFileRepository.get_inventories.
768
    'VersionedFileRepository.get_inventories', 'bzrlib.smart.repository',
769
    'SmartServerRepositoryGetInventories', info='read')
6300.1.2 by Jelmer Vernooij
Add remote side of Repository.reconcile.
770
request_handlers.register_lazy(
4797.85.32 by John Arbash Meinel
Per request, change
771
    'rmdir', 'bzrlib.smart.vfs', 'RmdirRequest', info='semivfs')
772
request_handlers.register_lazy(
773
    'stat', 'bzrlib.smart.vfs', 'StatRequest', info='read')
4797.85.31 by John Arbash Meinel
Categorize all of the requests as safe/unsafe/semi/stream for retrying purposes.
774
request_handlers.register_lazy(
6206.1.2 by Jelmer Vernooij
Merge bzr.dev.
775
    'Transport.is_readonly', 'bzrlib.smart.request',
776
    'SmartServerIsReadonly', info='read')