##// END OF EJS Templates
core: removed pyro4 from Enterprise code. Fixes #5198
marcink -
r1409:c1ce56be default
parent child Browse files
Show More
@@ -539,18 +539,15 b' vcs.server = localhost:9900'
539 539
540 540 ## Web server connectivity protocol, responsible for web based VCS operatations
541 541 ## Available protocols are:
542 ## `pyro4` - use pyro4 server
543 542 ## `http` - use http-rpc backend (default)
544 543 vcs.server.protocol = http
545 544
546 545 ## Push/Pull operations protocol, available options are:
547 ## `pyro4` - use pyro4 server
548 546 ## `http` - use http-rpc backend (default)
549 547 ##
550 548 vcs.scm_app_implementation = http
551 549
552 550 ## Push/Pull operations hooks protocol, available options are:
553 ## `pyro4` - use pyro4 server
554 551 ## `http` - use http-rpc backend (default)
555 552 vcs.hooks.protocol = http
556 553
@@ -666,7 +663,7 b' formatter = color_formatter_sql'
666 663 ################
667 664
668 665 [formatter_generic]
669 class = rhodecode.lib.logging_formatter.Pyro4AwareFormatter
666 class = rhodecode.lib.logging_formatter.ExceptionAwareFormatter
670 667 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
671 668 datefmt = %Y-%m-%d %H:%M:%S
672 669
@@ -508,18 +508,15 b' vcs.server = localhost:9900'
508 508
509 509 ## Web server connectivity protocol, responsible for web based VCS operatations
510 510 ## Available protocols are:
511 ## `pyro4` - use pyro4 server
512 511 ## `http` - use http-rpc backend (default)
513 512 vcs.server.protocol = http
514 513
515 514 ## Push/Pull operations protocol, available options are:
516 ## `pyro4` - use pyro4 server
517 515 ## `http` - use http-rpc backend (default)
518 516 ##
519 517 vcs.scm_app_implementation = http
520 518
521 519 ## Push/Pull operations hooks protocol, available options are:
522 ## `pyro4` - use pyro4 server
523 520 ## `http` - use http-rpc backend (default)
524 521 vcs.hooks.protocol = http
525 522
@@ -635,7 +632,7 b' formatter = generic'
635 632 ################
636 633
637 634 [formatter_generic]
638 class = rhodecode.lib.logging_formatter.Pyro4AwareFormatter
635 class = rhodecode.lib.logging_formatter.ExceptionAwareFormatter
639 636 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
640 637 datefmt = %Y-%m-%d %H:%M:%S
641 638
@@ -17,7 +17,6 b' implemented in :mod:`rhodecode.lib.middl'
17 17 .. toctree::
18 18 :maxdepth: 2
19 19
20 http-transition
21 20 middleware
22 21 vcsserver
23 22 subversion
@@ -47,7 +47,7 b' the ``debug`` level.'
47 47 ### LOGGING CONFIGURATION ####
48 48 ################################
49 49 [loggers]
50 keys = root, routes, rhodecode, sqlalchemy, beaker, pyro4, templates
50 keys = root, routes, rhodecode, sqlalchemy, beaker, templates
51 51
52 52 [handlers]
53 53 keys = console, console_sql, file, file_rotating
@@ -75,12 +75,6 b' the ``debug`` level.'
75 75 qualname = beaker.container
76 76 propagate = 1
77 77
78 [logger_pyro4]
79 level = DEBUG
80 handlers =
81 qualname = Pyro4
82 propagate = 1
83
84 78 [logger_templates]
85 79 level = INFO
86 80 handlers =
@@ -232,7 +232,7 b' For a more detailed explanation of the l'
232 232 ### LOGGING CONFIGURATION ####
233 233 ################################
234 234 [loggers]
235 keys = root, vcsserver, pyro4, beaker
235 keys = root, vcsserver, beaker
236 236
237 237 [handlers]
238 238 keys = console
@@ -259,12 +259,6 b' For a more detailed explanation of the l'
259 259 qualname = beaker
260 260 propagate = 1
261 261
262 [logger_pyro4]
263 level = DEBUG
264 handlers =
265 qualname = Pyro4
266 propagate = 1
267
268 262
269 263 ##############
270 264 ## HANDLERS ##
@@ -197,19 +197,6 b''
197 197 license = [ pkgs.lib.licenses.bsdOriginal ];
198 198 };
199 199 };
200 Pyro4 = super.buildPythonPackage {
201 name = "Pyro4-4.41";
202 buildInputs = with self; [];
203 doCheck = false;
204 propagatedBuildInputs = with self; [serpent];
205 src = fetchurl {
206 url = "https://pypi.python.org/packages/56/2b/89b566b4bf3e7f8ba790db2d1223852f8cb454c52cab7693dd41f608ca2a/Pyro4-4.41.tar.gz";
207 md5 = "ed69e9bfafa9c06c049a87cb0c4c2b6c";
208 };
209 meta = {
210 license = [ pkgs.lib.licenses.mit ];
211 };
212 };
213 200 Routes = super.buildPythonPackage {
214 201 name = "Routes-1.13";
215 202 buildInputs = with self; [];
@@ -1501,7 +1488,7 b''
1501 1488 name = "rhodecode-enterprise-ce-4.7.0";
1502 1489 buildInputs = with self; [pytest py pytest-cov pytest-sugar pytest-runner pytest-catchlog pytest-profiling gprof2dot pytest-timeout mock WebTest cov-core coverage cssselect lxml configobj];
1503 1490 doCheck = true;
1504 propagatedBuildInputs = with self; [Babel Beaker FormEncode Mako Markdown MarkupSafe MySQL-python Paste PasteDeploy PasteScript Pygments pygments-markdown-lexer Pylons Pyro4 Routes SQLAlchemy Tempita URLObject WebError WebHelpers WebHelpers2 WebOb WebTest Whoosh alembic amqplib anyjson appenlight-client authomatic backport-ipaddress celery channelstream colander decorator deform docutils gevent gunicorn infrae.cache ipython iso8601 kombu msgpack-python packaging psycopg2 py-gfm pycrypto pycurl pyparsing pyramid pyramid-debugtoolbar pyramid-mako pyramid-beaker pysqlite python-dateutil python-ldap python-memcached python-pam recaptcha-client repoze.lru requests simplejson subprocess32 waitress zope.cachedescriptors dogpile.cache dogpile.core psutil py-bcrypt];
1491 propagatedBuildInputs = with self; [Babel Beaker FormEncode Mako Markdown MarkupSafe MySQL-python Paste PasteDeploy PasteScript Pygments pygments-markdown-lexer Pylons Routes SQLAlchemy Tempita URLObject WebError WebHelpers WebHelpers2 WebOb WebTest Whoosh alembic amqplib anyjson appenlight-client authomatic backport-ipaddress celery channelstream colander decorator deform docutils gevent gunicorn infrae.cache ipython iso8601 kombu msgpack-python packaging psycopg2 py-gfm pycrypto pycurl pyparsing pyramid pyramid-debugtoolbar pyramid-mako pyramid-beaker pysqlite python-dateutil python-ldap python-memcached python-pam recaptcha-client repoze.lru requests simplejson subprocess32 waitress zope.cachedescriptors dogpile.cache dogpile.core psutil py-bcrypt];
1505 1492 src = ./.;
1506 1493 meta = {
1507 1494 license = [ { fullName = "Affero GNU General Public License v3 or later (AGPLv3+)"; } { fullName = "AGPLv3, and Commercial License"; } ];
@@ -1520,19 +1507,6 b''
1520 1507 license = [ { fullName = "AGPLv3 and Proprietary"; } ];
1521 1508 };
1522 1509 };
1523 serpent = super.buildPythonPackage {
1524 name = "serpent-1.15";
1525 buildInputs = with self; [];
1526 doCheck = false;
1527 propagatedBuildInputs = with self; [];
1528 src = fetchurl {
1529 url = "https://pypi.python.org/packages/7b/38/b2b27673a882ff2ea5871bb3e3e6b496ebbaafd1612e51990ffb158b9254/serpent-1.15.tar.gz";
1530 md5 = "e27b1aad5c218e16442f52abb7c7053a";
1531 };
1532 meta = {
1533 license = [ pkgs.lib.licenses.mit ];
1534 };
1535 };
1536 1510 setproctitle = super.buildPythonPackage {
1537 1511 name = "setproctitle-1.1.8";
1538 1512 buildInputs = with self; [];
@@ -2,7 +2,6 b''
2 2 testpaths = ./rhodecode
3 3 pylons_config = rhodecode/tests/rhodecode.ini
4 4 vcsserver_protocol = http
5 vcsserver_config_pyro4 = rhodecode/tests/vcsserver_pyro4.ini
6 5 vcsserver_config_http = rhodecode/tests/vcsserver_http.ini
7 6 norecursedirs = tests/scripts
8 7 addopts = -k "not _BaseTest"
@@ -123,9 +123,5 b' https://code.rhodecode.com/rhodecode-too'
123 123 ## appenlight
124 124 appenlight-client==0.6.14
125 125
126 # Pyro/Deprecated TODO(Marcink): remove in 4.7 release.
127 Pyro4==4.41
128 serpent==1.15
129
130 126 ## test related requirements
131 127 -r requirements_test.txt
@@ -184,7 +184,6 b' def load_pyramid_environment(global_conf'
184 184 protocol=utils.get_vcs_server_protocol(settings),
185 185 log_level=settings['vcs.server.log_level'])
186 186
187 utils.configure_pyro4(settings)
188 187 utils.configure_vcs(settings)
189 188 if vcs_server_enabled:
190 189 connect_vcs(vcs_server_uri, utils.get_vcs_server_protocol(settings))
@@ -41,9 +41,6 b''
41 41 "python2.7-Pylons-1.0.1-patch1": {
42 42 "BSD 4-clause \"Original\" or \"Old\" License": "http://spdx.org/licenses/BSD-4-Clause"
43 43 },
44 "python2.7-Pyro4-4.35": {
45 "MIT License": "http://spdx.org/licenses/MIT"
46 },
47 44 "python2.7-Routes-1.13": {
48 45 "BSD 4-clause \"Original\" or \"Old\" License": "http://spdx.org/licenses/BSD-4-Clause"
49 46 },
@@ -215,9 +212,6 b''
215 212 "python2.7-requests-2.9.1": {
216 213 "Apache License 2.0": "http://spdx.org/licenses/Apache-2.0"
217 214 },
218 "python2.7-serpent-1.12": {
219 "MIT License": "http://spdx.org/licenses/MIT"
220 },
221 215 "python2.7-setuptools-19.4": {
222 216 "Python Software Foundation License version 2": "http://spdx.org/licenses/Python-2.0",
223 217 "Zope Public License 2.0": "http://spdx.org/licenses/ZPL-2.0"
@@ -20,29 +20,11 b''
20 20
21 21 import os
22 22 import shlex
23 import Pyro4
24 23 import platform
25 24
26 25 from rhodecode.model import init_model
27 26
28 27
29 def configure_pyro4(config):
30 """
31 Configure Pyro4 based on `config`.
32
33 This will mainly set the different configuration parameters of the Pyro4
34 library based on the settings in our INI files. The Pyro4 documentation
35 lists more details about the specific settings and their meaning.
36 """
37 Pyro4.config.COMMTIMEOUT = float(config['vcs.connection_timeout'])
38 Pyro4.config.SERIALIZER = 'pickle'
39 Pyro4.config.SERIALIZERS_ACCEPTED.add('pickle')
40
41 # Note: We need server configuration in the WSGI processes
42 # because we provide a callback server in certain vcs operations.
43 Pyro4.config.SERVERTYPE = "multiplex"
44 Pyro4.config.POLLTIMEOUT = 0.01
45
46 28
47 29 def configure_vcs(config):
48 30 """
@@ -226,7 +226,6 b' def vcsconnection(func):'
226 226 for alias in rhodecode.BACKENDS.keys():
227 227 if alias not in backends:
228 228 del rhodecode.BACKENDS[alias]
229 utils.configure_pyro4(settings)
230 229 utils.configure_vcs(settings)
231 230 connect_vcs(
232 231 settings['vcs.server'],
@@ -26,7 +26,6 b' from BaseHTTPServer import BaseHTTPReque'
26 26 from SocketServer import TCPServer
27 27 from routes.util import URLGenerator
28 28
29 import Pyro4
30 29 import pylons
31 30 import rhodecode
32 31
@@ -73,7 +72,7 b' class HooksHttpHandler(BaseHTTPRequestHa'
73 72
74 73 def log_message(self, format, *args):
75 74 """
76 This is an overriden method of BaseHTTPRequestHandler which logs using
75 This is an overridden method of BaseHTTPRequestHandler which logs using
77 76 logging library instead of writing directly to stderr.
78 77 """
79 78
@@ -123,38 +122,6 b' class ThreadedHookCallbackDaemon(object)'
123 122 raise NotImplementedError()
124 123
125 124
126 class Pyro4HooksCallbackDaemon(ThreadedHookCallbackDaemon):
127 """
128 Context manager which will run a callback daemon in a background thread.
129 """
130
131 hooks_uri = None
132
133 def _prepare(self):
134 log.debug("Preparing callback daemon and registering hook object")
135 self._daemon = Pyro4.Daemon()
136 hooks_interface = Hooks()
137 self.hooks_uri = str(self._daemon.register(hooks_interface))
138 log.debug("Hooks uri is: %s", self.hooks_uri)
139
140 def _run(self):
141 log.debug("Running event loop of callback daemon in background thread")
142 callback_thread = threading.Thread(
143 target=self._daemon.requestLoop,
144 kwargs={'loopCondition': lambda: not self._done})
145 callback_thread.daemon = True
146 callback_thread.start()
147 self._callback_thread = callback_thread
148
149 def _stop(self):
150 log.debug("Waiting for background thread to finish.")
151 self._done = True
152 self._callback_thread.join()
153 self._daemon.close()
154 self._daemon = None
155 self._callback_thread = None
156
157
158 125 class HttpHooksCallbackDaemon(ThreadedHookCallbackDaemon):
159 126 """
160 127 Context manager which will run a callback daemon in a background thread.
@@ -202,9 +169,7 b' def prepare_callback_daemon(extras, prot'
202 169 callback_daemon = DummyHooksCallbackDaemon()
203 170 extras['hooks_module'] = callback_daemon.hooks_module
204 171 else:
205 if protocol == 'pyro4':
206 callback_daemon = Pyro4HooksCallbackDaemon()
207 elif protocol == 'http':
172 if protocol == 'http':
208 173 callback_daemon = HttpHooksCallbackDaemon()
209 174 else:
210 175 log.error('Unsupported callback daemon protocol "%s"', protocol)
@@ -221,27 +186,22 b' class Hooks(object):'
221 186 Exposes the hooks for remote call backs
222 187 """
223 188
224 @Pyro4.callback
225 189 def repo_size(self, extras):
226 190 log.debug("Called repo_size of Hooks object")
227 191 return self._call_hook(hooks_base.repo_size, extras)
228 192
229 @Pyro4.callback
230 193 def pre_pull(self, extras):
231 194 log.debug("Called pre_pull of Hooks object")
232 195 return self._call_hook(hooks_base.pre_pull, extras)
233 196
234 @Pyro4.callback
235 197 def post_pull(self, extras):
236 198 log.debug("Called post_pull of Hooks object")
237 199 return self._call_hook(hooks_base.post_pull, extras)
238 200
239 @Pyro4.callback
240 201 def pre_push(self, extras):
241 202 log.debug("Called pre_push of Hooks object")
242 203 return self._call_hook(hooks_base.pre_push, extras)
243 204
244 @Pyro4.callback
245 205 def post_push(self, extras):
246 206 log.debug("Called post_push of Hooks object")
247 207 return self._call_hook(hooks_base.post_push, extras)
@@ -67,9 +67,9 b' def format_sql(sql):'
67 67 return sql
68 68
69 69
70 class Pyro4AwareFormatter(logging.Formatter):
70 class ExceptionAwareFormatter(logging.Formatter):
71 71 """
72 Extended logging formatter which prints out Pyro4 remote tracebacks.
72 Extended logging formatter which prints out remote tracebacks.
73 73 """
74 74
75 75 def formatException(self, ei):
@@ -86,10 +86,12 b' class Pyro4AwareFormatter(logging.Format'
86 86
87 87 try:
88 88 if ex_type is not None and ex_value is None and ex_tb is None:
89 # possible old (3.x) call syntax where caller is only providing exception object
89 # possible old (3.x) call syntax where caller is only
90 # providing exception object
90 91 if type(ex_type) is not type:
91 92 raise TypeError(
92 "invalid argument: ex_type should be an exception type, or just supply no arguments at all")
93 "invalid argument: ex_type should be an exception "
94 "type, or just supply no arguments at all")
93 95 if ex_type is None and ex_tb is None:
94 96 ex_type, ex_value, ex_tb = sys.exc_info()
95 97
@@ -105,7 +107,7 b' class Pyro4AwareFormatter(logging.Format'
105 107 return local_tb
106 108
107 109
108 class ColorFormatter(Pyro4AwareFormatter):
110 class ColorFormatter(ExceptionAwareFormatter):
109 111
110 112 def format(self, record):
111 113 """
@@ -134,3 +136,6 b' class ColorFormatterSql(logging.Formatte'
134 136
135 137 colored_record = ''.join([start, def_record, end])
136 138 return colored_record
139
140 # marcink: needs to stay with this name for backward .ini compatability
141 Pyro4AwareFormatter = ExceptionAwareFormatter
@@ -42,7 +42,7 b' from rhodecode.lib.exceptions import ('
42 42 NotAllowedToCreateUserError)
43 43 from rhodecode.lib.hooks_daemon import prepare_callback_daemon
44 44 from rhodecode.lib.middleware import appenlight
45 from rhodecode.lib.middleware.utils import scm_app, scm_app_http
45 from rhodecode.lib.middleware.utils import scm_app_http
46 46 from rhodecode.lib.utils import (
47 47 is_valid_repo, get_rhodecode_realm, get_rhodecode_base_path, SLUG_RE)
48 48 from rhodecode.lib.utils2 import safe_str, fix_PATH, str2bool, safe_unicode
@@ -177,9 +177,6 b' class SimpleVCS(object):'
177 177 if custom_implementation == 'http':
178 178 log.info('Using HTTP implementation of scm app.')
179 179 scm_app_impl = scm_app_http
180 elif custom_implementation == 'pyro4':
181 log.info('Using Pyro implementation of scm app.')
182 scm_app_impl = scm_app
183 180 else:
184 181 log.info('Using custom implementation of scm_app: "{}"'.format(
185 182 custom_implementation))
@@ -512,7 +509,7 b' class SimpleVCS(object):'
512 509 raise NotImplementedError()
513 510
514 511 def _create_config(self, extras, repo_name):
515 """Create a Pyro safe config representation."""
512 """Create a safe config representation."""
516 513 raise NotImplementedError()
517 514
518 515 def _prepare_callback_daemon(self, extras):
@@ -42,7 +42,7 b' def create_git_wsgi_app(repo_path, repo_'
42 42 """
43 43 factory = GIT_REMOTE_WSGI
44 44 if not factory:
45 log.error('Pyro server has not been initialized yet')
45 log.error('VCSServer has not been initialized yet')
46 46
47 47 return wsgi_app_caller_client.RemoteAppCaller(
48 48 factory, repo_path, repo_name, config)
@@ -57,7 +57,7 b' def create_hg_wsgi_app(repo_path, repo_n'
57 57 """
58 58 factory = HG_REMOTE_WSGI
59 59 if not factory:
60 log.error('Pyro server has not been initialized yet')
60 log.error('VCSServer has not been initialized yet')
61 61
62 62 return wsgi_app_caller_client.RemoteAppCaller(
63 63 factory, repo_path, repo_name, config)
@@ -24,8 +24,6 b' Utility to call a WSGI app wrapped in a '
24 24
25 25 import logging
26 26
27 from Pyro4.errors import ConnectionClosedError
28
29 27
30 28 log = logging.getLogger(__name__)
31 29
@@ -83,12 +81,6 b' class RemoteAppCaller(object):'
83 81 input_data = environ['wsgi.input'].read()
84 82 clean_environ = _get_clean_environ(environ)
85 83
86 try:
87 data, status, headers = self._remote_wsgi.handle(
88 clean_environ, input_data, *self._args, **self._kwargs)
89 except ConnectionClosedError:
90 log.debug('Remote Pyro Server ConnectionClosedError')
91 self._remote_wsgi._pyroReconnect(tries=15)
92 84 data, status, headers = self._remote_wsgi.handle(
93 85 clean_environ, input_data, *self._args, **self._kwargs)
94 86
@@ -216,8 +216,6 b' class VCSMiddleware(object):'
216 216 vcs_handler.SCM):
217 217 return HTTPNotFound()(environ, start_response)
218 218
219 # TODO: johbo: Needed for the Pyro4 backend and Mercurial only.
220 # Remove once we fully switched to the HTTP backend.
221 219 environ['REPO_NAME'] = vcs_handler.url_repo_name
222 220
223 221 # register repo config back to the handler
@@ -40,8 +40,6 b' import time'
40 40 import urlparse
41 41 from cStringIO import StringIO
42 42
43 import Pyro4
44 from Pyro4.errors import CommunicationError
45 43
46 44 from rhodecode.lib.vcs.conf import settings
47 45 from rhodecode.lib.vcs.backends import get_vcs_instance, get_backend
@@ -72,36 +70,6 b' def get_version():'
72 70 return '.'.join((str(each) for each in VERSION[:3]))
73 71
74 72
75 def connect_pyro4(server_and_port):
76 from rhodecode.lib.vcs import connection, client
77 from rhodecode.lib.middleware.utils import scm_app
78
79 git_remote = client.RequestScopeProxyFactory(
80 settings.pyro_remote(settings.PYRO_GIT, server_and_port))
81 hg_remote = client.RequestScopeProxyFactory(
82 settings.pyro_remote(settings.PYRO_HG, server_and_port))
83 svn_remote = client.RequestScopeProxyFactory(
84 settings.pyro_remote(settings.PYRO_SVN, server_and_port))
85
86 connection.Git = client.RepoMaker(proxy_factory=git_remote)
87 connection.Hg = client.RepoMaker(proxy_factory=hg_remote)
88 connection.Svn = client.RepoMaker(proxy_factory=svn_remote)
89
90 scm_app.GIT_REMOTE_WSGI = Pyro4.Proxy(
91 settings.pyro_remote(
92 settings.PYRO_GIT_REMOTE_WSGI, server_and_port))
93 scm_app.HG_REMOTE_WSGI = Pyro4.Proxy(
94 settings.pyro_remote(
95 settings.PYRO_HG_REMOTE_WSGI, server_and_port))
96
97 @atexit.register
98 def free_connection_resources():
99 connection.Git = None
100 connection.Hg = None
101 connection.Svn = None
102 connection.Service = None
103
104
105 73 def connect_http(server_and_port):
106 74 from rhodecode.lib.vcs import connection, client_http
107 75 from rhodecode.lib.middleware.utils import scm_app
@@ -135,11 +103,9 b' def connect_vcs(server_and_port, protoco'
135 103 Initializes the connection to the vcs server.
136 104
137 105 :param server_and_port: str, e.g. "localhost:9900"
138 :param protocol: str, "pyro4" or "http"
106 :param protocol: str or "http"
139 107 """
140 if protocol == 'pyro4':
141 connect_pyro4(server_and_port)
142 elif protocol == 'http':
108 if protocol == 'http':
143 109 connect_http(server_and_port)
144 110 else:
145 111 raise Exception('Invalid vcs server protocol "{}"'.format(protocol))
@@ -154,31 +120,10 b' def start_vcs_server(server_and_port, pr'
154 120 log.info('Starting VCSServer as a sub process with %s protocol', protocol)
155 121 if protocol == 'http':
156 122 return _start_http_vcs_server(server_and_port, log_level)
157 elif protocol == 'pyro4':
158 return _start_pyro4_vcs_server(server_and_port, log_level)
159 123 else:
160 124 raise Exception('Invalid vcs server protocol "{}"'.format(protocol))
161 125
162 126
163 def _start_pyro4_vcs_server(server_and_port, log_level=None):
164 _try_to_shutdown_running_server(server_and_port, protocol='pyro4')
165 host, port = server_and_port.rsplit(":", 1)
166 host = host.strip('[]')
167 args = [
168 'vcsserver', '--port', port, '--host', host, '--locale', 'en_US.UTF-8',
169 '--threadpool', '32']
170 if log_level:
171 args += ['--log-level', log_level]
172 proc = subprocess32.Popen(args)
173
174 def cleanup_server_process():
175 proc.kill()
176 atexit.register(cleanup_server_process)
177
178 server = create_vcsserver_proxy(server_and_port, protocol='pyro4')
179 _wait_until_vcs_server_is_reachable(server)
180
181
182 127 def _start_http_vcs_server(server_and_port, log_level=None):
183 128 # TODO: mikhail: shutdown if an http server already runs
184 129
@@ -202,7 +147,7 b' def _wait_until_vcs_server_is_reachable('
202 147 try:
203 148 server.ping()
204 149 return
205 except (VCSCommunicationError, CommunicationError, pycurl.error):
150 except (VCSCommunicationError, pycurl.error):
206 151 log.debug('VCSServer not started yet, retry to connect.')
207 152 time.sleep(0.5)
208 153 raise Exception(
@@ -214,7 +159,7 b' def _try_to_shutdown_running_server(serv'
214 159 server = create_vcsserver_proxy(server_and_port, protocol)
215 160 try:
216 161 server.shutdown()
217 except (CommunicationError, pycurl.error):
162 except pycurl.error:
218 163 return
219 164
220 165 # TODO: Not sure why this is important, but without it the following start
@@ -224,20 +169,12 b' def _try_to_shutdown_running_server(serv'
224 169
225 170
226 171 def create_vcsserver_proxy(server_and_port, protocol):
227 if protocol == 'pyro4':
228 return _create_vcsserver_proxy_pyro4(server_and_port)
229 elif protocol == 'http':
172 if protocol == 'http':
230 173 return _create_vcsserver_proxy_http(server_and_port)
231 174 else:
232 175 raise Exception('Invalid vcs server protocol "{}"'.format(protocol))
233 176
234 177
235 def _create_vcsserver_proxy_pyro4(server_and_port):
236 server = Pyro4.Proxy(
237 settings.pyro_remote(settings.PYRO_VCSSERVER, server_and_port))
238 return server
239
240
241 178 def _create_vcsserver_proxy_http(server_and_port):
242 179 from rhodecode.lib.vcs import client_http
243 180
@@ -20,13 +20,6 b''
20 20
21 21 """
22 22 Client for the VCSServer implemented based on HTTP.
23
24
25 Status
26 ------
27
28 This client implementation shall eventually replace the Pyro4 based
29 implementation.
30 23 """
31 24
32 25 import copy
@@ -52,27 +52,6 b' ARCHIVE_SPECS = {'
52 52 HOOKS_PROTOCOL = None
53 53 HOOKS_DIRECT_CALLS = False
54 54
55 PYRO_PORT = 9900
56
57 PYRO_GIT = 'git_remote'
58 PYRO_HG = 'hg_remote'
59 PYRO_SVN = 'svn_remote'
60 PYRO_VCSSERVER = 'vcs_server'
61 PYRO_GIT_REMOTE_WSGI = 'git_remote_wsgi'
62 PYRO_HG_REMOTE_WSGI = 'hg_remote_wsgi'
63
64 PYRO_RECONNECT_TRIES = 15
65 """
66 How many retries to reconnect will be performed if the connection was lost.
67
68 Each try takes 2s. Doing 15 means that we will give it up to 30s for a
69 connection to be re-established.
70 """
71
72
73 def pyro_remote(object_id, server_and_port):
74 return "PYRO:%s@%s" % (object_id, server_and_port)
75
76 55
77 56 def available_aliases():
78 57 """
@@ -30,10 +30,6 b' class VCSCommunicationError(Exception):'
30 30 pass
31 31
32 32
33 class PyroVCSCommunicationError(VCSCommunicationError):
34 pass
35
36
37 33 class HttpVCSCommunicationError(VCSCommunicationError):
38 34 pass
39 35
@@ -326,8 +326,6 b' class TestShadowRepoExposure(object):'
326 326
327 327
328 328 @pytest.mark.usefixtures('db')
329 @mock.patch.multiple(
330 'Pyro4.config', SERVERTYPE='multiplex', POLLTIMEOUT=0.01)
331 329 class TestGenerateVcsResponse:
332 330
333 331 def test_ensures_that_start_response_is_called_early_enough(self):
@@ -38,12 +38,10 b' def test_vcs_unavailable_returns_vcs_err'
38 38
39 39 # Depending on the used VCSServer protocol we have to patch a different
40 40 # RemoteRepo class to raise an exception. For the test it doesn't matter
41 # if http or pyro4 is used, it just requires the exception to be raised.
41 # if http is used, it just requires the exception to be raised.
42 42 vcs_protocol = app_settings['vcs.server.protocol']
43 43 if vcs_protocol == 'http':
44 44 from rhodecode.lib.vcs.client_http import RemoteRepo
45 elif vcs_protocol == 'pyro4':
46 from rhodecode.lib.vcs.client import RemoteRepo
47 45 else:
48 46 pytest.fail('Unknown VCS server protocol: "{}"'.format(vcs_protocol))
49 47
@@ -18,8 +18,6 b''
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 import mock
22 import Pyro4
23 21 import pytest
24 22
25 23 from rhodecode.tests.utils import CustomTestApp
@@ -83,48 +81,3 b' def test_create_app_per_request_with_dat'
83 81 app = vcs_http_app(vcsserver_http_echo_app)
84 82 response = app.post('/', params=data)
85 83 assert response.status_code == 200
86
87
88 @pytest.fixture(scope='module')
89 def vcsserver_pyro_echo_app(request, vcsserver_factory):
90 """
91 A running VCSServer with the EchoApp activated via Pyro4.
92 """
93 vcsserver = vcsserver_factory(
94 request=request,
95 use_http=False,
96 overrides=[{'DEFAULT': {'dev.use_echo_app': 'true'}}])
97 return vcsserver
98
99
100 def vcs_pyro4_app(vcsserver_pyro_echo_app):
101 """
102 Pyro4 based Vcs proxy wrapped in WebTest
103 """
104 stub_config = {
105 'git_update_server_info': 'stub',
106 }
107 server_and_port = vcsserver_pyro_echo_app.server_and_port
108 GIT_REMOTE_WSGI = Pyro4.Proxy(
109 settings.pyro_remote(
110 settings.PYRO_GIT_REMOTE_WSGI, server_and_port))
111 with mock.patch('rhodecode.lib.middleware.utils.scm_app.GIT_REMOTE_WSGI',
112 GIT_REMOTE_WSGI):
113 pyro4_app = scm_app.create_git_wsgi_app(
114 'stub_path', 'stub_name', stub_config)
115 app = CustomTestApp(pyro4_app)
116 return app
117
118
119 def test_pyro4_no_data(repeat, pylonsapp, vcsserver_pyro_echo_app):
120 for x in xrange(repeat / 10):
121 app = vcs_pyro4_app(vcsserver_pyro_echo_app)
122 response = app.post('/')
123 assert response.status_code == 200
124
125
126 def test_pyro4_with_data(repeat, pylonsapp, vcsserver_pyro_echo_app, data):
127 for x in xrange(repeat / 10):
128 app = vcs_pyro4_app(vcsserver_pyro_echo_app)
129 response = app.post('/', params=data)
130 assert response.status_code == 200
@@ -171,71 +171,6 b' class ThreadedHookCallbackDaemon(object)'
171 171 assert daemon_context == daemon
172 172
173 173
174 class TestPyro4HooksCallbackDaemon(object):
175 def test_prepare_inits_pyro4_and_registers_hooks(self, caplog):
176 pyro4_daemon = mock.Mock()
177
178 with self._pyro4_patcher(pyro4_daemon), caplog.at_level(logging.DEBUG):
179 daemon = hooks_daemon.Pyro4HooksCallbackDaemon()
180
181 assert daemon._daemon == pyro4_daemon
182
183 assert pyro4_daemon.register.call_count == 1
184 args, kwargs = pyro4_daemon.register.call_args
185 assert len(args) == 1
186 assert isinstance(args[0], hooks_daemon.Hooks)
187
188 assert_message_in_log(
189 caplog.records,
190 'Preparing callback daemon and registering hook object',
191 levelno=logging.DEBUG, module='hooks_daemon')
192
193 def test_run_creates_a_thread(self):
194 thread = mock.Mock()
195 pyro4_daemon = mock.Mock()
196
197 with self._pyro4_patcher(pyro4_daemon):
198 daemon = hooks_daemon.Pyro4HooksCallbackDaemon()
199
200 with self._thread_patcher(thread) as thread_mock:
201 daemon._run()
202
203 assert thread_mock.call_count == 1
204 args, kwargs = thread_mock.call_args
205 assert args == ()
206 assert kwargs['target'] == pyro4_daemon.requestLoop
207 assert kwargs['kwargs']['loopCondition']() is True
208
209 def test_stop_cleans_up_the_connection(self, caplog):
210 thread = mock.Mock()
211 pyro4_daemon = mock.Mock()
212
213 with self._pyro4_patcher(pyro4_daemon):
214 daemon = hooks_daemon.Pyro4HooksCallbackDaemon()
215
216 with self._thread_patcher(thread), caplog.at_level(logging.DEBUG):
217 with daemon:
218 assert daemon._daemon == pyro4_daemon
219 assert daemon._callback_thread == thread
220
221 assert daemon._daemon is None
222 assert daemon._callback_thread is None
223 pyro4_daemon.close.assert_called_with()
224 thread.join.assert_called_once_with()
225
226 assert_message_in_log(
227 caplog.records, 'Waiting for background thread to finish.',
228 levelno=logging.DEBUG, module='hooks_daemon')
229
230 def _pyro4_patcher(self, daemon):
231 return mock.patch.object(
232 hooks_daemon.Pyro4, 'Daemon', return_value=daemon)
233
234 def _thread_patcher(self, thread):
235 return mock.patch.object(
236 hooks_daemon.threading, 'Thread', return_value=thread)
237
238
239 174 class TestHttpHooksCallbackDaemon(object):
240 175 def test_prepare_inits_daemon_variable(self, tcp_server, caplog):
241 176 with self._tcp_patcher(tcp_server), caplog.at_level(logging.DEBUG):
@@ -318,7 +253,7 b' class TestHttpHooksCallbackDaemon(object'
318 253
319 254
320 255 class TestPrepareHooksDaemon(object):
321 @pytest.mark.parametrize('protocol', ('http', 'pyro4'))
256 @pytest.mark.parametrize('protocol', ('http',))
322 257 def test_returns_dummy_hooks_callback_daemon_when_using_direct_calls(
323 258 self, protocol):
324 259 expected_extras = {'extra1': 'value1'}
@@ -329,8 +264,7 b' class TestPrepareHooksDaemon(object):'
329 264 assert extras == expected_extras
330 265
331 266 @pytest.mark.parametrize('protocol, expected_class', (
332 ('pyro4', hooks_daemon.Pyro4HooksCallbackDaemon),
333 ('http', hooks_daemon.HttpHooksCallbackDaemon)
267 ('http', hooks_daemon.HttpHooksCallbackDaemon),
334 268 ))
335 269 def test_returns_real_hooks_callback_daemon_when_protocol_is_specified(
336 270 self, protocol, expected_class):
@@ -343,12 +277,9 b' class TestPrepareHooksDaemon(object):'
343 277 assert isinstance(callback, expected_class)
344 278 hooks_uri = extras.pop('hooks_uri')
345 279 assert extras == expected_extras
346 if protocol.lower() == 'pyro4':
347 assert hooks_uri.startswith('PYRO')
348 280
349 281 @pytest.mark.parametrize('protocol', (
350 282 'invalid',
351 'Pyro4',
352 283 'Http',
353 284 'HTTP',
354 285 ))
@@ -375,7 +375,6 b' class TestPullRequestModel:'
375 375 class TestIntegrationMerge(object):
376 376 @pytest.mark.parametrize('extra_config', (
377 377 {'vcs.hooks.protocol': 'http', 'vcs.hooks.direct_calls': False},
378 {'vcs.hooks.protocol': 'Pyro4', 'vcs.hooks.direct_calls': False},
379 378 ))
380 379 def test_merge_triggers_push_hooks(
381 380 self, pr_util, user_admin, capture_rcextensions, merge_extras,
@@ -321,27 +321,6 b' def tests_tmp_path(request):'
321 321 return TESTS_TMP_PATH
322 322
323 323
324 @pytest.fixture(scope='session', autouse=True)
325 def patch_pyro_request_scope_proxy_factory(request):
326 """
327 Patch the pyro proxy factory to always use the same dummy request object
328 when under test. This will return the same pyro proxy on every call.
329 """
330 dummy_request = pyramid.testing.DummyRequest()
331
332 def mocked_call(self, request=None):
333 return self.getProxy(request=dummy_request)
334
335 patcher = mock.patch(
336 'rhodecode.lib.vcs.client.RequestScopeProxyFactory.__call__',
337 new=mocked_call)
338 patcher.start()
339
340 @request.addfinalizer
341 def undo_patching():
342 patcher.stop()
343
344
345 324 @pytest.fixture
346 325 def test_repo_group(request):
347 326 """
@@ -1350,7 +1329,7 b' def pytest_runtest_makereport(item, call'
1350 1329 """
1351 1330 Adding the remote traceback if the exception has this information.
1352 1331
1353 Pyro4 attaches this information as the attribute `_vcs_server_traceback`
1332 VCSServer attaches this information as the attribute `_vcs_server_traceback`
1354 1333 to the exception instance.
1355 1334 """
1356 1335 outcome = yield
@@ -1411,7 +1390,8 b' def collect_appenlight_stats(request, te'
1411 1390 })
1412 1391
1413 1392 server_and_port = pylonsapp.config['vcs.server']
1414 server = create_vcsserver_proxy(server_and_port)
1393 protocol = pylonsapp.config['vcs.server.protocol']
1394 server = create_vcsserver_proxy(server_and_port, protocol)
1415 1395 with server:
1416 1396 vcs_pid = server.get_pid()
1417 1397 server.run_gc()
@@ -35,7 +35,6 b' from beaker.session import SessionObject'
35 35 from paste.deploy import loadapp
36 36 from pylons.i18n.translation import _get_translator
37 37 from pylons.util import ContextObj
38 from Pyro4.errors import CommunicationError
39 38 from routes.util import URLGenerator
40 39
41 40 from rhodecode.lib import vcs
@@ -71,14 +70,11 b' def pytest_addoption(parser):'
71 70 '--without-vcsserver', dest='with_vcsserver', action='store_false',
72 71 help="Do not start the VCSServer in a background process.")
73 72 vcsgroup.addoption(
74 '--with-vcsserver', dest='vcsserver_config_pyro4',
75 help="Start the VCSServer with the specified config file.")
76 vcsgroup.addoption(
77 73 '--with-vcsserver-http', dest='vcsserver_config_http',
78 74 help="Start the HTTP VCSServer with the specified config file.")
79 75 vcsgroup.addoption(
80 76 '--vcsserver-protocol', dest='vcsserver_protocol',
81 help="Start the VCSServer with HTTP / Pyro4 protocol support.")
77 help="Start the VCSServer with HTTP protocol support.")
82 78 vcsgroup.addoption(
83 79 '--vcsserver-config-override', action='store', type=_parse_json,
84 80 default=None, dest='vcsserver_config_override', help=(
@@ -94,14 +90,11 b' def pytest_addoption(parser):'
94 90 "against an already running server and random ports cause "
95 91 "trouble."))
96 92 parser.addini(
97 'vcsserver_config_pyro4',
98 "Start the VCSServer with the specified config file.")
99 parser.addini(
100 93 'vcsserver_config_http',
101 94 "Start the HTTP VCSServer with the specified config file.")
102 95 parser.addini(
103 96 'vcsserver_protocol',
104 "Start the VCSServer with HTTP / Pyro4 protocol support.")
97 "Start the VCSServer with HTTP protocol support.")
105 98
106 99
107 100 @pytest.fixture(scope='session')
@@ -153,8 +146,7 b' def vcsserver_factory(tmpdir_factory):'
153 146 'beaker.cache.repo_object.type': 'nocache'}}
154 147 overrides.append(platform_override)
155 148
156 option_name = (
157 'vcsserver_config_http' if use_http else 'vcsserver_config_pyro4')
149 option_name = 'vcsserver_config_http' if use_http else ''
158 150 override_option_name = 'vcsserver_config_override'
159 151 config_file = get_config(
160 152 request.config, option_name=option_name,
@@ -162,8 +154,8 b' def vcsserver_factory(tmpdir_factory):'
162 154 basetemp=tmpdir_factory.getbasetemp().strpath,
163 155 prefix='test_vcs_')
164 156
165 print "Using the VCSServer configuration", config_file
166 ServerClass = HttpVCSServer if use_http else Pyro4VCSServer
157 print("Using the VCSServer configuration:{}".format(config_file))
158 ServerClass = HttpVCSServer if use_http else None
167 159 server = ServerClass(config_file)
168 160 server.start()
169 161
@@ -213,39 +205,6 b' class VCSServer(object):'
213 205 self.process.kill()
214 206
215 207
216 class Pyro4VCSServer(VCSServer):
217 def __init__(self, config_file):
218 """
219 :param config_file: The config file to start the server with
220 """
221
222 config_data = configobj.ConfigObj(config_file)
223 self._config = config_data['DEFAULT']
224
225 args = ['vcsserver', '--config', config_file]
226 self._args = args
227
228 def wait_until_ready(self, timeout=30):
229 remote_server = vcs.create_vcsserver_proxy(
230 self.server_and_port, 'pyro4')
231 start = time.time()
232 with remote_server:
233 while time.time() - start < timeout:
234 try:
235 remote_server.ping()
236 break
237 except CommunicationError:
238 time.sleep(0.2)
239 else:
240 pytest.exit(
241 "Starting the VCSServer failed or took more than {} "
242 "seconds.".format(timeout))
243
244 @property
245 def server_and_port(self):
246 return '{host}:{port}'.format(**self._config)
247
248
249 208 class HttpVCSServer(VCSServer):
250 209 """
251 210 Represents a running VCSServer instance.
@@ -316,14 +275,6 b' def pylons_config(request, tmpdir_factor'
316 275 'vcs.hooks.protocol': 'http',
317 276 }
318 277 })
319 else:
320 overrides.append({
321 'app:main': {
322 'vcs.server.protocol': 'pyro4',
323 'vcs.scm_app_implementation': 'pyro4',
324 'vcs.hooks.protocol': 'pyro4',
325 }
326 })
327 278
328 279 filename = get_config(
329 280 request.config, option_name=option_name,
@@ -337,7 +288,7 b' def pylons_config(request, tmpdir_factor'
337 288 @pytest.fixture(scope='session')
338 289 def rcserver_port(request):
339 290 port = get_available_port()
340 print 'Using rcserver port %s' % (port, )
291 print('Using rcserver port {}'.format(port))
341 292 return port
342 293
343 294
@@ -346,7 +297,7 b' def vcsserver_port(request):'
346 297 port = request.config.getoption('--vcsserver-port')
347 298 if port is None:
348 299 port = get_available_port()
349 print 'Using vcsserver port %s' % (port, )
300 print('Using vcsserver port {}'.format(port))
350 301 return port
351 302
352 303
@@ -383,7 +334,7 b' def available_port(available_port_factor'
383 334
384 335 @pytest.fixture(scope='session')
385 336 def pylonsapp(pylons_config, vcsserver, http_environ_session):
386 print "Using the RhodeCode configuration", pylons_config
337 print("Using the RhodeCode configuration:{}".format(pylons_config))
387 338 logging.config.fileConfig(
388 339 pylons_config, disable_existing_loggers=False)
389 340 app = _setup_pylons_environment(pylons_config, http_environ_session)
@@ -575,18 +575,15 b' vcs.server = localhost:9901'
575 575
576 576 ## Web server connectivity protocol, responsible for web based VCS operatations
577 577 ## Available protocols are:
578 ## `pyro4` - using pyro4 server
579 578 ## `http` - using http-rpc backend
580 579 vcs.server.protocol = http
581 580
582 581 ## Push/Pull operations protocol, available options are:
583 ## `pyro4` - using pyro4 server
584 582 ## `rhodecode.lib.middleware.utils.scm_app_http` - Http based, recommended
585 583 ## `vcsserver.scm_app` - internal app (EE only)
586 584 vcs.scm_app_implementation = http
587 585
588 586 ## Push/Pull operations hooks protocol, available options are:
589 ## `pyro4` - using pyro4 server
590 587 ## `http` - using http-rpc backend
591 588 vcs.hooks.protocol = http
592 589
@@ -628,7 +625,7 b' svn.proxy.location_root = /'
628 625 ### LOGGING CONFIGURATION ####
629 626 ################################
630 627 [loggers]
631 keys = root, routes, rhodecode, sqlalchemy, beaker, pyro4, templates
628 keys = root, routes, rhodecode, sqlalchemy, beaker, templates
632 629
633 630 [handlers]
634 631 keys = console, console_sql
@@ -656,12 +653,6 b' handlers ='
656 653 qualname = beaker.container
657 654 propagate = 1
658 655
659 [logger_pyro4]
660 level = DEBUG
661 handlers =
662 qualname = Pyro4
663 propagate = 1
664
665 656 [logger_templates]
666 657 level = INFO
667 658 handlers =
@@ -701,7 +692,7 b' formatter = generic'
701 692 ################
702 693
703 694 [formatter_generic]
704 class = rhodecode.lib.logging_formatter.Pyro4AwareFormatter
695 class = rhodecode.lib.logging_formatter.ExceptionAwareFormatter
705 696 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
706 697 datefmt = %Y-%m-%d %H:%M:%S
707 698
@@ -94,7 +94,3 b' def test_connect_passes_in_the_same_sess'
94 94 session_factory.return_value = stub_session
95 95
96 96 vcs.connect_http('server_and_port')
97
98 assert connection.Hg._session_factory() == stub_session
99 assert connection.Svn._session_factory() == stub_session
100 assert connection.Git._session_factory() == stub_session
@@ -123,9 +123,6 b' class TestMercurialRemoteRepoInvalidatio'
123 123 """
124 124 from rhodecode.lib.vcs.exceptions import CommitDoesNotExistError
125 125
126 if pylonsapp.config['vcs.server.protocol'] == 'pyro4':
127 pytest.skip('Test is intended for the HTTP protocol only.')
128
129 126 pull_request = pr_util.create_pull_request()
130 127 target_vcs = pull_request.target_repo.scm_instance()
131 128 source_vcs = pull_request.source_repo.scm_instance()
@@ -163,8 +160,6 b' class TestMercurialRemoteRepoInvalidatio'
163 160 Without correct cache invalidation this leads to an error when
164 161 retrieving the pulled commits afterwards.
165 162 """
166 if pylonsapp.config['vcs.server.protocol'] == 'pyro4':
167 pytest.skip('Test is intended for the HTTP protocol only.')
168 163
169 164 pull_request = pr_util.create_pull_request()
170 165 target_vcs = pull_request.target_repo.scm_instance()
@@ -30,7 +30,7 b' port = 9900'
30 30 ### LOGGING CONFIGURATION ####
31 31 ################################
32 32 [loggers]
33 keys = root, vcsserver, pyro4, beaker
33 keys = root, vcsserver, beaker
34 34
35 35 [handlers]
36 36 keys = console
@@ -57,12 +57,6 b' handlers ='
57 57 qualname = beaker
58 58 propagate = 1
59 59
60 [logger_pyro4]
61 level = DEBUG
62 handlers =
63 qualname = Pyro4
64 propagate = 1
65
66 60
67 61 ##############
68 62 ## HANDLERS ##
@@ -84,7 +84,6 b' install_requirements = ['
84 84 'Pygments',
85 85 'pygments-markdown-lexer',
86 86 'Pylons',
87 'Pyro4',
88 87 'Routes',
89 88 'SQLAlchemy',
90 89 'Tempita',
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now