##// END OF EJS Templates
env: removed old not used code for starting vcsserver together with rhodecode.
marcink -
r2458:457e5c61 default
parent child Browse files
Show More
@@ -1,90 +1,81 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2017 RhodeCode GmbH
3 # Copyright (C) 2010-2017 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21
21
22 import os
22 import os
23 import logging
23 import logging
24 import rhodecode
24 import rhodecode
25
25
26
26
27 from rhodecode.config import utils
27 from rhodecode.config import utils
28
28
29 from rhodecode.lib.utils import load_rcextensions
29 from rhodecode.lib.utils import load_rcextensions
30 from rhodecode.lib.utils2 import str2bool
30 from rhodecode.lib.utils2 import str2bool
31 from rhodecode.lib.vcs import connect_vcs, start_vcs_server
31 from rhodecode.lib.vcs import connect_vcs
32
32
33 log = logging.getLogger(__name__)
33 log = logging.getLogger(__name__)
34
34
35
35
36 def load_pyramid_environment(global_config, settings):
36 def load_pyramid_environment(global_config, settings):
37 # Some parts of the code expect a merge of global and app settings.
37 # Some parts of the code expect a merge of global and app settings.
38 settings_merged = global_config.copy()
38 settings_merged = global_config.copy()
39 settings_merged.update(settings)
39 settings_merged.update(settings)
40
40
41 # TODO(marcink): probably not required anymore
41 # TODO(marcink): probably not required anymore
42 # configure channelstream,
42 # configure channelstream,
43 settings_merged['channelstream_config'] = {
43 settings_merged['channelstream_config'] = {
44 'enabled': str2bool(settings_merged.get('channelstream.enabled', False)),
44 'enabled': str2bool(settings_merged.get('channelstream.enabled', False)),
45 'server': settings_merged.get('channelstream.server'),
45 'server': settings_merged.get('channelstream.server'),
46 'secret': settings_merged.get('channelstream.secret')
46 'secret': settings_merged.get('channelstream.secret')
47 }
47 }
48
48
49 # If this is a test run we prepare the test environment like
49 # If this is a test run we prepare the test environment like
50 # creating a test database, test search index and test repositories.
50 # creating a test database, test search index and test repositories.
51 # This has to be done before the database connection is initialized.
51 # This has to be done before the database connection is initialized.
52 if settings['is_test']:
52 if settings['is_test']:
53 rhodecode.is_test = True
53 rhodecode.is_test = True
54 rhodecode.disable_error_handler = True
54 rhodecode.disable_error_handler = True
55
55
56 utils.initialize_test_environment(settings_merged)
56 utils.initialize_test_environment(settings_merged)
57
57
58 # Initialize the database connection.
58 # Initialize the database connection.
59 utils.initialize_database(settings_merged)
59 utils.initialize_database(settings_merged)
60
60
61 load_rcextensions(root_path=settings_merged['here'])
61 load_rcextensions(root_path=settings_merged['here'])
62
62
63 # Limit backends to `vcs.backends` from configuration
63 # Limit backends to `vcs.backends` from configuration
64 for alias in rhodecode.BACKENDS.keys():
64 for alias in rhodecode.BACKENDS.keys():
65 if alias not in settings['vcs.backends']:
65 if alias not in settings['vcs.backends']:
66 del rhodecode.BACKENDS[alias]
66 del rhodecode.BACKENDS[alias]
67 log.info('Enabled VCS backends: %s', rhodecode.BACKENDS.keys())
67 log.info('Enabled VCS backends: %s', rhodecode.BACKENDS.keys())
68
68
69 # initialize vcs client and optionally run the server if enabled
69 # initialize vcs client and optionally run the server if enabled
70 vcs_server_uri = settings['vcs.server']
70 vcs_server_uri = settings['vcs.server']
71 vcs_server_enabled = settings['vcs.server.enable']
71 vcs_server_enabled = settings['vcs.server.enable']
72 start_server = (
73 settings['vcs.start_server'] and
74 not int(os.environ.get('RC_VCSSERVER_TEST_DISABLE', '0')))
75
76 if vcs_server_enabled and start_server:
77 log.info("Starting vcsserver")
78 start_vcs_server(server_and_port=vcs_server_uri,
79 protocol=utils.get_vcs_server_protocol(settings),
80 log_level=settings['vcs.server.log_level'])
81
72
82 utils.configure_vcs(settings)
73 utils.configure_vcs(settings)
83
74
84 # Store the settings to make them available to other modules.
75 # Store the settings to make them available to other modules.
85
76
86 rhodecode.PYRAMID_SETTINGS = settings_merged
77 rhodecode.PYRAMID_SETTINGS = settings_merged
87 rhodecode.CONFIG = settings_merged
78 rhodecode.CONFIG = settings_merged
88
79
89 if vcs_server_enabled:
80 if vcs_server_enabled:
90 connect_vcs(vcs_server_uri, utils.get_vcs_server_protocol(settings))
81 connect_vcs(vcs_server_uri, utils.get_vcs_server_protocol(settings))
@@ -1,248 +1,191 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2014-2017 RhodeCode GmbH
3 # Copyright (C) 2014-2017 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 """
21 """
22 Various version Control System version lib (vcs) management abstraction layer
22 Various version Control System version lib (vcs) management abstraction layer
23 for Python. Build with server client architecture.
23 for Python. Build with server client architecture.
24 """
24 """
25
25
26
26
27 VERSION = (0, 5, 0, 'dev')
27 VERSION = (0, 5, 0, 'dev')
28
28
29 __version__ = '.'.join((str(each) for each in VERSION[:4]))
29 __version__ = '.'.join((str(each) for each in VERSION[:4]))
30
30
31 __all__ = [
31 __all__ = [
32 'get_version', 'get_vcs_instance', 'get_backend',
32 'get_version', 'get_vcs_instance', 'get_backend',
33 'VCSError', 'RepositoryError', 'CommitError'
33 'VCSError', 'RepositoryError', 'CommitError'
34 ]
34 ]
35
35
36 import atexit
36 import atexit
37 import logging
37 import logging
38 import subprocess32
38 import subprocess32
39 import time
39 import time
40 import urlparse
40 import urlparse
41 from cStringIO import StringIO
41 from cStringIO import StringIO
42
42
43
43
44 from rhodecode.lib.vcs.conf import settings
44 from rhodecode.lib.vcs.conf import settings
45 from rhodecode.lib.vcs.backends import get_vcs_instance, get_backend
45 from rhodecode.lib.vcs.backends import get_vcs_instance, get_backend
46 from rhodecode.lib.vcs.exceptions import (
46 from rhodecode.lib.vcs.exceptions import (
47 VCSError, RepositoryError, CommitError, VCSCommunicationError)
47 VCSError, RepositoryError, CommitError, VCSCommunicationError)
48
48
49 log = logging.getLogger(__name__)
49 log = logging.getLogger(__name__)
50
50
51 # The pycurl library directly accesses C API functions and is not patched by
51 # The pycurl library directly accesses C API functions and is not patched by
52 # gevent. This will potentially lead to deadlocks due to incompatibility to
52 # gevent. This will potentially lead to deadlocks due to incompatibility to
53 # gevent. Therefore we check if gevent is active and import a gevent compatible
53 # gevent. Therefore we check if gevent is active and import a gevent compatible
54 # wrapper in that case.
54 # wrapper in that case.
55 try:
55 try:
56 from gevent import monkey
56 from gevent import monkey
57 if monkey.is_module_patched('__builtin__'):
57 if monkey.is_module_patched('__builtin__'):
58 import geventcurl as pycurl
58 import geventcurl as pycurl
59 log.debug('Using gevent comapatible pycurl: %s', pycurl)
59 log.debug('Using gevent comapatible pycurl: %s', pycurl)
60 else:
60 else:
61 import pycurl
61 import pycurl
62 except ImportError:
62 except ImportError:
63 import pycurl
63 import pycurl
64
64
65
65
66 def get_version():
66 def get_version():
67 """
67 """
68 Returns shorter version (digit parts only) as string.
68 Returns shorter version (digit parts only) as string.
69 """
69 """
70 return '.'.join((str(each) for each in VERSION[:3]))
70 return '.'.join((str(each) for each in VERSION[:3]))
71
71
72
72
73 def connect_http(server_and_port):
73 def connect_http(server_and_port):
74 from rhodecode.lib.vcs import connection, client_http
74 from rhodecode.lib.vcs import connection, client_http
75 from rhodecode.lib.middleware.utils import scm_app
75 from rhodecode.lib.middleware.utils import scm_app
76
76
77 session_factory = client_http.ThreadlocalSessionFactory()
77 session_factory = client_http.ThreadlocalSessionFactory()
78
78
79 connection.Git = client_http.RepoMaker(
79 connection.Git = client_http.RepoMaker(
80 server_and_port, '/git', 'git', session_factory)
80 server_and_port, '/git', 'git', session_factory)
81 connection.Hg = client_http.RepoMaker(
81 connection.Hg = client_http.RepoMaker(
82 server_and_port, '/hg', 'hg', session_factory)
82 server_and_port, '/hg', 'hg', session_factory)
83 connection.Svn = client_http.RepoMaker(
83 connection.Svn = client_http.RepoMaker(
84 server_and_port, '/svn', 'svn', session_factory)
84 server_and_port, '/svn', 'svn', session_factory)
85 connection.Service = client_http.ServiceConnection(
85 connection.Service = client_http.ServiceConnection(
86 server_and_port, '/_service', session_factory)
86 server_and_port, '/_service', session_factory)
87
87
88 scm_app.HG_REMOTE_WSGI = client_http.VcsHttpProxy(
88 scm_app.HG_REMOTE_WSGI = client_http.VcsHttpProxy(
89 server_and_port, '/proxy/hg')
89 server_and_port, '/proxy/hg')
90 scm_app.GIT_REMOTE_WSGI = client_http.VcsHttpProxy(
90 scm_app.GIT_REMOTE_WSGI = client_http.VcsHttpProxy(
91 server_and_port, '/proxy/git')
91 server_and_port, '/proxy/git')
92
92
93 @atexit.register
93 @atexit.register
94 def free_connection_resources():
94 def free_connection_resources():
95 connection.Git = None
95 connection.Git = None
96 connection.Hg = None
96 connection.Hg = None
97 connection.Svn = None
97 connection.Svn = None
98 connection.Service = None
98 connection.Service = None
99
99
100
100
101 def connect_vcs(server_and_port, protocol):
101 def connect_vcs(server_and_port, protocol):
102 """
102 """
103 Initializes the connection to the vcs server.
103 Initializes the connection to the vcs server.
104
104
105 :param server_and_port: str, e.g. "localhost:9900"
105 :param server_and_port: str, e.g. "localhost:9900"
106 :param protocol: str or "http"
106 :param protocol: str or "http"
107 """
107 """
108 if protocol == 'http':
108 if protocol == 'http':
109 connect_http(server_and_port)
109 connect_http(server_and_port)
110 else:
110 else:
111 raise Exception('Invalid vcs server protocol "{}"'.format(protocol))
111 raise Exception('Invalid vcs server protocol "{}"'.format(protocol))
112
112
113
113
114 # TODO: johbo: This function should be moved into our test suite, there is
115 # no reason to support starting the vcsserver in Enterprise itself.
116 def start_vcs_server(server_and_port, protocol, log_level=None):
117 """
118 Starts the vcs server in a subprocess.
119 """
120 log.info('Starting VCSServer as a sub process with %s protocol', protocol)
121 if protocol == 'http':
122 return _start_http_vcs_server(server_and_port, log_level)
123 else:
124 raise Exception('Invalid vcs server protocol "{}"'.format(protocol))
125
126
127 def _start_http_vcs_server(server_and_port, log_level=None):
128 # TODO: mikhail: shutdown if an http server already runs
129
130 host, port = server_and_port.rsplit(":", 1)
131 args = [
132 'pserve', 'rhodecode/tests/vcsserver_http.ini',
133 'http_port=%s' % (port, ), 'http_host=%s' % (host, )]
134 proc = subprocess32.Popen(args)
135
136 def cleanup_server_process():
137 proc.kill()
138 atexit.register(cleanup_server_process)
139
140 server = create_vcsserver_proxy(server_and_port, protocol='http')
141 _wait_until_vcs_server_is_reachable(server)
142
143
144 def _wait_until_vcs_server_is_reachable(server, timeout=40):
145 begin = time.time()
146 while (time.time() - begin) < timeout:
147 try:
148 server.ping()
149 return
150 except (VCSCommunicationError, pycurl.error):
151 log.debug('VCSServer not started yet, retry to connect.')
152 time.sleep(0.5)
153 raise Exception(
154 'Starting the VCSServer failed or took more than {} '
155 'seconds.'.format(timeout))
156
157
158 def _try_to_shutdown_running_server(server_and_port, protocol):
159 server = create_vcsserver_proxy(server_and_port, protocol)
160 try:
161 server.shutdown()
162 except pycurl.error:
163 return
164
165 # TODO: Not sure why this is important, but without it the following start
166 # of the server fails.
167 server = create_vcsserver_proxy(server_and_port, protocol)
168 server.ping()
169
170
171 def create_vcsserver_proxy(server_and_port, protocol):
114 def create_vcsserver_proxy(server_and_port, protocol):
172 if protocol == 'http':
115 if protocol == 'http':
173 return _create_vcsserver_proxy_http(server_and_port)
116 return _create_vcsserver_proxy_http(server_and_port)
174 else:
117 else:
175 raise Exception('Invalid vcs server protocol "{}"'.format(protocol))
118 raise Exception('Invalid vcs server protocol "{}"'.format(protocol))
176
119
177
120
178 def _create_vcsserver_proxy_http(server_and_port):
121 def _create_vcsserver_proxy_http(server_and_port):
179 from rhodecode.lib.vcs import client_http
122 from rhodecode.lib.vcs import client_http
180
123
181 session = _create_http_rpc_session()
124 session = _create_http_rpc_session()
182 url = urlparse.urljoin('http://%s' % server_and_port, '/server')
125 url = urlparse.urljoin('http://%s' % server_and_port, '/server')
183 return client_http.RemoteObject(url, session)
126 return client_http.RemoteObject(url, session)
184
127
185
128
186 class CurlSession(object):
129 class CurlSession(object):
187 """
130 """
188 Modeled so that it provides a subset of the requests interface.
131 Modeled so that it provides a subset of the requests interface.
189
132
190 This has been created so that it does only provide a minimal API for our
133 This has been created so that it does only provide a minimal API for our
191 needs. The parts which it provides are based on the API of the library
134 needs. The parts which it provides are based on the API of the library
192 `requests` which allows us to easily benchmark against it.
135 `requests` which allows us to easily benchmark against it.
193
136
194 Please have a look at the class :class:`requests.Session` when you extend
137 Please have a look at the class :class:`requests.Session` when you extend
195 it.
138 it.
196 """
139 """
197
140
198 def __init__(self):
141 def __init__(self):
199 curl = pycurl.Curl()
142 curl = pycurl.Curl()
200 # TODO: johbo: I did test with 7.19 of libcurl. This version has
143 # TODO: johbo: I did test with 7.19 of libcurl. This version has
201 # trouble with 100 - continue being set in the expect header. This
144 # trouble with 100 - continue being set in the expect header. This
202 # can lead to massive performance drops, switching it off here.
145 # can lead to massive performance drops, switching it off here.
203 curl.setopt(curl.HTTPHEADER, ["Expect:"])
146 curl.setopt(curl.HTTPHEADER, ["Expect:"])
204 curl.setopt(curl.TCP_NODELAY, True)
147 curl.setopt(curl.TCP_NODELAY, True)
205 curl.setopt(curl.PROTOCOLS, curl.PROTO_HTTP)
148 curl.setopt(curl.PROTOCOLS, curl.PROTO_HTTP)
206 self._curl = curl
149 self._curl = curl
207
150
208 def post(self, url, data, allow_redirects=False):
151 def post(self, url, data, allow_redirects=False):
209 response_buffer = StringIO()
152 response_buffer = StringIO()
210
153
211 curl = self._curl
154 curl = self._curl
212 curl.setopt(curl.URL, url)
155 curl.setopt(curl.URL, url)
213 curl.setopt(curl.POST, True)
156 curl.setopt(curl.POST, True)
214 curl.setopt(curl.POSTFIELDS, data)
157 curl.setopt(curl.POSTFIELDS, data)
215 curl.setopt(curl.FOLLOWLOCATION, allow_redirects)
158 curl.setopt(curl.FOLLOWLOCATION, allow_redirects)
216 curl.setopt(curl.WRITEDATA, response_buffer)
159 curl.setopt(curl.WRITEDATA, response_buffer)
217 curl.perform()
160 curl.perform()
218
161
219 status_code = curl.getinfo(pycurl.HTTP_CODE)
162 status_code = curl.getinfo(pycurl.HTTP_CODE)
220
163
221 return CurlResponse(response_buffer, status_code)
164 return CurlResponse(response_buffer, status_code)
222
165
223
166
224 class CurlResponse(object):
167 class CurlResponse(object):
225 """
168 """
226 The response of a request, modeled after the requests API.
169 The response of a request, modeled after the requests API.
227
170
228 This class provides a subset of the response interface known from the
171 This class provides a subset of the response interface known from the
229 library `requests`. It is intentionally kept similar, so that we can use
172 library `requests`. It is intentionally kept similar, so that we can use
230 `requests` as a drop in replacement for benchmarking purposes.
173 `requests` as a drop in replacement for benchmarking purposes.
231 """
174 """
232
175
233 def __init__(self, response_buffer, status_code):
176 def __init__(self, response_buffer, status_code):
234 self._response_buffer = response_buffer
177 self._response_buffer = response_buffer
235 self._status_code = status_code
178 self._status_code = status_code
236
179
237 @property
180 @property
238 def content(self):
181 def content(self):
239 return self._response_buffer.getvalue()
182 return self._response_buffer.getvalue()
240
183
241 @property
184 @property
242 def status_code(self):
185 def status_code(self):
243 return self._status_code
186 return self._status_code
244
187
245
188
246 def _create_http_rpc_session():
189 def _create_http_rpc_session():
247 session = CurlSession()
190 session = CurlSession()
248 return session
191 return session
General Comments 0
You need to be logged in to leave comments. Login now