##// END OF EJS Templates
hooks: made the callback host configurable....
marcink -
r2833:920dbf8a default
parent child Browse files
Show More
@@ -551,6 +551,10 b' vcs.scm_app_implementation = http'
551 ## `http` - use http-rpc backend (default)
551 ## `http` - use http-rpc backend (default)
552 vcs.hooks.protocol = http
552 vcs.hooks.protocol = http
553
553
554 ## Host on which this instance is listening for hooks. If vcsserver is in other location
555 ## this should be adjusted.
556 vcs.hooks.host = 127.0.0.1
557
554 vcs.server.log_level = debug
558 vcs.server.log_level = debug
555 ## Start VCSServer with this instance as a subprocess, usefull for development
559 ## Start VCSServer with this instance as a subprocess, usefull for development
556 vcs.start_server = false
560 vcs.start_server = false
@@ -520,6 +520,9 b' vcs.scm_app_implementation = http'
520 ## Push/Pull operations hooks protocol, available options are:
520 ## Push/Pull operations hooks protocol, available options are:
521 ## `http` - use http-rpc backend (default)
521 ## `http` - use http-rpc backend (default)
522 vcs.hooks.protocol = http
522 vcs.hooks.protocol = http
523 ## Host on which this instance is listening for hooks. If vcsserver is in other location
524 ## this should be adjusted.
525 vcs.hooks.host = 127.0.0.1
523
526
524 vcs.server.log_level = info
527 vcs.server.log_level = info
525 ## Start VCSServer with this instance as a subprocess, usefull for development
528 ## Start VCSServer with this instance as a subprocess, usefull for development
@@ -139,6 +139,7 b' class VcsServer(object):'
139
139
140 callback_daemon, extras = prepare_callback_daemon(
140 callback_daemon, extras = prepare_callback_daemon(
141 extras, protocol=vcs_settings.HOOKS_PROTOCOL,
141 extras, protocol=vcs_settings.HOOKS_PROTOCOL,
142 host=vcs_settings.HOOKS_HOST,
142 use_direct_calls=False)
143 use_direct_calls=False)
143
144
144 with callback_daemon:
145 with callback_daemon:
@@ -401,6 +401,7 b' def _sanitize_vcs_settings(settings):'
401 _string_setting(settings, 'vcs.svn.compatible_version', '')
401 _string_setting(settings, 'vcs.svn.compatible_version', '')
402 _string_setting(settings, 'git_rev_filter', '--all')
402 _string_setting(settings, 'git_rev_filter', '--all')
403 _string_setting(settings, 'vcs.hooks.protocol', 'http')
403 _string_setting(settings, 'vcs.hooks.protocol', 'http')
404 _string_setting(settings, 'vcs.hooks.host', '127.0.0.1')
404 _string_setting(settings, 'vcs.scm_app_implementation', 'http')
405 _string_setting(settings, 'vcs.scm_app_implementation', 'http')
405 _string_setting(settings, 'vcs.server', '')
406 _string_setting(settings, 'vcs.server', '')
406 _string_setting(settings, 'vcs.server.log_level', 'debug')
407 _string_setting(settings, 'vcs.server.log_level', 'debug')
@@ -25,12 +25,13 b' import platform'
25 from rhodecode.model import init_model
25 from rhodecode.model import init_model
26
26
27
27
28
29 def configure_vcs(config):
28 def configure_vcs(config):
30 """
29 """
31 Patch VCS config with some RhodeCode specific stuff
30 Patch VCS config with some RhodeCode specific stuff
32 """
31 """
33 from rhodecode.lib.vcs import conf
32 from rhodecode.lib.vcs import conf
33 import rhodecode.lib.vcs.conf.settings
34
34 conf.settings.BACKENDS = {
35 conf.settings.BACKENDS = {
35 'hg': 'rhodecode.lib.vcs.backends.hg.MercurialRepository',
36 'hg': 'rhodecode.lib.vcs.backends.hg.MercurialRepository',
36 'git': 'rhodecode.lib.vcs.backends.git.GitRepository',
37 'git': 'rhodecode.lib.vcs.backends.git.GitRepository',
@@ -38,6 +39,7 b' def configure_vcs(config):'
38 }
39 }
39
40
40 conf.settings.HOOKS_PROTOCOL = config['vcs.hooks.protocol']
41 conf.settings.HOOKS_PROTOCOL = config['vcs.hooks.protocol']
42 conf.settings.HOOKS_HOST = config['vcs.hooks.host']
41 conf.settings.HOOKS_DIRECT_CALLS = config['vcs.hooks.direct_calls']
43 conf.settings.HOOKS_DIRECT_CALLS = config['vcs.hooks.direct_calls']
42 conf.settings.GIT_REV_FILTER = shlex.split(config['git_rev_filter'])
44 conf.settings.GIT_REV_FILTER = shlex.split(config['git_rev_filter'])
43 conf.settings.DEFAULT_ENCODINGS = config['default_encoding']
45 conf.settings.DEFAULT_ENCODINGS = config['default_encoding']
@@ -119,8 +119,8 b' class ThreadedHookCallbackDaemon(object)'
119 _daemon = None
119 _daemon = None
120 _done = False
120 _done = False
121
121
122 def __init__(self, txn_id=None, port=None):
122 def __init__(self, txn_id=None, host=None, port=None):
123 self._prepare(txn_id=txn_id, port=port)
123 self._prepare(txn_id=txn_id, host=None, port=port)
124
124
125 def __enter__(self):
125 def __enter__(self):
126 self._run()
126 self._run()
@@ -130,7 +130,7 b' class ThreadedHookCallbackDaemon(object)'
130 log.debug('Callback daemon exiting now...')
130 log.debug('Callback daemon exiting now...')
131 self._stop()
131 self._stop()
132
132
133 def _prepare(self, txn_id=None, port=None):
133 def _prepare(self, txn_id=None, host=None, port=None):
134 raise NotImplementedError()
134 raise NotImplementedError()
135
135
136 def _run(self):
136 def _run(self):
@@ -147,17 +147,16 b' class HttpHooksCallbackDaemon(ThreadedHo'
147
147
148 hooks_uri = None
148 hooks_uri = None
149
149
150 IP_ADDRESS = '127.0.0.1'
151
152 # From Python docs: Polling reduces our responsiveness to a shutdown
150 # From Python docs: Polling reduces our responsiveness to a shutdown
153 # request and wastes cpu at all other times.
151 # request and wastes cpu at all other times.
154 POLL_INTERVAL = 0.01
152 POLL_INTERVAL = 0.01
155
153
156 def _prepare(self, txn_id=None, port=None):
154 def _prepare(self, txn_id=None, host=None, port=None):
155 host = host or '127.0.0.1'
157 self._done = False
156 self._done = False
158 self._daemon = TCPServer((self.IP_ADDRESS, port or 0), HooksHttpHandler)
157 self._daemon = TCPServer((host, port or 0), HooksHttpHandler)
159 _, port = self._daemon.server_address
158 _, port = self._daemon.server_address
160 self.hooks_uri = '{}:{}'.format(self.IP_ADDRESS, port)
159 self.hooks_uri = '{}:{}'.format(host, port)
161 self.txn_id = txn_id
160 self.txn_id = txn_id
162 # inject transaction_id for later verification
161 # inject transaction_id for later verification
163 self._daemon.txn_id = self.txn_id
162 self._daemon.txn_id = self.txn_id
@@ -220,7 +219,7 b' def get_txn_id_from_store(txn_id):'
220 return {}
219 return {}
221
220
222
221
223 def prepare_callback_daemon(extras, protocol, use_direct_calls, txn_id=None):
222 def prepare_callback_daemon(extras, protocol, host, use_direct_calls, txn_id=None):
224 txn_details = get_txn_id_from_store(txn_id)
223 txn_details = get_txn_id_from_store(txn_id)
225 port = txn_details.get('port', 0)
224 port = txn_details.get('port', 0)
226 if use_direct_calls:
225 if use_direct_calls:
@@ -228,7 +227,8 b' def prepare_callback_daemon(extras, prot'
228 extras['hooks_module'] = callback_daemon.hooks_module
227 extras['hooks_module'] = callback_daemon.hooks_module
229 else:
228 else:
230 if protocol == 'http':
229 if protocol == 'http':
231 callback_daemon = HttpHooksCallbackDaemon(txn_id=txn_id, port=port)
230 callback_daemon = HttpHooksCallbackDaemon(
231 txn_id=txn_id, host=host, port=port)
232 else:
232 else:
233 log.error('Unsupported callback daemon protocol "%s"', protocol)
233 log.error('Unsupported callback daemon protocol "%s"', protocol)
234 raise Exception('Unsupported callback daemon protocol.')
234 raise Exception('Unsupported callback daemon protocol.')
@@ -663,7 +663,7 b' class SimpleVCS(object):'
663
663
664 return prepare_callback_daemon(
664 return prepare_callback_daemon(
665 extras, protocol=vcs_settings.HOOKS_PROTOCOL,
665 extras, protocol=vcs_settings.HOOKS_PROTOCOL,
666 use_direct_calls=direct_calls, txn_id=txn_id)
666 host=vcs_settings.HOOKS_HOST, use_direct_calls=direct_calls, txn_id=txn_id)
667
667
668
668
669 def _should_check_locking(query_string):
669 def _should_check_locking(query_string):
@@ -51,6 +51,7 b' ARCHIVE_SPECS = {'
51
51
52 HOOKS_PROTOCOL = None
52 HOOKS_PROTOCOL = None
53 HOOKS_DIRECT_CALLS = False
53 HOOKS_DIRECT_CALLS = False
54 HOOKS_HOST = '127.0.0.1'
54
55
55
56
56 def available_aliases():
57 def available_aliases():
@@ -622,6 +622,7 b' class PullRequestModel(BaseModel):'
622
622
623 callback_daemon, extras = prepare_callback_daemon(
623 callback_daemon, extras = prepare_callback_daemon(
624 extras, protocol=vcs_settings.HOOKS_PROTOCOL,
624 extras, protocol=vcs_settings.HOOKS_PROTOCOL,
625 host=vcs_settings.HOOKS_HOST,
625 use_direct_calls=vcs_settings.HOOKS_DIRECT_CALLS)
626 use_direct_calls=vcs_settings.HOOKS_DIRECT_CALLS)
626
627
627 with callback_daemon:
628 with callback_daemon:
@@ -117,6 +117,7 b' class TestSanitizeVcsSettings(object):'
117 ('vcs.svn.compatible_version', ''),
117 ('vcs.svn.compatible_version', ''),
118 ('git_rev_filter', '--all'),
118 ('git_rev_filter', '--all'),
119 ('vcs.hooks.protocol', 'http'),
119 ('vcs.hooks.protocol', 'http'),
120 ('vcs.hooks.host', '127.0.0.1'),
120 ('vcs.scm_app_implementation', 'http'),
121 ('vcs.scm_app_implementation', 'http'),
121 ('vcs.server', ''),
122 ('vcs.server', ''),
122 ('vcs.server.log_level', 'debug'),
123 ('vcs.server.log_level', 'debug'),
@@ -465,6 +465,7 b' class TestPrepareHooksDaemon(object):'
465 prepare_mock.assert_called_once_with(
465 prepare_mock.assert_called_once_with(
466 expected_extras,
466 expected_extras,
467 protocol=app_settings['vcs.hooks.protocol'],
467 protocol=app_settings['vcs.hooks.protocol'],
468 host=app_settings['vcs.hooks.host'],
468 txn_id=None,
469 txn_id=None,
469 use_direct_calls=app_settings['vcs.hooks.direct_calls'])
470 use_direct_calls=app_settings['vcs.hooks.direct_calls'])
470
471
@@ -180,7 +180,7 b' class TestHttpHooksCallbackDaemon(object'
180 assert daemon._daemon == tcp_server
180 assert daemon._daemon == tcp_server
181
181
182 _, port = tcp_server.server_address
182 _, port = tcp_server.server_address
183 expected_uri = '{}:{}'.format(daemon.IP_ADDRESS, port)
183 expected_uri = '{}:{}'.format('127.0.0.1', port)
184 msg = 'Preparing HTTP callback daemon at `{}` and ' \
184 msg = 'Preparing HTTP callback daemon at `{}` and ' \
185 'registering hook object'.format(expected_uri)
185 'registering hook object'.format(expected_uri)
186 assert_message_in_log(
186 assert_message_in_log(
@@ -192,7 +192,7 b' class TestHttpHooksCallbackDaemon(object'
192 daemon = hooks_daemon.HttpHooksCallbackDaemon()
192 daemon = hooks_daemon.HttpHooksCallbackDaemon()
193
193
194 _, port = tcp_server.server_address
194 _, port = tcp_server.server_address
195 expected_uri = '{}:{}'.format(daemon.IP_ADDRESS, port)
195 expected_uri = '{}:{}'.format('127.0.0.1', port)
196 assert daemon.hooks_uri == expected_uri
196 assert daemon.hooks_uri == expected_uri
197
197
198 msg = 'Preparing HTTP callback daemon at `{}` and ' \
198 msg = 'Preparing HTTP callback daemon at `{}` and ' \
@@ -264,7 +264,8 b' class TestPrepareHooksDaemon(object):'
264 self, protocol):
264 self, protocol):
265 expected_extras = {'extra1': 'value1'}
265 expected_extras = {'extra1': 'value1'}
266 callback, extras = hooks_daemon.prepare_callback_daemon(
266 callback, extras = hooks_daemon.prepare_callback_daemon(
267 expected_extras.copy(), protocol=protocol, use_direct_calls=True)
267 expected_extras.copy(), protocol=protocol,
268 host='127.0.0.1', use_direct_calls=True)
268 assert isinstance(callback, hooks_daemon.DummyHooksCallbackDaemon)
269 assert isinstance(callback, hooks_daemon.DummyHooksCallbackDaemon)
269 expected_extras['hooks_module'] = 'rhodecode.lib.hooks_daemon'
270 expected_extras['hooks_module'] = 'rhodecode.lib.hooks_daemon'
270 expected_extras['time'] = extras['time']
271 expected_extras['time'] = extras['time']
@@ -281,7 +282,8 b' class TestPrepareHooksDaemon(object):'
281 'hooks_protocol': protocol.lower()
282 'hooks_protocol': protocol.lower()
282 }
283 }
283 callback, extras = hooks_daemon.prepare_callback_daemon(
284 callback, extras = hooks_daemon.prepare_callback_daemon(
284 expected_extras.copy(), protocol=protocol, use_direct_calls=False,
285 expected_extras.copy(), protocol=protocol, host='127.0.0.1',
286 use_direct_calls=False,
285 txn_id='txnid2')
287 txn_id='txnid2')
286 assert isinstance(callback, expected_class)
288 assert isinstance(callback, expected_class)
287 extras.pop('hooks_uri')
289 extras.pop('hooks_uri')
@@ -301,7 +303,7 b' class TestPrepareHooksDaemon(object):'
301 with pytest.raises(Exception):
303 with pytest.raises(Exception):
302 callback, extras = hooks_daemon.prepare_callback_daemon(
304 callback, extras = hooks_daemon.prepare_callback_daemon(
303 expected_extras.copy(),
305 expected_extras.copy(),
304 protocol=protocol,
306 protocol=protocol, host='127.0.0.1',
305 use_direct_calls=False)
307 use_direct_calls=False)
306
308
307
309
@@ -177,6 +177,7 b' def ini_config(request, tmpdir_factory, '
177 'vcs.server.protocol': 'http',
177 'vcs.server.protocol': 'http',
178 'vcs.scm_app_implementation': 'http',
178 'vcs.scm_app_implementation': 'http',
179 'vcs.hooks.protocol': 'http',
179 'vcs.hooks.protocol': 'http',
180 'vcs.hooks.host': '127.0.0.1',
180 }},
181 }},
181
182
182 {'handler_console': {
183 {'handler_console': {
@@ -521,6 +521,7 b' vcs.scm_app_implementation = http'
521 ## Push/Pull operations hooks protocol, available options are:
521 ## Push/Pull operations hooks protocol, available options are:
522 ## `http` - use http-rpc backend (default)
522 ## `http` - use http-rpc backend (default)
523 vcs.hooks.protocol = http
523 vcs.hooks.protocol = http
524 vcs.hooks.host = 127.0.0.1
524
525
525 vcs.server.log_level = debug
526 vcs.server.log_level = debug
526 ## Start VCSServer with this instance as a subprocess, usefull for development
527 ## Start VCSServer with this instance as a subprocess, usefull for development
General Comments 0
You need to be logged in to leave comments. Login now