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