diff --git a/configs/development.ini b/configs/development.ini --- a/configs/development.ini +++ b/configs/development.ini @@ -645,9 +645,10 @@ vcs.scm_app_implementation = http ; `http` - use http-rpc backend (default) vcs.hooks.protocol = http -; Host on which this instance is listening for hooks. If vcsserver is in other location -; this should be adjusted. -vcs.hooks.host = 127.0.0.1 +; Host on which this instance is listening for hooks. vcsserver will call this host to pull/push hooks so it should be +; accessible via network. +; Use vcs.hooks.host = "*" to bind to current hostname (for Docker) +vcs.hooks.host = * ; Start VCSServer with this instance as a subprocess, useful for development vcs.start_server = false diff --git a/configs/production.ini b/configs/production.ini --- a/configs/production.ini +++ b/configs/production.ini @@ -596,9 +596,10 @@ vcs.scm_app_implementation = http ; `http` - use http-rpc backend (default) vcs.hooks.protocol = http -; Host on which this instance is listening for hooks. If vcsserver is in other location -; this should be adjusted. -vcs.hooks.host = 127.0.0.1 +; Host on which this instance is listening for hooks. vcsserver will call this host to pull/push hooks so it should be +; accessible via network. +; Use vcs.hooks.host = "*" to bind to current hostname (for Docker) +vcs.hooks.host = * ; Start VCSServer with this instance as a subprocess, useful for development vcs.start_server = false diff --git a/rhodecode/lib/hooks_daemon.py b/rhodecode/lib/hooks_daemon.py --- a/rhodecode/lib/hooks_daemon.py +++ b/rhodecode/lib/hooks_daemon.py @@ -153,18 +153,23 @@ class HttpHooksCallbackDaemon(ThreadedHo # request and wastes cpu at all other times. POLL_INTERVAL = 0.01 + def get_hostname(self): + return socket.gethostname() or '127.0.0.1' + def get_available_port(self): mysocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - mysocket.bind(('127.0.0.1', 0)) + mysocket.bind((self.get_hostname(), 0)) port = mysocket.getsockname()[1] mysocket.close() del mysocket return port def _prepare(self, txn_id=None, host=None, port=None): + if not host or host == "*": + host = self.get_hostname() + if not port: + port = self.get_available_port() - host = host or '127.0.0.1' - port = port or self.get_available_port() server_address = (host, port) self.hooks_uri = '{}:{}'.format(host, port) self.txn_id = txn_id diff --git a/rhodecode/tests/lib/test_hooks_daemon.py b/rhodecode/tests/lib/test_hooks_daemon.py --- a/rhodecode/tests/lib/test_hooks_daemon.py +++ b/rhodecode/tests/lib/test_hooks_daemon.py @@ -175,29 +175,39 @@ class ThreadedHookCallbackDaemon(object) class TestHttpHooksCallbackDaemon(object): + def test_hooks_callback_generates_new_port(self, caplog): + with caplog.at_level(logging.DEBUG): + daemon = hooks_daemon.HttpHooksCallbackDaemon(host='127.0.0.1', port=8881) + assert daemon._daemon.server_address == ('127.0.0.1', 8881) + + with caplog.at_level(logging.DEBUG): + daemon = hooks_daemon.HttpHooksCallbackDaemon(host=None, port=None) + assert daemon._daemon.server_address[1] in range(0, 66000) + assert daemon._daemon.server_address[0] != '127.0.0.1' + def test_prepare_inits_daemon_variable(self, tcp_server, caplog): with self._tcp_patcher(tcp_server), caplog.at_level(logging.DEBUG): - daemon = hooks_daemon.HttpHooksCallbackDaemon() + daemon = hooks_daemon.HttpHooksCallbackDaemon(host='127.0.0.1', port=8881) assert daemon._daemon == tcp_server _, port = tcp_server.server_address expected_uri = '{}:{}'.format('127.0.0.1', port) msg = 'Preparing HTTP callback daemon at `{}` and ' \ - 'registering hook object'.format(expected_uri) + 'registering hook object: rhodecode.lib.hooks_daemon.HooksHttpHandler'.format(expected_uri) assert_message_in_log( caplog.records, msg, levelno=logging.DEBUG, module='hooks_daemon') def test_prepare_inits_hooks_uri_and_logs_it( self, tcp_server, caplog): with self._tcp_patcher(tcp_server), caplog.at_level(logging.DEBUG): - daemon = hooks_daemon.HttpHooksCallbackDaemon() + daemon = hooks_daemon.HttpHooksCallbackDaemon(host='127.0.0.1', port=8881) _, port = tcp_server.server_address expected_uri = '{}:{}'.format('127.0.0.1', port) assert daemon.hooks_uri == expected_uri msg = 'Preparing HTTP callback daemon at `{}` and ' \ - 'registering hook object'.format(expected_uri) + 'registering hook object: rhodecode.lib.hooks_daemon.HooksHttpHandler'.format(expected_uri) assert_message_in_log( caplog.records, msg, levelno=logging.DEBUG, module='hooks_daemon') diff --git a/rhodecode/tests/rhodecode.ini b/rhodecode/tests/rhodecode.ini --- a/rhodecode/tests/rhodecode.ini +++ b/rhodecode/tests/rhodecode.ini @@ -494,7 +494,7 @@ vcs.hooks.protocol = http ; Host on which this instance is listening for hooks. If vcsserver is in other location ; this should be adjusted. -vcs.hooks.host = 127.0.0.1 +vcs.hooks.host = * ; Start VCSServer with this instance as a subprocess, useful for development vcs.start_server = false