##// END OF EJS Templates
config: removed vcsserver log_level deprecated option.
marcink -
r4168:2a769b0d default
parent child Browse files
Show More
@@ -1,754 +1,753 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2010-2019 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 logging
24 24 import collections
25 25 import tempfile
26 26 import time
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.environment import load_pyramid_environment
42 42
43 43 import rhodecode.events
44 44 from rhodecode.lib.middleware.vcs import VCSMiddleware
45 45 from rhodecode.lib.request import Request
46 46 from rhodecode.lib.vcs import VCSCommunicationError
47 47 from rhodecode.lib.exceptions import VCSServerUnavailable
48 48 from rhodecode.lib.middleware.appenlight import wrap_in_appenlight_if_enabled
49 49 from rhodecode.lib.middleware.https_fixup import HttpsFixup
50 50 from rhodecode.lib.celerylib.loader import configure_celery
51 51 from rhodecode.lib.plugins.utils import register_rhodecode_plugin
52 52 from rhodecode.lib.utils2 import aslist as rhodecode_aslist, 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, inject_app_settings)
57 57
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
92 92 # Allows to use format style "{ENV_NAME}" placeholders in the configuration. It
93 93 # will be replaced by the value of the environment variable "NAME" in this case.
94 94 start_time = time.time()
95 95
96 96 debug = asbool(global_config.get('debug'))
97 97 if debug:
98 98 enable_debug()
99 99
100 100 environ = {'ENV_{}'.format(key): value for key, value in os.environ.items()}
101 101
102 102 global_config = _substitute_values(global_config, environ)
103 103 settings = _substitute_values(settings, environ)
104 104
105 105 sanitize_settings_and_apply_defaults(global_config, settings)
106 106
107 107 config = Configurator(settings=settings)
108 108
109 109 # Apply compatibility patches
110 110 patches.inspect_getargspec()
111 111
112 112 load_pyramid_environment(global_config, settings)
113 113
114 114 # Static file view comes first
115 115 includeme_first(config)
116 116
117 117 includeme(config)
118 118
119 119 pyramid_app = config.make_wsgi_app()
120 120 pyramid_app = wrap_app_in_wsgi_middlewares(pyramid_app, config)
121 121 pyramid_app.config = config
122 122
123 123 config.configure_celery(global_config['__file__'])
124 124 # creating the app uses a connection - return it after we are done
125 125 meta.Session.remove()
126 126 total_time = time.time() - start_time
127 127 log.info('Pyramid app `%s` created and configured in %.2fs',
128 128 pyramid_app.func_name, total_time)
129 129
130 130 return pyramid_app
131 131
132 132
133 133 def not_found_view(request):
134 134 """
135 135 This creates the view which should be registered as not-found-view to
136 136 pyramid.
137 137 """
138 138
139 139 if not getattr(request, 'vcs_call', None):
140 140 # handle like regular case with our error_handler
141 141 return error_handler(HTTPNotFound(), request)
142 142
143 143 # handle not found view as a vcs call
144 144 settings = request.registry.settings
145 145 ae_client = getattr(request, 'ae_client', None)
146 146 vcs_app = VCSMiddleware(
147 147 HTTPNotFound(), request.registry, settings,
148 148 appenlight_client=ae_client)
149 149
150 150 return wsgiapp(vcs_app)(None, request)
151 151
152 152
153 153 def error_handler(exception, request):
154 154 import rhodecode
155 155 from rhodecode.lib import helpers
156 156
157 157 rhodecode_title = rhodecode.CONFIG.get('rhodecode_title') or 'RhodeCode'
158 158
159 159 base_response = HTTPInternalServerError()
160 160 # prefer original exception for the response since it may have headers set
161 161 if isinstance(exception, HTTPException):
162 162 base_response = exception
163 163 elif isinstance(exception, VCSCommunicationError):
164 164 base_response = VCSServerUnavailable()
165 165
166 166 if is_http_error(base_response):
167 167 log.exception(
168 168 'error occurred handling this request for path: %s', request.path)
169 169
170 170 error_explanation = base_response.explanation or str(base_response)
171 171 if base_response.status_code == 404:
172 172 error_explanation += " Optionally you don't have permission to access this page."
173 173 c = AttributeDict()
174 174 c.error_message = base_response.status
175 175 c.error_explanation = error_explanation
176 176 c.visual = AttributeDict()
177 177
178 178 c.visual.rhodecode_support_url = (
179 179 request.registry.settings.get('rhodecode_support_url') or
180 180 request.route_url('rhodecode_support')
181 181 )
182 182 c.redirect_time = 0
183 183 c.rhodecode_name = rhodecode_title
184 184 if not c.rhodecode_name:
185 185 c.rhodecode_name = 'Rhodecode'
186 186
187 187 c.causes = []
188 188 if is_http_error(base_response):
189 189 c.causes.append('Server is overloaded.')
190 190 c.causes.append('Server database connection is lost.')
191 191 c.causes.append('Server expected unhandled error.')
192 192
193 193 if hasattr(base_response, 'causes'):
194 194 c.causes = base_response.causes
195 195
196 196 c.messages = helpers.flash.pop_messages(request=request)
197 197
198 198 exc_info = sys.exc_info()
199 199 c.exception_id = id(exc_info)
200 200 c.show_exception_id = isinstance(base_response, VCSServerUnavailable) \
201 201 or base_response.status_code > 499
202 202 c.exception_id_url = request.route_url(
203 203 'admin_settings_exception_tracker_show', exception_id=c.exception_id)
204 204
205 205 if c.show_exception_id:
206 206 store_exception(c.exception_id, exc_info)
207 207
208 208 response = render_to_response(
209 209 '/errors/error_document.mako', {'c': c, 'h': helpers}, request=request,
210 210 response=base_response)
211 211
212 212 return response
213 213
214 214
215 215 def includeme_first(config):
216 216 # redirect automatic browser favicon.ico requests to correct place
217 217 def favicon_redirect(context, request):
218 218 return HTTPFound(
219 219 request.static_path('rhodecode:public/images/favicon.ico'))
220 220
221 221 config.add_view(favicon_redirect, route_name='favicon')
222 222 config.add_route('favicon', '/favicon.ico')
223 223
224 224 def robots_redirect(context, request):
225 225 return HTTPFound(
226 226 request.static_path('rhodecode:public/robots.txt'))
227 227
228 228 config.add_view(robots_redirect, route_name='robots')
229 229 config.add_route('robots', '/robots.txt')
230 230
231 231 config.add_static_view(
232 232 '_static/deform', 'deform:static')
233 233 config.add_static_view(
234 234 '_static/rhodecode', path='rhodecode:public', cache_max_age=3600 * 24)
235 235
236 236
237 237 def includeme(config):
238 238 log.debug('Initializing main includeme from %s', os.path.basename(__file__))
239 239 settings = config.registry.settings
240 240 config.set_request_factory(Request)
241 241
242 242 # plugin information
243 243 config.registry.rhodecode_plugins = collections.OrderedDict()
244 244
245 245 config.add_directive(
246 246 'register_rhodecode_plugin', register_rhodecode_plugin)
247 247
248 248 config.add_directive('configure_celery', configure_celery)
249 249
250 250 if asbool(settings.get('appenlight', 'false')):
251 251 config.include('appenlight_client.ext.pyramid_tween')
252 252
253 253 load_all = should_load_all()
254 254
255 255 # Includes which are required. The application would fail without them.
256 256 config.include('pyramid_mako')
257 257 config.include('rhodecode.lib.rc_beaker')
258 258 config.include('rhodecode.lib.rc_cache')
259 259
260 260 config.include('rhodecode.apps._base.navigation')
261 261 config.include('rhodecode.apps._base.subscribers')
262 262 config.include('rhodecode.tweens')
263 263 config.include('rhodecode.authentication')
264 264
265 265 if load_all:
266 266 config.include('rhodecode.integrations')
267 267
268 268 if load_all:
269 269 # load CE authentication plugins
270 270 config.include('rhodecode.authentication.plugins.auth_crowd')
271 271 config.include('rhodecode.authentication.plugins.auth_headers')
272 272 config.include('rhodecode.authentication.plugins.auth_jasig_cas')
273 273 config.include('rhodecode.authentication.plugins.auth_ldap')
274 274 config.include('rhodecode.authentication.plugins.auth_pam')
275 275 config.include('rhodecode.authentication.plugins.auth_rhodecode')
276 276 config.include('rhodecode.authentication.plugins.auth_token')
277 277
278 278 # Auto discover authentication plugins and include their configuration.
279 279 if asbool(settings.get('auth_plugin.import_legacy_plugins', 'true')):
280 280 from rhodecode.authentication import discover_legacy_plugins
281 281 discover_legacy_plugins(config)
282 282
283 283 # apps
284 284 if load_all:
285 285 config.include('rhodecode.apps._base')
286 286 config.include('rhodecode.apps.hovercards')
287 287 config.include('rhodecode.apps.ops')
288 288 config.include('rhodecode.apps.admin')
289 289 config.include('rhodecode.apps.channelstream')
290 290 config.include('rhodecode.apps.file_store')
291 291 config.include('rhodecode.apps.login')
292 292 config.include('rhodecode.apps.home')
293 293 config.include('rhodecode.apps.journal')
294 294 config.include('rhodecode.apps.repository')
295 295 config.include('rhodecode.apps.repo_group')
296 296 config.include('rhodecode.apps.user_group')
297 297 config.include('rhodecode.apps.search')
298 298 config.include('rhodecode.apps.user_profile')
299 299 config.include('rhodecode.apps.user_group_profile')
300 300 config.include('rhodecode.apps.my_account')
301 301 config.include('rhodecode.apps.svn_support')
302 302 config.include('rhodecode.apps.ssh_support')
303 303 config.include('rhodecode.apps.gist')
304 304 config.include('rhodecode.apps.debug_style')
305 305 config.include('rhodecode.api')
306 306
307 307 config.add_route('rhodecode_support', 'https://rhodecode.com/help/', static=True)
308 308 config.add_translation_dirs('rhodecode:i18n/')
309 309 settings['default_locale_name'] = settings.get('lang', 'en')
310 310
311 311 # Add subscribers.
312 312 if load_all:
313 313 config.add_subscriber(inject_app_settings,
314 314 pyramid.events.ApplicationCreated)
315 315 config.add_subscriber(scan_repositories_if_enabled,
316 316 pyramid.events.ApplicationCreated)
317 317 config.add_subscriber(write_metadata_if_needed,
318 318 pyramid.events.ApplicationCreated)
319 319 config.add_subscriber(write_js_routes_if_enabled,
320 320 pyramid.events.ApplicationCreated)
321 321
322 322 # request custom methods
323 323 config.add_request_method(
324 324 'rhodecode.lib.partial_renderer.get_partial_renderer',
325 325 'get_partial_renderer')
326 326
327 327 config.add_request_method(
328 328 'rhodecode.lib.request_counter.get_request_counter',
329 329 'request_count')
330 330
331 331 # Set the authorization policy.
332 332 authz_policy = ACLAuthorizationPolicy()
333 333 config.set_authorization_policy(authz_policy)
334 334
335 335 # Set the default renderer for HTML templates to mako.
336 336 config.add_mako_renderer('.html')
337 337
338 338 config.add_renderer(
339 339 name='json_ext',
340 340 factory='rhodecode.lib.ext_json_renderer.pyramid_ext_json')
341 341
342 342 # include RhodeCode plugins
343 343 includes = aslist(settings.get('rhodecode.includes', []))
344 344 for inc in includes:
345 345 config.include(inc)
346 346
347 347 # custom not found view, if our pyramid app doesn't know how to handle
348 348 # the request pass it to potential VCS handling ap
349 349 config.add_notfound_view(not_found_view)
350 350 if not settings.get('debugtoolbar.enabled', False):
351 351 # disabled debugtoolbar handle all exceptions via the error_handlers
352 352 config.add_view(error_handler, context=Exception)
353 353
354 354 # all errors including 403/404/50X
355 355 config.add_view(error_handler, context=HTTPError)
356 356
357 357
358 358 def wrap_app_in_wsgi_middlewares(pyramid_app, config):
359 359 """
360 360 Apply outer WSGI middlewares around the application.
361 361 """
362 362 registry = config.registry
363 363 settings = registry.settings
364 364
365 365 # enable https redirects based on HTTP_X_URL_SCHEME set by proxy
366 366 pyramid_app = HttpsFixup(pyramid_app, settings)
367 367
368 368 pyramid_app, _ae_client = wrap_in_appenlight_if_enabled(
369 369 pyramid_app, settings)
370 370 registry.ae_client = _ae_client
371 371
372 372 if settings['gzip_responses']:
373 373 pyramid_app = make_gzip_middleware(
374 374 pyramid_app, settings, compress_level=1)
375 375
376 376 # this should be the outer most middleware in the wsgi stack since
377 377 # middleware like Routes make database calls
378 378 def pyramid_app_with_cleanup(environ, start_response):
379 379 try:
380 380 return pyramid_app(environ, start_response)
381 381 finally:
382 382 # Dispose current database session and rollback uncommitted
383 383 # transactions.
384 384 meta.Session.remove()
385 385
386 386 # In a single threaded mode server, on non sqlite db we should have
387 387 # '0 Current Checked out connections' at the end of a request,
388 388 # if not, then something, somewhere is leaving a connection open
389 389 pool = meta.Base.metadata.bind.engine.pool
390 390 log.debug('sa pool status: %s', pool.status())
391 391 log.debug('Request processing finalized')
392 392
393 393 return pyramid_app_with_cleanup
394 394
395 395
396 396 def sanitize_settings_and_apply_defaults(global_config, settings):
397 397 """
398 398 Applies settings defaults and does all type conversion.
399 399
400 400 We would move all settings parsing and preparation into this place, so that
401 401 we have only one place left which deals with this part. The remaining parts
402 402 of the application would start to rely fully on well prepared settings.
403 403
404 404 This piece would later be split up per topic to avoid a big fat monster
405 405 function.
406 406 """
407 407
408 408 settings.setdefault('rhodecode.edition', 'Community Edition')
409 409
410 410 if 'mako.default_filters' not in settings:
411 411 # set custom default filters if we don't have it defined
412 412 settings['mako.imports'] = 'from rhodecode.lib.base import h_filter'
413 413 settings['mako.default_filters'] = 'h_filter'
414 414
415 415 if 'mako.directories' not in settings:
416 416 mako_directories = settings.setdefault('mako.directories', [
417 417 # Base templates of the original application
418 418 'rhodecode:templates',
419 419 ])
420 420 log.debug(
421 421 "Using the following Mako template directories: %s",
422 422 mako_directories)
423 423
424 424 # NOTE(marcink): fix redis requirement for schema of connection since 3.X
425 425 if 'beaker.session.type' in settings and settings['beaker.session.type'] == 'ext:redis':
426 426 raw_url = settings['beaker.session.url']
427 427 if not raw_url.startswith(('redis://', 'rediss://', 'unix://')):
428 428 settings['beaker.session.url'] = 'redis://' + raw_url
429 429
430 430 # Default includes, possible to change as a user
431 431 pyramid_includes = settings.setdefault('pyramid.includes', [])
432 432 log.debug(
433 433 "Using the following pyramid.includes: %s",
434 434 pyramid_includes)
435 435
436 436 # TODO: johbo: Re-think this, usually the call to config.include
437 437 # should allow to pass in a prefix.
438 438 settings.setdefault('rhodecode.api.url', '/_admin/api')
439 439 settings.setdefault('__file__', global_config.get('__file__'))
440 440
441 441 # Sanitize generic settings.
442 442 _list_setting(settings, 'default_encoding', 'UTF-8')
443 443 _bool_setting(settings, 'is_test', 'false')
444 444 _bool_setting(settings, 'gzip_responses', 'false')
445 445
446 446 # Call split out functions that sanitize settings for each topic.
447 447 _sanitize_appenlight_settings(settings)
448 448 _sanitize_vcs_settings(settings)
449 449 _sanitize_cache_settings(settings)
450 450
451 451 # configure instance id
452 452 config_utils.set_instance_id(settings)
453 453
454 454 return settings
455 455
456 456
457 457 def enable_debug():
458 458 """
459 459 Helper to enable debug on running instance
460 460 :return:
461 461 """
462 462 import tempfile
463 463 import textwrap
464 464 import logging.config
465 465
466 466 ini_template = textwrap.dedent("""
467 467 #####################################
468 468 ### DEBUG LOGGING CONFIGURATION ####
469 469 #####################################
470 470 [loggers]
471 471 keys = root, sqlalchemy, beaker, celery, rhodecode, ssh_wrapper
472 472
473 473 [handlers]
474 474 keys = console, console_sql
475 475
476 476 [formatters]
477 477 keys = generic, color_formatter, color_formatter_sql
478 478
479 479 #############
480 480 ## LOGGERS ##
481 481 #############
482 482 [logger_root]
483 483 level = NOTSET
484 484 handlers = console
485 485
486 486 [logger_sqlalchemy]
487 487 level = INFO
488 488 handlers = console_sql
489 489 qualname = sqlalchemy.engine
490 490 propagate = 0
491 491
492 492 [logger_beaker]
493 493 level = DEBUG
494 494 handlers =
495 495 qualname = beaker.container
496 496 propagate = 1
497 497
498 498 [logger_rhodecode]
499 499 level = DEBUG
500 500 handlers =
501 501 qualname = rhodecode
502 502 propagate = 1
503 503
504 504 [logger_ssh_wrapper]
505 505 level = DEBUG
506 506 handlers =
507 507 qualname = ssh_wrapper
508 508 propagate = 1
509 509
510 510 [logger_celery]
511 511 level = DEBUG
512 512 handlers =
513 513 qualname = celery
514 514
515 515
516 516 ##############
517 517 ## HANDLERS ##
518 518 ##############
519 519
520 520 [handler_console]
521 521 class = StreamHandler
522 522 args = (sys.stderr, )
523 523 level = DEBUG
524 524 formatter = color_formatter
525 525
526 526 [handler_console_sql]
527 527 # "level = DEBUG" logs SQL queries and results.
528 528 # "level = INFO" logs SQL queries.
529 529 # "level = WARN" logs neither. (Recommended for production systems.)
530 530 class = StreamHandler
531 531 args = (sys.stderr, )
532 532 level = WARN
533 533 formatter = color_formatter_sql
534 534
535 535 ################
536 536 ## FORMATTERS ##
537 537 ################
538 538
539 539 [formatter_generic]
540 540 class = rhodecode.lib.logging_formatter.ExceptionAwareFormatter
541 541 format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s | %(req_id)s
542 542 datefmt = %Y-%m-%d %H:%M:%S
543 543
544 544 [formatter_color_formatter]
545 545 class = rhodecode.lib.logging_formatter.ColorRequestTrackingFormatter
546 546 format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s | %(req_id)s
547 547 datefmt = %Y-%m-%d %H:%M:%S
548 548
549 549 [formatter_color_formatter_sql]
550 550 class = rhodecode.lib.logging_formatter.ColorFormatterSql
551 551 format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s
552 552 datefmt = %Y-%m-%d %H:%M:%S
553 553 """)
554 554
555 555 with tempfile.NamedTemporaryFile(prefix='rc_debug_logging_', suffix='.ini',
556 556 delete=False) as f:
557 557 log.info('Saved Temporary DEBUG config at %s', f.name)
558 558 f.write(ini_template)
559 559
560 560 logging.config.fileConfig(f.name)
561 561 log.debug('DEBUG MODE ON')
562 562 os.remove(f.name)
563 563
564 564
565 565 def _sanitize_appenlight_settings(settings):
566 566 _bool_setting(settings, 'appenlight', 'false')
567 567
568 568
569 569 def _sanitize_vcs_settings(settings):
570 570 """
571 571 Applies settings defaults and does type conversion for all VCS related
572 572 settings.
573 573 """
574 574 _string_setting(settings, 'vcs.svn.compatible_version', '')
575 575 _string_setting(settings, 'vcs.hooks.protocol', 'http')
576 576 _string_setting(settings, 'vcs.hooks.host', '127.0.0.1')
577 577 _string_setting(settings, 'vcs.scm_app_implementation', 'http')
578 578 _string_setting(settings, 'vcs.server', '')
579 _string_setting(settings, 'vcs.server.log_level', 'debug')
580 579 _string_setting(settings, 'vcs.server.protocol', 'http')
581 580 _bool_setting(settings, 'startup.import_repos', 'false')
582 581 _bool_setting(settings, 'vcs.hooks.direct_calls', 'false')
583 582 _bool_setting(settings, 'vcs.server.enable', 'true')
584 583 _bool_setting(settings, 'vcs.start_server', 'false')
585 584 _list_setting(settings, 'vcs.backends', 'hg, git, svn')
586 585 _int_setting(settings, 'vcs.connection_timeout', 3600)
587 586
588 587 # Support legacy values of vcs.scm_app_implementation. Legacy
589 588 # configurations may use 'rhodecode.lib.middleware.utils.scm_app_http', or
590 589 # disabled since 4.13 'vcsserver.scm_app' which is now mapped to 'http'.
591 590 scm_app_impl = settings['vcs.scm_app_implementation']
592 591 if scm_app_impl in ['rhodecode.lib.middleware.utils.scm_app_http', 'vcsserver.scm_app']:
593 592 settings['vcs.scm_app_implementation'] = 'http'
594 593
595 594
596 595 def _sanitize_cache_settings(settings):
597 596 temp_store = tempfile.gettempdir()
598 597 default_cache_dir = os.path.join(temp_store, 'rc_cache')
599 598
600 599 # save default, cache dir, and use it for all backends later.
601 600 default_cache_dir = _string_setting(
602 601 settings,
603 602 'cache_dir',
604 603 default_cache_dir, lower=False, default_when_empty=True)
605 604
606 605 # ensure we have our dir created
607 606 if not os.path.isdir(default_cache_dir):
608 607 os.makedirs(default_cache_dir, mode=0o755)
609 608
610 609 # exception store cache
611 610 _string_setting(
612 611 settings,
613 612 'exception_tracker.store_path',
614 613 temp_store, lower=False, default_when_empty=True)
615 614
616 615 # cache_perms
617 616 _string_setting(
618 617 settings,
619 618 'rc_cache.cache_perms.backend',
620 619 'dogpile.cache.rc.file_namespace', lower=False)
621 620 _int_setting(
622 621 settings,
623 622 'rc_cache.cache_perms.expiration_time',
624 623 60)
625 624 _string_setting(
626 625 settings,
627 626 'rc_cache.cache_perms.arguments.filename',
628 627 os.path.join(default_cache_dir, 'rc_cache_1'), lower=False)
629 628
630 629 # cache_repo
631 630 _string_setting(
632 631 settings,
633 632 'rc_cache.cache_repo.backend',
634 633 'dogpile.cache.rc.file_namespace', lower=False)
635 634 _int_setting(
636 635 settings,
637 636 'rc_cache.cache_repo.expiration_time',
638 637 60)
639 638 _string_setting(
640 639 settings,
641 640 'rc_cache.cache_repo.arguments.filename',
642 641 os.path.join(default_cache_dir, 'rc_cache_2'), lower=False)
643 642
644 643 # cache_license
645 644 _string_setting(
646 645 settings,
647 646 'rc_cache.cache_license.backend',
648 647 'dogpile.cache.rc.file_namespace', lower=False)
649 648 _int_setting(
650 649 settings,
651 650 'rc_cache.cache_license.expiration_time',
652 651 5*60)
653 652 _string_setting(
654 653 settings,
655 654 'rc_cache.cache_license.arguments.filename',
656 655 os.path.join(default_cache_dir, 'rc_cache_3'), lower=False)
657 656
658 657 # cache_repo_longterm memory, 96H
659 658 _string_setting(
660 659 settings,
661 660 'rc_cache.cache_repo_longterm.backend',
662 661 'dogpile.cache.rc.memory_lru', lower=False)
663 662 _int_setting(
664 663 settings,
665 664 'rc_cache.cache_repo_longterm.expiration_time',
666 665 345600)
667 666 _int_setting(
668 667 settings,
669 668 'rc_cache.cache_repo_longterm.max_size',
670 669 10000)
671 670
672 671 # sql_cache_short
673 672 _string_setting(
674 673 settings,
675 674 'rc_cache.sql_cache_short.backend',
676 675 'dogpile.cache.rc.memory_lru', lower=False)
677 676 _int_setting(
678 677 settings,
679 678 'rc_cache.sql_cache_short.expiration_time',
680 679 30)
681 680 _int_setting(
682 681 settings,
683 682 'rc_cache.sql_cache_short.max_size',
684 683 10000)
685 684
686 685
687 686 def _int_setting(settings, name, default):
688 687 settings[name] = int(settings.get(name, default))
689 688 return settings[name]
690 689
691 690
692 691 def _bool_setting(settings, name, default):
693 692 input_val = settings.get(name, default)
694 693 if isinstance(input_val, unicode):
695 694 input_val = input_val.encode('utf8')
696 695 settings[name] = asbool(input_val)
697 696 return settings[name]
698 697
699 698
700 699 def _list_setting(settings, name, default):
701 700 raw_value = settings.get(name, default)
702 701
703 702 old_separator = ','
704 703 if old_separator in raw_value:
705 704 # If we get a comma separated list, pass it to our own function.
706 705 settings[name] = rhodecode_aslist(raw_value, sep=old_separator)
707 706 else:
708 707 # Otherwise we assume it uses pyramids space/newline separation.
709 708 settings[name] = aslist(raw_value)
710 709 return settings[name]
711 710
712 711
713 712 def _string_setting(settings, name, default, lower=True, default_when_empty=False):
714 713 value = settings.get(name, default)
715 714
716 715 if default_when_empty and not value:
717 716 # use default value when value is empty
718 717 value = default
719 718
720 719 if lower:
721 720 value = value.lower()
722 721 settings[name] = value
723 722 return settings[name]
724 723
725 724
726 725 def _substitute_values(mapping, substitutions):
727 726 result = {}
728 727
729 728 try:
730 729 for key, value in mapping.items():
731 730 # initialize without substitution first
732 731 result[key] = value
733 732
734 733 # Note: Cannot use regular replacements, since they would clash
735 734 # with the implementation of ConfigParser. Using "format" instead.
736 735 try:
737 736 result[key] = value.format(**substitutions)
738 737 except KeyError as e:
739 738 env_var = '{}'.format(e.args[0])
740 739
741 740 msg = 'Failed to substitute: `{key}={{{var}}}` with environment entry. ' \
742 741 'Make sure your environment has {var} set, or remove this ' \
743 742 'variable from config file'.format(key=key, var=env_var)
744 743
745 744 if env_var.startswith('ENV_'):
746 745 raise ValueError(msg)
747 746 else:
748 747 log.warning(msg)
749 748
750 749 except ValueError as e:
751 750 log.warning('Failed to substitute ENV variable: %s', e)
752 751 result = mapping
753 752
754 753 return result
@@ -1,204 +1,203 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2016-2019 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
22 22 import pytest
23 23
24 24 from rhodecode.tests import no_newline_id_generator
25 25 from rhodecode.config.middleware import (
26 26 _sanitize_vcs_settings, _bool_setting, _string_setting, _list_setting,
27 27 _int_setting)
28 28
29 29
30 30 class TestHelperFunctions(object):
31 31 @pytest.mark.parametrize('raw, expected', [
32 32 ('true', True), (u'true', True),
33 33 ('yes', True), (u'yes', True),
34 34 ('on', True), (u'on', True),
35 35 ('false', False), (u'false', False),
36 36 ('no', False), (u'no', False),
37 37 ('off', False), (u'off', False),
38 38 ('invalid-bool-value', False),
39 39 ('invalid-∫øø@-√Γ₯@¨€', False),
40 40 (u'invalid-∫øø@-√Γ₯@¨€', False),
41 41 ])
42 42 def test_bool_setting_helper(self, raw, expected):
43 43 key = 'dummy-key'
44 44 settings = {key: raw}
45 45 _bool_setting(settings, key, None)
46 46 assert settings[key] is expected
47 47
48 48 @pytest.mark.parametrize('raw, expected', [
49 49 ('', ''),
50 50 ('test-string', 'test-string'),
51 51 ('CaSe-TeSt', 'case-test'),
52 52 ('test-string-烩€', 'test-string-烩€'),
53 53 (u'test-string-烩€', u'test-string-烩€'),
54 54 ])
55 55 def test_string_setting_helper(self, raw, expected):
56 56 key = 'dummy-key'
57 57 settings = {key: raw}
58 58 _string_setting(settings, key, None)
59 59 assert settings[key] == expected
60 60
61 61 @pytest.mark.parametrize('raw, expected', [
62 62 ('', []),
63 63 ('test', ['test']),
64 64 ('CaSe-TeSt', ['CaSe-TeSt']),
65 65 ('test-string-烩€', ['test-string-烩€']),
66 66 (u'test-string-烩€', [u'test-string-烩€']),
67 67 ('hg git svn', ['hg', 'git', 'svn']),
68 68 ('hg,git,svn', ['hg', 'git', 'svn']),
69 69 ('hg, git, svn', ['hg', 'git', 'svn']),
70 70 ('hg\ngit\nsvn', ['hg', 'git', 'svn']),
71 71 (' hg\n git\n svn ', ['hg', 'git', 'svn']),
72 72 (', hg , git , svn , ', ['', 'hg', 'git', 'svn', '']),
73 73 ('cheese,free node,other', ['cheese', 'free node', 'other']),
74 74 ], ids=no_newline_id_generator)
75 75 def test_list_setting_helper(self, raw, expected):
76 76 key = 'dummy-key'
77 77 settings = {key: raw}
78 78 _list_setting(settings, key, None)
79 79 assert settings[key] == expected
80 80
81 81 @pytest.mark.parametrize('raw, expected', [
82 82 ('0', 0),
83 83 ('-0', 0),
84 84 ('12345', 12345),
85 85 ('-12345', -12345),
86 86 (u'-12345', -12345),
87 87 ])
88 88 def test_int_setting_helper(self, raw, expected):
89 89 key = 'dummy-key'
90 90 settings = {key: raw}
91 91 _int_setting(settings, key, None)
92 92 assert settings[key] == expected
93 93
94 94 @pytest.mark.parametrize('raw', [
95 95 ('0xff'),
96 96 (''),
97 97 ('invalid-int'),
98 98 ('invalid-⁄~†'),
99 99 (u'invalid-⁄~†'),
100 100 ])
101 101 def test_int_setting_helper_invalid_input(self, raw):
102 102 key = 'dummy-key'
103 103 settings = {key: raw}
104 104 with pytest.raises(Exception):
105 105 _int_setting(settings, key, None)
106 106
107 107
108 108 class TestSanitizeVcsSettings(object):
109 109 _bool_settings = [
110 110 ('vcs.hooks.direct_calls', False),
111 111 ('vcs.server.enable', True),
112 112 ('vcs.start_server', False),
113 113 ('startup.import_repos', False),
114 114 ]
115 115
116 116 _string_settings = [
117 117 ('vcs.svn.compatible_version', ''),
118 118 ('vcs.hooks.protocol', 'http'),
119 119 ('vcs.hooks.host', '127.0.0.1'),
120 120 ('vcs.scm_app_implementation', 'http'),
121 121 ('vcs.server', ''),
122 ('vcs.server.log_level', 'debug'),
123 122 ('vcs.server.protocol', 'http'),
124 123 ]
125 124
126 125 _list_settings = [
127 126 ('vcs.backends', 'hg git'),
128 127 ]
129 128
130 129 @pytest.mark.parametrize('key, default', _list_settings)
131 130 def test_list_setting_spacesep_list(self, key, default):
132 131 test_list = ['test', 'list', 'values', 'for', key]
133 132 input_value = ' '.join(test_list)
134 133 settings = {key: input_value}
135 134 _sanitize_vcs_settings(settings)
136 135 assert settings[key] == test_list
137 136
138 137 @pytest.mark.parametrize('key, default', _list_settings)
139 138 def test_list_setting_newlinesep_list(self, key, default):
140 139 test_list = ['test', 'list', 'values', 'for', key]
141 140 input_value = '\n'.join(test_list)
142 141 settings = {key: input_value}
143 142 _sanitize_vcs_settings(settings)
144 143 assert settings[key] == test_list
145 144
146 145 @pytest.mark.parametrize('key, default', _list_settings)
147 146 def test_list_setting_commasep_list(self, key, default):
148 147 test_list = ['test', 'list', 'values', 'for', key]
149 148 input_value = ','.join(test_list)
150 149 settings = {key: input_value}
151 150 _sanitize_vcs_settings(settings)
152 151 assert settings[key] == test_list
153 152
154 153 @pytest.mark.parametrize('key, default', _list_settings)
155 154 def test_list_setting_comma_and_space_sep_list(self, key, default):
156 155 test_list = ['test', 'list', 'values', 'for', key]
157 156 input_value = ', '.join(test_list)
158 157 settings = {key: input_value}
159 158 _sanitize_vcs_settings(settings)
160 159 assert settings[key] == test_list
161 160
162 161 @pytest.mark.parametrize('key, default', _string_settings)
163 162 def test_string_setting_string(self, key, default):
164 163 test_value = 'test-string-for-{}'.format(key)
165 164 settings = {key: test_value}
166 165 _sanitize_vcs_settings(settings)
167 166 assert settings[key] == test_value
168 167
169 168 @pytest.mark.parametrize('key, default', _string_settings)
170 169 def test_string_setting_default(self, key, default):
171 170 settings = {}
172 171 _sanitize_vcs_settings(settings)
173 172 assert settings[key] == default
174 173
175 174 @pytest.mark.parametrize('key, default', _string_settings)
176 175 def test_string_setting_lowercase(self, key, default):
177 176 test_value = 'Test-String-For-{}'.format(key)
178 177 settings = {key: test_value}
179 178 _sanitize_vcs_settings(settings)
180 179 assert settings[key] == test_value.lower()
181 180
182 181 @pytest.mark.parametrize('key, default', _bool_settings)
183 182 def test_bool_setting_true(self, key, default):
184 183 settings = {key: 'true'}
185 184 _sanitize_vcs_settings(settings)
186 185 assert settings[key] is True
187 186
188 187 @pytest.mark.parametrize('key, default', _bool_settings)
189 188 def test_bool_setting_false(self, key, default):
190 189 settings = {key: 'false'}
191 190 _sanitize_vcs_settings(settings)
192 191 assert settings[key] is False
193 192
194 193 @pytest.mark.parametrize('key, default', _bool_settings)
195 194 def test_bool_setting_invalid_string(self, key, default):
196 195 settings = {key: 'no-bool-val-string'}
197 196 _sanitize_vcs_settings(settings)
198 197 assert settings[key] is False
199 198
200 199 @pytest.mark.parametrize('key, default', _bool_settings)
201 200 def test_bool_setting_default(self, key, default):
202 201 settings = {}
203 202 _sanitize_vcs_settings(settings)
204 203 assert settings[key] is default
@@ -1,664 +1,664 b''
1 1
2 2
3 3 ################################################################################
4 4 ## RHODECODE COMMUNITY EDITION CONFIGURATION ##
5 5 # The %(here)s variable will be replaced with the parent directory of this file#
6 6 ################################################################################
7 7
8 8 [DEFAULT]
9 9 debug = true
10 10
11 11 ################################################################################
12 12 ## EMAIL CONFIGURATION ##
13 13 ## Uncomment and replace with the email address which should receive ##
14 14 ## any error reports after an application crash ##
15 15 ## Additionally these settings will be used by the RhodeCode mailing system ##
16 16 ################################################################################
17 17
18 18 ## prefix all emails subjects with given prefix, helps filtering out emails
19 19 #email_prefix = [RhodeCode]
20 20
21 21 ## email FROM address all mails will be sent
22 22 #app_email_from = rhodecode-noreply@localhost
23 23
24 24 ## Uncomment and replace with the address which should receive any error report
25 25 ## note: using appenlight for error handling doesn't need this to be uncommented
26 26 #email_to = admin@localhost
27 27
28 28 #smtp_server = mail.server.com
29 29 #smtp_username =
30 30 #smtp_password =
31 31 #smtp_port =
32 32 #smtp_use_tls = false
33 33 #smtp_use_ssl = true
34 34
35 35 [server:main]
36 36 ## COMMON ##
37 37 host = 0.0.0.0
38 38 port = 5000
39 39
40 40 ##########################
41 41 ## GUNICORN WSGI SERVER ##
42 42 ##########################
43 43 ## run with gunicorn --log-config rhodecode.ini --paste rhodecode.ini
44 44
45 45 use = egg:gunicorn#main
46 46 ## Sets the number of process workers. You must set `instance_id = *`
47 47 ## when this option is set to more than one worker, recommended
48 48 ## value is (2 * NUMBER_OF_CPUS + 1), eg 2CPU = 5 workers
49 49 ## The `instance_id = *` must be set in the [app:main] section below
50 50 #workers = 2
51 51 ## number of threads for each of the worker, must be set to 1 for gevent
52 52 ## generally recommened to be at 1
53 53 #threads = 1
54 54 ## process name
55 55 #proc_name = rhodecode
56 56 ## type of worker class, one of sync, gevent
57 57 ## recommended for bigger setup is using of of other than sync one
58 58 #worker_class = sync
59 59 ## The maximum number of simultaneous clients. Valid only for Gevent
60 60 #worker_connections = 10
61 61 ## max number of requests that worker will handle before being gracefully
62 62 ## restarted, could prevent memory leaks
63 63 #max_requests = 1000
64 64 #max_requests_jitter = 30
65 65 ## amount of time a worker can spend with handling a request before it
66 66 ## gets killed and restarted. Set to 6hrs
67 67 #timeout = 21600
68 68
69 69 ## prefix middleware for RhodeCode.
70 70 ## recommended when using proxy setup.
71 71 ## allows to set RhodeCode under a prefix in server.
72 72 ## eg https://server.com/custom_prefix. Enable `filter-with =` option below as well.
73 73 ## And set your prefix like: `prefix = /custom_prefix`
74 74 ## be sure to also set beaker.session.cookie_path = /custom_prefix if you need
75 75 ## to make your cookies only work on prefix url
76 76 [filter:proxy-prefix]
77 77 use = egg:PasteDeploy#prefix
78 78 prefix = /
79 79
80 80 [app:main]
81 81 is_test = True
82 82 use = egg:rhodecode-enterprise-ce
83 83
84 84 ## enable proxy prefix middleware, defined above
85 85 #filter-with = proxy-prefix
86 86
87 87
88 88 ## RHODECODE PLUGINS ##
89 89 rhodecode.includes = rhodecode.api
90 90
91 91 # api prefix url
92 92 rhodecode.api.url = /_admin/api
93 93
94 94
95 95 ## END RHODECODE PLUGINS ##
96 96
97 97 ## encryption key used to encrypt social plugin tokens,
98 98 ## remote_urls with credentials etc, if not set it defaults to
99 99 ## `beaker.session.secret`
100 100 #rhodecode.encrypted_values.secret =
101 101
102 102 ## decryption strict mode (enabled by default). It controls if decryption raises
103 103 ## `SignatureVerificationError` in case of wrong key, or damaged encryption data.
104 104 #rhodecode.encrypted_values.strict = false
105 105
106 106 ## return gzipped responses from Rhodecode (static files/application)
107 107 gzip_responses = false
108 108
109 109 ## autogenerate javascript routes file on startup
110 110 generate_js_files = false
111 111
112 112 ## Optional Languages
113 113 ## en(default), be, de, es, fr, it, ja, pl, pt, ru, zh
114 114 lang = en
115 115
116 116 ## perform a full repository scan on each server start, this should be
117 117 ## set to false after first startup, to allow faster server restarts.
118 118 startup.import_repos = true
119 119
120 120 ## Uncomment and set this path to use archive download cache.
121 121 ## Once enabled, generated archives will be cached at this location
122 122 ## and served from the cache during subsequent requests for the same archive of
123 123 ## the repository.
124 124 #archive_cache_dir = /tmp/tarballcache
125 125
126 126 ## URL at which the application is running. This is used for bootstraping
127 127 ## requests in context when no web request is available. Used in ishell, or
128 128 ## SSH calls. Set this for events to receive proper url for SSH calls.
129 129 app.base_url = http://rhodecode.local
130 130
131 131 ## change this to unique ID for security
132 132 app_instance_uuid = rc-production
133 133
134 134 ## cut off limit for large diffs (size in bytes)
135 135 cut_off_limit_diff = 1024000
136 136 cut_off_limit_file = 256000
137 137
138 138 ## use cache version of scm repo everywhere
139 139 vcs_full_cache = false
140 140
141 141 ## force https in RhodeCode, fixes https redirects, assumes it's always https
142 142 ## Normally this is controlled by proper http flags sent from http server
143 143 force_https = false
144 144
145 145 ## use Strict-Transport-Security headers
146 146 use_htsts = false
147 147
148 148 # Set to true if your repos are exposed using the dumb protocol
149 149 git_update_server_info = false
150 150
151 151 ## RSS/ATOM feed options
152 152 rss_cut_off_limit = 256000
153 153 rss_items_per_page = 10
154 154 rss_include_diff = false
155 155
156 156 ## gist URL alias, used to create nicer urls for gist. This should be an
157 157 ## url that does rewrites to _admin/gists/{gistid}.
158 158 ## example: http://gist.rhodecode.org/{gistid}. Empty means use the internal
159 159 ## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/{gistid}
160 160 gist_alias_url =
161 161
162 162 ## List of views (using glob pattern syntax) that AUTH TOKENS could be
163 163 ## used for access.
164 164 ## Adding ?auth_token=TOKEN_HASH to the url authenticates this request as if it
165 165 ## came from the the logged in user who own this authentication token.
166 166 ## Additionally @TOKEN syntaxt can be used to bound the view to specific
167 167 ## authentication token. Such view would be only accessible when used together
168 168 ## with this authentication token
169 169 ##
170 170 ## list of all views can be found under `/_admin/permissions/auth_token_access`
171 171 ## The list should be "," separated and on a single line.
172 172 ##
173 173 ## Most common views to enable:
174 174 # RepoCommitsView:repo_commit_download
175 175 # RepoCommitsView:repo_commit_patch
176 176 # RepoCommitsView:repo_commit_raw
177 177 # RepoCommitsView:repo_commit_raw@TOKEN
178 178 # RepoFilesView:repo_files_diff
179 179 # RepoFilesView:repo_archivefile
180 180 # RepoFilesView:repo_file_raw
181 181 # GistView:*
182 182 api_access_controllers_whitelist =
183 183
184 184 ## default encoding used to convert from and to unicode
185 185 ## can be also a comma separated list of encoding in case of mixed encodings
186 186 default_encoding = UTF-8
187 187
188 188 ## instance-id prefix
189 189 ## a prefix key for this instance used for cache invalidation when running
190 190 ## multiple instances of rhodecode, make sure it's globally unique for
191 191 ## all running rhodecode instances. Leave empty if you don't use it
192 192 instance_id =
193 193
194 194 ## Fallback authentication plugin. Set this to a plugin ID to force the usage
195 195 ## of an authentication plugin also if it is disabled by it's settings.
196 196 ## This could be useful if you are unable to log in to the system due to broken
197 197 ## authentication settings. Then you can enable e.g. the internal rhodecode auth
198 198 ## module to log in again and fix the settings.
199 199 ##
200 200 ## Available builtin plugin IDs (hash is part of the ID):
201 201 ## egg:rhodecode-enterprise-ce#rhodecode
202 202 ## egg:rhodecode-enterprise-ce#pam
203 203 ## egg:rhodecode-enterprise-ce#ldap
204 204 ## egg:rhodecode-enterprise-ce#jasig_cas
205 205 ## egg:rhodecode-enterprise-ce#headers
206 206 ## egg:rhodecode-enterprise-ce#crowd
207 207 #rhodecode.auth_plugin_fallback = egg:rhodecode-enterprise-ce#rhodecode
208 208
209 209 ## alternative return HTTP header for failed authentication. Default HTTP
210 210 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
211 211 ## handling that causing a series of failed authentication calls.
212 212 ## Set this variable to 403 to return HTTPForbidden, or any other HTTP code
213 213 ## This will be served instead of default 401 on bad authnetication
214 214 auth_ret_code =
215 215
216 216 ## use special detection method when serving auth_ret_code, instead of serving
217 217 ## ret_code directly, use 401 initially (Which triggers credentials prompt)
218 218 ## and then serve auth_ret_code to clients
219 219 auth_ret_code_detection = false
220 220
221 221 ## locking return code. When repository is locked return this HTTP code. 2XX
222 222 ## codes don't break the transactions while 4XX codes do
223 223 lock_ret_code = 423
224 224
225 225 ## allows to change the repository location in settings page
226 226 allow_repo_location_change = true
227 227
228 228 ## allows to setup custom hooks in settings page
229 229 allow_custom_hooks_settings = true
230 230
231 231 ## generated license token, goto license page in RhodeCode settings to obtain
232 232 ## new token
233 233 license_token = abra-cada-bra1-rce3
234 234
235 235 ## supervisor connection uri, for managing supervisor and logs.
236 236 supervisor.uri =
237 237 ## supervisord group name/id we only want this RC instance to handle
238 238 supervisor.group_id = dev
239 239
240 240 ## Display extended labs settings
241 241 labs_settings_active = true
242 242
243 243 ####################################
244 244 ### CELERY CONFIG ####
245 245 ####################################
246 246 use_celery = false
247 247 broker.host = localhost
248 248 broker.vhost = rabbitmqhost
249 249 broker.port = 5672
250 250 broker.user = rabbitmq
251 251 broker.password = qweqwe
252 252
253 253 celery.imports = rhodecode.lib.celerylib.tasks
254 254
255 255 celery.result.backend = amqp
256 256 celery.result.dburi = amqp://
257 257 celery.result.serialier = json
258 258
259 259 #celery.send.task.error.emails = true
260 260 #celery.amqp.task.result.expires = 18000
261 261
262 262 celeryd.concurrency = 2
263 263 #celeryd.log.file = celeryd.log
264 264 celeryd.log.level = debug
265 265 celeryd.max.tasks.per.child = 1
266 266
267 267 ## tasks will never be sent to the queue, but executed locally instead.
268 268 celery.always.eager = false
269 269
270 270 ####################################
271 271 ### BEAKER CACHE ####
272 272 ####################################
273 273 # default cache dir for templates. Putting this into a ramdisk
274 274 ## can boost performance, eg. %(here)s/data_ramdisk
275 275 cache_dir = %(here)s/data
276 276
277 277 ## locking and default file storage for Beaker. Putting this into a ramdisk
278 278 ## can boost performance, eg. %(here)s/data_ramdisk/cache/beaker_data
279 279 beaker.cache.data_dir = %(here)s/rc/data/cache/beaker_data
280 280 beaker.cache.lock_dir = %(here)s/rc/data/cache/beaker_lock
281 281
282 282 beaker.cache.regions = long_term
283 283
284 284 beaker.cache.long_term.type = memory
285 285 beaker.cache.long_term.expire = 36000
286 286 beaker.cache.long_term.key_length = 256
287 287
288 288
289 289 #####################################
290 290 ### DOGPILE CACHE ####
291 291 #####################################
292 292
293 293 ## permission tree cache settings
294 294 rc_cache.cache_perms.backend = dogpile.cache.rc.file_namespace
295 295 rc_cache.cache_perms.expiration_time = 0
296 296 rc_cache.cache_perms.arguments.filename = /tmp/rc_cache_1
297 297
298 298
299 299 ## cache settings for SQL queries
300 300 rc_cache.sql_cache_short.backend = dogpile.cache.rc.memory_lru
301 301 rc_cache.sql_cache_short.expiration_time = 0
302 302
303 303
304 304 ####################################
305 305 ### BEAKER SESSION ####
306 306 ####################################
307 307
308 308 ## .session.type is type of storage options for the session, current allowed
309 309 ## types are file, ext:memcached, ext:database, and memory (default).
310 310 beaker.session.type = file
311 311 beaker.session.data_dir = %(here)s/rc/data/sessions/data
312 312
313 313 ## db based session, fast, and allows easy management over logged in users
314 314 #beaker.session.type = ext:database
315 315 #beaker.session.table_name = db_session
316 316 #beaker.session.sa.url = postgresql://postgres:secret@localhost/rhodecode
317 317 #beaker.session.sa.url = mysql://root:secret@127.0.0.1/rhodecode
318 318 #beaker.session.sa.pool_recycle = 3600
319 319 #beaker.session.sa.echo = false
320 320
321 321 beaker.session.key = rhodecode
322 322 beaker.session.secret = test-rc-uytcxaz
323 323 beaker.session.lock_dir = %(here)s/rc/data/sessions/lock
324 324
325 325 ## Secure encrypted cookie. Requires AES and AES python libraries
326 326 ## you must disable beaker.session.secret to use this
327 327 #beaker.session.encrypt_key = key_for_encryption
328 328 #beaker.session.validate_key = validation_key
329 329
330 330 ## sets session as invalid(also logging out user) if it haven not been
331 331 ## accessed for given amount of time in seconds
332 332 beaker.session.timeout = 2592000
333 333 beaker.session.httponly = true
334 334 ## Path to use for the cookie. Set to prefix if you use prefix middleware
335 335 #beaker.session.cookie_path = /custom_prefix
336 336
337 337 ## uncomment for https secure cookie
338 338 beaker.session.secure = false
339 339
340 340 ## auto save the session to not to use .save()
341 341 beaker.session.auto = false
342 342
343 343 ## default cookie expiration time in seconds, set to `true` to set expire
344 344 ## at browser close
345 345 #beaker.session.cookie_expires = 3600
346 346
347 347 ###################################
348 348 ## SEARCH INDEXING CONFIGURATION ##
349 349 ###################################
350 350 ## Full text search indexer is available in rhodecode-tools under
351 351 ## `rhodecode-tools index` command
352 352
353 353 ## WHOOSH Backend, doesn't require additional services to run
354 354 ## it works good with few dozen repos
355 355 search.module = rhodecode.lib.index.whoosh
356 356 search.location = %(here)s/data/index
357 357
358 358 ########################################
359 359 ### CHANNELSTREAM CONFIG ####
360 360 ########################################
361 361 ## channelstream enables persistent connections and live notification
362 362 ## in the system. It's also used by the chat system
363 363
364 364 channelstream.enabled = false
365 365
366 366 ## server address for channelstream server on the backend
367 367 channelstream.server = 127.0.0.1:9800
368 368 ## location of the channelstream server from outside world
369 369 ## use ws:// for http or wss:// for https. This address needs to be handled
370 370 ## by external HTTP server such as Nginx or Apache
371 371 ## see nginx/apache configuration examples in our docs
372 372 channelstream.ws_url = ws://rhodecode.yourserver.com/_channelstream
373 373 channelstream.secret = secret
374 374 channelstream.history.location = %(here)s/channelstream_history
375 375
376 376 ## Internal application path that Javascript uses to connect into.
377 377 ## If you use proxy-prefix the prefix should be added before /_channelstream
378 378 channelstream.proxy_path = /_channelstream
379 379
380 380
381 381 ###################################
382 382 ## APPENLIGHT CONFIG ##
383 383 ###################################
384 384
385 385 ## Appenlight is tailored to work with RhodeCode, see
386 386 ## http://appenlight.com for details how to obtain an account
387 387
388 388 ## appenlight integration enabled
389 389 appenlight = false
390 390
391 391 appenlight.server_url = https://api.appenlight.com
392 392 appenlight.api_key = YOUR_API_KEY
393 393 #appenlight.transport_config = https://api.appenlight.com?threaded=1&timeout=5
394 394
395 395 # used for JS client
396 396 appenlight.api_public_key = YOUR_API_PUBLIC_KEY
397 397
398 398 ## TWEAK AMOUNT OF INFO SENT HERE
399 399
400 400 ## enables 404 error logging (default False)
401 401 appenlight.report_404 = false
402 402
403 403 ## time in seconds after request is considered being slow (default 1)
404 404 appenlight.slow_request_time = 1
405 405
406 406 ## record slow requests in application
407 407 ## (needs to be enabled for slow datastore recording and time tracking)
408 408 appenlight.slow_requests = true
409 409
410 410 ## enable hooking to application loggers
411 411 appenlight.logging = true
412 412
413 413 ## minimum log level for log capture
414 414 appenlight.logging.level = WARNING
415 415
416 416 ## send logs only from erroneous/slow requests
417 417 ## (saves API quota for intensive logging)
418 418 appenlight.logging_on_error = false
419 419
420 420 ## list of additonal keywords that should be grabbed from environ object
421 421 ## can be string with comma separated list of words in lowercase
422 422 ## (by default client will always send following info:
423 423 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
424 424 ## start with HTTP* this list be extended with additional keywords here
425 425 appenlight.environ_keys_whitelist =
426 426
427 427 ## list of keywords that should be blanked from request object
428 428 ## can be string with comma separated list of words in lowercase
429 429 ## (by default client will always blank keys that contain following words
430 430 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
431 431 ## this list be extended with additional keywords set here
432 432 appenlight.request_keys_blacklist =
433 433
434 434 ## list of namespaces that should be ignores when gathering log entries
435 435 ## can be string with comma separated list of namespaces
436 436 ## (by default the client ignores own entries: appenlight_client.client)
437 437 appenlight.log_namespace_blacklist =
438 438
439 439
440 440 ################################################################################
441 441 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
442 442 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
443 443 ## execute malicious code after an exception is raised. ##
444 444 ################################################################################
445 445 set debug = false
446 446
447 447
448 448 ##############
449 449 ## STYLING ##
450 450 ##############
451 451 debug_style = false
452 452
453 453 ###########################################
454 454 ### MAIN RHODECODE DATABASE CONFIG ###
455 455 ###########################################
456 456 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode_test.db?timeout=30
457 457 #sqlalchemy.db1.url = postgresql://postgres:qweqwe@localhost/rhodecode_test
458 458 #sqlalchemy.db1.url = mysql://root:qweqwe@localhost/rhodecode_test
459 459 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode_test.db?timeout=30
460 460
461 461 # see sqlalchemy docs for other advanced settings
462 462
463 463 ## print the sql statements to output
464 464 sqlalchemy.db1.echo = false
465 465 ## recycle the connections after this amount of seconds
466 466 sqlalchemy.db1.pool_recycle = 3600
467 467
468 468 ## the number of connections to keep open inside the connection pool.
469 469 ## 0 indicates no limit
470 470 #sqlalchemy.db1.pool_size = 5
471 471
472 472 ## the number of connections to allow in connection pool "overflow", that is
473 473 ## connections that can be opened above and beyond the pool_size setting,
474 474 ## which defaults to five.
475 475 #sqlalchemy.db1.max_overflow = 10
476 476
477 477
478 478 ##################
479 479 ### VCS CONFIG ###
480 480 ##################
481 481 vcs.server.enable = true
482 482 vcs.server = localhost:9901
483 483
484 484 ## Web server connectivity protocol, responsible for web based VCS operatations
485 485 ## Available protocols are:
486 486 ## `http` - use http-rpc backend (default)
487 487 vcs.server.protocol = http
488 488
489 489 ## Push/Pull operations protocol, available options are:
490 490 ## `http` - use http-rpc backend (default)
491 491 ## `vcsserver.scm_app` - internal app (EE only)
492 492 vcs.scm_app_implementation = http
493 493
494 494 ## Push/Pull operations hooks protocol, available options are:
495 495 ## `http` - use http-rpc backend (default)
496 496 vcs.hooks.protocol = http
497 497 vcs.hooks.host = 127.0.0.1
498 498
499 vcs.server.log_level = debug
499
500 500 ## Start VCSServer with this instance as a subprocess, Useful for development
501 501 vcs.start_server = false
502 502
503 503 ## List of enabled VCS backends, available options are:
504 504 ## `hg` - mercurial
505 505 ## `git` - git
506 506 ## `svn` - subversion
507 507 vcs.backends = hg, git, svn
508 508
509 509 vcs.connection_timeout = 3600
510 510 ## Compatibility version when creating SVN repositories. Defaults to newest version when commented out.
511 511 ## Available options are: pre-1.4-compatible, pre-1.5-compatible, pre-1.6-compatible, pre-1.8-compatible, pre-1.9-compatible
512 512 #vcs.svn.compatible_version = pre-1.8-compatible
513 513
514 514
515 515 ############################################################
516 516 ### Subversion proxy support (mod_dav_svn) ###
517 517 ### Maps RhodeCode repo groups into SVN paths for Apache ###
518 518 ############################################################
519 519 ## Enable or disable the config file generation.
520 520 svn.proxy.generate_config = false
521 521 ## Generate config file with `SVNListParentPath` set to `On`.
522 522 svn.proxy.list_parent_path = true
523 523 ## Set location and file name of generated config file.
524 524 svn.proxy.config_file_path = %(here)s/mod_dav_svn.conf
525 525 ## Used as a prefix to the `Location` block in the generated config file.
526 526 ## In most cases it should be set to `/`.
527 527 svn.proxy.location_root = /
528 528 ## Command to reload the mod dav svn configuration on change.
529 529 ## Example: `/etc/init.d/apache2 reload`
530 530 #svn.proxy.reload_cmd = /etc/init.d/apache2 reload
531 531 ## If the timeout expires before the reload command finishes, the command will
532 532 ## be killed. Setting it to zero means no timeout. Defaults to 10 seconds.
533 533 #svn.proxy.reload_timeout = 10
534 534
535 535 ############################################################
536 536 ### SSH Support Settings ###
537 537 ############################################################
538 538
539 539 ## Defines if the authorized_keys file should be written on any change of
540 540 ## user ssh keys, setting this to false also disables posibility of adding
541 541 ## ssh keys for users from web interface.
542 542 ssh.generate_authorized_keyfile = true
543 543
544 544 ## Options for ssh, default is `no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding`
545 545 # ssh.authorized_keys_ssh_opts =
546 546
547 547 ## File to generate the authorized keys together with options
548 548 ## It is possible to have multiple key files specified in `sshd_config` e.g.
549 549 ## AuthorizedKeysFile %h/.ssh/authorized_keys %h/.ssh/authorized_keys_rhodecode
550 550 ssh.authorized_keys_file_path = %(here)s/rc/authorized_keys_rhodecode
551 551
552 552 ## Command to execute the SSH wrapper. The binary is available in the
553 553 ## rhodecode installation directory.
554 554 ## e.g ~/.rccontrol/community-1/profile/bin/rc-ssh-wrapper
555 555 ssh.wrapper_cmd = ~/.rccontrol/community-1/rc-ssh-wrapper
556 556
557 557 ## Allow shell when executing the ssh-wrapper command
558 558 ssh.wrapper_cmd_allow_shell = false
559 559
560 560 ## Enables logging, and detailed output send back to the client. Useful for
561 561 ## debugging, shouldn't be used in production.
562 562 ssh.enable_debug_logging = false
563 563
564 564 ## Paths to binary executrables, by default they are the names, but we can
565 565 ## override them if we want to use a custom one
566 566 ssh.executable.hg = ~/.rccontrol/vcsserver-1/profile/bin/hg
567 567 ssh.executable.git = ~/.rccontrol/vcsserver-1/profile/bin/git
568 568 ssh.executable.svn = ~/.rccontrol/vcsserver-1/profile/bin/svnserve
569 569
570 570 ## Enables SSH key generator web interface. Disabling this still allows users
571 571 ## to add their own keys.
572 572 ssh.enable_ui_key_generator = true
573 573
574 574
575 575 ## Dummy marker to add new entries after.
576 576 ## Add any custom entries below. Please don't remove.
577 577 custom.conf = 1
578 578
579 579
580 580 ################################
581 581 ### LOGGING CONFIGURATION ####
582 582 ################################
583 583 [loggers]
584 584 keys = root, sqlalchemy, beaker, rhodecode, ssh_wrapper
585 585
586 586 [handlers]
587 587 keys = console, console_sql
588 588
589 589 [formatters]
590 590 keys = generic, color_formatter, color_formatter_sql
591 591
592 592 #############
593 593 ## LOGGERS ##
594 594 #############
595 595 [logger_root]
596 596 level = NOTSET
597 597 handlers = console
598 598
599 599 [logger_routes]
600 600 level = DEBUG
601 601 handlers =
602 602 qualname = routes.middleware
603 603 ## "level = DEBUG" logs the route matched and routing variables.
604 604 propagate = 1
605 605
606 606 [logger_beaker]
607 607 level = DEBUG
608 608 handlers =
609 609 qualname = beaker.container
610 610 propagate = 1
611 611
612 612 [logger_rhodecode]
613 613 level = DEBUG
614 614 handlers =
615 615 qualname = rhodecode
616 616 propagate = 1
617 617
618 618 [logger_sqlalchemy]
619 619 level = ERROR
620 620 handlers = console_sql
621 621 qualname = sqlalchemy.engine
622 622 propagate = 0
623 623
624 624 [logger_ssh_wrapper]
625 625 level = DEBUG
626 626 handlers =
627 627 qualname = ssh_wrapper
628 628 propagate = 1
629 629
630 630
631 631 ##############
632 632 ## HANDLERS ##
633 633 ##############
634 634
635 635 [handler_console]
636 636 class = StreamHandler
637 637 args = (sys.stderr,)
638 638 level = DEBUG
639 639 formatter = generic
640 640
641 641 [handler_console_sql]
642 642 class = StreamHandler
643 643 args = (sys.stderr,)
644 644 level = WARN
645 645 formatter = generic
646 646
647 647 ################
648 648 ## FORMATTERS ##
649 649 ################
650 650
651 651 [formatter_generic]
652 652 class = rhodecode.lib.logging_formatter.ExceptionAwareFormatter
653 653 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
654 654 datefmt = %Y-%m-%d %H:%M:%S
655 655
656 656 [formatter_color_formatter]
657 657 class = rhodecode.lib.logging_formatter.ColorFormatter
658 658 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
659 659 datefmt = %Y-%m-%d %H:%M:%S
660 660
661 661 [formatter_color_formatter_sql]
662 662 class = rhodecode.lib.logging_formatter.ColorFormatterSql
663 663 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
664 664 datefmt = %Y-%m-%d %H:%M:%S
General Comments 0
You need to be logged in to leave comments. Login now