26
from ...hooks import Hooks
28
from bzrlib.hooks import Hooks
30
32
transport as _mod_transport,
32
from ...i18n import gettext
33
from ...lazy_import import lazy_import
34
from bzrlib.i18n import gettext
35
from bzrlib.lazy_import import lazy_import
34
36
lazy_import(globals(), """
35
from breezy.bzr.smart import (
37
from bzrlib.smart import (
39
from breezy.transport import (
41
from bzrlib.transport import (
100
102
self._socket_error = socket_error
101
103
self._socket_timeout = socket_timeout
102
104
addrs = socket.getaddrinfo(host, port, socket.AF_UNSPEC,
103
socket.SOCK_STREAM, 0, socket.AI_PASSIVE)[0]
105
socket.SOCK_STREAM, 0, socket.AI_PASSIVE)[0]
105
107
(family, socktype, proto, canonname, sockaddr) = addrs
108
110
# SO_REUSERADDR has a different meaning on Windows
109
111
if sys.platform != 'win32':
110
112
self._server_socket.setsockopt(socket.SOL_SOCKET,
111
socket.SO_REUSEADDR, 1)
113
socket.SO_REUSEADDR, 1)
113
115
self._server_socket.bind(sockaddr)
114
except self._socket_error as message:
116
except self._socket_error, message:
115
117
raise errors.CannotBindAddress(host, port, message)
116
118
self._sockname = self._server_socket.getsockname()
117
119
self.port = self._sockname[1]
286
288
def start_background_thread(self, thread_name_suffix=''):
287
289
self._started.clear()
288
290
self._server_thread = threading.Thread(None,
290
thread_name_suffix,),
291
name='server-' + self.get_url())
291
self.serve, args=(thread_name_suffix,),
292
name='server-' + self.get_url())
292
293
self._server_thread.setDaemon(True)
293
294
self._server_thread.start()
294
295
self._started.wait()
328
329
These are all empty initially, because by default nothing should get
331
Hooks.__init__(self, "breezy.bzr.smart.server", "SmartTCPServer.hooks")
332
Hooks.__init__(self, "bzrlib.smart.server", "SmartTCPServer.hooks")
332
333
self.add_hook('server_started',
333
"Called by the bzr server when it starts serving a directory. "
334
"server_started is called with (backing urls, public url), "
335
"where backing_url is a list of URLs giving the "
336
"server-specific directory locations, and public_url is the "
337
"public URL for the directory being served.", (0, 16))
334
"Called by the bzr server when it starts serving a directory. "
335
"server_started is called with (backing urls, public url), "
336
"where backing_url is a list of URLs giving the "
337
"server-specific directory locations, and public_url is the "
338
"public URL for the directory being served.", (0, 16))
338
339
self.add_hook('server_started_ex',
339
"Called by the bzr server when it starts serving a directory. "
340
"server_started is called with (backing_urls, server_obj).",
340
"Called by the bzr server when it starts serving a directory. "
341
"server_started is called with (backing_urls, server_obj).",
342
343
self.add_hook('server_stopped',
343
"Called by the bzr server when it stops serving a directory. "
344
"server_stopped is called with the same parameters as the "
345
"server_started hook: (backing_urls, public_url).", (0, 16))
344
"Called by the bzr server when it stops serving a directory. "
345
"server_stopped is called with the same parameters as the "
346
"server_started hook: (backing_urls, public_url).", (0, 16))
346
347
self.add_hook('server_exception',
347
"Called by the bzr server when an exception occurs. "
348
"server_exception is called with the sys.exc_info() tuple "
349
"return true for the hook if the exception has been handled, "
350
"in which case the server will exit normally.", (2, 4))
348
"Called by the bzr server when an exception occurs. "
349
"server_exception is called with the sys.exc_info() tuple "
350
"return true for the hook if the exception has been handled, "
351
"in which case the server will exit normally.", (2, 4))
353
353
SmartTCPServer.hooks = SmartServerHooks()
356
356
def _local_path_for_transport(transport):
357
357
"""Return a local path for transport, if reasonably possible.
359
359
This function works even if transport's url has a "readonly+" prefix,
360
360
unlike local_path_from_url.
362
362
This essentially recovers the --directory argument the user passed to "bzr
363
363
serve" from the transport passed to serve_bzr.
420
420
chroot_server = chroot.ChrootServer(transport)
421
421
chroot_server.start_server()
422
422
self.cleanups.append(chroot_server.stop_server)
423
transport = _mod_transport.get_transport_from_url(
424
chroot_server.get_url())
423
transport = _mod_transport.get_transport_from_url(chroot_server.get_url())
425
424
if self.base_path is not None:
426
425
# Decorate the server's backing transport with a filter that can
427
426
# expand homedirs.
428
427
expand_userdirs = self._make_expand_userdirs_filter(transport)
429
428
expand_userdirs.start_server()
430
429
self.cleanups.append(expand_userdirs.stop_server)
431
transport = _mod_transport.get_transport_from_url(
432
expand_userdirs.get_url())
430
transport = _mod_transport.get_transport_from_url(expand_userdirs.get_url())
433
431
self.transport = transport
435
433
def _get_stdin_stdout(self):
436
return sys.stdin.buffer, sys.stdout.buffer
434
return sys.stdin, sys.stdout
438
436
def _make_smart_server(self, host, port, inet, timeout):
439
437
if timeout is None:
451
449
smart_server = SmartTCPServer(self.transport,
452
450
client_timeout=timeout)
453
451
smart_server.start_server(host, port)
454
trace.note(gettext('listening on port: %s'),
455
str(smart_server.port))
452
trace.note(gettext('listening on port: %s') % smart_server.port)
456
453
self.smart_server = smart_server
458
455
def _change_globals(self):
459
from breezy import lockdir, ui
456
from bzrlib import lockdir, ui
460
457
# For the duration of this server, no UI output is permitted. note
461
458
# that this may cause problems with blackbox tests. This should be
462
459
# changed with care though, as we dont want to use bandwidth sending
463
460
# progress over stderr to smart server clients!
464
461
old_factory = ui.ui_factory
465
462
old_lockdir_timeout = lockdir._DEFAULT_TIMEOUT_SECONDS
467
463
def restore_default_ui_factory_and_lockdir_timeout():
468
464
ui.ui_factory = old_factory
469
465
lockdir._DEFAULT_TIMEOUT_SECONDS = old_lockdir_timeout