##// END OF EJS Templates
app-setup: allow skip of legacy plugin discovery.
marcink -
r4108:eaa05819 default
parent child Browse files
Show More
@@ -1,785 +1,788 b''
1 1
2 2
3 3 ################################################################################
4 4 ## RHODECODE COMMUNITY EDITION CONFIGURATION ##
5 5 ################################################################################
6 6
7 7 [DEFAULT]
8 8 ## Debug flag sets all loggers to debug, and enables request tracking
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 #smtp_server = mail.server.com
25 25 #smtp_username =
26 26 #smtp_password =
27 27 #smtp_port =
28 28 #smtp_use_tls = false
29 29 #smtp_use_ssl = true
30 30
31 31 [server:main]
32 32 ## COMMON ##
33 33 host = 127.0.0.1
34 34 port = 5000
35 35
36 36 ###########################################################
37 37 ## WAITRESS WSGI SERVER - Recommended for Development ####
38 38 ###########################################################
39 39
40 40 use = egg:waitress#main
41 41 ## number of worker threads
42 42 threads = 5
43 43 ## MAX BODY SIZE 100GB
44 44 max_request_body_size = 107374182400
45 45 ## Use poll instead of select, fixes file descriptors limits problems.
46 46 ## May not work on old windows systems.
47 47 asyncore_use_poll = true
48 48
49 49
50 50 ##########################
51 51 ## GUNICORN WSGI SERVER ##
52 52 ##########################
53 53 ## run with gunicorn --log-config rhodecode.ini --paste rhodecode.ini
54 54
55 55 #use = egg:gunicorn#main
56 56 ## Sets the number of process workers. More workers means more concurrent connections
57 57 ## RhodeCode can handle at the same time. Each additional worker also it increases
58 58 ## memory usage as each has it's own set of caches.
59 59 ## Recommended value is (2 * NUMBER_OF_CPUS + 1), eg 2CPU = 5 workers, but no more
60 60 ## than 8-10 unless for really big deployments .e.g 700-1000 users.
61 61 ## `instance_id = *` must be set in the [app:main] section below (which is the default)
62 62 ## when using more than 1 worker.
63 63 #workers = 2
64 64
65 65 ## Gunicorn access log level
66 66 #loglevel = info
67 67
68 68 ## process name visible in process list
69 69 #proc_name = rhodecode
70 70
71 71 ## type of worker class, one of sync, gevent
72 72 ## recommended for bigger setup is using of of other than sync one
73 73 #worker_class = gevent
74 74
75 75 ## The maximum number of simultaneous clients. Valid only for Gevent
76 76 #worker_connections = 10
77 77
78 78 ## max number of requests that worker will handle before being gracefully
79 79 ## restarted, could prevent memory leaks
80 80 #max_requests = 1000
81 81 #max_requests_jitter = 30
82 82
83 83 ## amount of time a worker can spend with handling a request before it
84 84 ## gets killed and restarted. Set to 6hrs
85 85 #timeout = 21600
86 86
87 87 ## The maximum size of HTTP request line in bytes.
88 88 ## 0 for unlimited
89 89 #limit_request_line = 0
90 90
91 91 ## Limit the number of HTTP headers fields in a request.
92 92 ## By default this value is 100 and can't be larger than 32768.
93 93 #limit_request_fields = 32768
94 94
95 95 ## Limit the allowed size of an HTTP request header field.
96 96 ## Value is a positive number or 0.
97 97 ## Setting it to 0 will allow unlimited header field sizes.
98 98 #limit_request_field_size = 0
99 99
100 100 ## Timeout for graceful workers restart.
101 101 ## After receiving a restart signal, workers have this much time to finish
102 102 ## serving requests. Workers still alive after the timeout (starting from the
103 103 ## receipt of the restart signal) are force killed.
104 104 #graceful_timeout = 3600
105 105
106 106 # The number of seconds to wait for requests on a Keep-Alive connection.
107 107 # Generally set in the 1-5 seconds range.
108 108 #keepalive = 2
109 109
110 110 ## Maximum memory usage that each worker can use before it will receive a
111 111 ## graceful restart signal, e.g 10MB = 10485760 (10 * 1024 * 1024)
112 112 # 0 = memory monitoring is disabled
113 113 #memory_max_usage = 0
114 114
115 115 ## How often in seconds to check for memory usage for each gunicorn worker
116 116 #memory_usage_check_interval = 60
117 117
118 118 ## Threshold value for which we don't recycle worker if GarbageCollection
119 119 ## frees up enough resources. Before each restart we try to run GC on worker
120 120 ## in case we get enough free memory after that, restart will not happen.
121 121 #memory_usage_recovery_threshold = 0.8
122 122
123 123 ## prefix middleware for RhodeCode.
124 124 ## recommended when using proxy setup.
125 125 ## allows to set RhodeCode under a prefix in server.
126 126 ## eg https://server.com/custom_prefix. Enable `filter-with =` option below as well.
127 127 ## And set your prefix like: `prefix = /custom_prefix`
128 128 ## be sure to also set beaker.session.cookie_path = /custom_prefix if you need
129 129 ## to make your cookies only work on prefix url
130 130 [filter:proxy-prefix]
131 131 use = egg:PasteDeploy#prefix
132 132 prefix = /
133 133
134 134 [app:main]
135 135 ## The %(here)s variable will be replaced with the absolute path of parent directory
136 136 ## of this file
137 137 ## In addition ENVIRONMENT variables usage is possible, e.g
138 138 ## sqlalchemy.db1.url = {ENV_RC_DB_URL}
139 139
140 140 use = egg:rhodecode-enterprise-ce
141 141
142 142 ## enable proxy prefix middleware, defined above
143 143 #filter-with = proxy-prefix
144 144
145 145 # During development the we want to have the debug toolbar enabled
146 146 pyramid.includes =
147 147 pyramid_debugtoolbar
148 148 rhodecode.lib.middleware.request_wrapper
149 149
150 150 pyramid.reload_templates = true
151 151
152 152 debugtoolbar.hosts = 0.0.0.0/0
153 153 debugtoolbar.exclude_prefixes =
154 154 /css
155 155 /fonts
156 156 /images
157 157 /js
158 158
159 159 ## RHODECODE PLUGINS ##
160 160 rhodecode.includes =
161 161 rhodecode.api
162 162
163 163
164 164 # api prefix url
165 165 rhodecode.api.url = /_admin/api
166 166
167 167
168 168 ## END RHODECODE PLUGINS ##
169 169
170 170 ## encryption key used to encrypt social plugin tokens,
171 171 ## remote_urls with credentials etc, if not set it defaults to
172 172 ## `beaker.session.secret`
173 173 #rhodecode.encrypted_values.secret =
174 174
175 175 ## decryption strict mode (enabled by default). It controls if decryption raises
176 176 ## `SignatureVerificationError` in case of wrong key, or damaged encryption data.
177 177 #rhodecode.encrypted_values.strict = false
178 178
179 179 ## Pick algorithm for encryption. Either fernet (more secure) or aes (default)
180 180 ## fernet is safer, and we strongly recommend switching to it.
181 181 ## Due to backward compatibility aes is used as default.
182 182 #rhodecode.encrypted_values.algorithm = fernet
183 183
184 184 ## return gzipped responses from RhodeCode (static files/application)
185 185 gzip_responses = false
186 186
187 187 ## auto-generate javascript routes file on startup
188 188 generate_js_files = false
189 189
190 190 ## System global default language.
191 191 ## All available languages: en(default), be, de, es, fr, it, ja, pl, pt, ru, zh
192 192 lang = en
193 193
194 194 ## Perform a full repository scan and import on each server start.
195 195 ## Settings this to true could lead to very long startup time.
196 196 startup.import_repos = false
197 197
198 198 ## Uncomment and set this path to use archive download cache.
199 199 ## Once enabled, generated archives will be cached at this location
200 200 ## and served from the cache during subsequent requests for the same archive of
201 201 ## the repository.
202 202 #archive_cache_dir = /tmp/tarballcache
203 203
204 204 ## URL at which the application is running. This is used for Bootstrapping
205 205 ## requests in context when no web request is available. Used in ishell, or
206 206 ## SSH calls. Set this for events to receive proper url for SSH calls.
207 207 app.base_url = http://rhodecode.local
208 208
209 209 ## Unique application ID. Should be a random unique string for security.
210 210 app_instance_uuid = rc-production
211 211
212 212 ## Cut off limit for large diffs (size in bytes). If overall diff size on
213 213 ## commit, or pull request exceeds this limit this diff will be displayed
214 214 ## partially. E.g 512000 == 512Kb
215 215 cut_off_limit_diff = 512000
216 216
217 217 ## Cut off limit for large files inside diffs (size in bytes). Each individual
218 218 ## file inside diff which exceeds this limit will be displayed partially.
219 219 ## E.g 128000 == 128Kb
220 220 cut_off_limit_file = 128000
221 221
222 222 ## use cached version of vcs repositories everywhere. Recommended to be `true`
223 223 vcs_full_cache = true
224 224
225 225 ## Force https in RhodeCode, fixes https redirects, assumes it's always https.
226 226 ## Normally this is controlled by proper http flags sent from http server
227 227 force_https = false
228 228
229 229 ## use Strict-Transport-Security headers
230 230 use_htsts = false
231 231
232 232 # Set to true if your repos are exposed using the dumb protocol
233 233 git_update_server_info = false
234 234
235 235 ## RSS/ATOM feed options
236 236 rss_cut_off_limit = 256000
237 237 rss_items_per_page = 10
238 238 rss_include_diff = false
239 239
240 240 ## gist URL alias, used to create nicer urls for gist. This should be an
241 241 ## url that does rewrites to _admin/gists/{gistid}.
242 242 ## example: http://gist.rhodecode.org/{gistid}. Empty means use the internal
243 243 ## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/{gistid}
244 244 gist_alias_url =
245 245
246 246 ## List of views (using glob pattern syntax) that AUTH TOKENS could be
247 247 ## used for access.
248 248 ## Adding ?auth_token=TOKEN_HASH to the url authenticates this request as if it
249 249 ## came from the the logged in user who own this authentication token.
250 250 ## Additionally @TOKEN syntax can be used to bound the view to specific
251 251 ## authentication token. Such view would be only accessible when used together
252 252 ## with this authentication token
253 253 ##
254 254 ## list of all views can be found under `/_admin/permissions/auth_token_access`
255 255 ## The list should be "," separated and on a single line.
256 256 ##
257 257 ## Most common views to enable:
258 258 # RepoCommitsView:repo_commit_download
259 259 # RepoCommitsView:repo_commit_patch
260 260 # RepoCommitsView:repo_commit_raw
261 261 # RepoCommitsView:repo_commit_raw@TOKEN
262 262 # RepoFilesView:repo_files_diff
263 263 # RepoFilesView:repo_archivefile
264 264 # RepoFilesView:repo_file_raw
265 265 # GistView:*
266 266 api_access_controllers_whitelist =
267 267
268 268 ## Default encoding used to convert from and to unicode
269 269 ## can be also a comma separated list of encoding in case of mixed encodings
270 270 default_encoding = UTF-8
271 271
272 272 ## instance-id prefix
273 273 ## a prefix key for this instance used for cache invalidation when running
274 274 ## multiple instances of RhodeCode, make sure it's globally unique for
275 275 ## all running RhodeCode instances. Leave empty if you don't use it
276 276 instance_id =
277 277
278 278 ## Fallback authentication plugin. Set this to a plugin ID to force the usage
279 279 ## of an authentication plugin also if it is disabled by it's settings.
280 280 ## This could be useful if you are unable to log in to the system due to broken
281 281 ## authentication settings. Then you can enable e.g. the internal RhodeCode auth
282 282 ## module to log in again and fix the settings.
283 283 ##
284 284 ## Available builtin plugin IDs (hash is part of the ID):
285 285 ## egg:rhodecode-enterprise-ce#rhodecode
286 286 ## egg:rhodecode-enterprise-ce#pam
287 287 ## egg:rhodecode-enterprise-ce#ldap
288 288 ## egg:rhodecode-enterprise-ce#jasig_cas
289 289 ## egg:rhodecode-enterprise-ce#headers
290 290 ## egg:rhodecode-enterprise-ce#crowd
291 291 #rhodecode.auth_plugin_fallback = egg:rhodecode-enterprise-ce#rhodecode
292 292
293 ## Flag to control loading of legacy plugins in py:/path format
294 auth_plugin.import_legacy_plugins = true
295
293 296 ## alternative return HTTP header for failed authentication. Default HTTP
294 297 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
295 298 ## handling that causing a series of failed authentication calls.
296 299 ## Set this variable to 403 to return HTTPForbidden, or any other HTTP code
297 300 ## This will be served instead of default 401 on bad authentication
298 301 auth_ret_code =
299 302
300 303 ## use special detection method when serving auth_ret_code, instead of serving
301 304 ## ret_code directly, use 401 initially (Which triggers credentials prompt)
302 305 ## and then serve auth_ret_code to clients
303 306 auth_ret_code_detection = false
304 307
305 308 ## locking return code. When repository is locked return this HTTP code. 2XX
306 309 ## codes don't break the transactions while 4XX codes do
307 310 lock_ret_code = 423
308 311
309 312 ## allows to change the repository location in settings page
310 313 allow_repo_location_change = true
311 314
312 315 ## allows to setup custom hooks in settings page
313 316 allow_custom_hooks_settings = true
314 317
315 318 ## Generated license token required for EE edition license.
316 319 ## New generated token value can be found in Admin > settings > license page.
317 320 license_token =
318 321
319 322 ## This flag would hide sensitive information on the license page
320 323 license.hide_license_info = false
321 324
322 325 ## supervisor connection uri, for managing supervisor and logs.
323 326 supervisor.uri =
324 327 ## supervisord group name/id we only want this RC instance to handle
325 328 supervisor.group_id = dev
326 329
327 330 ## Display extended labs settings
328 331 labs_settings_active = true
329 332
330 333 ## Custom exception store path, defaults to TMPDIR
331 334 ## This is used to store exception from RhodeCode in shared directory
332 335 #exception_tracker.store_path =
333 336
334 337 ## File store configuration. This is used to store and serve uploaded files
335 338 file_store.enabled = true
336 339 ## Storage backend, available options are: local
337 340 file_store.backend = local
338 341 ## path to store the uploaded binaries
339 342 file_store.storage_path = %(here)s/data/file_store
340 343
341 344
342 345 ####################################
343 346 ### CELERY CONFIG ####
344 347 ####################################
345 348 ## run: /path/to/celery worker \
346 349 ## -E --beat --app rhodecode.lib.celerylib.loader \
347 350 ## --scheduler rhodecode.lib.celerylib.scheduler.RcScheduler \
348 351 ## --loglevel DEBUG --ini /path/to/rhodecode.ini
349 352
350 353 use_celery = false
351 354
352 355 ## connection url to the message broker (default redis)
353 356 celery.broker_url = redis://localhost:6379/8
354 357
355 358 ## rabbitmq example
356 359 #celery.broker_url = amqp://rabbitmq:qweqwe@localhost:5672/rabbitmqhost
357 360
358 361 ## maximum tasks to execute before worker restart
359 362 celery.max_tasks_per_child = 100
360 363
361 364 ## tasks will never be sent to the queue, but executed locally instead.
362 365 celery.task_always_eager = false
363 366
364 367 #####################################
365 368 ### DOGPILE CACHE ####
366 369 #####################################
367 370 ## Default cache dir for caches. Putting this into a ramdisk
368 371 ## can boost performance, eg. /tmpfs/data_ramdisk, however this directory might require
369 372 ## large amount of space
370 373 cache_dir = %(here)s/data
371 374
372 375 ## `cache_perms` cache settings for permission tree, auth TTL.
373 376 rc_cache.cache_perms.backend = dogpile.cache.rc.file_namespace
374 377 rc_cache.cache_perms.expiration_time = 300
375 378
376 379 ## alternative `cache_perms` redis backend with distributed lock
377 380 #rc_cache.cache_perms.backend = dogpile.cache.rc.redis
378 381 #rc_cache.cache_perms.expiration_time = 300
379 382 ## redis_expiration_time needs to be greater then expiration_time
380 383 #rc_cache.cache_perms.arguments.redis_expiration_time = 7200
381 384 #rc_cache.cache_perms.arguments.socket_timeout = 30
382 385 #rc_cache.cache_perms.arguments.host = localhost
383 386 #rc_cache.cache_perms.arguments.port = 6379
384 387 #rc_cache.cache_perms.arguments.db = 0
385 388 ## more Redis options: https://dogpilecache.sqlalchemy.org/en/latest/api.html#redis-backends
386 389 #rc_cache.cache_perms.arguments.distributed_lock = true
387 390
388 391 ## `cache_repo` cache settings for FileTree, Readme, RSS FEEDS
389 392 rc_cache.cache_repo.backend = dogpile.cache.rc.file_namespace
390 393 rc_cache.cache_repo.expiration_time = 2592000
391 394
392 395 ## alternative `cache_repo` redis backend with distributed lock
393 396 #rc_cache.cache_repo.backend = dogpile.cache.rc.redis
394 397 #rc_cache.cache_repo.expiration_time = 2592000
395 398 ## redis_expiration_time needs to be greater then expiration_time
396 399 #rc_cache.cache_repo.arguments.redis_expiration_time = 2678400
397 400 #rc_cache.cache_repo.arguments.socket_timeout = 30
398 401 #rc_cache.cache_repo.arguments.host = localhost
399 402 #rc_cache.cache_repo.arguments.port = 6379
400 403 #rc_cache.cache_repo.arguments.db = 1
401 404 ## more Redis options: https://dogpilecache.sqlalchemy.org/en/latest/api.html#redis-backends
402 405 #rc_cache.cache_repo.arguments.distributed_lock = true
403 406
404 407 ## cache settings for SQL queries, this needs to use memory type backend
405 408 rc_cache.sql_cache_short.backend = dogpile.cache.rc.memory_lru
406 409 rc_cache.sql_cache_short.expiration_time = 30
407 410
408 411 ## `cache_repo_longterm` cache for repo object instances, this needs to use memory
409 412 ## type backend as the objects kept are not pickle serializable
410 413 rc_cache.cache_repo_longterm.backend = dogpile.cache.rc.memory_lru
411 414 ## by default we use 96H, this is using invalidation on push anyway
412 415 rc_cache.cache_repo_longterm.expiration_time = 345600
413 416 ## max items in LRU cache, reduce this number to save memory, and expire last used
414 417 ## cached objects
415 418 rc_cache.cache_repo_longterm.max_size = 10000
416 419
417 420
418 421 ####################################
419 422 ### BEAKER SESSION ####
420 423 ####################################
421 424
422 425 ## .session.type is type of storage options for the session, current allowed
423 426 ## types are file, ext:memcached, ext:redis, ext:database, and memory (default).
424 427 beaker.session.type = file
425 428 beaker.session.data_dir = %(here)s/data/sessions
426 429
427 430 ## redis sessions
428 431 #beaker.session.type = ext:redis
429 432 #beaker.session.url = redis://127.0.0.1:6379/2
430 433
431 434 ## db based session, fast, and allows easy management over logged in users
432 435 #beaker.session.type = ext:database
433 436 #beaker.session.table_name = db_session
434 437 #beaker.session.sa.url = postgresql://postgres:secret@localhost/rhodecode
435 438 #beaker.session.sa.url = mysql://root:secret@127.0.0.1/rhodecode
436 439 #beaker.session.sa.pool_recycle = 3600
437 440 #beaker.session.sa.echo = false
438 441
439 442 beaker.session.key = rhodecode
440 443 beaker.session.secret = develop-rc-uytcxaz
441 444 beaker.session.lock_dir = %(here)s/data/sessions/lock
442 445
443 446 ## Secure encrypted cookie. Requires AES and AES python libraries
444 447 ## you must disable beaker.session.secret to use this
445 448 #beaker.session.encrypt_key = key_for_encryption
446 449 #beaker.session.validate_key = validation_key
447 450
448 451 ## sets session as invalid(also logging out user) if it haven not been
449 452 ## accessed for given amount of time in seconds
450 453 beaker.session.timeout = 2592000
451 454 beaker.session.httponly = true
452 455 ## Path to use for the cookie. Set to prefix if you use prefix middleware
453 456 #beaker.session.cookie_path = /custom_prefix
454 457
455 458 ## uncomment for https secure cookie
456 459 beaker.session.secure = false
457 460
458 461 ## auto save the session to not to use .save()
459 462 beaker.session.auto = false
460 463
461 464 ## default cookie expiration time in seconds, set to `true` to set expire
462 465 ## at browser close
463 466 #beaker.session.cookie_expires = 3600
464 467
465 468 ###################################
466 469 ## SEARCH INDEXING CONFIGURATION ##
467 470 ###################################
468 471 ## Full text search indexer is available in rhodecode-tools under
469 472 ## `rhodecode-tools index` command
470 473
471 474 ## WHOOSH Backend, doesn't require additional services to run
472 475 ## it works good with few dozen repos
473 476 search.module = rhodecode.lib.index.whoosh
474 477 search.location = %(here)s/data/index
475 478
476 479 ########################################
477 480 ### CHANNELSTREAM CONFIG ####
478 481 ########################################
479 482 ## channelstream enables persistent connections and live notification
480 483 ## in the system. It's also used by the chat system
481 484
482 485 channelstream.enabled = false
483 486
484 487 ## server address for channelstream server on the backend
485 488 channelstream.server = 127.0.0.1:9800
486 489
487 490 ## location of the channelstream server from outside world
488 491 ## use ws:// for http or wss:// for https. This address needs to be handled
489 492 ## by external HTTP server such as Nginx or Apache
490 493 ## see Nginx/Apache configuration examples in our docs
491 494 channelstream.ws_url = ws://rhodecode.yourserver.com/_channelstream
492 495 channelstream.secret = secret
493 496 channelstream.history.location = %(here)s/channelstream_history
494 497
495 498 ## Internal application path that Javascript uses to connect into.
496 499 ## If you use proxy-prefix the prefix should be added before /_channelstream
497 500 channelstream.proxy_path = /_channelstream
498 501
499 502
500 503 ###################################
501 504 ## APPENLIGHT CONFIG ##
502 505 ###################################
503 506
504 507 ## Appenlight is tailored to work with RhodeCode, see
505 508 ## http://appenlight.com for details how to obtain an account
506 509
507 510 ## Appenlight integration enabled
508 511 appenlight = false
509 512
510 513 appenlight.server_url = https://api.appenlight.com
511 514 appenlight.api_key = YOUR_API_KEY
512 515 #appenlight.transport_config = https://api.appenlight.com?threaded=1&timeout=5
513 516
514 517 ## used for JS client
515 518 appenlight.api_public_key = YOUR_API_PUBLIC_KEY
516 519
517 520 ## TWEAK AMOUNT OF INFO SENT HERE
518 521
519 522 ## enables 404 error logging (default False)
520 523 appenlight.report_404 = false
521 524
522 525 ## time in seconds after request is considered being slow (default 1)
523 526 appenlight.slow_request_time = 1
524 527
525 528 ## record slow requests in application
526 529 ## (needs to be enabled for slow datastore recording and time tracking)
527 530 appenlight.slow_requests = true
528 531
529 532 ## enable hooking to application loggers
530 533 appenlight.logging = true
531 534
532 535 ## minimum log level for log capture
533 536 appenlight.logging.level = WARNING
534 537
535 538 ## send logs only from erroneous/slow requests
536 539 ## (saves API quota for intensive logging)
537 540 appenlight.logging_on_error = false
538 541
539 542 ## list of additional keywords that should be grabbed from environ object
540 543 ## can be string with comma separated list of words in lowercase
541 544 ## (by default client will always send following info:
542 545 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
543 546 ## start with HTTP* this list be extended with additional keywords here
544 547 appenlight.environ_keys_whitelist =
545 548
546 549 ## list of keywords that should be blanked from request object
547 550 ## can be string with comma separated list of words in lowercase
548 551 ## (by default client will always blank keys that contain following words
549 552 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
550 553 ## this list be extended with additional keywords set here
551 554 appenlight.request_keys_blacklist =
552 555
553 556 ## list of namespaces that should be ignores when gathering log entries
554 557 ## can be string with comma separated list of namespaces
555 558 ## (by default the client ignores own entries: appenlight_client.client)
556 559 appenlight.log_namespace_blacklist =
557 560
558 561 # enable debug style page
559 562 debug_style = true
560 563
561 564 ###########################################
562 565 ### MAIN RHODECODE DATABASE CONFIG ###
563 566 ###########################################
564 567 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db?timeout=30
565 568 #sqlalchemy.db1.url = postgresql://postgres:qweqwe@localhost/rhodecode
566 569 #sqlalchemy.db1.url = mysql://root:qweqwe@localhost/rhodecode?charset=utf8
567 570 # pymysql is an alternative driver for MySQL, use in case of problems with default one
568 571 #sqlalchemy.db1.url = mysql+pymysql://root:qweqwe@localhost/rhodecode
569 572
570 573 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db?timeout=30
571 574
572 575 # see sqlalchemy docs for other advanced settings
573 576
574 577 ## print the sql statements to output
575 578 sqlalchemy.db1.echo = false
576 579 ## recycle the connections after this amount of seconds
577 580 sqlalchemy.db1.pool_recycle = 3600
578 581
579 582 ## the number of connections to keep open inside the connection pool.
580 583 ## 0 indicates no limit
581 584 #sqlalchemy.db1.pool_size = 5
582 585
583 586 ## the number of connections to allow in connection pool "overflow", that is
584 587 ## connections that can be opened above and beyond the pool_size setting,
585 588 ## which defaults to five.
586 589 #sqlalchemy.db1.max_overflow = 10
587 590
588 591 ## Connection check ping, used to detect broken database connections
589 592 ## could be enabled to better handle cases if MySQL has gone away errors
590 593 #sqlalchemy.db1.ping_connection = true
591 594
592 595 ##################
593 596 ### VCS CONFIG ###
594 597 ##################
595 598 vcs.server.enable = true
596 599 vcs.server = localhost:9900
597 600
598 601 ## Web server connectivity protocol, responsible for web based VCS operations
599 602 ## Available protocols are:
600 603 ## `http` - use http-rpc backend (default)
601 604 vcs.server.protocol = http
602 605
603 606 ## Push/Pull operations protocol, available options are:
604 607 ## `http` - use http-rpc backend (default)
605 608 vcs.scm_app_implementation = http
606 609
607 610 ## Push/Pull operations hooks protocol, available options are:
608 611 ## `http` - use http-rpc backend (default)
609 612 vcs.hooks.protocol = http
610 613
611 614 ## Host on which this instance is listening for hooks. If vcsserver is in other location
612 615 ## this should be adjusted.
613 616 vcs.hooks.host = 127.0.0.1
614 617
615 618 vcs.server.log_level = debug
616 619 ## Start VCSServer with this instance as a subprocess, useful for development
617 620 vcs.start_server = false
618 621
619 622 ## List of enabled VCS backends, available options are:
620 623 ## `hg` - mercurial
621 624 ## `git` - git
622 625 ## `svn` - subversion
623 626 vcs.backends = hg, git, svn
624 627
625 628 vcs.connection_timeout = 3600
626 629 ## Compatibility version when creating SVN repositories. Defaults to newest version when commented out.
627 630 ## Available options are: pre-1.4-compatible, pre-1.5-compatible, pre-1.6-compatible, pre-1.8-compatible, pre-1.9-compatible
628 631 #vcs.svn.compatible_version = pre-1.8-compatible
629 632
630 633
631 634 ############################################################
632 635 ### Subversion proxy support (mod_dav_svn) ###
633 636 ### Maps RhodeCode repo groups into SVN paths for Apache ###
634 637 ############################################################
635 638 ## Enable or disable the config file generation.
636 639 svn.proxy.generate_config = false
637 640 ## Generate config file with `SVNListParentPath` set to `On`.
638 641 svn.proxy.list_parent_path = true
639 642 ## Set location and file name of generated config file.
640 643 svn.proxy.config_file_path = %(here)s/mod_dav_svn.conf
641 644 ## alternative mod_dav config template. This needs to be a mako template
642 645 #svn.proxy.config_template = ~/.rccontrol/enterprise-1/custom_svn_conf.mako
643 646 ## Used as a prefix to the `Location` block in the generated config file.
644 647 ## In most cases it should be set to `/`.
645 648 svn.proxy.location_root = /
646 649 ## Command to reload the mod dav svn configuration on change.
647 650 ## Example: `/etc/init.d/apache2 reload` or /home/USER/apache_reload.sh
648 651 ## Make sure user who runs RhodeCode process is allowed to reload Apache
649 652 #svn.proxy.reload_cmd = /etc/init.d/apache2 reload
650 653 ## If the timeout expires before the reload command finishes, the command will
651 654 ## be killed. Setting it to zero means no timeout. Defaults to 10 seconds.
652 655 #svn.proxy.reload_timeout = 10
653 656
654 657 ############################################################
655 658 ### SSH Support Settings ###
656 659 ############################################################
657 660
658 661 ## Defines if a custom authorized_keys file should be created and written on
659 662 ## any change user ssh keys. Setting this to false also disables possibility
660 663 ## of adding SSH keys by users from web interface. Super admins can still
661 664 ## manage SSH Keys.
662 665 ssh.generate_authorized_keyfile = false
663 666
664 667 ## Options for ssh, default is `no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding`
665 668 # ssh.authorized_keys_ssh_opts =
666 669
667 670 ## Path to the authorized_keys file where the generate entries are placed.
668 671 ## It is possible to have multiple key files specified in `sshd_config` e.g.
669 672 ## AuthorizedKeysFile %h/.ssh/authorized_keys %h/.ssh/authorized_keys_rhodecode
670 673 ssh.authorized_keys_file_path = ~/.ssh/authorized_keys_rhodecode
671 674
672 675 ## Command to execute the SSH wrapper. The binary is available in the
673 676 ## RhodeCode installation directory.
674 677 ## e.g ~/.rccontrol/community-1/profile/bin/rc-ssh-wrapper
675 678 ssh.wrapper_cmd = ~/.rccontrol/community-1/rc-ssh-wrapper
676 679
677 680 ## Allow shell when executing the ssh-wrapper command
678 681 ssh.wrapper_cmd_allow_shell = false
679 682
680 683 ## Enables logging, and detailed output send back to the client during SSH
681 684 ## operations. Useful for debugging, shouldn't be used in production.
682 685 ssh.enable_debug_logging = true
683 686
684 687 ## Paths to binary executable, by default they are the names, but we can
685 688 ## override them if we want to use a custom one
686 689 ssh.executable.hg = ~/.rccontrol/vcsserver-1/profile/bin/hg
687 690 ssh.executable.git = ~/.rccontrol/vcsserver-1/profile/bin/git
688 691 ssh.executable.svn = ~/.rccontrol/vcsserver-1/profile/bin/svnserve
689 692
690 693 ## Enables SSH key generator web interface. Disabling this still allows users
691 694 ## to add their own keys.
692 695 ssh.enable_ui_key_generator = true
693 696
694 697
695 698 ## Dummy marker to add new entries after.
696 699 ## Add any custom entries below. Please don't remove.
697 700 custom.conf = 1
698 701
699 702
700 703 ################################
701 704 ### LOGGING CONFIGURATION ####
702 705 ################################
703 706 [loggers]
704 707 keys = root, sqlalchemy, beaker, celery, rhodecode, ssh_wrapper
705 708
706 709 [handlers]
707 710 keys = console, console_sql
708 711
709 712 [formatters]
710 713 keys = generic, color_formatter, color_formatter_sql
711 714
712 715 #############
713 716 ## LOGGERS ##
714 717 #############
715 718 [logger_root]
716 719 level = NOTSET
717 720 handlers = console
718 721
719 722 [logger_sqlalchemy]
720 723 level = INFO
721 724 handlers = console_sql
722 725 qualname = sqlalchemy.engine
723 726 propagate = 0
724 727
725 728 [logger_beaker]
726 729 level = DEBUG
727 730 handlers =
728 731 qualname = beaker.container
729 732 propagate = 1
730 733
731 734 [logger_rhodecode]
732 735 level = DEBUG
733 736 handlers =
734 737 qualname = rhodecode
735 738 propagate = 1
736 739
737 740 [logger_ssh_wrapper]
738 741 level = DEBUG
739 742 handlers =
740 743 qualname = ssh_wrapper
741 744 propagate = 1
742 745
743 746 [logger_celery]
744 747 level = DEBUG
745 748 handlers =
746 749 qualname = celery
747 750
748 751
749 752 ##############
750 753 ## HANDLERS ##
751 754 ##############
752 755
753 756 [handler_console]
754 757 class = StreamHandler
755 758 args = (sys.stderr, )
756 759 level = DEBUG
757 760 formatter = color_formatter
758 761
759 762 [handler_console_sql]
760 763 # "level = DEBUG" logs SQL queries and results.
761 764 # "level = INFO" logs SQL queries.
762 765 # "level = WARN" logs neither. (Recommended for production systems.)
763 766 class = StreamHandler
764 767 args = (sys.stderr, )
765 768 level = WARN
766 769 formatter = color_formatter_sql
767 770
768 771 ################
769 772 ## FORMATTERS ##
770 773 ################
771 774
772 775 [formatter_generic]
773 776 class = rhodecode.lib.logging_formatter.ExceptionAwareFormatter
774 777 format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s
775 778 datefmt = %Y-%m-%d %H:%M:%S
776 779
777 780 [formatter_color_formatter]
778 781 class = rhodecode.lib.logging_formatter.ColorFormatter
779 782 format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s
780 783 datefmt = %Y-%m-%d %H:%M:%S
781 784
782 785 [formatter_color_formatter_sql]
783 786 class = rhodecode.lib.logging_formatter.ColorFormatterSql
784 787 format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s
785 788 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,762 +1,765 b''
1 1
2 2
3 3 ################################################################################
4 4 ## RHODECODE COMMUNITY EDITION CONFIGURATION ##
5 5 ################################################################################
6 6
7 7 [DEFAULT]
8 8 ## Debug flag sets all loggers to debug, and enables request tracking
9 9 debug = false
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 #smtp_server = mail.server.com
25 25 #smtp_username =
26 26 #smtp_password =
27 27 #smtp_port =
28 28 #smtp_use_tls = false
29 29 #smtp_use_ssl = true
30 30
31 31 [server:main]
32 32 ## COMMON ##
33 33 host = 127.0.0.1
34 34 port = 5000
35 35
36 36 ###########################################################
37 37 ## WAITRESS WSGI SERVER - Recommended for Development ####
38 38 ###########################################################
39 39
40 40 #use = egg:waitress#main
41 41 ## number of worker threads
42 42 #threads = 5
43 43 ## MAX BODY SIZE 100GB
44 44 #max_request_body_size = 107374182400
45 45 ## Use poll instead of select, fixes file descriptors limits problems.
46 46 ## May not work on old windows systems.
47 47 #asyncore_use_poll = true
48 48
49 49
50 50 ##########################
51 51 ## GUNICORN WSGI SERVER ##
52 52 ##########################
53 53 ## run with gunicorn --log-config rhodecode.ini --paste rhodecode.ini
54 54
55 55 use = egg:gunicorn#main
56 56 ## Sets the number of process workers. More workers means more concurrent connections
57 57 ## RhodeCode can handle at the same time. Each additional worker also it increases
58 58 ## memory usage as each has it's own set of caches.
59 59 ## Recommended value is (2 * NUMBER_OF_CPUS + 1), eg 2CPU = 5 workers, but no more
60 60 ## than 8-10 unless for really big deployments .e.g 700-1000 users.
61 61 ## `instance_id = *` must be set in the [app:main] section below (which is the default)
62 62 ## when using more than 1 worker.
63 63 workers = 2
64 64
65 65 ## Gunicorn access log level
66 66 loglevel = info
67 67
68 68 ## process name visible in process list
69 69 proc_name = rhodecode
70 70
71 71 ## type of worker class, one of sync, gevent
72 72 ## recommended for bigger setup is using of of other than sync one
73 73 worker_class = gevent
74 74
75 75 ## The maximum number of simultaneous clients. Valid only for Gevent
76 76 worker_connections = 10
77 77
78 78 ## max number of requests that worker will handle before being gracefully
79 79 ## restarted, could prevent memory leaks
80 80 max_requests = 1000
81 81 max_requests_jitter = 30
82 82
83 83 ## amount of time a worker can spend with handling a request before it
84 84 ## gets killed and restarted. Set to 6hrs
85 85 timeout = 21600
86 86
87 87 ## The maximum size of HTTP request line in bytes.
88 88 ## 0 for unlimited
89 89 limit_request_line = 0
90 90
91 91 ## Limit the number of HTTP headers fields in a request.
92 92 ## By default this value is 100 and can't be larger than 32768.
93 93 limit_request_fields = 32768
94 94
95 95 ## Limit the allowed size of an HTTP request header field.
96 96 ## Value is a positive number or 0.
97 97 ## Setting it to 0 will allow unlimited header field sizes.
98 98 limit_request_field_size = 0
99 99
100 100 ## Timeout for graceful workers restart.
101 101 ## After receiving a restart signal, workers have this much time to finish
102 102 ## serving requests. Workers still alive after the timeout (starting from the
103 103 ## receipt of the restart signal) are force killed.
104 104 graceful_timeout = 3600
105 105
106 106 # The number of seconds to wait for requests on a Keep-Alive connection.
107 107 # Generally set in the 1-5 seconds range.
108 108 keepalive = 2
109 109
110 110 ## Maximum memory usage that each worker can use before it will receive a
111 111 ## graceful restart signal, e.g 10MB = 10485760 (10 * 1024 * 1024)
112 112 # 0 = memory monitoring is disabled
113 113 memory_max_usage = 0
114 114
115 115 ## How often in seconds to check for memory usage for each gunicorn worker
116 116 memory_usage_check_interval = 60
117 117
118 118 ## Threshold value for which we don't recycle worker if GarbageCollection
119 119 ## frees up enough resources. Before each restart we try to run GC on worker
120 120 ## in case we get enough free memory after that, restart will not happen.
121 121 memory_usage_recovery_threshold = 0.8
122 122
123 123 ## prefix middleware for RhodeCode.
124 124 ## recommended when using proxy setup.
125 125 ## allows to set RhodeCode under a prefix in server.
126 126 ## eg https://server.com/custom_prefix. Enable `filter-with =` option below as well.
127 127 ## And set your prefix like: `prefix = /custom_prefix`
128 128 ## be sure to also set beaker.session.cookie_path = /custom_prefix if you need
129 129 ## to make your cookies only work on prefix url
130 130 [filter:proxy-prefix]
131 131 use = egg:PasteDeploy#prefix
132 132 prefix = /
133 133
134 134 [app:main]
135 135 ## The %(here)s variable will be replaced with the absolute path of parent directory
136 136 ## of this file
137 137 ## In addition ENVIRONMENT variables usage is possible, e.g
138 138 ## sqlalchemy.db1.url = {ENV_RC_DB_URL}
139 139
140 140 use = egg:rhodecode-enterprise-ce
141 141
142 142 ## enable proxy prefix middleware, defined above
143 143 #filter-with = proxy-prefix
144 144
145 145 ## encryption key used to encrypt social plugin tokens,
146 146 ## remote_urls with credentials etc, if not set it defaults to
147 147 ## `beaker.session.secret`
148 148 #rhodecode.encrypted_values.secret =
149 149
150 150 ## decryption strict mode (enabled by default). It controls if decryption raises
151 151 ## `SignatureVerificationError` in case of wrong key, or damaged encryption data.
152 152 #rhodecode.encrypted_values.strict = false
153 153
154 154 ## Pick algorithm for encryption. Either fernet (more secure) or aes (default)
155 155 ## fernet is safer, and we strongly recommend switching to it.
156 156 ## Due to backward compatibility aes is used as default.
157 157 #rhodecode.encrypted_values.algorithm = fernet
158 158
159 159 ## return gzipped responses from RhodeCode (static files/application)
160 160 gzip_responses = false
161 161
162 162 ## auto-generate javascript routes file on startup
163 163 generate_js_files = false
164 164
165 165 ## System global default language.
166 166 ## All available languages: en(default), be, de, es, fr, it, ja, pl, pt, ru, zh
167 167 lang = en
168 168
169 169 ## Perform a full repository scan and import on each server start.
170 170 ## Settings this to true could lead to very long startup time.
171 171 startup.import_repos = false
172 172
173 173 ## Uncomment and set this path to use archive download cache.
174 174 ## Once enabled, generated archives will be cached at this location
175 175 ## and served from the cache during subsequent requests for the same archive of
176 176 ## the repository.
177 177 #archive_cache_dir = /tmp/tarballcache
178 178
179 179 ## URL at which the application is running. This is used for Bootstrapping
180 180 ## requests in context when no web request is available. Used in ishell, or
181 181 ## SSH calls. Set this for events to receive proper url for SSH calls.
182 182 app.base_url = http://rhodecode.local
183 183
184 184 ## Unique application ID. Should be a random unique string for security.
185 185 app_instance_uuid = rc-production
186 186
187 187 ## Cut off limit for large diffs (size in bytes). If overall diff size on
188 188 ## commit, or pull request exceeds this limit this diff will be displayed
189 189 ## partially. E.g 512000 == 512Kb
190 190 cut_off_limit_diff = 512000
191 191
192 192 ## Cut off limit for large files inside diffs (size in bytes). Each individual
193 193 ## file inside diff which exceeds this limit will be displayed partially.
194 194 ## E.g 128000 == 128Kb
195 195 cut_off_limit_file = 128000
196 196
197 197 ## use cached version of vcs repositories everywhere. Recommended to be `true`
198 198 vcs_full_cache = true
199 199
200 200 ## Force https in RhodeCode, fixes https redirects, assumes it's always https.
201 201 ## Normally this is controlled by proper http flags sent from http server
202 202 force_https = false
203 203
204 204 ## use Strict-Transport-Security headers
205 205 use_htsts = false
206 206
207 207 # Set to true if your repos are exposed using the dumb protocol
208 208 git_update_server_info = false
209 209
210 210 ## RSS/ATOM feed options
211 211 rss_cut_off_limit = 256000
212 212 rss_items_per_page = 10
213 213 rss_include_diff = false
214 214
215 215 ## gist URL alias, used to create nicer urls for gist. This should be an
216 216 ## url that does rewrites to _admin/gists/{gistid}.
217 217 ## example: http://gist.rhodecode.org/{gistid}. Empty means use the internal
218 218 ## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/{gistid}
219 219 gist_alias_url =
220 220
221 221 ## List of views (using glob pattern syntax) that AUTH TOKENS could be
222 222 ## used for access.
223 223 ## Adding ?auth_token=TOKEN_HASH to the url authenticates this request as if it
224 224 ## came from the the logged in user who own this authentication token.
225 225 ## Additionally @TOKEN syntax can be used to bound the view to specific
226 226 ## authentication token. Such view would be only accessible when used together
227 227 ## with this authentication token
228 228 ##
229 229 ## list of all views can be found under `/_admin/permissions/auth_token_access`
230 230 ## The list should be "," separated and on a single line.
231 231 ##
232 232 ## Most common views to enable:
233 233 # RepoCommitsView:repo_commit_download
234 234 # RepoCommitsView:repo_commit_patch
235 235 # RepoCommitsView:repo_commit_raw
236 236 # RepoCommitsView:repo_commit_raw@TOKEN
237 237 # RepoFilesView:repo_files_diff
238 238 # RepoFilesView:repo_archivefile
239 239 # RepoFilesView:repo_file_raw
240 240 # GistView:*
241 241 api_access_controllers_whitelist =
242 242
243 243 ## Default encoding used to convert from and to unicode
244 244 ## can be also a comma separated list of encoding in case of mixed encodings
245 245 default_encoding = UTF-8
246 246
247 247 ## instance-id prefix
248 248 ## a prefix key for this instance used for cache invalidation when running
249 249 ## multiple instances of RhodeCode, make sure it's globally unique for
250 250 ## all running RhodeCode instances. Leave empty if you don't use it
251 251 instance_id =
252 252
253 253 ## Fallback authentication plugin. Set this to a plugin ID to force the usage
254 254 ## of an authentication plugin also if it is disabled by it's settings.
255 255 ## This could be useful if you are unable to log in to the system due to broken
256 256 ## authentication settings. Then you can enable e.g. the internal RhodeCode auth
257 257 ## module to log in again and fix the settings.
258 258 ##
259 259 ## Available builtin plugin IDs (hash is part of the ID):
260 260 ## egg:rhodecode-enterprise-ce#rhodecode
261 261 ## egg:rhodecode-enterprise-ce#pam
262 262 ## egg:rhodecode-enterprise-ce#ldap
263 263 ## egg:rhodecode-enterprise-ce#jasig_cas
264 264 ## egg:rhodecode-enterprise-ce#headers
265 265 ## egg:rhodecode-enterprise-ce#crowd
266 266 #rhodecode.auth_plugin_fallback = egg:rhodecode-enterprise-ce#rhodecode
267 267
268 ## Flag to control loading of legacy plugins in py:/path format
269 auth_plugin.import_legacy_plugins = true
270
268 271 ## alternative return HTTP header for failed authentication. Default HTTP
269 272 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
270 273 ## handling that causing a series of failed authentication calls.
271 274 ## Set this variable to 403 to return HTTPForbidden, or any other HTTP code
272 275 ## This will be served instead of default 401 on bad authentication
273 276 auth_ret_code =
274 277
275 278 ## use special detection method when serving auth_ret_code, instead of serving
276 279 ## ret_code directly, use 401 initially (Which triggers credentials prompt)
277 280 ## and then serve auth_ret_code to clients
278 281 auth_ret_code_detection = false
279 282
280 283 ## locking return code. When repository is locked return this HTTP code. 2XX
281 284 ## codes don't break the transactions while 4XX codes do
282 285 lock_ret_code = 423
283 286
284 287 ## allows to change the repository location in settings page
285 288 allow_repo_location_change = true
286 289
287 290 ## allows to setup custom hooks in settings page
288 291 allow_custom_hooks_settings = true
289 292
290 293 ## Generated license token required for EE edition license.
291 294 ## New generated token value can be found in Admin > settings > license page.
292 295 license_token =
293 296
294 297 ## This flag would hide sensitive information on the license page
295 298 license.hide_license_info = false
296 299
297 300 ## supervisor connection uri, for managing supervisor and logs.
298 301 supervisor.uri =
299 302 ## supervisord group name/id we only want this RC instance to handle
300 303 supervisor.group_id = prod
301 304
302 305 ## Display extended labs settings
303 306 labs_settings_active = true
304 307
305 308 ## Custom exception store path, defaults to TMPDIR
306 309 ## This is used to store exception from RhodeCode in shared directory
307 310 #exception_tracker.store_path =
308 311
309 312 ## File store configuration. This is used to store and serve uploaded files
310 313 file_store.enabled = true
311 314 ## Storage backend, available options are: local
312 315 file_store.backend = local
313 316 ## path to store the uploaded binaries
314 317 file_store.storage_path = %(here)s/data/file_store
315 318
316 319
317 320 ####################################
318 321 ### CELERY CONFIG ####
319 322 ####################################
320 323 ## run: /path/to/celery worker \
321 324 ## -E --beat --app rhodecode.lib.celerylib.loader \
322 325 ## --scheduler rhodecode.lib.celerylib.scheduler.RcScheduler \
323 326 ## --loglevel DEBUG --ini /path/to/rhodecode.ini
324 327
325 328 use_celery = false
326 329
327 330 ## connection url to the message broker (default redis)
328 331 celery.broker_url = redis://localhost:6379/8
329 332
330 333 ## rabbitmq example
331 334 #celery.broker_url = amqp://rabbitmq:qweqwe@localhost:5672/rabbitmqhost
332 335
333 336 ## maximum tasks to execute before worker restart
334 337 celery.max_tasks_per_child = 100
335 338
336 339 ## tasks will never be sent to the queue, but executed locally instead.
337 340 celery.task_always_eager = false
338 341
339 342 #####################################
340 343 ### DOGPILE CACHE ####
341 344 #####################################
342 345 ## Default cache dir for caches. Putting this into a ramdisk
343 346 ## can boost performance, eg. /tmpfs/data_ramdisk, however this directory might require
344 347 ## large amount of space
345 348 cache_dir = %(here)s/data
346 349
347 350 ## `cache_perms` cache settings for permission tree, auth TTL.
348 351 rc_cache.cache_perms.backend = dogpile.cache.rc.file_namespace
349 352 rc_cache.cache_perms.expiration_time = 300
350 353
351 354 ## alternative `cache_perms` redis backend with distributed lock
352 355 #rc_cache.cache_perms.backend = dogpile.cache.rc.redis
353 356 #rc_cache.cache_perms.expiration_time = 300
354 357 ## redis_expiration_time needs to be greater then expiration_time
355 358 #rc_cache.cache_perms.arguments.redis_expiration_time = 7200
356 359 #rc_cache.cache_perms.arguments.socket_timeout = 30
357 360 #rc_cache.cache_perms.arguments.host = localhost
358 361 #rc_cache.cache_perms.arguments.port = 6379
359 362 #rc_cache.cache_perms.arguments.db = 0
360 363 ## more Redis options: https://dogpilecache.sqlalchemy.org/en/latest/api.html#redis-backends
361 364 #rc_cache.cache_perms.arguments.distributed_lock = true
362 365
363 366 ## `cache_repo` cache settings for FileTree, Readme, RSS FEEDS
364 367 rc_cache.cache_repo.backend = dogpile.cache.rc.file_namespace
365 368 rc_cache.cache_repo.expiration_time = 2592000
366 369
367 370 ## alternative `cache_repo` redis backend with distributed lock
368 371 #rc_cache.cache_repo.backend = dogpile.cache.rc.redis
369 372 #rc_cache.cache_repo.expiration_time = 2592000
370 373 ## redis_expiration_time needs to be greater then expiration_time
371 374 #rc_cache.cache_repo.arguments.redis_expiration_time = 2678400
372 375 #rc_cache.cache_repo.arguments.socket_timeout = 30
373 376 #rc_cache.cache_repo.arguments.host = localhost
374 377 #rc_cache.cache_repo.arguments.port = 6379
375 378 #rc_cache.cache_repo.arguments.db = 1
376 379 ## more Redis options: https://dogpilecache.sqlalchemy.org/en/latest/api.html#redis-backends
377 380 #rc_cache.cache_repo.arguments.distributed_lock = true
378 381
379 382 ## cache settings for SQL queries, this needs to use memory type backend
380 383 rc_cache.sql_cache_short.backend = dogpile.cache.rc.memory_lru
381 384 rc_cache.sql_cache_short.expiration_time = 30
382 385
383 386 ## `cache_repo_longterm` cache for repo object instances, this needs to use memory
384 387 ## type backend as the objects kept are not pickle serializable
385 388 rc_cache.cache_repo_longterm.backend = dogpile.cache.rc.memory_lru
386 389 ## by default we use 96H, this is using invalidation on push anyway
387 390 rc_cache.cache_repo_longterm.expiration_time = 345600
388 391 ## max items in LRU cache, reduce this number to save memory, and expire last used
389 392 ## cached objects
390 393 rc_cache.cache_repo_longterm.max_size = 10000
391 394
392 395
393 396 ####################################
394 397 ### BEAKER SESSION ####
395 398 ####################################
396 399
397 400 ## .session.type is type of storage options for the session, current allowed
398 401 ## types are file, ext:memcached, ext:redis, ext:database, and memory (default).
399 402 beaker.session.type = file
400 403 beaker.session.data_dir = %(here)s/data/sessions
401 404
402 405 ## redis sessions
403 406 #beaker.session.type = ext:redis
404 407 #beaker.session.url = redis://127.0.0.1:6379/2
405 408
406 409 ## db based session, fast, and allows easy management over logged in users
407 410 #beaker.session.type = ext:database
408 411 #beaker.session.table_name = db_session
409 412 #beaker.session.sa.url = postgresql://postgres:secret@localhost/rhodecode
410 413 #beaker.session.sa.url = mysql://root:secret@127.0.0.1/rhodecode
411 414 #beaker.session.sa.pool_recycle = 3600
412 415 #beaker.session.sa.echo = false
413 416
414 417 beaker.session.key = rhodecode
415 418 beaker.session.secret = production-rc-uytcxaz
416 419 beaker.session.lock_dir = %(here)s/data/sessions/lock
417 420
418 421 ## Secure encrypted cookie. Requires AES and AES python libraries
419 422 ## you must disable beaker.session.secret to use this
420 423 #beaker.session.encrypt_key = key_for_encryption
421 424 #beaker.session.validate_key = validation_key
422 425
423 426 ## sets session as invalid(also logging out user) if it haven not been
424 427 ## accessed for given amount of time in seconds
425 428 beaker.session.timeout = 2592000
426 429 beaker.session.httponly = true
427 430 ## Path to use for the cookie. Set to prefix if you use prefix middleware
428 431 #beaker.session.cookie_path = /custom_prefix
429 432
430 433 ## uncomment for https secure cookie
431 434 beaker.session.secure = false
432 435
433 436 ## auto save the session to not to use .save()
434 437 beaker.session.auto = false
435 438
436 439 ## default cookie expiration time in seconds, set to `true` to set expire
437 440 ## at browser close
438 441 #beaker.session.cookie_expires = 3600
439 442
440 443 ###################################
441 444 ## SEARCH INDEXING CONFIGURATION ##
442 445 ###################################
443 446 ## Full text search indexer is available in rhodecode-tools under
444 447 ## `rhodecode-tools index` command
445 448
446 449 ## WHOOSH Backend, doesn't require additional services to run
447 450 ## it works good with few dozen repos
448 451 search.module = rhodecode.lib.index.whoosh
449 452 search.location = %(here)s/data/index
450 453
451 454 ########################################
452 455 ### CHANNELSTREAM CONFIG ####
453 456 ########################################
454 457 ## channelstream enables persistent connections and live notification
455 458 ## in the system. It's also used by the chat system
456 459
457 460 channelstream.enabled = false
458 461
459 462 ## server address for channelstream server on the backend
460 463 channelstream.server = 127.0.0.1:9800
461 464
462 465 ## location of the channelstream server from outside world
463 466 ## use ws:// for http or wss:// for https. This address needs to be handled
464 467 ## by external HTTP server such as Nginx or Apache
465 468 ## see Nginx/Apache configuration examples in our docs
466 469 channelstream.ws_url = ws://rhodecode.yourserver.com/_channelstream
467 470 channelstream.secret = secret
468 471 channelstream.history.location = %(here)s/channelstream_history
469 472
470 473 ## Internal application path that Javascript uses to connect into.
471 474 ## If you use proxy-prefix the prefix should be added before /_channelstream
472 475 channelstream.proxy_path = /_channelstream
473 476
474 477 ## Live chat for commits/pull requests. Requires CHANNELSTREAM to be enabled
475 478 ## and configured. (EE edition only)
476 479 chat.enabled = true
477 480
478 481
479 482 ###################################
480 483 ## APPENLIGHT CONFIG ##
481 484 ###################################
482 485
483 486 ## Appenlight is tailored to work with RhodeCode, see
484 487 ## http://appenlight.com for details how to obtain an account
485 488
486 489 ## Appenlight integration enabled
487 490 appenlight = false
488 491
489 492 appenlight.server_url = https://api.appenlight.com
490 493 appenlight.api_key = YOUR_API_KEY
491 494 #appenlight.transport_config = https://api.appenlight.com?threaded=1&timeout=5
492 495
493 496 ## used for JS client
494 497 appenlight.api_public_key = YOUR_API_PUBLIC_KEY
495 498
496 499 ## TWEAK AMOUNT OF INFO SENT HERE
497 500
498 501 ## enables 404 error logging (default False)
499 502 appenlight.report_404 = false
500 503
501 504 ## time in seconds after request is considered being slow (default 1)
502 505 appenlight.slow_request_time = 1
503 506
504 507 ## record slow requests in application
505 508 ## (needs to be enabled for slow datastore recording and time tracking)
506 509 appenlight.slow_requests = true
507 510
508 511 ## enable hooking to application loggers
509 512 appenlight.logging = true
510 513
511 514 ## minimum log level for log capture
512 515 appenlight.logging.level = WARNING
513 516
514 517 ## send logs only from erroneous/slow requests
515 518 ## (saves API quota for intensive logging)
516 519 appenlight.logging_on_error = false
517 520
518 521 ## list of additional keywords that should be grabbed from environ object
519 522 ## can be string with comma separated list of words in lowercase
520 523 ## (by default client will always send following info:
521 524 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
522 525 ## start with HTTP* this list be extended with additional keywords here
523 526 appenlight.environ_keys_whitelist =
524 527
525 528 ## list of keywords that should be blanked from request object
526 529 ## can be string with comma separated list of words in lowercase
527 530 ## (by default client will always blank keys that contain following words
528 531 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
529 532 ## this list be extended with additional keywords set here
530 533 appenlight.request_keys_blacklist =
531 534
532 535 ## list of namespaces that should be ignores when gathering log entries
533 536 ## can be string with comma separated list of namespaces
534 537 ## (by default the client ignores own entries: appenlight_client.client)
535 538 appenlight.log_namespace_blacklist =
536 539
537 540
538 541 ###########################################
539 542 ### MAIN RHODECODE DATABASE CONFIG ###
540 543 ###########################################
541 544 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db?timeout=30
542 545 #sqlalchemy.db1.url = postgresql://postgres:qweqwe@localhost/rhodecode
543 546 #sqlalchemy.db1.url = mysql://root:qweqwe@localhost/rhodecode?charset=utf8
544 547 # pymysql is an alternative driver for MySQL, use in case of problems with default one
545 548 #sqlalchemy.db1.url = mysql+pymysql://root:qweqwe@localhost/rhodecode
546 549
547 550 sqlalchemy.db1.url = postgresql://postgres:qweqwe@localhost/rhodecode
548 551
549 552 # see sqlalchemy docs for other advanced settings
550 553
551 554 ## print the sql statements to output
552 555 sqlalchemy.db1.echo = false
553 556 ## recycle the connections after this amount of seconds
554 557 sqlalchemy.db1.pool_recycle = 3600
555 558
556 559 ## the number of connections to keep open inside the connection pool.
557 560 ## 0 indicates no limit
558 561 #sqlalchemy.db1.pool_size = 5
559 562
560 563 ## the number of connections to allow in connection pool "overflow", that is
561 564 ## connections that can be opened above and beyond the pool_size setting,
562 565 ## which defaults to five.
563 566 #sqlalchemy.db1.max_overflow = 10
564 567
565 568 ## Connection check ping, used to detect broken database connections
566 569 ## could be enabled to better handle cases if MySQL has gone away errors
567 570 #sqlalchemy.db1.ping_connection = true
568 571
569 572 ##################
570 573 ### VCS CONFIG ###
571 574 ##################
572 575 vcs.server.enable = true
573 576 vcs.server = localhost:9900
574 577
575 578 ## Web server connectivity protocol, responsible for web based VCS operations
576 579 ## Available protocols are:
577 580 ## `http` - use http-rpc backend (default)
578 581 vcs.server.protocol = http
579 582
580 583 ## Push/Pull operations protocol, available options are:
581 584 ## `http` - use http-rpc backend (default)
582 585 vcs.scm_app_implementation = http
583 586
584 587 ## Push/Pull operations hooks protocol, available options are:
585 588 ## `http` - use http-rpc backend (default)
586 589 vcs.hooks.protocol = http
587 590
588 591 ## Host on which this instance is listening for hooks. If vcsserver is in other location
589 592 ## this should be adjusted.
590 593 vcs.hooks.host = 127.0.0.1
591 594
592 595 vcs.server.log_level = info
593 596 ## Start VCSServer with this instance as a subprocess, useful for development
594 597 vcs.start_server = false
595 598
596 599 ## List of enabled VCS backends, available options are:
597 600 ## `hg` - mercurial
598 601 ## `git` - git
599 602 ## `svn` - subversion
600 603 vcs.backends = hg, git, svn
601 604
602 605 vcs.connection_timeout = 3600
603 606 ## Compatibility version when creating SVN repositories. Defaults to newest version when commented out.
604 607 ## Available options are: pre-1.4-compatible, pre-1.5-compatible, pre-1.6-compatible, pre-1.8-compatible, pre-1.9-compatible
605 608 #vcs.svn.compatible_version = pre-1.8-compatible
606 609
607 610
608 611 ############################################################
609 612 ### Subversion proxy support (mod_dav_svn) ###
610 613 ### Maps RhodeCode repo groups into SVN paths for Apache ###
611 614 ############################################################
612 615 ## Enable or disable the config file generation.
613 616 svn.proxy.generate_config = false
614 617 ## Generate config file with `SVNListParentPath` set to `On`.
615 618 svn.proxy.list_parent_path = true
616 619 ## Set location and file name of generated config file.
617 620 svn.proxy.config_file_path = %(here)s/mod_dav_svn.conf
618 621 ## alternative mod_dav config template. This needs to be a mako template
619 622 #svn.proxy.config_template = ~/.rccontrol/enterprise-1/custom_svn_conf.mako
620 623 ## Used as a prefix to the `Location` block in the generated config file.
621 624 ## In most cases it should be set to `/`.
622 625 svn.proxy.location_root = /
623 626 ## Command to reload the mod dav svn configuration on change.
624 627 ## Example: `/etc/init.d/apache2 reload` or /home/USER/apache_reload.sh
625 628 ## Make sure user who runs RhodeCode process is allowed to reload Apache
626 629 #svn.proxy.reload_cmd = /etc/init.d/apache2 reload
627 630 ## If the timeout expires before the reload command finishes, the command will
628 631 ## be killed. Setting it to zero means no timeout. Defaults to 10 seconds.
629 632 #svn.proxy.reload_timeout = 10
630 633
631 634 ############################################################
632 635 ### SSH Support Settings ###
633 636 ############################################################
634 637
635 638 ## Defines if a custom authorized_keys file should be created and written on
636 639 ## any change user ssh keys. Setting this to false also disables possibility
637 640 ## of adding SSH keys by users from web interface. Super admins can still
638 641 ## manage SSH Keys.
639 642 ssh.generate_authorized_keyfile = false
640 643
641 644 ## Options for ssh, default is `no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding`
642 645 # ssh.authorized_keys_ssh_opts =
643 646
644 647 ## Path to the authorized_keys file where the generate entries are placed.
645 648 ## It is possible to have multiple key files specified in `sshd_config` e.g.
646 649 ## AuthorizedKeysFile %h/.ssh/authorized_keys %h/.ssh/authorized_keys_rhodecode
647 650 ssh.authorized_keys_file_path = ~/.ssh/authorized_keys_rhodecode
648 651
649 652 ## Command to execute the SSH wrapper. The binary is available in the
650 653 ## RhodeCode installation directory.
651 654 ## e.g ~/.rccontrol/community-1/profile/bin/rc-ssh-wrapper
652 655 ssh.wrapper_cmd = ~/.rccontrol/community-1/rc-ssh-wrapper
653 656
654 657 ## Allow shell when executing the ssh-wrapper command
655 658 ssh.wrapper_cmd_allow_shell = false
656 659
657 660 ## Enables logging, and detailed output send back to the client during SSH
658 661 ## operations. Useful for debugging, shouldn't be used in production.
659 662 ssh.enable_debug_logging = false
660 663
661 664 ## Paths to binary executable, by default they are the names, but we can
662 665 ## override them if we want to use a custom one
663 666 ssh.executable.hg = ~/.rccontrol/vcsserver-1/profile/bin/hg
664 667 ssh.executable.git = ~/.rccontrol/vcsserver-1/profile/bin/git
665 668 ssh.executable.svn = ~/.rccontrol/vcsserver-1/profile/bin/svnserve
666 669
667 670 ## Enables SSH key generator web interface. Disabling this still allows users
668 671 ## to add their own keys.
669 672 ssh.enable_ui_key_generator = true
670 673
671 674
672 675 ## Dummy marker to add new entries after.
673 676 ## Add any custom entries below. Please don't remove.
674 677 custom.conf = 1
675 678
676 679
677 680 ################################
678 681 ### LOGGING CONFIGURATION ####
679 682 ################################
680 683 [loggers]
681 684 keys = root, sqlalchemy, beaker, celery, rhodecode, ssh_wrapper
682 685
683 686 [handlers]
684 687 keys = console, console_sql
685 688
686 689 [formatters]
687 690 keys = generic, color_formatter, color_formatter_sql
688 691
689 692 #############
690 693 ## LOGGERS ##
691 694 #############
692 695 [logger_root]
693 696 level = NOTSET
694 697 handlers = console
695 698
696 699 [logger_sqlalchemy]
697 700 level = INFO
698 701 handlers = console_sql
699 702 qualname = sqlalchemy.engine
700 703 propagate = 0
701 704
702 705 [logger_beaker]
703 706 level = DEBUG
704 707 handlers =
705 708 qualname = beaker.container
706 709 propagate = 1
707 710
708 711 [logger_rhodecode]
709 712 level = DEBUG
710 713 handlers =
711 714 qualname = rhodecode
712 715 propagate = 1
713 716
714 717 [logger_ssh_wrapper]
715 718 level = DEBUG
716 719 handlers =
717 720 qualname = ssh_wrapper
718 721 propagate = 1
719 722
720 723 [logger_celery]
721 724 level = DEBUG
722 725 handlers =
723 726 qualname = celery
724 727
725 728
726 729 ##############
727 730 ## HANDLERS ##
728 731 ##############
729 732
730 733 [handler_console]
731 734 class = StreamHandler
732 735 args = (sys.stderr, )
733 736 level = INFO
734 737 formatter = generic
735 738
736 739 [handler_console_sql]
737 740 # "level = DEBUG" logs SQL queries and results.
738 741 # "level = INFO" logs SQL queries.
739 742 # "level = WARN" logs neither. (Recommended for production systems.)
740 743 class = StreamHandler
741 744 args = (sys.stderr, )
742 745 level = WARN
743 746 formatter = generic
744 747
745 748 ################
746 749 ## FORMATTERS ##
747 750 ################
748 751
749 752 [formatter_generic]
750 753 class = rhodecode.lib.logging_formatter.ExceptionAwareFormatter
751 754 format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s
752 755 datefmt = %Y-%m-%d %H:%M:%S
753 756
754 757 [formatter_color_formatter]
755 758 class = rhodecode.lib.logging_formatter.ColorFormatter
756 759 format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s
757 760 datefmt = %Y-%m-%d %H:%M:%S
758 761
759 762 [formatter_color_formatter_sql]
760 763 class = rhodecode.lib.logging_formatter.ColorFormatterSql
761 764 format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s
762 765 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,755 +1,756 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 from rhodecode.authentication import discover_legacy_plugins
270 269 # load CE authentication plugins
271 270 config.include('rhodecode.authentication.plugins.auth_crowd')
272 271 config.include('rhodecode.authentication.plugins.auth_headers')
273 272 config.include('rhodecode.authentication.plugins.auth_jasig_cas')
274 273 config.include('rhodecode.authentication.plugins.auth_ldap')
275 274 config.include('rhodecode.authentication.plugins.auth_pam')
276 275 config.include('rhodecode.authentication.plugins.auth_rhodecode')
277 276 config.include('rhodecode.authentication.plugins.auth_token')
278 277
279 278 # Auto discover authentication plugins and include their configuration.
279 if asbool(settings.get('auth_plugin.import_legacy_plugins', 'true')):
280 from rhodecode.authentication import discover_legacy_plugins
280 281 discover_legacy_plugins(config)
281 282
282 283 # apps
283 284 if load_all:
284 285 config.include('rhodecode.apps._base')
285 286 config.include('rhodecode.apps.hovercards')
286 287 config.include('rhodecode.apps.ops')
287 288 config.include('rhodecode.apps.admin')
288 289 config.include('rhodecode.apps.channelstream')
289 290 config.include('rhodecode.apps.file_store')
290 291 config.include('rhodecode.apps.login')
291 292 config.include('rhodecode.apps.home')
292 293 config.include('rhodecode.apps.journal')
293 294 config.include('rhodecode.apps.repository')
294 295 config.include('rhodecode.apps.repo_group')
295 296 config.include('rhodecode.apps.user_group')
296 297 config.include('rhodecode.apps.search')
297 298 config.include('rhodecode.apps.user_profile')
298 299 config.include('rhodecode.apps.user_group_profile')
299 300 config.include('rhodecode.apps.my_account')
300 301 config.include('rhodecode.apps.svn_support')
301 302 config.include('rhodecode.apps.ssh_support')
302 303 config.include('rhodecode.apps.gist')
303 304 config.include('rhodecode.apps.debug_style')
304 305 config.include('rhodecode.api')
305 306
306 307 config.add_route('rhodecode_support', 'https://rhodecode.com/help/', static=True)
307 308 config.add_translation_dirs('rhodecode:i18n/')
308 309 settings['default_locale_name'] = settings.get('lang', 'en')
309 310
310 311 # Add subscribers.
311 312 if load_all:
312 313 config.add_subscriber(inject_app_settings,
313 314 pyramid.events.ApplicationCreated)
314 315 config.add_subscriber(scan_repositories_if_enabled,
315 316 pyramid.events.ApplicationCreated)
316 317 config.add_subscriber(write_metadata_if_needed,
317 318 pyramid.events.ApplicationCreated)
318 319 config.add_subscriber(write_js_routes_if_enabled,
319 320 pyramid.events.ApplicationCreated)
320 321
321 322 # request custom methods
322 323 config.add_request_method(
323 324 'rhodecode.lib.partial_renderer.get_partial_renderer',
324 325 'get_partial_renderer')
325 326
326 327 config.add_request_method(
327 328 'rhodecode.lib.request_counter.get_request_counter',
328 329 'request_count')
329 330
330 331 # Set the authorization policy.
331 332 authz_policy = ACLAuthorizationPolicy()
332 333 config.set_authorization_policy(authz_policy)
333 334
334 335 # Set the default renderer for HTML templates to mako.
335 336 config.add_mako_renderer('.html')
336 337
337 338 config.add_renderer(
338 339 name='json_ext',
339 340 factory='rhodecode.lib.ext_json_renderer.pyramid_ext_json')
340 341
341 342 # include RhodeCode plugins
342 343 includes = aslist(settings.get('rhodecode.includes', []))
343 344 for inc in includes:
344 345 config.include(inc)
345 346
346 347 # custom not found view, if our pyramid app doesn't know how to handle
347 348 # the request pass it to potential VCS handling ap
348 349 config.add_notfound_view(not_found_view)
349 350 if not settings.get('debugtoolbar.enabled', False):
350 351 # disabled debugtoolbar handle all exceptions via the error_handlers
351 352 config.add_view(error_handler, context=Exception)
352 353
353 354 # all errors including 403/404/50X
354 355 config.add_view(error_handler, context=HTTPError)
355 356
356 357
357 358 def wrap_app_in_wsgi_middlewares(pyramid_app, config):
358 359 """
359 360 Apply outer WSGI middlewares around the application.
360 361 """
361 362 registry = config.registry
362 363 settings = registry.settings
363 364
364 365 # enable https redirects based on HTTP_X_URL_SCHEME set by proxy
365 366 pyramid_app = HttpsFixup(pyramid_app, settings)
366 367
367 368 pyramid_app, _ae_client = wrap_in_appenlight_if_enabled(
368 369 pyramid_app, settings)
369 370 registry.ae_client = _ae_client
370 371
371 372 if settings['gzip_responses']:
372 373 pyramid_app = make_gzip_middleware(
373 374 pyramid_app, settings, compress_level=1)
374 375
375 376 # this should be the outer most middleware in the wsgi stack since
376 377 # middleware like Routes make database calls
377 378 def pyramid_app_with_cleanup(environ, start_response):
378 379 try:
379 380 return pyramid_app(environ, start_response)
380 381 finally:
381 382 # Dispose current database session and rollback uncommitted
382 383 # transactions.
383 384 meta.Session.remove()
384 385
385 386 # In a single threaded mode server, on non sqlite db we should have
386 387 # '0 Current Checked out connections' at the end of a request,
387 388 # if not, then something, somewhere is leaving a connection open
388 389 pool = meta.Base.metadata.bind.engine.pool
389 390 log.debug('sa pool status: %s', pool.status())
390 391 log.debug('Request processing finalized')
391 392
392 393 return pyramid_app_with_cleanup
393 394
394 395
395 396 def sanitize_settings_and_apply_defaults(global_config, settings):
396 397 """
397 398 Applies settings defaults and does all type conversion.
398 399
399 400 We would move all settings parsing and preparation into this place, so that
400 401 we have only one place left which deals with this part. The remaining parts
401 402 of the application would start to rely fully on well prepared settings.
402 403
403 404 This piece would later be split up per topic to avoid a big fat monster
404 405 function.
405 406 """
406 407
407 408 settings.setdefault('rhodecode.edition', 'Community Edition')
408 409
409 410 if 'mako.default_filters' not in settings:
410 411 # set custom default filters if we don't have it defined
411 412 settings['mako.imports'] = 'from rhodecode.lib.base import h_filter'
412 413 settings['mako.default_filters'] = 'h_filter'
413 414
414 415 if 'mako.directories' not in settings:
415 416 mako_directories = settings.setdefault('mako.directories', [
416 417 # Base templates of the original application
417 418 'rhodecode:templates',
418 419 ])
419 420 log.debug(
420 421 "Using the following Mako template directories: %s",
421 422 mako_directories)
422 423
423 424 # NOTE(marcink): fix redis requirement for schema of connection since 3.X
424 425 if 'beaker.session.type' in settings and settings['beaker.session.type'] == 'ext:redis':
425 426 raw_url = settings['beaker.session.url']
426 427 if not raw_url.startswith(('redis://', 'rediss://', 'unix://')):
427 428 settings['beaker.session.url'] = 'redis://' + raw_url
428 429
429 430 # Default includes, possible to change as a user
430 431 pyramid_includes = settings.setdefault('pyramid.includes', [
431 432 'rhodecode.lib.middleware.request_wrapper',
432 433 ])
433 434 log.debug(
434 435 "Using the following pyramid.includes: %s",
435 436 pyramid_includes)
436 437
437 438 # TODO: johbo: Re-think this, usually the call to config.include
438 439 # should allow to pass in a prefix.
439 440 settings.setdefault('rhodecode.api.url', '/_admin/api')
440 441 settings.setdefault('__file__', global_config.get('__file__'))
441 442
442 443 # Sanitize generic settings.
443 444 _list_setting(settings, 'default_encoding', 'UTF-8')
444 445 _bool_setting(settings, 'is_test', 'false')
445 446 _bool_setting(settings, 'gzip_responses', 'false')
446 447
447 448 # Call split out functions that sanitize settings for each topic.
448 449 _sanitize_appenlight_settings(settings)
449 450 _sanitize_vcs_settings(settings)
450 451 _sanitize_cache_settings(settings)
451 452
452 453 # configure instance id
453 454 config_utils.set_instance_id(settings)
454 455
455 456 return settings
456 457
457 458
458 459 def enable_debug():
459 460 """
460 461 Helper to enable debug on running instance
461 462 :return:
462 463 """
463 464 import tempfile
464 465 import textwrap
465 466 import logging.config
466 467
467 468 ini_template = textwrap.dedent("""
468 469 #####################################
469 470 ### DEBUG LOGGING CONFIGURATION ####
470 471 #####################################
471 472 [loggers]
472 473 keys = root, sqlalchemy, beaker, celery, rhodecode, ssh_wrapper
473 474
474 475 [handlers]
475 476 keys = console, console_sql
476 477
477 478 [formatters]
478 479 keys = generic, color_formatter, color_formatter_sql
479 480
480 481 #############
481 482 ## LOGGERS ##
482 483 #############
483 484 [logger_root]
484 485 level = NOTSET
485 486 handlers = console
486 487
487 488 [logger_sqlalchemy]
488 489 level = INFO
489 490 handlers = console_sql
490 491 qualname = sqlalchemy.engine
491 492 propagate = 0
492 493
493 494 [logger_beaker]
494 495 level = DEBUG
495 496 handlers =
496 497 qualname = beaker.container
497 498 propagate = 1
498 499
499 500 [logger_rhodecode]
500 501 level = DEBUG
501 502 handlers =
502 503 qualname = rhodecode
503 504 propagate = 1
504 505
505 506 [logger_ssh_wrapper]
506 507 level = DEBUG
507 508 handlers =
508 509 qualname = ssh_wrapper
509 510 propagate = 1
510 511
511 512 [logger_celery]
512 513 level = DEBUG
513 514 handlers =
514 515 qualname = celery
515 516
516 517
517 518 ##############
518 519 ## HANDLERS ##
519 520 ##############
520 521
521 522 [handler_console]
522 523 class = StreamHandler
523 524 args = (sys.stderr, )
524 525 level = DEBUG
525 526 formatter = color_formatter
526 527
527 528 [handler_console_sql]
528 529 # "level = DEBUG" logs SQL queries and results.
529 530 # "level = INFO" logs SQL queries.
530 531 # "level = WARN" logs neither. (Recommended for production systems.)
531 532 class = StreamHandler
532 533 args = (sys.stderr, )
533 534 level = WARN
534 535 formatter = color_formatter_sql
535 536
536 537 ################
537 538 ## FORMATTERS ##
538 539 ################
539 540
540 541 [formatter_generic]
541 542 class = rhodecode.lib.logging_formatter.ExceptionAwareFormatter
542 543 format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s | %(req_id)s
543 544 datefmt = %Y-%m-%d %H:%M:%S
544 545
545 546 [formatter_color_formatter]
546 547 class = rhodecode.lib.logging_formatter.ColorRequestTrackingFormatter
547 548 format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s | %(req_id)s
548 549 datefmt = %Y-%m-%d %H:%M:%S
549 550
550 551 [formatter_color_formatter_sql]
551 552 class = rhodecode.lib.logging_formatter.ColorFormatterSql
552 553 format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s
553 554 datefmt = %Y-%m-%d %H:%M:%S
554 555 """)
555 556
556 557 with tempfile.NamedTemporaryFile(prefix='rc_debug_logging_', suffix='.ini',
557 558 delete=False) as f:
558 559 log.info('Saved Temporary DEBUG config at %s', f.name)
559 560 f.write(ini_template)
560 561
561 562 logging.config.fileConfig(f.name)
562 563 log.debug('DEBUG MODE ON')
563 564 os.remove(f.name)
564 565
565 566
566 567 def _sanitize_appenlight_settings(settings):
567 568 _bool_setting(settings, 'appenlight', 'false')
568 569
569 570
570 571 def _sanitize_vcs_settings(settings):
571 572 """
572 573 Applies settings defaults and does type conversion for all VCS related
573 574 settings.
574 575 """
575 576 _string_setting(settings, 'vcs.svn.compatible_version', '')
576 577 _string_setting(settings, 'vcs.hooks.protocol', 'http')
577 578 _string_setting(settings, 'vcs.hooks.host', '127.0.0.1')
578 579 _string_setting(settings, 'vcs.scm_app_implementation', 'http')
579 580 _string_setting(settings, 'vcs.server', '')
580 581 _string_setting(settings, 'vcs.server.log_level', 'debug')
581 582 _string_setting(settings, 'vcs.server.protocol', 'http')
582 583 _bool_setting(settings, 'startup.import_repos', 'false')
583 584 _bool_setting(settings, 'vcs.hooks.direct_calls', 'false')
584 585 _bool_setting(settings, 'vcs.server.enable', 'true')
585 586 _bool_setting(settings, 'vcs.start_server', 'false')
586 587 _list_setting(settings, 'vcs.backends', 'hg, git, svn')
587 588 _int_setting(settings, 'vcs.connection_timeout', 3600)
588 589
589 590 # Support legacy values of vcs.scm_app_implementation. Legacy
590 591 # configurations may use 'rhodecode.lib.middleware.utils.scm_app_http', or
591 592 # disabled since 4.13 'vcsserver.scm_app' which is now mapped to 'http'.
592 593 scm_app_impl = settings['vcs.scm_app_implementation']
593 594 if scm_app_impl in ['rhodecode.lib.middleware.utils.scm_app_http', 'vcsserver.scm_app']:
594 595 settings['vcs.scm_app_implementation'] = 'http'
595 596
596 597
597 598 def _sanitize_cache_settings(settings):
598 599 temp_store = tempfile.gettempdir()
599 600 default_cache_dir = os.path.join(temp_store, 'rc_cache')
600 601
601 602 # save default, cache dir, and use it for all backends later.
602 603 default_cache_dir = _string_setting(
603 604 settings,
604 605 'cache_dir',
605 606 default_cache_dir, lower=False, default_when_empty=True)
606 607
607 608 # ensure we have our dir created
608 609 if not os.path.isdir(default_cache_dir):
609 610 os.makedirs(default_cache_dir, mode=0o755)
610 611
611 612 # exception store cache
612 613 _string_setting(
613 614 settings,
614 615 'exception_tracker.store_path',
615 616 temp_store, lower=False, default_when_empty=True)
616 617
617 618 # cache_perms
618 619 _string_setting(
619 620 settings,
620 621 'rc_cache.cache_perms.backend',
621 622 'dogpile.cache.rc.file_namespace', lower=False)
622 623 _int_setting(
623 624 settings,
624 625 'rc_cache.cache_perms.expiration_time',
625 626 60)
626 627 _string_setting(
627 628 settings,
628 629 'rc_cache.cache_perms.arguments.filename',
629 630 os.path.join(default_cache_dir, 'rc_cache_1'), lower=False)
630 631
631 632 # cache_repo
632 633 _string_setting(
633 634 settings,
634 635 'rc_cache.cache_repo.backend',
635 636 'dogpile.cache.rc.file_namespace', lower=False)
636 637 _int_setting(
637 638 settings,
638 639 'rc_cache.cache_repo.expiration_time',
639 640 60)
640 641 _string_setting(
641 642 settings,
642 643 'rc_cache.cache_repo.arguments.filename',
643 644 os.path.join(default_cache_dir, 'rc_cache_2'), lower=False)
644 645
645 646 # cache_license
646 647 _string_setting(
647 648 settings,
648 649 'rc_cache.cache_license.backend',
649 650 'dogpile.cache.rc.file_namespace', lower=False)
650 651 _int_setting(
651 652 settings,
652 653 'rc_cache.cache_license.expiration_time',
653 654 5*60)
654 655 _string_setting(
655 656 settings,
656 657 'rc_cache.cache_license.arguments.filename',
657 658 os.path.join(default_cache_dir, 'rc_cache_3'), lower=False)
658 659
659 660 # cache_repo_longterm memory, 96H
660 661 _string_setting(
661 662 settings,
662 663 'rc_cache.cache_repo_longterm.backend',
663 664 'dogpile.cache.rc.memory_lru', lower=False)
664 665 _int_setting(
665 666 settings,
666 667 'rc_cache.cache_repo_longterm.expiration_time',
667 668 345600)
668 669 _int_setting(
669 670 settings,
670 671 'rc_cache.cache_repo_longterm.max_size',
671 672 10000)
672 673
673 674 # sql_cache_short
674 675 _string_setting(
675 676 settings,
676 677 'rc_cache.sql_cache_short.backend',
677 678 'dogpile.cache.rc.memory_lru', lower=False)
678 679 _int_setting(
679 680 settings,
680 681 'rc_cache.sql_cache_short.expiration_time',
681 682 30)
682 683 _int_setting(
683 684 settings,
684 685 'rc_cache.sql_cache_short.max_size',
685 686 10000)
686 687
687 688
688 689 def _int_setting(settings, name, default):
689 690 settings[name] = int(settings.get(name, default))
690 691 return settings[name]
691 692
692 693
693 694 def _bool_setting(settings, name, default):
694 695 input_val = settings.get(name, default)
695 696 if isinstance(input_val, unicode):
696 697 input_val = input_val.encode('utf8')
697 698 settings[name] = asbool(input_val)
698 699 return settings[name]
699 700
700 701
701 702 def _list_setting(settings, name, default):
702 703 raw_value = settings.get(name, default)
703 704
704 705 old_separator = ','
705 706 if old_separator in raw_value:
706 707 # If we get a comma separated list, pass it to our own function.
707 708 settings[name] = rhodecode_aslist(raw_value, sep=old_separator)
708 709 else:
709 710 # Otherwise we assume it uses pyramids space/newline separation.
710 711 settings[name] = aslist(raw_value)
711 712 return settings[name]
712 713
713 714
714 715 def _string_setting(settings, name, default, lower=True, default_when_empty=False):
715 716 value = settings.get(name, default)
716 717
717 718 if default_when_empty and not value:
718 719 # use default value when value is empty
719 720 value = default
720 721
721 722 if lower:
722 723 value = value.lower()
723 724 settings[name] = value
724 725 return settings[name]
725 726
726 727
727 728 def _substitute_values(mapping, substitutions):
728 729 result = {}
729 730
730 731 try:
731 732 for key, value in mapping.items():
732 733 # initialize without substitution first
733 734 result[key] = value
734 735
735 736 # Note: Cannot use regular replacements, since they would clash
736 737 # with the implementation of ConfigParser. Using "format" instead.
737 738 try:
738 739 result[key] = value.format(**substitutions)
739 740 except KeyError as e:
740 741 env_var = '{}'.format(e.args[0])
741 742
742 743 msg = 'Failed to substitute: `{key}={{{var}}}` with environment entry. ' \
743 744 'Make sure your environment has {var} set, or remove this ' \
744 745 'variable from config file'.format(key=key, var=env_var)
745 746
746 747 if env_var.startswith('ENV_'):
747 748 raise ValueError(msg)
748 749 else:
749 750 log.warning(msg)
750 751
751 752 except ValueError as e:
752 753 log.warning('Failed to substitute ENV variable: %s', e)
753 754 result = mapping
754 755
755 756 return result
General Comments 0
You need to be logged in to leave comments. Login now