##// END OF EJS Templates
middleware: use explicit call to .includeme while importing apps and modules. This is a bit faster for code discovery and app startup
super-admin -
r5024:cc92b68c default
parent child Browse files
Show More
@@ -1,612 +1,617 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2010-2020 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
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 21 import os
22 22 import sys
23 23 import collections
24 24 import tempfile
25 25 import time
26 26 import logging.config
27 27
28 28 from paste.gzipper import make_gzip_middleware
29 29 import pyramid.events
30 30 from pyramid.wsgi import wsgiapp
31 31 from pyramid.authorization import ACLAuthorizationPolicy
32 32 from pyramid.config import Configurator
33 33 from pyramid.settings import asbool, aslist
34 34 from pyramid.httpexceptions import (
35 35 HTTPException, HTTPError, HTTPInternalServerError, HTTPFound, HTTPNotFound)
36 36 from pyramid.renderers import render_to_response
37 37
38 38 from rhodecode.model import meta
39 39 from rhodecode.config import patches
40 40 from rhodecode.config import utils as config_utils
41 41 from rhodecode.config.settings_maker import SettingsMaker
42 42 from rhodecode.config.environment import load_pyramid_environment
43 43
44 44 import rhodecode.events
45 45 from rhodecode.lib.middleware.vcs import VCSMiddleware
46 46 from rhodecode.lib.request import Request
47 47 from rhodecode.lib.vcs import VCSCommunicationError
48 48 from rhodecode.lib.exceptions import VCSServerUnavailable
49 49 from rhodecode.lib.middleware.appenlight import wrap_in_appenlight_if_enabled
50 50 from rhodecode.lib.middleware.https_fixup import HttpsFixup
51 51 from rhodecode.lib.plugins.utils import register_rhodecode_plugin
52 52 from rhodecode.lib.utils2 import AttributeDict
53 53 from rhodecode.lib.exc_tracking import store_exception
54 54 from rhodecode.subscribers import (
55 55 scan_repositories_if_enabled, write_js_routes_if_enabled,
56 56 write_metadata_if_needed, write_usage_data)
57 57 from rhodecode.lib.statsd_client import StatsdClient
58 58
59 59 log = logging.getLogger(__name__)
60 60
61 61
62 62 def is_http_error(response):
63 63 # error which should have traceback
64 64 return response.status_code > 499
65 65
66 66
67 67 def should_load_all():
68 68 """
69 69 Returns if all application components should be loaded. In some cases it's
70 70 desired to skip apps loading for faster shell script execution
71 71 """
72 72 ssh_cmd = os.environ.get('RC_CMD_SSH_WRAPPER')
73 73 if ssh_cmd:
74 74 return False
75 75
76 76 return True
77 77
78 78
79 79 def make_pyramid_app(global_config, **settings):
80 80 """
81 81 Constructs the WSGI application based on Pyramid.
82 82
83 83 Specials:
84 84
85 85 * The application can also be integrated like a plugin via the call to
86 86 `includeme`. This is accompanied with the other utility functions which
87 87 are called. Changing this should be done with great care to not break
88 88 cases when these fragments are assembled from another place.
89 89
90 90 """
91 91 start_time = time.time()
92 92 log.info('Pyramid app config starting')
93 93
94 94 sanitize_settings_and_apply_defaults(global_config, settings)
95 95
96 96 # init and bootstrap StatsdClient
97 97 StatsdClient.setup(settings)
98 98
99 99 config = Configurator(settings=settings)
100 100 # Init our statsd at very start
101 101 config.registry.statsd = StatsdClient.statsd
102 102
103 103 # Apply compatibility patches
104 104 patches.inspect_getargspec()
105 105
106 106 load_pyramid_environment(global_config, settings)
107 107
108 108 # Static file view comes first
109 109 includeme_first(config)
110 110
111 111 includeme(config)
112 112
113 113 pyramid_app = config.make_wsgi_app()
114 114 pyramid_app = wrap_app_in_wsgi_middlewares(pyramid_app, config)
115 115 pyramid_app.config = config
116 116
117 117 celery_settings = get_celery_config(settings)
118 118 config.configure_celery(celery_settings)
119 119
120 120 # creating the app uses a connection - return it after we are done
121 121 meta.Session.remove()
122 122
123 123 total_time = time.time() - start_time
124 124 log.info('Pyramid app `%s` created and configured in %.2fs',
125 125 getattr(pyramid_app, 'func_name', 'pyramid_app'), total_time)
126 126 return pyramid_app
127 127
128 128
129 129 def get_celery_config(settings):
130 130 """
131 131 Converts basic ini configuration into celery 4.X options
132 132 """
133 133
134 134 def key_converter(key_name):
135 135 pref = 'celery.'
136 136 if key_name.startswith(pref):
137 137 return key_name[len(pref):].replace('.', '_').lower()
138 138
139 139 def type_converter(parsed_key, value):
140 140 # cast to int
141 141 if value.isdigit():
142 142 return int(value)
143 143
144 144 # cast to bool
145 145 if value.lower() in ['true', 'false', 'True', 'False']:
146 146 return value.lower() == 'true'
147 147 return value
148 148
149 149 celery_config = {}
150 150 for k, v in settings.items():
151 151 pref = 'celery.'
152 152 if k.startswith(pref):
153 153 celery_config[key_converter(k)] = type_converter(key_converter(k), v)
154 154
155 155 # TODO:rethink if we want to support celerybeat based file config, probably NOT
156 156 # beat_config = {}
157 157 # for section in parser.sections():
158 158 # if section.startswith('celerybeat:'):
159 159 # name = section.split(':', 1)[1]
160 160 # beat_config[name] = get_beat_config(parser, section)
161 161
162 162 # final compose of settings
163 163 celery_settings = {}
164 164
165 165 if celery_config:
166 166 celery_settings.update(celery_config)
167 167 # if beat_config:
168 168 # celery_settings.update({'beat_schedule': beat_config})
169 169
170 170 return celery_settings
171 171
172 172
173 173 def not_found_view(request):
174 174 """
175 175 This creates the view which should be registered as not-found-view to
176 176 pyramid.
177 177 """
178 178
179 179 if not getattr(request, 'vcs_call', None):
180 180 # handle like regular case with our error_handler
181 181 return error_handler(HTTPNotFound(), request)
182 182
183 183 # handle not found view as a vcs call
184 184 settings = request.registry.settings
185 185 ae_client = getattr(request, 'ae_client', None)
186 186 vcs_app = VCSMiddleware(
187 187 HTTPNotFound(), request.registry, settings,
188 188 appenlight_client=ae_client)
189 189
190 190 return wsgiapp(vcs_app)(None, request)
191 191
192 192
193 193 def error_handler(exception, request):
194 194 import rhodecode
195 195 from rhodecode.lib import helpers
196 196 from rhodecode.lib.utils2 import str2bool
197 197
198 198 rhodecode_title = rhodecode.CONFIG.get('rhodecode_title') or 'RhodeCode'
199 199
200 200 base_response = HTTPInternalServerError()
201 201 # prefer original exception for the response since it may have headers set
202 202 if isinstance(exception, HTTPException):
203 203 base_response = exception
204 204 elif isinstance(exception, VCSCommunicationError):
205 205 base_response = VCSServerUnavailable()
206 206
207 207 if is_http_error(base_response):
208 208 log.exception(
209 209 'error occurred handling this request for path: %s', request.path)
210 210
211 211 error_explanation = base_response.explanation or str(base_response)
212 212 if base_response.status_code == 404:
213 213 error_explanation += " Optionally you don't have permission to access this page."
214 214 c = AttributeDict()
215 215 c.error_message = base_response.status
216 216 c.error_explanation = error_explanation
217 217 c.visual = AttributeDict()
218 218
219 219 c.visual.rhodecode_support_url = (
220 220 request.registry.settings.get('rhodecode_support_url') or
221 221 request.route_url('rhodecode_support')
222 222 )
223 223 c.redirect_time = 0
224 224 c.rhodecode_name = rhodecode_title
225 225 if not c.rhodecode_name:
226 226 c.rhodecode_name = 'Rhodecode'
227 227
228 228 c.causes = []
229 229 if is_http_error(base_response):
230 230 c.causes.append('Server is overloaded.')
231 231 c.causes.append('Server database connection is lost.')
232 232 c.causes.append('Server expected unhandled error.')
233 233
234 234 if hasattr(base_response, 'causes'):
235 235 c.causes = base_response.causes
236 236
237 237 c.messages = helpers.flash.pop_messages(request=request)
238
239 238 exc_info = sys.exc_info()
240 239 c.exception_id = id(exc_info)
241 240 c.show_exception_id = isinstance(base_response, VCSServerUnavailable) \
242 241 or base_response.status_code > 499
243 242 c.exception_id_url = request.route_url(
244 243 'admin_settings_exception_tracker_show', exception_id=c.exception_id)
245 244
246 245 if c.show_exception_id:
247 246 store_exception(c.exception_id, exc_info)
248 247 c.exception_debug = str2bool(rhodecode.CONFIG.get('debug'))
249 248 c.exception_config_ini = rhodecode.CONFIG.get('__file__')
250 249
251 250 response = render_to_response(
252 251 '/errors/error_document.mako', {'c': c, 'h': helpers}, request=request,
253 252 response=base_response)
254 253
255 254 statsd = request.registry.statsd
256 255 if statsd and base_response.status_code > 499:
257 256 exc_type = "{}.{}".format(exception.__class__.__module__, exception.__class__.__name__)
258 257 statsd.incr('rhodecode_exception_total',
259 258 tags=["exc_source:web",
260 259 "http_code:{}".format(base_response.status_code),
261 260 "type:{}".format(exc_type)])
262 261
263 262 return response
264 263
265 264
266 265 def includeme_first(config):
267 266 # redirect automatic browser favicon.ico requests to correct place
268 267 def favicon_redirect(context, request):
269 268 return HTTPFound(
270 269 request.static_path('rhodecode:public/images/favicon.ico'))
271 270
272 271 config.add_view(favicon_redirect, route_name='favicon')
273 272 config.add_route('favicon', '/favicon.ico')
274 273
275 274 def robots_redirect(context, request):
276 275 return HTTPFound(
277 276 request.static_path('rhodecode:public/robots.txt'))
278 277
279 278 config.add_view(robots_redirect, route_name='robots')
280 279 config.add_route('robots', '/robots.txt')
281 280
282 281 config.add_static_view(
283 282 '_static/deform', 'deform:static')
284 283 config.add_static_view(
285 284 '_static/rhodecode', path='rhodecode:public', cache_max_age=3600 * 24)
286 285
287 286
288 287 def includeme(config, auth_resources=None):
289 288 from rhodecode.lib.celerylib.loader import configure_celery
290 289 log.debug('Initializing main includeme from %s', os.path.basename(__file__))
291 290 settings = config.registry.settings
292 291 config.set_request_factory(Request)
293 292
294 293 # plugin information
295 294 config.registry.rhodecode_plugins = collections.OrderedDict()
296 295
297 296 config.add_directive(
298 297 'register_rhodecode_plugin', register_rhodecode_plugin)
299 298
300 299 config.add_directive('configure_celery', configure_celery)
301 300
302 301 if settings.get('appenlight', False):
303 302 config.include('appenlight_client.ext.pyramid_tween')
304 303
305 304 load_all = should_load_all()
306 305
307 306 # Includes which are required. The application would fail without them.
308 307 config.include('pyramid_mako')
309 308 config.include('rhodecode.lib.rc_beaker')
310 309 config.include('rhodecode.lib.rc_cache')
311 310 config.include('rhodecode.apps._base.navigation')
312 311 config.include('rhodecode.apps._base.subscribers')
313 312 config.include('rhodecode.tweens')
314 313 config.include('rhodecode.authentication')
315 314
316 315 if load_all:
317 316 ce_auth_resources = [
318 317 'rhodecode.authentication.plugins.auth_crowd',
319 318 'rhodecode.authentication.plugins.auth_headers',
320 319 'rhodecode.authentication.plugins.auth_jasig_cas',
321 320 'rhodecode.authentication.plugins.auth_ldap',
322 321 'rhodecode.authentication.plugins.auth_pam',
323 322 'rhodecode.authentication.plugins.auth_rhodecode',
324 323 'rhodecode.authentication.plugins.auth_token',
325 324 ]
326 325
327 326 # load CE authentication plugins
328 327
329 328 if auth_resources:
330 329 ce_auth_resources.extend(auth_resources)
331 330
332 331 for resource in ce_auth_resources:
333 332 config.include(resource)
334 333
335 334 # Auto discover authentication plugins and include their configuration.
336 335 if asbool(settings.get('auth_plugin.import_legacy_plugins', 'true')):
337 336 from rhodecode.authentication import discover_legacy_plugins
338 337 discover_legacy_plugins(config)
339 338
340 339 # apps
341 340 if load_all:
342 config.include('rhodecode.api')
343 config.include('rhodecode.apps._base')
344 config.include('rhodecode.apps.hovercards')
345 config.include('rhodecode.apps.ops')
346 config.include('rhodecode.apps.channelstream')
347 config.include('rhodecode.apps.file_store')
348 config.include('rhodecode.apps.admin')
349 config.include('rhodecode.apps.login')
350 config.include('rhodecode.apps.home')
351 config.include('rhodecode.apps.journal')
341 log.debug('Starting config.include() calls')
342 config.include('rhodecode.api.includeme')
343 config.include('rhodecode.apps._base.includeme')
344 config.include('rhodecode.apps._base.navigation.includeme')
345 config.include('rhodecode.apps._base.subscribers.includeme')
346 config.include('rhodecode.apps.hovercards.includeme')
347 config.include('rhodecode.apps.ops.includeme')
348 config.include('rhodecode.apps.channelstream.includeme')
349 config.include('rhodecode.apps.file_store.includeme')
350 config.include('rhodecode.apps.admin.includeme')
351 config.include('rhodecode.apps.login.includeme')
352 config.include('rhodecode.apps.home.includeme')
353 config.include('rhodecode.apps.journal.includeme')
352 354
353 config.include('rhodecode.apps.repository')
354 config.include('rhodecode.apps.repo_group')
355 config.include('rhodecode.apps.user_group')
356 config.include('rhodecode.apps.search')
357 config.include('rhodecode.apps.user_profile')
358 config.include('rhodecode.apps.user_group_profile')
359 config.include('rhodecode.apps.my_account')
360 config.include('rhodecode.apps.gist')
355 config.include('rhodecode.apps.repository.includeme')
356 config.include('rhodecode.apps.repo_group.includeme')
357 config.include('rhodecode.apps.user_group.includeme')
358 config.include('rhodecode.apps.search.includeme')
359 config.include('rhodecode.apps.user_profile.includeme')
360 config.include('rhodecode.apps.user_group_profile.includeme')
361 config.include('rhodecode.apps.my_account.includeme')
362 config.include('rhodecode.apps.gist.includeme')
361 363
362 config.include('rhodecode.apps.svn_support')
363 config.include('rhodecode.apps.ssh_support')
364 config.include('rhodecode.apps.svn_support.includeme')
365 config.include('rhodecode.apps.ssh_support.includeme')
364 366 config.include('rhodecode.apps.debug_style')
365 367
366 368 if load_all:
367 config.include('rhodecode.integrations')
369 config.include('rhodecode.integrations.includeme')
370 config.include('rhodecode.integrations.routes.includeme')
368 371
369 372 config.add_route('rhodecode_support', 'https://rhodecode.com/help/', static=True)
370 373 settings['default_locale_name'] = settings.get('lang', 'en')
371 374 config.add_translation_dirs('rhodecode:i18n/')
372 375
373 376 # Add subscribers.
374 377 if load_all:
378 log.debug('Adding subscribers....')
375 379 config.add_subscriber(scan_repositories_if_enabled,
376 380 pyramid.events.ApplicationCreated)
377 381 config.add_subscriber(write_metadata_if_needed,
378 382 pyramid.events.ApplicationCreated)
379 383 config.add_subscriber(write_usage_data,
380 384 pyramid.events.ApplicationCreated)
381 385 config.add_subscriber(write_js_routes_if_enabled,
382 386 pyramid.events.ApplicationCreated)
383 387
384 388 # Set the authorization policy.
385 389 authz_policy = ACLAuthorizationPolicy()
386 390 config.set_authorization_policy(authz_policy)
387 391
388 392 # Set the default renderer for HTML templates to mako.
389 393 config.add_mako_renderer('.html')
390 394
391 395 config.add_renderer(
392 396 name='json_ext',
393 397 factory='rhodecode.lib.ext_json_renderer.pyramid_ext_json')
394 398
395 399 config.add_renderer(
396 400 name='string_html',
397 401 factory='rhodecode.lib.string_renderer.html')
398 402
399 403 # include RhodeCode plugins
400 404 includes = aslist(settings.get('rhodecode.includes', []))
405 log.debug('processing rhodecode.includes data...')
401 406 for inc in includes:
402 407 config.include(inc)
403 408
404 409 # custom not found view, if our pyramid app doesn't know how to handle
405 410 # the request pass it to potential VCS handling ap
406 411 config.add_notfound_view(not_found_view)
407 412 if not settings.get('debugtoolbar.enabled', False):
408 413 # disabled debugtoolbar handle all exceptions via the error_handlers
409 414 config.add_view(error_handler, context=Exception)
410 415
411 416 # all errors including 403/404/50X
412 417 config.add_view(error_handler, context=HTTPError)
413 418
414 419
415 420 def wrap_app_in_wsgi_middlewares(pyramid_app, config):
416 421 """
417 422 Apply outer WSGI middlewares around the application.
418 423 """
419 424 registry = config.registry
420 425 settings = registry.settings
421 426
422 427 # enable https redirects based on HTTP_X_URL_SCHEME set by proxy
423 428 pyramid_app = HttpsFixup(pyramid_app, settings)
424 429
425 430 pyramid_app, _ae_client = wrap_in_appenlight_if_enabled(
426 431 pyramid_app, settings)
427 432 registry.ae_client = _ae_client
428 433
429 434 if settings['gzip_responses']:
430 435 pyramid_app = make_gzip_middleware(
431 436 pyramid_app, settings, compress_level=1)
432 437
433 438 # this should be the outer most middleware in the wsgi stack since
434 439 # middleware like Routes make database calls
435 440 def pyramid_app_with_cleanup(environ, start_response):
436 441 start = time.time()
437 442 try:
438 443 return pyramid_app(environ, start_response)
439 444 finally:
440 445 # Dispose current database session and rollback uncommitted
441 446 # transactions.
442 447 meta.Session.remove()
443 448
444 449 # In a single threaded mode server, on non sqlite db we should have
445 450 # '0 Current Checked out connections' at the end of a request,
446 451 # if not, then something, somewhere is leaving a connection open
447 452 pool = meta.Base.metadata.bind.engine.pool
448 453 log.debug('sa pool status: %s', pool.status())
449 454 total = time.time() - start
450 455 log.debug('Request processing finalized: %.4fs', total)
451 456
452 457 return pyramid_app_with_cleanup
453 458
454 459
455 460 def sanitize_settings_and_apply_defaults(global_config, settings):
456 461 """
457 462 Applies settings defaults and does all type conversion.
458 463
459 464 We would move all settings parsing and preparation into this place, so that
460 465 we have only one place left which deals with this part. The remaining parts
461 466 of the application would start to rely fully on well prepared settings.
462 467
463 468 This piece would later be split up per topic to avoid a big fat monster
464 469 function.
465 470 """
466 471
467 472 global_settings_maker = SettingsMaker(global_config)
468 473 global_settings_maker.make_setting('debug', default=False, parser='bool')
469 474 debug_enabled = asbool(global_config.get('debug'))
470 475
471 476 settings_maker = SettingsMaker(settings)
472 477
473 478 settings_maker.make_setting(
474 479 'logging.autoconfigure',
475 480 default=False,
476 481 parser='bool')
477 482
478 483 logging_conf = os.path.join(os.path.dirname(global_config.get('__file__')), 'logging.ini')
479 484 settings_maker.enable_logging(logging_conf, level='INFO' if debug_enabled else 'DEBUG')
480 485
481 486 # Default includes, possible to change as a user
482 487 pyramid_includes = settings_maker.make_setting('pyramid.includes', [], parser='list:newline')
483 488 log.debug(
484 489 "Using the following pyramid.includes: %s",
485 490 pyramid_includes)
486 491
487 492 settings_maker.make_setting('rhodecode.edition', 'Community Edition')
488 493 settings_maker.make_setting('rhodecode.edition_id', 'CE')
489 494
490 495 if 'mako.default_filters' not in settings:
491 496 # set custom default filters if we don't have it defined
492 497 settings['mako.imports'] = 'from rhodecode.lib.base import h_filter'
493 498 settings['mako.default_filters'] = 'h_filter'
494 499
495 500 if 'mako.directories' not in settings:
496 501 mako_directories = settings.setdefault('mako.directories', [
497 502 # Base templates of the original application
498 503 'rhodecode:templates',
499 504 ])
500 505 log.debug(
501 506 "Using the following Mako template directories: %s",
502 507 mako_directories)
503 508
504 509 # NOTE(marcink): fix redis requirement for schema of connection since 3.X
505 510 if 'beaker.session.type' in settings and settings['beaker.session.type'] == 'ext:redis':
506 511 raw_url = settings['beaker.session.url']
507 512 if not raw_url.startswith(('redis://', 'rediss://', 'unix://')):
508 513 settings['beaker.session.url'] = 'redis://' + raw_url
509 514
510 515 settings_maker.make_setting('__file__', global_config.get('__file__'))
511 516
512 517 # TODO: johbo: Re-think this, usually the call to config.include
513 518 # should allow to pass in a prefix.
514 519 settings_maker.make_setting('rhodecode.api.url', '/_admin/api')
515 520
516 521 # Sanitize generic settings.
517 522 settings_maker.make_setting('default_encoding', 'UTF-8', parser='list')
518 523 settings_maker.make_setting('is_test', False, parser='bool')
519 524 settings_maker.make_setting('gzip_responses', False, parser='bool')
520 525
521 526 # statsd
522 527 settings_maker.make_setting('statsd.enabled', False, parser='bool')
523 528 settings_maker.make_setting('statsd.statsd_host', 'statsd-exporter', parser='string')
524 529 settings_maker.make_setting('statsd.statsd_port', 9125, parser='int')
525 530 settings_maker.make_setting('statsd.statsd_prefix', '')
526 531 settings_maker.make_setting('statsd.statsd_ipv6', False, parser='bool')
527 532
528 533 settings_maker.make_setting('vcs.svn.compatible_version', '')
529 534 settings_maker.make_setting('vcs.hooks.protocol', 'http')
530 535 settings_maker.make_setting('vcs.hooks.host', '127.0.0.1')
531 536 settings_maker.make_setting('vcs.scm_app_implementation', 'http')
532 537 settings_maker.make_setting('vcs.server', '')
533 538 settings_maker.make_setting('vcs.server.protocol', 'http')
534 539 settings_maker.make_setting('vcs.server.enable', 'true', parser='bool')
535 540 settings_maker.make_setting('startup.import_repos', 'false', parser='bool')
536 541 settings_maker.make_setting('vcs.hooks.direct_calls', 'false', parser='bool')
537 542 settings_maker.make_setting('vcs.start_server', 'false', parser='bool')
538 543 settings_maker.make_setting('vcs.backends', 'hg, git, svn', parser='list')
539 544 settings_maker.make_setting('vcs.connection_timeout', 3600, parser='int')
540 545
541 546 settings_maker.make_setting('vcs.methods.cache', True, parser='bool')
542 547
543 548 # Support legacy values of vcs.scm_app_implementation. Legacy
544 549 # configurations may use 'rhodecode.lib.middleware.utils.scm_app_http', or
545 550 # disabled since 4.13 'vcsserver.scm_app' which is now mapped to 'http'.
546 551 scm_app_impl = settings['vcs.scm_app_implementation']
547 552 if scm_app_impl in ['rhodecode.lib.middleware.utils.scm_app_http', 'vcsserver.scm_app']:
548 553 settings['vcs.scm_app_implementation'] = 'http'
549 554
550 555 settings_maker.make_setting('appenlight', False, parser='bool')
551 556
552 557 temp_store = tempfile.gettempdir()
553 558 tmp_cache_dir = os.path.join(temp_store, 'rc_cache')
554 559
555 560 # save default, cache dir, and use it for all backends later.
556 561 default_cache_dir = settings_maker.make_setting(
557 562 'cache_dir',
558 563 default=tmp_cache_dir, default_when_empty=True,
559 564 parser='dir:ensured')
560 565
561 566 # exception store cache
562 567 settings_maker.make_setting(
563 568 'exception_tracker.store_path',
564 569 default=os.path.join(default_cache_dir, 'exc_store'), default_when_empty=True,
565 570 parser='dir:ensured'
566 571 )
567 572
568 573 settings_maker.make_setting(
569 574 'celerybeat-schedule.path',
570 575 default=os.path.join(default_cache_dir, 'celerybeat_schedule', 'celerybeat-schedule.db'), default_when_empty=True,
571 576 parser='file:ensured'
572 577 )
573 578
574 579 settings_maker.make_setting('exception_tracker.send_email', False, parser='bool')
575 580 settings_maker.make_setting('exception_tracker.email_prefix', '[RHODECODE ERROR]', default_when_empty=True)
576 581
577 582 # cache_general
578 583 settings_maker.make_setting('rc_cache.cache_general.backend', 'dogpile.cache.rc.file_namespace')
579 584 settings_maker.make_setting('rc_cache.cache_general.expiration_time', 60 * 60 * 12, parser='int')
580 585 settings_maker.make_setting('rc_cache.cache_general.arguments.filename', os.path.join(default_cache_dir, 'rhodecode_cache_general.db'))
581 586
582 587 # cache_perms
583 588 settings_maker.make_setting('rc_cache.cache_perms.backend', 'dogpile.cache.rc.file_namespace')
584 589 settings_maker.make_setting('rc_cache.cache_perms.expiration_time', 60 * 60, parser='int')
585 590 settings_maker.make_setting('rc_cache.cache_perms.arguments.filename', os.path.join(default_cache_dir, 'rhodecode_cache_perms.db'))
586 591
587 592 # cache_repo
588 593 settings_maker.make_setting('rc_cache.cache_repo.backend', 'dogpile.cache.rc.file_namespace')
589 594 settings_maker.make_setting('rc_cache.cache_repo.expiration_time', 60 * 60 * 24 * 30, parser='int')
590 595 settings_maker.make_setting('rc_cache.cache_repo.arguments.filename', os.path.join(default_cache_dir, 'rhodecode_cache_repo.db'))
591 596
592 597 # cache_license
593 598 settings_maker.make_setting('rc_cache.cache_license.backend', 'dogpile.cache.rc.file_namespace')
594 599 settings_maker.make_setting('rc_cache.cache_license.expiration_time', 60 * 5, parser='int')
595 600 settings_maker.make_setting('rc_cache.cache_license.arguments.filename', os.path.join(default_cache_dir, 'rhodecode_cache_license.db'))
596 601
597 602 # cache_repo_longterm memory, 96H
598 603 settings_maker.make_setting('rc_cache.cache_repo_longterm.backend', 'dogpile.cache.rc.memory_lru')
599 604 settings_maker.make_setting('rc_cache.cache_repo_longterm.expiration_time', 345600, parser='int')
600 605 settings_maker.make_setting('rc_cache.cache_repo_longterm.max_size', 10000, parser='int')
601 606
602 607 # sql_cache_short
603 608 settings_maker.make_setting('rc_cache.sql_cache_short.backend', 'dogpile.cache.rc.memory_lru')
604 609 settings_maker.make_setting('rc_cache.sql_cache_short.expiration_time', 30, parser='int')
605 610 settings_maker.make_setting('rc_cache.sql_cache_short.max_size', 10000, parser='int')
606 611
607 612 settings_maker.env_expand()
608 613
609 614 # configure instance id
610 615 config_utils.set_instance_id(settings)
611 616
612 617 return settings
General Comments 0
You need to be logged in to leave comments. Login now