##// END OF EJS Templates
indexers: load additional indexers settings from ini
Takumi IINO -
r5559:6ed126ef default
parent child Browse files
Show More
@@ -1,586 +1,598 b''
1 1 ################################################################################
2 2 ################################################################################
3 3 # Kallithea - Development config: #
4 4 # listening on *:5000 #
5 5 # sqlite and kallithea.db #
6 6 # initial_repo_scan = true #
7 7 # set debug = true #
8 8 # verbose and colorful logging #
9 9 # #
10 10 # The %(here)s variable will be replaced with the parent directory of this file#
11 11 ################################################################################
12 12 ################################################################################
13 13
14 14 [DEFAULT]
15 15 debug = true
16 16 pdebug = false
17 17
18 18 ################################################################################
19 19 ## Email settings ##
20 20 ## ##
21 21 ## Refer to the documentation ("Email settings") for more details. ##
22 22 ## ##
23 23 ## It is recommended to use a valid sender address that passes access ##
24 24 ## validation and spam filtering in mail servers. ##
25 25 ################################################################################
26 26
27 27 ## 'From' header for application emails. You can optionally add a name.
28 28 ## Default:
29 29 #app_email_from = Kallithea
30 30 ## Examples:
31 31 #app_email_from = Kallithea <kallithea-noreply@example.com>
32 32 #app_email_from = kallithea-noreply@example.com
33 33
34 34 ## Subject prefix for application emails.
35 35 ## A space between this prefix and the real subject is automatically added.
36 36 ## Default:
37 37 #email_prefix =
38 38 ## Example:
39 39 #email_prefix = [Kallithea]
40 40
41 41 ## Recipients for error emails and fallback recipients of application mails.
42 42 ## Multiple addresses can be specified, space-separated.
43 43 ## Only addresses are allowed, do not add any name part.
44 44 ## Default:
45 45 #email_to =
46 46 ## Examples:
47 47 #email_to = admin@example.com
48 48 #email_to = admin@example.com another_admin@example.com
49 49
50 50 ## 'From' header for error emails. You can optionally add a name.
51 51 ## Default:
52 52 #error_email_from = pylons@yourapp.com
53 53 ## Examples:
54 54 #error_email_from = Kallithea Errors <kallithea-noreply@example.com>
55 55 #error_email_from = paste_error@example.com
56 56
57 57 ## SMTP server settings
58 58 ## Only smtp_server is mandatory. All other settings take the specified default
59 59 ## values.
60 60 #smtp_server = smtp.example.com
61 61 #smtp_username =
62 62 #smtp_password =
63 63 #smtp_port = 25
64 64 #smtp_use_tls = false
65 65 #smtp_use_ssl = false
66 66 ## SMTP authentication parameters to use (e.g. LOGIN PLAIN CRAM-MD5, etc.).
67 67 ## If empty, use any of the authentication parameters supported by the server.
68 68 #smtp_auth =
69 69
70 70 [server:main]
71 71 ## PASTE ##
72 72 #use = egg:Paste#http
73 73 ## nr of worker threads to spawn
74 74 #threadpool_workers = 5
75 75 ## max request before thread respawn
76 76 #threadpool_max_requests = 10
77 77 ## option to use threads of process
78 78 #use_threadpool = true
79 79
80 80 ## WAITRESS ##
81 81 use = egg:waitress#main
82 82 ## number of worker threads
83 83 threads = 5
84 84 ## MAX BODY SIZE 100GB
85 85 max_request_body_size = 107374182400
86 86 ## use poll instead of select, fixes fd limits, may not work on old
87 87 ## windows systems.
88 88 #asyncore_use_poll = True
89 89
90 90 ## GUNICORN ##
91 91 #use = egg:gunicorn#main
92 92 ## number of process workers. You must set `instance_id = *` when this option
93 93 ## is set to more than one worker
94 94 #workers = 1
95 95 ## process name
96 96 #proc_name = kallithea
97 97 ## type of worker class, one of sync, eventlet, gevent, tornado
98 98 ## recommended for bigger setup is using of of other than sync one
99 99 #worker_class = sync
100 100 #max_requests = 1000
101 101 ## ammount of time a worker can handle request before it gets killed and
102 102 ## restarted
103 103 #timeout = 3600
104 104
105 105 ## UWSGI ##
106 106 ## run with uwsgi --ini-paste-logged <inifile.ini>
107 107 #[uwsgi]
108 108 #socket = /tmp/uwsgi.sock
109 109 #master = true
110 110 #http = 127.0.0.1:5000
111 111
112 112 ## set as deamon and redirect all output to file
113 113 #daemonize = ./uwsgi_kallithea.log
114 114
115 115 ## master process PID
116 116 #pidfile = ./uwsgi_kallithea.pid
117 117
118 118 ## stats server with workers statistics, use uwsgitop
119 119 ## for monitoring, `uwsgitop 127.0.0.1:1717`
120 120 #stats = 127.0.0.1:1717
121 121 #memory-report = true
122 122
123 123 ## log 5XX errors
124 124 #log-5xx = true
125 125
126 126 ## Set the socket listen queue size.
127 127 #listen = 256
128 128
129 129 ## Gracefully Reload workers after the specified amount of managed requests
130 130 ## (avoid memory leaks).
131 131 #max-requests = 1000
132 132
133 133 ## enable large buffers
134 134 #buffer-size = 65535
135 135
136 136 ## socket and http timeouts ##
137 137 #http-timeout = 3600
138 138 #socket-timeout = 3600
139 139
140 140 ## Log requests slower than the specified number of milliseconds.
141 141 #log-slow = 10
142 142
143 143 ## Exit if no app can be loaded.
144 144 #need-app = true
145 145
146 146 ## Set lazy mode (load apps in workers instead of master).
147 147 #lazy = true
148 148
149 149 ## scaling ##
150 150 ## set cheaper algorithm to use, if not set default will be used
151 151 #cheaper-algo = spare
152 152
153 153 ## minimum number of workers to keep at all times
154 154 #cheaper = 1
155 155
156 156 ## number of workers to spawn at startup
157 157 #cheaper-initial = 1
158 158
159 159 ## maximum number of workers that can be spawned
160 160 #workers = 4
161 161
162 162 ## how many workers should be spawned at a time
163 163 #cheaper-step = 1
164 164
165 165 ## COMMON ##
166 166 #host = 127.0.0.1
167 167 host = 0.0.0.0
168 168 port = 5000
169 169
170 170 ## middleware for hosting the WSGI application under a URL prefix
171 171 #[filter:proxy-prefix]
172 172 #use = egg:PasteDeploy#prefix
173 173 #prefix = /<your-prefix>
174 174
175 175 [app:main]
176 176 use = egg:kallithea
177 177 ## enable proxy prefix middleware
178 178 #filter-with = proxy-prefix
179 179
180 180 full_stack = true
181 181 static_files = true
182 182 ## Available Languages:
183 183 ## cs de fr hu ja nl_BE pl pt_BR ru sk zh_CN zh_TW
184 184 lang =
185 185 cache_dir = %(here)s/data
186 186 index_dir = %(here)s/data/index
187 187
188 188 ## perform a full repository scan on each server start, this should be
189 189 ## set to false after first startup, to allow faster server restarts.
190 190 #initial_repo_scan = false
191 191 initial_repo_scan = true
192 192
193 193 ## uncomment and set this path to use archive download cache
194 194 archive_cache_dir = %(here)s/tarballcache
195 195
196 196 ## change this to unique ID for security
197 197 app_instance_uuid = development-not-secret
198 198
199 199 ## cut off limit for large diffs (size in bytes)
200 200 cut_off_limit = 256000
201 201
202 202 ## use cache version of scm repo everywhere
203 203 vcs_full_cache = true
204 204
205 205 ## force https in Kallithea, fixes https redirects, assumes it's always https
206 206 force_https = false
207 207
208 208 ## use Strict-Transport-Security headers
209 209 use_htsts = false
210 210
211 211 ## number of commits stats will parse on each iteration
212 212 commit_parse_limit = 25
213 213
214 214 ## path to git executable
215 215 git_path = git
216 216
217 217 ## git rev filter option, --all is the default filter, if you need to
218 218 ## hide all refs in changelog switch this to --branches --tags
219 219 #git_rev_filter = --branches --tags
220 220
221 221 ## RSS feed options
222 222 rss_cut_off_limit = 256000
223 223 rss_items_per_page = 10
224 224 rss_include_diff = false
225 225
226 226 ## options for showing and identifying changesets
227 227 show_sha_length = 12
228 228 show_revision_number = false
229 229
230 230 ## gist URL alias, used to create nicer urls for gist. This should be an
231 231 ## url that does rewrites to _admin/gists/<gistid>.
232 232 ## example: http://gist.example.com/{gistid}. Empty means use the internal
233 233 ## Kallithea url, ie. http[s]://kallithea.example.com/_admin/gists/<gistid>
234 234 gist_alias_url =
235 235
236 236 ## white list of API enabled controllers. This allows to add list of
237 237 ## controllers to which access will be enabled by api_key. eg: to enable
238 238 ## api access to raw_files put `FilesController:raw`, to enable access to patches
239 239 ## add `ChangesetController:changeset_patch`. This list should be "," separated
240 240 ## Syntax is <ControllerClass>:<function>. Check debug logs for generated names
241 241 ## Recommended settings below are commented out:
242 242 api_access_controllers_whitelist =
243 243 # ChangesetController:changeset_patch,
244 244 # ChangesetController:changeset_raw,
245 245 # FilesController:raw,
246 246 # FilesController:archivefile
247 247
248 248 ## default encoding used to convert from and to unicode
249 249 ## can be also a comma seperated list of encoding in case of mixed encodings
250 250 default_encoding = utf8
251 251
252 252 ## issue tracker for Kallithea (leave blank to disable, absent for default)
253 253 #bugtracker = https://bitbucket.org/conservancy/kallithea/issues
254 254
255 255 ## issue tracking mapping for commits messages
256 256 ## comment out issue_pat, issue_server, issue_prefix to enable
257 257
258 258 ## pattern to get the issues from commit messages
259 259 ## default one used here is #<numbers> with a regex passive group for `#`
260 260 ## {id} will be all groups matched from this pattern
261 261
262 262 issue_pat = (?:\s*#)(\d+)
263 263
264 264 ## server url to the issue, each {id} will be replaced with match
265 265 ## fetched from the regex and {repo} is replaced with full repository name
266 266 ## including groups {repo_name} is replaced with just name of repo
267 267
268 268 issue_server_link = https://issues.example.com/{repo}/issue/{id}
269 269
270 270 ## prefix to add to link to indicate it's an url
271 271 ## #314 will be replaced by <issue_prefix><id>
272 272
273 273 issue_prefix = #
274 274
275 275 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
276 276 ## multiple patterns, to other issues server, wiki or others
277 277 ## below an example how to create a wiki pattern
278 278 # wiki-some-id -> https://wiki.example.com/some-id
279 279
280 280 #issue_pat_wiki = (?:wiki-)(.+)
281 281 #issue_server_link_wiki = https://wiki.example.com/{id}
282 282 #issue_prefix_wiki = WIKI-
283 283
284 284 ## alternative return HTTP header for failed authentication. Default HTTP
285 285 ## response is 401 HTTPUnauthorized. Currently Mercurial clients have trouble with
286 286 ## handling that. Set this variable to 403 to return HTTPForbidden
287 287 auth_ret_code =
288 288
289 289 ## locking return code. When repository is locked return this HTTP code. 2XX
290 290 ## codes don't break the transactions while 4XX codes do
291 291 lock_ret_code = 423
292 292
293 293 ## allows to change the repository location in settings page
294 294 allow_repo_location_change = True
295 295
296 296 ## allows to setup custom hooks in settings page
297 297 allow_custom_hooks_settings = True
298 298
299 ## extra extensions for indexing, space separated and without the leading '.'.
300 # index.extensions =
301 # gemfile
302 # lock
303
304 ## extra filenames for indexing, space separated
305 # index.filenames =
306 # .dockerignore
307 # .editorconfig
308 # INSTALL
309 # CHANGELOG
310
299 311 ####################################
300 312 ### CELERY CONFIG ####
301 313 ####################################
302 314
303 315 use_celery = false
304 316 broker.host = localhost
305 317 broker.vhost = rabbitmqhost
306 318 broker.port = 5672
307 319 broker.user = rabbitmq
308 320 broker.password = qweqwe
309 321
310 322 celery.imports = kallithea.lib.celerylib.tasks
311 323
312 324 celery.result.backend = amqp
313 325 celery.result.dburi = amqp://
314 326 celery.result.serialier = json
315 327
316 328 #celery.send.task.error.emails = true
317 329 #celery.amqp.task.result.expires = 18000
318 330
319 331 celeryd.concurrency = 2
320 332 #celeryd.log.file = celeryd.log
321 333 celeryd.log.level = DEBUG
322 334 celeryd.max.tasks.per.child = 1
323 335
324 336 ## tasks will never be sent to the queue, but executed locally instead.
325 337 celery.always.eager = false
326 338
327 339 ####################################
328 340 ### BEAKER CACHE ####
329 341 ####################################
330 342
331 343 beaker.cache.data_dir = %(here)s/data/cache/data
332 344 beaker.cache.lock_dir = %(here)s/data/cache/lock
333 345
334 346 beaker.cache.regions = short_term,long_term,sql_cache_short
335 347
336 348 beaker.cache.short_term.type = memory
337 349 beaker.cache.short_term.expire = 60
338 350 beaker.cache.short_term.key_length = 256
339 351
340 352 beaker.cache.long_term.type = memory
341 353 beaker.cache.long_term.expire = 36000
342 354 beaker.cache.long_term.key_length = 256
343 355
344 356 beaker.cache.sql_cache_short.type = memory
345 357 beaker.cache.sql_cache_short.expire = 10
346 358 beaker.cache.sql_cache_short.key_length = 256
347 359
348 360 ####################################
349 361 ### BEAKER SESSION ####
350 362 ####################################
351 363
352 364 ## Name of session cookie. Should be unique for a given host and path, even when running
353 365 ## on different ports. Otherwise, cookie sessions will be shared and messed up.
354 366 beaker.session.key = kallithea
355 367 ## Sessions should always only be accessible by the browser, not directly by JavaScript.
356 368 beaker.session.httponly = true
357 369 ## Session lifetime. 2592000 seconds is 30 days.
358 370 beaker.session.timeout = 2592000
359 371
360 372 ## Server secret used with HMAC to ensure integrity of cookies.
361 373 beaker.session.secret = development-not-secret
362 374 ## Further, encrypt the data with AES.
363 375 #beaker.session.encrypt_key = <key_for_encryption>
364 376 #beaker.session.validate_key = <validation_key>
365 377
366 378 ## Type of storage used for the session, current types are
367 379 ## dbm, file, memcached, database, and memory.
368 380
369 381 ## File system storage of session data. (default)
370 382 #beaker.session.type = file
371 383
372 384 ## Cookie only, store all session data inside the cookie. Requires secure secrets.
373 385 #beaker.session.type = cookie
374 386
375 387 ## Database storage of session data.
376 388 #beaker.session.type = ext:database
377 389 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/kallithea
378 390 #beaker.session.table_name = db_session
379 391
380 392 ############################
381 393 ## ERROR HANDLING SYSTEMS ##
382 394 ############################
383 395
384 396 ####################
385 397 ### [errormator] ###
386 398 ####################
387 399
388 400 ## Errormator is tailored to work with Kallithea, see
389 401 ## http://errormator.com for details how to obtain an account
390 402 ## you must install python package `errormator_client` to make it work
391 403
392 404 ## errormator enabled
393 405 errormator = false
394 406
395 407 errormator.server_url = https://api.errormator.com
396 408 errormator.api_key = YOUR_API_KEY
397 409
398 410 ## TWEAK AMOUNT OF INFO SENT HERE
399 411
400 412 ## enables 404 error logging (default False)
401 413 errormator.report_404 = false
402 414
403 415 ## time in seconds after request is considered being slow (default 1)
404 416 errormator.slow_request_time = 1
405 417
406 418 ## record slow requests in application
407 419 ## (needs to be enabled for slow datastore recording and time tracking)
408 420 errormator.slow_requests = true
409 421
410 422 ## enable hooking to application loggers
411 423 #errormator.logging = true
412 424
413 425 ## minimum log level for log capture
414 426 #errormator.logging.level = WARNING
415 427
416 428 ## send logs only from erroneous/slow requests
417 429 ## (saves API quota for intensive logging)
418 430 errormator.logging_on_error = false
419 431
420 432 ## list of additonal keywords that should be grabbed from environ object
421 433 ## can be string with comma separated list of words in lowercase
422 434 ## (by default client will always send following info:
423 435 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
424 436 ## start with HTTP* this list be extended with additional keywords here
425 437 errormator.environ_keys_whitelist =
426 438
427 439 ## list of keywords that should be blanked from request object
428 440 ## can be string with comma separated list of words in lowercase
429 441 ## (by default client will always blank keys that contain following words
430 442 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
431 443 ## this list be extended with additional keywords set here
432 444 errormator.request_keys_blacklist =
433 445
434 446 ## list of namespaces that should be ignores when gathering log entries
435 447 ## can be string with comma separated list of namespaces
436 448 ## (by default the client ignores own entries: errormator_client.client)
437 449 errormator.log_namespace_blacklist =
438 450
439 451 ################
440 452 ### [sentry] ###
441 453 ################
442 454
443 455 ## sentry is a alternative open source error aggregator
444 456 ## you must install python packages `sentry` and `raven` to enable
445 457
446 458 sentry.dsn = YOUR_DNS
447 459 sentry.servers =
448 460 sentry.name =
449 461 sentry.key =
450 462 sentry.public_key =
451 463 sentry.secret_key =
452 464 sentry.project =
453 465 sentry.site =
454 466 sentry.include_paths =
455 467 sentry.exclude_paths =
456 468
457 469 ################################################################################
458 470 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
459 471 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
460 472 ## execute malicious code after an exception is raised. ##
461 473 ################################################################################
462 474 #set debug = false
463 475 set debug = true
464 476
465 477 ##################################
466 478 ### LOGVIEW CONFIG ###
467 479 ##################################
468 480
469 481 logview.sqlalchemy = #faa
470 482 logview.pylons.templating = #bfb
471 483 logview.pylons.util = #eee
472 484
473 485 #########################################################
474 486 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
475 487 #########################################################
476 488
477 489 # SQLITE [default]
478 490 sqlalchemy.db1.url = sqlite:///%(here)s/kallithea.db?timeout=60
479 491
480 492 # POSTGRESQL
481 493 #sqlalchemy.db1.url = postgresql://user:pass@localhost/kallithea
482 494
483 495 # MySQL
484 496 #sqlalchemy.db1.url = mysql://user:pass@localhost/kallithea
485 497
486 498 # see sqlalchemy docs for others
487 499
488 500 sqlalchemy.db1.echo = false
489 501 sqlalchemy.db1.pool_recycle = 3600
490 502 sqlalchemy.db1.convert_unicode = true
491 503
492 504 ################################
493 505 ### LOGGING CONFIGURATION ####
494 506 ################################
495 507
496 508 [loggers]
497 509 keys = root, routes, kallithea, sqlalchemy, beaker, templates, whoosh_indexer
498 510
499 511 [handlers]
500 512 keys = console, console_sql
501 513
502 514 [formatters]
503 515 keys = generic, color_formatter, color_formatter_sql
504 516
505 517 #############
506 518 ## LOGGERS ##
507 519 #############
508 520
509 521 [logger_root]
510 522 level = NOTSET
511 523 handlers = console
512 524
513 525 [logger_routes]
514 526 level = DEBUG
515 527 handlers =
516 528 qualname = routes.middleware
517 529 ## "level = DEBUG" logs the route matched and routing variables.
518 530 propagate = 1
519 531
520 532 [logger_beaker]
521 533 level = DEBUG
522 534 handlers =
523 535 qualname = beaker.container
524 536 propagate = 1
525 537
526 538 [logger_templates]
527 539 level = INFO
528 540 handlers =
529 541 qualname = pylons.templating
530 542 propagate = 1
531 543
532 544 [logger_kallithea]
533 545 level = DEBUG
534 546 handlers =
535 547 qualname = kallithea
536 548 propagate = 1
537 549
538 550 [logger_sqlalchemy]
539 551 level = INFO
540 552 handlers = console_sql
541 553 qualname = sqlalchemy.engine
542 554 propagate = 0
543 555
544 556 [logger_whoosh_indexer]
545 557 level = DEBUG
546 558 handlers =
547 559 qualname = whoosh_indexer
548 560 propagate = 1
549 561
550 562 ##############
551 563 ## HANDLERS ##
552 564 ##############
553 565
554 566 [handler_console]
555 567 class = StreamHandler
556 568 args = (sys.stderr,)
557 569 #level = INFO
558 570 level = DEBUG
559 571 #formatter = generic
560 572 formatter = color_formatter
561 573
562 574 [handler_console_sql]
563 575 class = StreamHandler
564 576 args = (sys.stderr,)
565 577 #level = WARN
566 578 level = DEBUG
567 579 #formatter = generic
568 580 formatter = color_formatter_sql
569 581
570 582 ################
571 583 ## FORMATTERS ##
572 584 ################
573 585
574 586 [formatter_generic]
575 587 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
576 588 datefmt = %Y-%m-%d %H:%M:%S
577 589
578 590 [formatter_color_formatter]
579 591 class = kallithea.lib.colored_formatter.ColorFormatter
580 592 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
581 593 datefmt = %Y-%m-%d %H:%M:%S
582 594
583 595 [formatter_color_formatter_sql]
584 596 class = kallithea.lib.colored_formatter.ColorFormatterSql
585 597 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
586 598 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,585 +1,597 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <%text>################################################################################</%text>
3 3 <%text>################################################################################</%text>
4 4 # Kallithea - config file generated with kallithea-config #
5 5 <%text>################################################################################</%text>
6 6 <%text>################################################################################</%text>
7 7
8 8 [DEFAULT]
9 9 debug = true
10 10 pdebug = false
11 11
12 12 <%text>################################################################################</%text>
13 13 <%text>## Email settings ##</%text>
14 14 <%text>## ##</%text>
15 15 <%text>## Refer to the documentation ("Email settings") for more details. ##</%text>
16 16 <%text>## ##</%text>
17 17 <%text>## It is recommended to use a valid sender address that passes access ##</%text>
18 18 <%text>## validation and spam filtering in mail servers. ##</%text>
19 19 <%text>################################################################################</%text>
20 20
21 21 <%text>## 'From' header for application emails. You can optionally add a name.</%text>
22 22 <%text>## Default:</%text>
23 23 #app_email_from = Kallithea
24 24 <%text>## Examples:</%text>
25 25 #app_email_from = Kallithea <kallithea-noreply@example.com>
26 26 #app_email_from = kallithea-noreply@example.com
27 27
28 28 <%text>## Subject prefix for application emails.</%text>
29 29 <%text>## A space between this prefix and the real subject is automatically added.</%text>
30 30 <%text>## Default:</%text>
31 31 #email_prefix =
32 32 <%text>## Example:</%text>
33 33 #email_prefix = [Kallithea]
34 34
35 35 <%text>## Recipients for error emails and fallback recipients of application mails.</%text>
36 36 <%text>## Multiple addresses can be specified, space-separated.</%text>
37 37 <%text>## Only addresses are allowed, do not add any name part.</%text>
38 38 <%text>## Default:</%text>
39 39 #email_to =
40 40 <%text>## Examples:</%text>
41 41 #email_to = admin@example.com
42 42 #email_to = admin@example.com another_admin@example.com
43 43
44 44 <%text>## 'From' header for error emails. You can optionally add a name.</%text>
45 45 <%text>## Default:</%text>
46 46 #error_email_from = pylons@yourapp.com
47 47 <%text>## Examples:</%text>
48 48 #error_email_from = Kallithea Errors <kallithea-noreply@example.com>
49 49 #error_email_from = paste_error@example.com
50 50
51 51 <%text>## SMTP server settings</%text>
52 52 <%text>## Only smtp_server is mandatory. All other settings take the specified default</%text>
53 53 <%text>## values.</%text>
54 54 #smtp_server = smtp.example.com
55 55 #smtp_username =
56 56 #smtp_password =
57 57 #smtp_port = 25
58 58 #smtp_use_tls = false
59 59 #smtp_use_ssl = false
60 60 <%text>## SMTP authentication parameters to use (e.g. LOGIN PLAIN CRAM-MD5, etc.).</%text>
61 61 <%text>## If empty, use any of the authentication parameters supported by the server.</%text>
62 62 #smtp_auth =
63 63
64 64 [server:main]
65 65 %if http_server == 'paste':
66 66 <%text>## PASTE ##</%text>
67 67 use = egg:Paste#http
68 68 <%text>## nr of worker threads to spawn</%text>
69 69 threadpool_workers = 5
70 70 <%text>## max request before thread respawn</%text>
71 71 threadpool_max_requests = 10
72 72 <%text>## option to use threads of process</%text>
73 73 use_threadpool = true
74 74
75 75 %elif http_server == 'waitress':
76 76 <%text>## WAITRESS ##</%text>
77 77 use = egg:waitress#main
78 78 <%text>## number of worker threads</%text>
79 79 threads = 5
80 80 <%text>## MAX BODY SIZE 100GB</%text>
81 81 max_request_body_size = 107374182400
82 82 <%text>## use poll instead of select, fixes fd limits, may not work on old</%text>
83 83 <%text>## windows systems.</%text>
84 84 #asyncore_use_poll = True
85 85
86 86 %elif http_server == 'gunicorn':
87 87 <%text>## GUNICORN ##</%text>
88 88 use = egg:gunicorn#main
89 89 <%text>## number of process workers. You must set `instance_id = *` when this option</%text>
90 90 <%text>## is set to more than one worker</%text>
91 91 workers = 1
92 92 <%text>## process name</%text>
93 93 proc_name = kallithea
94 94 <%text>## type of worker class, one of sync, eventlet, gevent, tornado</%text>
95 95 <%text>## recommended for bigger setup is using of of other than sync one</%text>
96 96 worker_class = sync
97 97 max_requests = 1000
98 98 <%text>## ammount of time a worker can handle request before it gets killed and</%text>
99 99 <%text>## restarted</%text>
100 100 timeout = 3600
101 101
102 102 %elif http_server == 'uwsgi':
103 103 <%text>## UWSGI ##</%text>
104 104 <%text>## run with uwsgi --ini-paste-logged <inifile.ini></%text>
105 105 [uwsgi]
106 106 socket = /tmp/uwsgi.sock
107 107 master = true
108 108 http = 127.0.0.1:5000
109 109
110 110 <%text>## set as deamon and redirect all output to file</%text>
111 111 #daemonize = ./uwsgi_kallithea.log
112 112
113 113 <%text>## master process PID</%text>
114 114 pidfile = ./uwsgi_kallithea.pid
115 115
116 116 <%text>## stats server with workers statistics, use uwsgitop</%text>
117 117 <%text>## for monitoring, `uwsgitop 127.0.0.1:1717`</%text>
118 118 stats = 127.0.0.1:1717
119 119 memory-report = true
120 120
121 121 <%text>## log 5XX errors</%text>
122 122 log-5xx = true
123 123
124 124 <%text>## Set the socket listen queue size.</%text>
125 125 listen = 256
126 126
127 127 <%text>## Gracefully Reload workers after the specified amount of managed requests</%text>
128 128 <%text>## (avoid memory leaks).</%text>
129 129 max-requests = 1000
130 130
131 131 <%text>## enable large buffers</%text>
132 132 buffer-size = 65535
133 133
134 134 <%text>## socket and http timeouts ##</%text>
135 135 http-timeout = 3600
136 136 socket-timeout = 3600
137 137
138 138 <%text>## Log requests slower than the specified number of milliseconds.</%text>
139 139 log-slow = 10
140 140
141 141 <%text>## Exit if no app can be loaded.</%text>
142 142 need-app = true
143 143
144 144 <%text>## Set lazy mode (load apps in workers instead of master).</%text>
145 145 lazy = true
146 146
147 147 <%text>## scaling ##</%text>
148 148 <%text>## set cheaper algorithm to use, if not set default will be used</%text>
149 149 cheaper-algo = spare
150 150
151 151 <%text>## minimum number of workers to keep at all times</%text>
152 152 cheaper = 1
153 153
154 154 <%text>## number of workers to spawn at startup</%text>
155 155 cheaper-initial = 1
156 156
157 157 <%text>## maximum number of workers that can be spawned</%text>
158 158 workers = 4
159 159
160 160 <%text>## how many workers should be spawned at a time</%text>
161 161 cheaper-step = 1
162 162
163 163 %endif
164 164 <%text>## COMMON ##</%text>
165 165 host = ${host}
166 166 port = ${port}
167 167
168 168 <%text>## middleware for hosting the WSGI application under a URL prefix</%text>
169 169 #[filter:proxy-prefix]
170 170 #use = egg:PasteDeploy#prefix
171 171 #prefix = /<your-prefix>
172 172
173 173 [app:main]
174 174 use = egg:kallithea
175 175 <%text>## enable proxy prefix middleware</%text>
176 176 #filter-with = proxy-prefix
177 177
178 178 full_stack = true
179 179 static_files = true
180 180 <%text>## Available Languages:</%text>
181 181 <%text>## cs de fr hu ja nl_BE pl pt_BR ru sk zh_CN zh_TW</%text>
182 182 lang =
183 183 cache_dir = ${here}/data
184 184 index_dir = ${here}/data/index
185 185
186 186 <%text>## perform a full repository scan on each server start, this should be</%text>
187 187 <%text>## set to false after first startup, to allow faster server restarts.</%text>
188 188 initial_repo_scan = false
189 189
190 190 <%text>## uncomment and set this path to use archive download cache</%text>
191 191 archive_cache_dir = ${here}/tarballcache
192 192
193 193 <%text>## change this to unique ID for security</%text>
194 194 app_instance_uuid = ${uuid()}
195 195
196 196 <%text>## cut off limit for large diffs (size in bytes)</%text>
197 197 cut_off_limit = 256000
198 198
199 199 <%text>## use cache version of scm repo everywhere</%text>
200 200 vcs_full_cache = true
201 201
202 202 <%text>## force https in Kallithea, fixes https redirects, assumes it's always https</%text>
203 203 force_https = false
204 204
205 205 <%text>## use Strict-Transport-Security headers</%text>
206 206 use_htsts = false
207 207
208 208 <%text>## number of commits stats will parse on each iteration</%text>
209 209 commit_parse_limit = 25
210 210
211 211 <%text>## path to git executable</%text>
212 212 git_path = git
213 213
214 214 <%text>## git rev filter option, --all is the default filter, if you need to</%text>
215 215 <%text>## hide all refs in changelog switch this to --branches --tags</%text>
216 216 #git_rev_filter = --branches --tags
217 217
218 218 <%text>## RSS feed options</%text>
219 219 rss_cut_off_limit = 256000
220 220 rss_items_per_page = 10
221 221 rss_include_diff = false
222 222
223 223 <%text>## options for showing and identifying changesets</%text>
224 224 show_sha_length = 12
225 225 show_revision_number = false
226 226
227 227 <%text>## gist URL alias, used to create nicer urls for gist. This should be an</%text>
228 228 <%text>## url that does rewrites to _admin/gists/<gistid>.</%text>
229 229 <%text>## example: http://gist.example.com/{gistid}. Empty means use the internal</%text>
230 230 <%text>## Kallithea url, ie. http[s]://kallithea.example.com/_admin/gists/<gistid></%text>
231 231 gist_alias_url =
232 232
233 233 <%text>## white list of API enabled controllers. This allows to add list of</%text>
234 234 <%text>## controllers to which access will be enabled by api_key. eg: to enable</%text>
235 235 <%text>## api access to raw_files put `FilesController:raw`, to enable access to patches</%text>
236 236 <%text>## add `ChangesetController:changeset_patch`. This list should be "," separated</%text>
237 237 <%text>## Syntax is <ControllerClass>:<function>. Check debug logs for generated names</%text>
238 238 <%text>## Recommended settings below are commented out:</%text>
239 239 api_access_controllers_whitelist =
240 240 # ChangesetController:changeset_patch,
241 241 # ChangesetController:changeset_raw,
242 242 # FilesController:raw,
243 243 # FilesController:archivefile
244 244
245 245 <%text>## default encoding used to convert from and to unicode</%text>
246 246 <%text>## can be also a comma seperated list of encoding in case of mixed encodings</%text>
247 247 default_encoding = utf8
248 248
249 249 <%text>## issue tracker for Kallithea (leave blank to disable, absent for default)</%text>
250 250 #bugtracker = https://bitbucket.org/conservancy/kallithea/issues
251 251
252 252 <%text>## issue tracking mapping for commits messages</%text>
253 253 <%text>## comment out issue_pat, issue_server, issue_prefix to enable</%text>
254 254
255 255 <%text>## pattern to get the issues from commit messages</%text>
256 256 <%text>## default one used here is #<numbers> with a regex passive group for `#`</%text>
257 257 <%text>## {id} will be all groups matched from this pattern</%text>
258 258
259 259 issue_pat = (?:\s*#)(\d+)
260 260
261 261 <%text>## server url to the issue, each {id} will be replaced with match</%text>
262 262 <%text>## fetched from the regex and {repo} is replaced with full repository name</%text>
263 263 <%text>## including groups {repo_name} is replaced with just name of repo</%text>
264 264
265 265 issue_server_link = https://issues.example.com/{repo}/issue/{id}
266 266
267 267 <%text>## prefix to add to link to indicate it's an url</%text>
268 268 <%text>## #314 will be replaced by <issue_prefix><id></%text>
269 269
270 270 issue_prefix = #
271 271
272 272 <%text>## issue_pat, issue_server_link, issue_prefix can have suffixes to specify</%text>
273 273 <%text>## multiple patterns, to other issues server, wiki or others</%text>
274 274 <%text>## below an example how to create a wiki pattern</%text>
275 275 # wiki-some-id -> https://wiki.example.com/some-id
276 276
277 277 #issue_pat_wiki = (?:wiki-)(.+)
278 278 #issue_server_link_wiki = https://wiki.example.com/{id}
279 279 #issue_prefix_wiki = WIKI-
280 280
281 281 <%text>## alternative return HTTP header for failed authentication. Default HTTP</%text>
282 282 <%text>## response is 401 HTTPUnauthorized. Currently Mercurial clients have trouble with</%text>
283 283 <%text>## handling that. Set this variable to 403 to return HTTPForbidden</%text>
284 284 auth_ret_code =
285 285
286 286 <%text>## locking return code. When repository is locked return this HTTP code. 2XX</%text>
287 287 <%text>## codes don't break the transactions while 4XX codes do</%text>
288 288 lock_ret_code = 423
289 289
290 290 <%text>## allows to change the repository location in settings page</%text>
291 291 allow_repo_location_change = True
292 292
293 293 <%text>## allows to setup custom hooks in settings page</%text>
294 294 allow_custom_hooks_settings = True
295 295
296 <%text>## extra extensions for indexing, space separated and without the leading '.'.</%text>
297 # index.extensions =
298 # gemfile
299 # lock
300
301 <%text>## extra filenames for indexing, space separated</%text>
302 # index.filenames =
303 # .dockerignore
304 # .editorconfig
305 # INSTALL
306 # CHANGELOG
307
296 308 <%text>####################################</%text>
297 309 <%text>### CELERY CONFIG ####</%text>
298 310 <%text>####################################</%text>
299 311
300 312 use_celery = false
301 313 broker.host = localhost
302 314 broker.vhost = rabbitmqhost
303 315 broker.port = 5672
304 316 broker.user = rabbitmq
305 317 broker.password = qweqwe
306 318
307 319 celery.imports = kallithea.lib.celerylib.tasks
308 320
309 321 celery.result.backend = amqp
310 322 celery.result.dburi = amqp://
311 323 celery.result.serialier = json
312 324
313 325 #celery.send.task.error.emails = true
314 326 #celery.amqp.task.result.expires = 18000
315 327
316 328 celeryd.concurrency = 2
317 329 #celeryd.log.file = celeryd.log
318 330 celeryd.log.level = DEBUG
319 331 celeryd.max.tasks.per.child = 1
320 332
321 333 <%text>## tasks will never be sent to the queue, but executed locally instead.</%text>
322 334 celery.always.eager = false
323 335
324 336 <%text>####################################</%text>
325 337 <%text>### BEAKER CACHE ####</%text>
326 338 <%text>####################################</%text>
327 339
328 340 beaker.cache.data_dir = ${here}/data/cache/data
329 341 beaker.cache.lock_dir = ${here}/data/cache/lock
330 342
331 343 beaker.cache.regions = short_term,long_term,sql_cache_short
332 344
333 345 beaker.cache.short_term.type = memory
334 346 beaker.cache.short_term.expire = 60
335 347 beaker.cache.short_term.key_length = 256
336 348
337 349 beaker.cache.long_term.type = memory
338 350 beaker.cache.long_term.expire = 36000
339 351 beaker.cache.long_term.key_length = 256
340 352
341 353 beaker.cache.sql_cache_short.type = memory
342 354 beaker.cache.sql_cache_short.expire = 10
343 355 beaker.cache.sql_cache_short.key_length = 256
344 356
345 357 <%text>####################################</%text>
346 358 <%text>### BEAKER SESSION ####</%text>
347 359 <%text>####################################</%text>
348 360
349 361 <%text>## Name of session cookie. Should be unique for a given host and path, even when running</%text>
350 362 <%text>## on different ports. Otherwise, cookie sessions will be shared and messed up.</%text>
351 363 beaker.session.key = kallithea
352 364 <%text>## Sessions should always only be accessible by the browser, not directly by JavaScript.</%text>
353 365 beaker.session.httponly = true
354 366 <%text>## Session lifetime. 2592000 seconds is 30 days.</%text>
355 367 beaker.session.timeout = 2592000
356 368
357 369 <%text>## Server secret used with HMAC to ensure integrity of cookies.</%text>
358 370 beaker.session.secret = ${uuid()}
359 371 <%text>## Further, encrypt the data with AES.</%text>
360 372 #beaker.session.encrypt_key = <key_for_encryption>
361 373 #beaker.session.validate_key = <validation_key>
362 374
363 375 <%text>## Type of storage used for the session, current types are</%text>
364 376 <%text>## dbm, file, memcached, database, and memory.</%text>
365 377
366 378 <%text>## File system storage of session data. (default)</%text>
367 379 #beaker.session.type = file
368 380
369 381 <%text>## Cookie only, store all session data inside the cookie. Requires secure secrets.</%text>
370 382 #beaker.session.type = cookie
371 383
372 384 <%text>## Database storage of session data.</%text>
373 385 #beaker.session.type = ext:database
374 386 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/kallithea
375 387 #beaker.session.table_name = db_session
376 388
377 389 %if error_aggregation_service == 'errormator':
378 390 <%text>############################</%text>
379 391 <%text>## ERROR HANDLING SYSTEMS ##</%text>
380 392 <%text>############################</%text>
381 393
382 394 <%text>####################</%text>
383 395 <%text>### [errormator] ###</%text>
384 396 <%text>####################</%text>
385 397
386 398 <%text>## Errormator is tailored to work with Kallithea, see</%text>
387 399 <%text>## http://errormator.com for details how to obtain an account</%text>
388 400 <%text>## you must install python package `errormator_client` to make it work</%text>
389 401
390 402 <%text>## errormator enabled</%text>
391 403 errormator = false
392 404
393 405 errormator.server_url = https://api.errormator.com
394 406 errormator.api_key = YOUR_API_KEY
395 407
396 408 <%text>## TWEAK AMOUNT OF INFO SENT HERE</%text>
397 409
398 410 <%text>## enables 404 error logging (default False)</%text>
399 411 errormator.report_404 = false
400 412
401 413 <%text>## time in seconds after request is considered being slow (default 1)</%text>
402 414 errormator.slow_request_time = 1
403 415
404 416 <%text>## record slow requests in application</%text>
405 417 <%text>## (needs to be enabled for slow datastore recording and time tracking)</%text>
406 418 errormator.slow_requests = true
407 419
408 420 <%text>## enable hooking to application loggers</%text>
409 421 #errormator.logging = true
410 422
411 423 <%text>## minimum log level for log capture</%text>
412 424 #errormator.logging.level = WARNING
413 425
414 426 <%text>## send logs only from erroneous/slow requests</%text>
415 427 <%text>## (saves API quota for intensive logging)</%text>
416 428 errormator.logging_on_error = false
417 429
418 430 <%text>## list of additonal keywords that should be grabbed from environ object</%text>
419 431 <%text>## can be string with comma separated list of words in lowercase</%text>
420 432 <%text>## (by default client will always send following info:</%text>
421 433 <%text>## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that</%text>
422 434 <%text>## start with HTTP* this list be extended with additional keywords here</%text>
423 435 errormator.environ_keys_whitelist =
424 436
425 437 <%text>## list of keywords that should be blanked from request object</%text>
426 438 <%text>## can be string with comma separated list of words in lowercase</%text>
427 439 <%text>## (by default client will always blank keys that contain following words</%text>
428 440 <%text>## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'</%text>
429 441 <%text>## this list be extended with additional keywords set here</%text>
430 442 errormator.request_keys_blacklist =
431 443
432 444 <%text>## list of namespaces that should be ignores when gathering log entries</%text>
433 445 <%text>## can be string with comma separated list of namespaces</%text>
434 446 <%text>## (by default the client ignores own entries: errormator_client.client)</%text>
435 447 errormator.log_namespace_blacklist =
436 448
437 449 %elif error_aggregation_service == 'sentry':
438 450 <%text>################</%text>
439 451 <%text>### [sentry] ###</%text>
440 452 <%text>################</%text>
441 453
442 454 <%text>## sentry is a alternative open source error aggregator</%text>
443 455 <%text>## you must install python packages `sentry` and `raven` to enable</%text>
444 456
445 457 sentry.dsn = YOUR_DNS
446 458 sentry.servers =
447 459 sentry.name =
448 460 sentry.key =
449 461 sentry.public_key =
450 462 sentry.secret_key =
451 463 sentry.project =
452 464 sentry.site =
453 465 sentry.include_paths =
454 466 sentry.exclude_paths =
455 467
456 468 %endif
457 469 <%text>################################################################################</%text>
458 470 <%text>## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##</%text>
459 471 <%text>## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##</%text>
460 472 <%text>## execute malicious code after an exception is raised. ##</%text>
461 473 <%text>################################################################################</%text>
462 474 set debug = false
463 475
464 476 <%text>##################################</%text>
465 477 <%text>### LOGVIEW CONFIG ###</%text>
466 478 <%text>##################################</%text>
467 479
468 480 logview.sqlalchemy = #faa
469 481 logview.pylons.templating = #bfb
470 482 logview.pylons.util = #eee
471 483
472 484 <%text>#########################################################</%text>
473 485 <%text>### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###</%text>
474 486 <%text>#########################################################</%text>
475 487
476 488 %if database_engine == 'sqlite':
477 489 # SQLITE [default]
478 490 sqlalchemy.db1.url = sqlite:///${here}/kallithea.db?timeout=60
479 491
480 492 %elif database_engine == 'postgres':
481 493 # POSTGRESQL
482 494 sqlalchemy.db1.url = postgresql://user:pass@localhost/kallithea
483 495
484 496 %elif database_engine == 'mysql':
485 497 # MySQL
486 498 sqlalchemy.db1.url = mysql://user:pass@localhost/kallithea
487 499
488 500 %endif
489 501 # see sqlalchemy docs for others
490 502
491 503 sqlalchemy.db1.echo = false
492 504 sqlalchemy.db1.pool_recycle = 3600
493 505 sqlalchemy.db1.convert_unicode = true
494 506
495 507 <%text>################################</%text>
496 508 <%text>### LOGGING CONFIGURATION ####</%text>
497 509 <%text>################################</%text>
498 510
499 511 [loggers]
500 512 keys = root, routes, kallithea, sqlalchemy, beaker, templates, whoosh_indexer
501 513
502 514 [handlers]
503 515 keys = console, console_sql
504 516
505 517 [formatters]
506 518 keys = generic, color_formatter, color_formatter_sql
507 519
508 520 <%text>#############</%text>
509 521 <%text>## LOGGERS ##</%text>
510 522 <%text>#############</%text>
511 523
512 524 [logger_root]
513 525 level = NOTSET
514 526 handlers = console
515 527
516 528 [logger_routes]
517 529 level = DEBUG
518 530 handlers =
519 531 qualname = routes.middleware
520 532 <%text>## "level = DEBUG" logs the route matched and routing variables.</%text>
521 533 propagate = 1
522 534
523 535 [logger_beaker]
524 536 level = DEBUG
525 537 handlers =
526 538 qualname = beaker.container
527 539 propagate = 1
528 540
529 541 [logger_templates]
530 542 level = INFO
531 543 handlers =
532 544 qualname = pylons.templating
533 545 propagate = 1
534 546
535 547 [logger_kallithea]
536 548 level = DEBUG
537 549 handlers =
538 550 qualname = kallithea
539 551 propagate = 1
540 552
541 553 [logger_sqlalchemy]
542 554 level = INFO
543 555 handlers = console_sql
544 556 qualname = sqlalchemy.engine
545 557 propagate = 0
546 558
547 559 [logger_whoosh_indexer]
548 560 level = DEBUG
549 561 handlers =
550 562 qualname = whoosh_indexer
551 563 propagate = 1
552 564
553 565 <%text>##############</%text>
554 566 <%text>## HANDLERS ##</%text>
555 567 <%text>##############</%text>
556 568
557 569 [handler_console]
558 570 class = StreamHandler
559 571 args = (sys.stderr,)
560 572 level = INFO
561 573 formatter = generic
562 574
563 575 [handler_console_sql]
564 576 class = StreamHandler
565 577 args = (sys.stderr,)
566 578 level = WARN
567 579 formatter = generic
568 580
569 581 <%text>################</%text>
570 582 <%text>## FORMATTERS ##</%text>
571 583 <%text>################</%text>
572 584
573 585 [formatter_generic]
574 586 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
575 587 datefmt = %Y-%m-%d %H:%M:%S
576 588
577 589 [formatter_color_formatter]
578 590 class = kallithea.lib.colored_formatter.ColorFormatter
579 591 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
580 592 datefmt = %Y-%m-%d %H:%M:%S
581 593
582 594 [formatter_color_formatter_sql]
583 595 class = kallithea.lib.colored_formatter.ColorFormatterSql
584 596 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
585 597 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,574 +1,586 b''
1 1 ################################################################################
2 2 ################################################################################
3 3 # Kallithea - Example config #
4 4 # #
5 5 # The %(here)s variable will be replaced with the parent directory of this file#
6 6 ################################################################################
7 7 ################################################################################
8 8
9 9 [DEFAULT]
10 10 debug = true
11 11 pdebug = false
12 12
13 13 ################################################################################
14 14 ## Email settings ##
15 15 ## ##
16 16 ## Refer to the documentation ("Email settings") for more details. ##
17 17 ## ##
18 18 ## It is recommended to use a valid sender address that passes access ##
19 19 ## validation and spam filtering in mail servers. ##
20 20 ################################################################################
21 21
22 22 ## 'From' header for application emails. You can optionally add a name.
23 23 ## Default:
24 24 #app_email_from = Kallithea
25 25 ## Examples:
26 26 #app_email_from = Kallithea <kallithea-noreply@example.com>
27 27 #app_email_from = kallithea-noreply@example.com
28 28
29 29 ## Subject prefix for application emails.
30 30 ## A space between this prefix and the real subject is automatically added.
31 31 ## Default:
32 32 #email_prefix =
33 33 ## Example:
34 34 #email_prefix = [Kallithea]
35 35
36 36 ## Recipients for error emails and fallback recipients of application mails.
37 37 ## Multiple addresses can be specified, space-separated.
38 38 ## Only addresses are allowed, do not add any name part.
39 39 ## Default:
40 40 #email_to =
41 41 ## Examples:
42 42 #email_to = admin@example.com
43 43 #email_to = admin@example.com another_admin@example.com
44 44
45 45 ## 'From' header for error emails. You can optionally add a name.
46 46 ## Default:
47 47 #error_email_from = pylons@yourapp.com
48 48 ## Examples:
49 49 #error_email_from = Kallithea Errors <kallithea-noreply@example.com>
50 50 #error_email_from = paste_error@example.com
51 51
52 52 ## SMTP server settings
53 53 ## Only smtp_server is mandatory. All other settings take the specified default
54 54 ## values.
55 55 #smtp_server = smtp.example.com
56 56 #smtp_username =
57 57 #smtp_password =
58 58 #smtp_port = 25
59 59 #smtp_use_tls = false
60 60 #smtp_use_ssl = false
61 61 ## SMTP authentication parameters to use (e.g. LOGIN PLAIN CRAM-MD5, etc.).
62 62 ## If empty, use any of the authentication parameters supported by the server.
63 63 #smtp_auth =
64 64
65 65 [server:main]
66 66 ## PASTE ##
67 67 #use = egg:Paste#http
68 68 ## nr of worker threads to spawn
69 69 #threadpool_workers = 5
70 70 ## max request before thread respawn
71 71 #threadpool_max_requests = 10
72 72 ## option to use threads of process
73 73 #use_threadpool = true
74 74
75 75 ## WAITRESS ##
76 76 use = egg:waitress#main
77 77 ## number of worker threads
78 78 threads = 5
79 79 ## MAX BODY SIZE 100GB
80 80 max_request_body_size = 107374182400
81 81 ## use poll instead of select, fixes fd limits, may not work on old
82 82 ## windows systems.
83 83 #asyncore_use_poll = True
84 84
85 85 ## GUNICORN ##
86 86 #use = egg:gunicorn#main
87 87 ## number of process workers. You must set `instance_id = *` when this option
88 88 ## is set to more than one worker
89 89 #workers = 1
90 90 ## process name
91 91 #proc_name = kallithea
92 92 ## type of worker class, one of sync, eventlet, gevent, tornado
93 93 ## recommended for bigger setup is using of of other than sync one
94 94 #worker_class = sync
95 95 #max_requests = 1000
96 96 ## ammount of time a worker can handle request before it gets killed and
97 97 ## restarted
98 98 #timeout = 3600
99 99
100 100 ## UWSGI ##
101 101 ## run with uwsgi --ini-paste-logged <inifile.ini>
102 102 #[uwsgi]
103 103 #socket = /tmp/uwsgi.sock
104 104 #master = true
105 105 #http = 127.0.0.1:5000
106 106
107 107 ## set as deamon and redirect all output to file
108 108 #daemonize = ./uwsgi_kallithea.log
109 109
110 110 ## master process PID
111 111 #pidfile = ./uwsgi_kallithea.pid
112 112
113 113 ## stats server with workers statistics, use uwsgitop
114 114 ## for monitoring, `uwsgitop 127.0.0.1:1717`
115 115 #stats = 127.0.0.1:1717
116 116 #memory-report = true
117 117
118 118 ## log 5XX errors
119 119 #log-5xx = true
120 120
121 121 ## Set the socket listen queue size.
122 122 #listen = 256
123 123
124 124 ## Gracefully Reload workers after the specified amount of managed requests
125 125 ## (avoid memory leaks).
126 126 #max-requests = 1000
127 127
128 128 ## enable large buffers
129 129 #buffer-size = 65535
130 130
131 131 ## socket and http timeouts ##
132 132 #http-timeout = 3600
133 133 #socket-timeout = 3600
134 134
135 135 ## Log requests slower than the specified number of milliseconds.
136 136 #log-slow = 10
137 137
138 138 ## Exit if no app can be loaded.
139 139 #need-app = true
140 140
141 141 ## Set lazy mode (load apps in workers instead of master).
142 142 #lazy = true
143 143
144 144 ## scaling ##
145 145 ## set cheaper algorithm to use, if not set default will be used
146 146 #cheaper-algo = spare
147 147
148 148 ## minimum number of workers to keep at all times
149 149 #cheaper = 1
150 150
151 151 ## number of workers to spawn at startup
152 152 #cheaper-initial = 1
153 153
154 154 ## maximum number of workers that can be spawned
155 155 #workers = 4
156 156
157 157 ## how many workers should be spawned at a time
158 158 #cheaper-step = 1
159 159
160 160 ## COMMON ##
161 161 host = 127.0.0.1
162 162 port = 5000
163 163
164 164 ## middleware for hosting the WSGI application under a URL prefix
165 165 #[filter:proxy-prefix]
166 166 #use = egg:PasteDeploy#prefix
167 167 #prefix = /<your-prefix>
168 168
169 169 [app:main]
170 170 use = egg:kallithea
171 171 ## enable proxy prefix middleware
172 172 #filter-with = proxy-prefix
173 173
174 174 full_stack = true
175 175 static_files = true
176 176 ## Available Languages:
177 177 ## cs de fr hu ja nl_BE pl pt_BR ru sk zh_CN zh_TW
178 178 lang =
179 179 cache_dir = %(here)s/data
180 180 index_dir = %(here)s/data/index
181 181
182 182 ## perform a full repository scan on each server start, this should be
183 183 ## set to false after first startup, to allow faster server restarts.
184 184 initial_repo_scan = false
185 185
186 186 ## uncomment and set this path to use archive download cache
187 187 archive_cache_dir = %(here)s/tarballcache
188 188
189 189 ## change this to unique ID for security
190 190 app_instance_uuid = ${app_instance_uuid}
191 191
192 192 ## cut off limit for large diffs (size in bytes)
193 193 cut_off_limit = 256000
194 194
195 195 ## use cache version of scm repo everywhere
196 196 vcs_full_cache = true
197 197
198 198 ## force https in Kallithea, fixes https redirects, assumes it's always https
199 199 force_https = false
200 200
201 201 ## use Strict-Transport-Security headers
202 202 use_htsts = false
203 203
204 204 ## number of commits stats will parse on each iteration
205 205 commit_parse_limit = 25
206 206
207 207 ## path to git executable
208 208 git_path = git
209 209
210 210 ## git rev filter option, --all is the default filter, if you need to
211 211 ## hide all refs in changelog switch this to --branches --tags
212 212 #git_rev_filter = --branches --tags
213 213
214 214 ## RSS feed options
215 215 rss_cut_off_limit = 256000
216 216 rss_items_per_page = 10
217 217 rss_include_diff = false
218 218
219 219 ## options for showing and identifying changesets
220 220 show_sha_length = 12
221 221 show_revision_number = false
222 222
223 223 ## gist URL alias, used to create nicer urls for gist. This should be an
224 224 ## url that does rewrites to _admin/gists/<gistid>.
225 225 ## example: http://gist.example.com/{gistid}. Empty means use the internal
226 226 ## Kallithea url, ie. http[s]://kallithea.example.com/_admin/gists/<gistid>
227 227 gist_alias_url =
228 228
229 229 ## white list of API enabled controllers. This allows to add list of
230 230 ## controllers to which access will be enabled by api_key. eg: to enable
231 231 ## api access to raw_files put `FilesController:raw`, to enable access to patches
232 232 ## add `ChangesetController:changeset_patch`. This list should be "," separated
233 233 ## Syntax is <ControllerClass>:<function>. Check debug logs for generated names
234 234 ## Recommended settings below are commented out:
235 235 api_access_controllers_whitelist =
236 236 # ChangesetController:changeset_patch,
237 237 # ChangesetController:changeset_raw,
238 238 # FilesController:raw,
239 239 # FilesController:archivefile
240 240
241 241 ## default encoding used to convert from and to unicode
242 242 ## can be also a comma seperated list of encoding in case of mixed encodings
243 243 default_encoding = utf8
244 244
245 245 ## issue tracker for Kallithea (leave blank to disable, absent for default)
246 246 #bugtracker = https://bitbucket.org/conservancy/kallithea/issues
247 247
248 248 ## issue tracking mapping for commits messages
249 249 ## comment out issue_pat, issue_server, issue_prefix to enable
250 250
251 251 ## pattern to get the issues from commit messages
252 252 ## default one used here is #<numbers> with a regex passive group for `#`
253 253 ## {id} will be all groups matched from this pattern
254 254
255 255 issue_pat = (?:\s*#)(\d+)
256 256
257 257 ## server url to the issue, each {id} will be replaced with match
258 258 ## fetched from the regex and {repo} is replaced with full repository name
259 259 ## including groups {repo_name} is replaced with just name of repo
260 260
261 261 issue_server_link = https://issues.example.com/{repo}/issue/{id}
262 262
263 263 ## prefix to add to link to indicate it's an url
264 264 ## #314 will be replaced by <issue_prefix><id>
265 265
266 266 issue_prefix = #
267 267
268 268 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
269 269 ## multiple patterns, to other issues server, wiki or others
270 270 ## below an example how to create a wiki pattern
271 271 # wiki-some-id -> https://wiki.example.com/some-id
272 272
273 273 #issue_pat_wiki = (?:wiki-)(.+)
274 274 #issue_server_link_wiki = https://wiki.example.com/{id}
275 275 #issue_prefix_wiki = WIKI-
276 276
277 277 ## alternative return HTTP header for failed authentication. Default HTTP
278 278 ## response is 401 HTTPUnauthorized. Currently Mercurial clients have trouble with
279 279 ## handling that. Set this variable to 403 to return HTTPForbidden
280 280 auth_ret_code =
281 281
282 282 ## locking return code. When repository is locked return this HTTP code. 2XX
283 283 ## codes don't break the transactions while 4XX codes do
284 284 lock_ret_code = 423
285 285
286 286 ## allows to change the repository location in settings page
287 287 allow_repo_location_change = True
288 288
289 289 ## allows to setup custom hooks in settings page
290 290 allow_custom_hooks_settings = True
291 291
292 ## extra extensions for indexing, space separated and without the leading '.'.
293 # index.extensions =
294 # gemfile
295 # lock
296
297 ## extra filenames for indexing, space separated
298 # index.filenames =
299 # .dockerignore
300 # .editorconfig
301 # INSTALL
302 # CHANGELOG
303
292 304 ####################################
293 305 ### CELERY CONFIG ####
294 306 ####################################
295 307
296 308 use_celery = false
297 309 broker.host = localhost
298 310 broker.vhost = rabbitmqhost
299 311 broker.port = 5672
300 312 broker.user = rabbitmq
301 313 broker.password = qweqwe
302 314
303 315 celery.imports = kallithea.lib.celerylib.tasks
304 316
305 317 celery.result.backend = amqp
306 318 celery.result.dburi = amqp://
307 319 celery.result.serialier = json
308 320
309 321 #celery.send.task.error.emails = true
310 322 #celery.amqp.task.result.expires = 18000
311 323
312 324 celeryd.concurrency = 2
313 325 #celeryd.log.file = celeryd.log
314 326 celeryd.log.level = DEBUG
315 327 celeryd.max.tasks.per.child = 1
316 328
317 329 ## tasks will never be sent to the queue, but executed locally instead.
318 330 celery.always.eager = false
319 331
320 332 ####################################
321 333 ### BEAKER CACHE ####
322 334 ####################################
323 335
324 336 beaker.cache.data_dir = %(here)s/data/cache/data
325 337 beaker.cache.lock_dir = %(here)s/data/cache/lock
326 338
327 339 beaker.cache.regions = short_term,long_term,sql_cache_short
328 340
329 341 beaker.cache.short_term.type = memory
330 342 beaker.cache.short_term.expire = 60
331 343 beaker.cache.short_term.key_length = 256
332 344
333 345 beaker.cache.long_term.type = memory
334 346 beaker.cache.long_term.expire = 36000
335 347 beaker.cache.long_term.key_length = 256
336 348
337 349 beaker.cache.sql_cache_short.type = memory
338 350 beaker.cache.sql_cache_short.expire = 10
339 351 beaker.cache.sql_cache_short.key_length = 256
340 352
341 353 ####################################
342 354 ### BEAKER SESSION ####
343 355 ####################################
344 356
345 357 ## Name of session cookie. Should be unique for a given host and path, even when running
346 358 ## on different ports. Otherwise, cookie sessions will be shared and messed up.
347 359 beaker.session.key = kallithea
348 360 ## Sessions should always only be accessible by the browser, not directly by JavaScript.
349 361 beaker.session.httponly = true
350 362 ## Session lifetime. 2592000 seconds is 30 days.
351 363 beaker.session.timeout = 2592000
352 364
353 365 ## Server secret used with HMAC to ensure integrity of cookies.
354 366 beaker.session.secret = ${app_instance_uuid}
355 367 ## Further, encrypt the data with AES.
356 368 #beaker.session.encrypt_key = <key_for_encryption>
357 369 #beaker.session.validate_key = <validation_key>
358 370
359 371 ## Type of storage used for the session, current types are
360 372 ## dbm, file, memcached, database, and memory.
361 373
362 374 ## File system storage of session data. (default)
363 375 #beaker.session.type = file
364 376
365 377 ## Cookie only, store all session data inside the cookie. Requires secure secrets.
366 378 #beaker.session.type = cookie
367 379
368 380 ## Database storage of session data.
369 381 #beaker.session.type = ext:database
370 382 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/kallithea
371 383 #beaker.session.table_name = db_session
372 384
373 385 ############################
374 386 ## ERROR HANDLING SYSTEMS ##
375 387 ############################
376 388
377 389 ####################
378 390 ### [errormator] ###
379 391 ####################
380 392
381 393 ## Errormator is tailored to work with Kallithea, see
382 394 ## http://errormator.com for details how to obtain an account
383 395 ## you must install python package `errormator_client` to make it work
384 396
385 397 ## errormator enabled
386 398 errormator = false
387 399
388 400 errormator.server_url = https://api.errormator.com
389 401 errormator.api_key = YOUR_API_KEY
390 402
391 403 ## TWEAK AMOUNT OF INFO SENT HERE
392 404
393 405 ## enables 404 error logging (default False)
394 406 errormator.report_404 = false
395 407
396 408 ## time in seconds after request is considered being slow (default 1)
397 409 errormator.slow_request_time = 1
398 410
399 411 ## record slow requests in application
400 412 ## (needs to be enabled for slow datastore recording and time tracking)
401 413 errormator.slow_requests = true
402 414
403 415 ## enable hooking to application loggers
404 416 #errormator.logging = true
405 417
406 418 ## minimum log level for log capture
407 419 #errormator.logging.level = WARNING
408 420
409 421 ## send logs only from erroneous/slow requests
410 422 ## (saves API quota for intensive logging)
411 423 errormator.logging_on_error = false
412 424
413 425 ## list of additonal keywords that should be grabbed from environ object
414 426 ## can be string with comma separated list of words in lowercase
415 427 ## (by default client will always send following info:
416 428 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
417 429 ## start with HTTP* this list be extended with additional keywords here
418 430 errormator.environ_keys_whitelist =
419 431
420 432 ## list of keywords that should be blanked from request object
421 433 ## can be string with comma separated list of words in lowercase
422 434 ## (by default client will always blank keys that contain following words
423 435 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
424 436 ## this list be extended with additional keywords set here
425 437 errormator.request_keys_blacklist =
426 438
427 439 ## list of namespaces that should be ignores when gathering log entries
428 440 ## can be string with comma separated list of namespaces
429 441 ## (by default the client ignores own entries: errormator_client.client)
430 442 errormator.log_namespace_blacklist =
431 443
432 444 ################
433 445 ### [sentry] ###
434 446 ################
435 447
436 448 ## sentry is a alternative open source error aggregator
437 449 ## you must install python packages `sentry` and `raven` to enable
438 450
439 451 sentry.dsn = YOUR_DNS
440 452 sentry.servers =
441 453 sentry.name =
442 454 sentry.key =
443 455 sentry.public_key =
444 456 sentry.secret_key =
445 457 sentry.project =
446 458 sentry.site =
447 459 sentry.include_paths =
448 460 sentry.exclude_paths =
449 461
450 462 ################################################################################
451 463 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
452 464 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
453 465 ## execute malicious code after an exception is raised. ##
454 466 ################################################################################
455 467 set debug = false
456 468
457 469 ##################################
458 470 ### LOGVIEW CONFIG ###
459 471 ##################################
460 472
461 473 logview.sqlalchemy = #faa
462 474 logview.pylons.templating = #bfb
463 475 logview.pylons.util = #eee
464 476
465 477 #########################################################
466 478 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
467 479 #########################################################
468 480
469 481 # SQLITE [default]
470 482 sqlalchemy.db1.url = sqlite:///%(here)s/kallithea.db?timeout=60
471 483
472 484 # POSTGRESQL
473 485 #sqlalchemy.db1.url = postgresql://user:pass@localhost/kallithea
474 486
475 487 # MySQL
476 488 #sqlalchemy.db1.url = mysql://user:pass@localhost/kallithea
477 489
478 490 # see sqlalchemy docs for others
479 491
480 492 sqlalchemy.db1.echo = false
481 493 sqlalchemy.db1.pool_recycle = 3600
482 494 sqlalchemy.db1.convert_unicode = true
483 495
484 496 ################################
485 497 ### LOGGING CONFIGURATION ####
486 498 ################################
487 499
488 500 [loggers]
489 501 keys = root, routes, kallithea, sqlalchemy, beaker, templates, whoosh_indexer
490 502
491 503 [handlers]
492 504 keys = console, console_sql
493 505
494 506 [formatters]
495 507 keys = generic, color_formatter, color_formatter_sql
496 508
497 509 #############
498 510 ## LOGGERS ##
499 511 #############
500 512
501 513 [logger_root]
502 514 level = NOTSET
503 515 handlers = console
504 516
505 517 [logger_routes]
506 518 level = DEBUG
507 519 handlers =
508 520 qualname = routes.middleware
509 521 ## "level = DEBUG" logs the route matched and routing variables.
510 522 propagate = 1
511 523
512 524 [logger_beaker]
513 525 level = DEBUG
514 526 handlers =
515 527 qualname = beaker.container
516 528 propagate = 1
517 529
518 530 [logger_templates]
519 531 level = INFO
520 532 handlers =
521 533 qualname = pylons.templating
522 534 propagate = 1
523 535
524 536 [logger_kallithea]
525 537 level = DEBUG
526 538 handlers =
527 539 qualname = kallithea
528 540 propagate = 1
529 541
530 542 [logger_sqlalchemy]
531 543 level = INFO
532 544 handlers = console_sql
533 545 qualname = sqlalchemy.engine
534 546 propagate = 0
535 547
536 548 [logger_whoosh_indexer]
537 549 level = DEBUG
538 550 handlers =
539 551 qualname = whoosh_indexer
540 552 propagate = 1
541 553
542 554 ##############
543 555 ## HANDLERS ##
544 556 ##############
545 557
546 558 [handler_console]
547 559 class = StreamHandler
548 560 args = (sys.stderr,)
549 561 level = INFO
550 562 formatter = generic
551 563
552 564 [handler_console_sql]
553 565 class = StreamHandler
554 566 args = (sys.stderr,)
555 567 level = WARN
556 568 formatter = generic
557 569
558 570 ################
559 571 ## FORMATTERS ##
560 572 ################
561 573
562 574 [formatter_generic]
563 575 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
564 576 datefmt = %Y-%m-%d %H:%M:%S
565 577
566 578 [formatter_color_formatter]
567 579 class = kallithea.lib.colored_formatter.ColorFormatter
568 580 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
569 581 datefmt = %Y-%m-%d %H:%M:%S
570 582
571 583 [formatter_color_formatter_sql]
572 584 class = kallithea.lib.colored_formatter.ColorFormatterSql
573 585 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
574 586 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,140 +1,141 b''
1 1 # -*- coding: utf-8 -*-
2 2 # This program is free software: you can redistribute it and/or modify
3 3 # it under the terms of the GNU General Public License as published by
4 4 # the Free Software Foundation, either version 3 of the License, or
5 5 # (at your option) any later version.
6 6 #
7 7 # This program is distributed in the hope that it will be useful,
8 8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 10 # GNU General Public License for more details.
11 11 #
12 12 # You should have received a copy of the GNU General Public License
13 13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 14 """
15 15 Pylons environment configuration
16 16 """
17 17
18 18 import os
19 19 import logging
20 20 import kallithea
21 21 import platform
22 22
23 23 import pylons
24 24 import mako.lookup
25 25 import beaker
26 26
27 27 # don't remove this import it does magic for celery
28 28 from kallithea.lib import celerypylons
29 29
30 30 import kallithea.lib.app_globals as app_globals
31 31
32 32 from kallithea.config.routing import make_map
33 33
34 34 from kallithea.lib import helpers
35 35 from kallithea.lib.auth import set_available_permissions
36 36 from kallithea.lib.utils import repo2db_mapper, make_ui, set_app_settings,\
37 load_rcextensions, check_git_version, set_vcs_config
37 load_rcextensions, check_git_version, set_vcs_config, set_indexer_config
38 38 from kallithea.lib.utils2 import engine_from_config, str2bool
39 39 from kallithea.lib.db_manage import DbManage
40 40 from kallithea.model import init_model
41 41 from kallithea.model.scm import ScmModel
42 42
43 43 log = logging.getLogger(__name__)
44 44
45 45
46 46 def load_environment(global_conf, app_conf, initial=False,
47 47 test_env=None, test_index=None):
48 48 """
49 49 Configure the Pylons environment via the ``pylons.config``
50 50 object
51 51 """
52 52 config = pylons.configuration.PylonsConfig()
53 53
54 54 # Pylons paths
55 55 root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
56 56 paths = dict(
57 57 root=root,
58 58 controllers=os.path.join(root, 'controllers'),
59 59 static_files=os.path.join(root, 'public'),
60 60 templates=[os.path.join(root, 'templates')]
61 61 )
62 62
63 63 # Initialize config with the basic options
64 64 config.init_app(global_conf, app_conf, package='kallithea', paths=paths)
65 65
66 66 # store some globals into kallithea
67 67 kallithea.CELERY_ON = str2bool(config['app_conf'].get('use_celery'))
68 68 kallithea.CELERY_EAGER = str2bool(config['app_conf'].get('celery.always.eager'))
69 69
70 70 config['routes.map'] = make_map(config)
71 71 config['pylons.app_globals'] = app_globals.Globals(config)
72 72 config['pylons.h'] = helpers
73 73 kallithea.CONFIG = config
74 74
75 75 load_rcextensions(root_path=config['here'])
76 76
77 77 # Setup cache object as early as possible
78 78 pylons.cache._push_object(config['pylons.app_globals'].cache)
79 79
80 80 # Create the Mako TemplateLookup, with the default auto-escaping
81 81 config['pylons.app_globals'].mako_lookup = mako.lookup.TemplateLookup(
82 82 directories=paths['templates'],
83 83 error_handler=pylons.error.handle_mako_error,
84 84 module_directory=os.path.join(app_conf['cache_dir'], 'templates'),
85 85 input_encoding='utf-8', default_filters=['escape'],
86 86 imports=['from webhelpers.html import escape'])
87 87
88 88 # sets the c attribute access when don't existing attribute are accessed
89 89 config['pylons.strict_tmpl_context'] = True
90 90 test = os.path.split(config['__file__'])[-1] == 'test.ini'
91 91 if test:
92 92 if test_env is None:
93 93 test_env = not int(os.environ.get('KALLITHEA_NO_TMP_PATH', 0))
94 94 if test_index is None:
95 95 test_index = not int(os.environ.get('KALLITHEA_WHOOSH_TEST_DISABLE', 0))
96 96 if os.environ.get('TEST_DB'):
97 97 # swap config if we pass enviroment variable
98 98 config['sqlalchemy.db1.url'] = os.environ.get('TEST_DB')
99 99
100 100 from kallithea.lib.utils import create_test_env, create_test_index
101 101 from kallithea.tests import TESTS_TMP_PATH
102 102 #set KALLITHEA_NO_TMP_PATH=1 to disable re-creating the database and
103 103 #test repos
104 104 if test_env:
105 105 create_test_env(TESTS_TMP_PATH, config)
106 106 #set KALLITHEA_WHOOSH_TEST_DISABLE=1 to disable whoosh index during tests
107 107 if test_index:
108 108 create_test_index(TESTS_TMP_PATH, config, True)
109 109
110 110 DbManage.check_waitress()
111 111 # MULTIPLE DB configs
112 112 # Setup the SQLAlchemy database engine
113 113 sa_engine_db1 = engine_from_config(config, 'sqlalchemy.db1.')
114 114 init_model(sa_engine_db1)
115 115
116 116 set_available_permissions(config)
117 117 repos_path = make_ui('db').configitems('paths')[0][1]
118 118 config['base_path'] = repos_path
119 119 set_app_settings(config)
120 120
121 121 instance_id = kallithea.CONFIG.get('instance_id', '*')
122 122 if instance_id == '*':
123 123 instance_id = '%s-%s' % (platform.uname()[1], os.getpid())
124 124 kallithea.CONFIG['instance_id'] = instance_id
125 125
126 126 # CONFIGURATION OPTIONS HERE (note: all config options will override
127 127 # any Pylons config options)
128 128
129 129 # store config reference into our module to skip import magic of
130 130 # pylons
131 131 kallithea.CONFIG.update(config)
132 132 set_vcs_config(kallithea.CONFIG)
133 set_indexer_config(kallithea.CONFIG)
133 134
134 135 #check git version
135 136 check_git_version()
136 137
137 138 if str2bool(config.get('initial_repo_scan', True)):
138 139 repo2db_mapper(ScmModel().repo_scan(repos_path),
139 140 remove_obsolete=False, install_git_hooks=False)
140 141 return config
@@ -1,871 +1,886 b''
1 1 # -*- coding: utf-8 -*-
2 2 # This program is free software: you can redistribute it and/or modify
3 3 # it under the terms of the GNU General Public License as published by
4 4 # the Free Software Foundation, either version 3 of the License, or
5 5 # (at your option) any later version.
6 6 #
7 7 # This program is distributed in the hope that it will be useful,
8 8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 10 # GNU General Public License for more details.
11 11 #
12 12 # You should have received a copy of the GNU General Public License
13 13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 14 """
15 15 kallithea.lib.utils
16 16 ~~~~~~~~~~~~~~~~~~~
17 17
18 18 Utilities library for Kallithea
19 19
20 20 This file was forked by the Kallithea project in July 2014.
21 21 Original author and date, and relevant copyright and licensing information is below:
22 22 :created_on: Apr 18, 2010
23 23 :author: marcink
24 24 :copyright: (c) 2013 RhodeCode GmbH, and others.
25 25 :license: GPLv3, see LICENSE.md for more details.
26 26 """
27 27
28 28 import os
29 29 import re
30 30 import logging
31 31 import datetime
32 32 import traceback
33 33 import paste
34 34 import beaker
35 35 import tarfile
36 36 import shutil
37 37 import decorator
38 38 import warnings
39 39 from os.path import abspath
40 40 from os.path import dirname as dn, join as jn
41 41
42 42 from paste.script.command import Command, BadCommand
43 43
44 44 from webhelpers.text import collapse, remove_formatting, strip_tags
45 45 from beaker.cache import _cache_decorate
46 46
47 47 from kallithea import BRAND
48 48
49 49 from kallithea.lib.vcs.utils.hgcompat import ui, config
50 50 from kallithea.lib.vcs.utils.helpers import get_scm
51 51 from kallithea.lib.vcs.exceptions import VCSError
52 52
53 53 from kallithea.model import meta
54 54 from kallithea.model.db import Repository, User, Ui, \
55 55 UserLog, RepoGroup, Setting, UserGroup
56 56 from kallithea.model.meta import Session
57 57 from kallithea.model.repo_group import RepoGroupModel
58 58 from kallithea.lib.utils2 import safe_str, safe_unicode, get_current_authuser
59 59 from kallithea.lib.vcs.utils.fakemod import create_module
60 60
61 61 log = logging.getLogger(__name__)
62 62
63 63 REMOVED_REPO_PAT = re.compile(r'rm__\d{8}_\d{6}_\d{6}_.*')
64 64
65 65
66 66 def recursive_replace(str_, replace=' '):
67 67 """
68 68 Recursive replace of given sign to just one instance
69 69
70 70 :param str_: given string
71 71 :param replace: char to find and replace multiple instances
72 72
73 73 Examples::
74 74 >>> recursive_replace("Mighty---Mighty-Bo--sstones",'-')
75 75 'Mighty-Mighty-Bo-sstones'
76 76 """
77 77
78 78 if str_.find(replace * 2) == -1:
79 79 return str_
80 80 else:
81 81 str_ = str_.replace(replace * 2, replace)
82 82 return recursive_replace(str_, replace)
83 83
84 84
85 85 def repo_name_slug(value):
86 86 """
87 87 Return slug of name of repository
88 88 This function is called on each creation/modification
89 89 of repository to prevent bad names in repo
90 90 """
91 91
92 92 slug = remove_formatting(value)
93 93 slug = strip_tags(slug)
94 94
95 95 for c in """`?=[]\;'"<>,/~!@#$%^&*()+{}|: """:
96 96 slug = slug.replace(c, '-')
97 97 slug = recursive_replace(slug, '-')
98 98 slug = collapse(slug, '-')
99 99 return slug
100 100
101 101
102 102 #==============================================================================
103 103 # PERM DECORATOR HELPERS FOR EXTRACTING NAMES FOR PERM CHECKS
104 104 #==============================================================================
105 105 def get_repo_slug(request):
106 106 _repo = request.environ['pylons.routes_dict'].get('repo_name')
107 107 if _repo:
108 108 _repo = _repo.rstrip('/')
109 109 return _repo
110 110
111 111
112 112 def get_repo_group_slug(request):
113 113 _group = request.environ['pylons.routes_dict'].get('group_name')
114 114 if _group:
115 115 _group = _group.rstrip('/')
116 116 return _group
117 117
118 118
119 119 def get_user_group_slug(request):
120 120 _group = request.environ['pylons.routes_dict'].get('id')
121 121 _group = UserGroup.get(_group)
122 122 if _group:
123 123 return _group.users_group_name
124 124 return None
125 125
126 126
127 127 def _extract_id_from_repo_name(repo_name):
128 128 if repo_name.startswith('/'):
129 129 repo_name = repo_name.lstrip('/')
130 130 by_id_match = re.match(r'^_(\d{1,})', repo_name)
131 131 if by_id_match:
132 132 return by_id_match.groups()[0]
133 133
134 134
135 135 def get_repo_by_id(repo_name):
136 136 """
137 137 Extracts repo_name by id from special urls. Example url is _11/repo_name
138 138
139 139 :param repo_name:
140 140 :return: repo_name if matched else None
141 141 """
142 142 _repo_id = _extract_id_from_repo_name(repo_name)
143 143 if _repo_id:
144 144 from kallithea.model.db import Repository
145 145 repo = Repository.get(_repo_id)
146 146 if repo:
147 147 # TODO: return repo instead of reponame? or would that be a layering violation?
148 148 return repo.repo_name
149 149 return None
150 150
151 151
152 152 def action_logger(user, action, repo, ipaddr='', sa=None, commit=False):
153 153 """
154 154 Action logger for various actions made by users
155 155
156 156 :param user: user that made this action, can be a unique username string or
157 157 object containing user_id attribute
158 158 :param action: action to log, should be on of predefined unique actions for
159 159 easy translations
160 160 :param repo: string name of repository or object containing repo_id,
161 161 that action was made on
162 162 :param ipaddr: optional IP address from what the action was made
163 163 :param sa: optional sqlalchemy session
164 164
165 165 """
166 166
167 167 if not sa:
168 168 sa = meta.Session()
169 169 # if we don't get explicit IP address try to get one from registered user
170 170 # in tmpl context var
171 171 if not ipaddr:
172 172 ipaddr = getattr(get_current_authuser(), 'ip_addr', '')
173 173
174 174 if getattr(user, 'user_id', None):
175 175 user_obj = User.get(user.user_id)
176 176 elif isinstance(user, basestring):
177 177 user_obj = User.get_by_username(user)
178 178 else:
179 179 raise Exception('You have to provide a user object or a username')
180 180
181 181 if getattr(repo, 'repo_id', None):
182 182 repo_obj = Repository.get(repo.repo_id)
183 183 repo_name = repo_obj.repo_name
184 184 elif isinstance(repo, basestring):
185 185 repo_name = repo.lstrip('/')
186 186 repo_obj = Repository.get_by_repo_name(repo_name)
187 187 else:
188 188 repo_obj = None
189 189 repo_name = ''
190 190
191 191 user_log = UserLog()
192 192 user_log.user_id = user_obj.user_id
193 193 user_log.username = user_obj.username
194 194 user_log.action = safe_unicode(action)
195 195
196 196 user_log.repository = repo_obj
197 197 user_log.repository_name = repo_name
198 198
199 199 user_log.action_date = datetime.datetime.now()
200 200 user_log.user_ip = ipaddr
201 201 sa.add(user_log)
202 202
203 203 log.info('Logging action:%s on %s by user:%s ip:%s',
204 204 action, safe_unicode(repo), user_obj, ipaddr)
205 205 if commit:
206 206 sa.commit()
207 207
208 208
209 209 def get_filesystem_repos(path, recursive=False, skip_removed_repos=True):
210 210 """
211 211 Scans given path for repos and return (name,(type,path)) tuple
212 212
213 213 :param path: path to scan for repositories
214 214 :param recursive: recursive search and return names with subdirs in front
215 215 """
216 216
217 217 # remove ending slash for better results
218 218 path = path.rstrip(os.sep)
219 219 log.debug('now scanning in %s location recursive:%s...', path, recursive)
220 220
221 221 def _get_repos(p):
222 222 if not os.access(p, os.R_OK) or not os.access(p, os.X_OK):
223 223 log.warning('ignoring repo path without access: %s', p)
224 224 return
225 225 if not os.access(p, os.W_OK):
226 226 log.warning('repo path without write access: %s', p)
227 227 for dirpath in os.listdir(p):
228 228 if os.path.isfile(os.path.join(p, dirpath)):
229 229 continue
230 230 cur_path = os.path.join(p, dirpath)
231 231
232 232 # skip removed repos
233 233 if skip_removed_repos and REMOVED_REPO_PAT.match(dirpath):
234 234 continue
235 235
236 236 #skip .<somethin> dirs
237 237 if dirpath.startswith('.'):
238 238 continue
239 239
240 240 try:
241 241 scm_info = get_scm(cur_path)
242 242 yield scm_info[1].split(path, 1)[-1].lstrip(os.sep), scm_info
243 243 except VCSError:
244 244 if not recursive:
245 245 continue
246 246 #check if this dir containts other repos for recursive scan
247 247 rec_path = os.path.join(p, dirpath)
248 248 if not os.path.islink(rec_path) and os.path.isdir(rec_path):
249 249 for inner_scm in _get_repos(rec_path):
250 250 yield inner_scm
251 251
252 252 return _get_repos(path)
253 253
254 254
255 255 def is_valid_repo(repo_name, base_path, scm=None):
256 256 """
257 257 Returns True if given path is a valid repository False otherwise.
258 258 If scm param is given also compare if given scm is the same as expected
259 259 from scm parameter
260 260
261 261 :param repo_name:
262 262 :param base_path:
263 263 :param scm:
264 264
265 265 :return True: if given path is a valid repository
266 266 """
267 267 full_path = os.path.join(safe_str(base_path), safe_str(repo_name))
268 268
269 269 try:
270 270 scm_ = get_scm(full_path)
271 271 if scm:
272 272 return scm_[0] == scm
273 273 return True
274 274 except VCSError:
275 275 return False
276 276
277 277
278 278 def is_valid_repo_group(repo_group_name, base_path, skip_path_check=False):
279 279 """
280 280 Returns True if given path is a repository group False otherwise
281 281
282 282 :param repo_name:
283 283 :param base_path:
284 284 """
285 285 full_path = os.path.join(safe_str(base_path), safe_str(repo_group_name))
286 286
287 287 # check if it's not a repo
288 288 if is_valid_repo(repo_group_name, base_path):
289 289 return False
290 290
291 291 try:
292 292 # we need to check bare git repos at higher level
293 293 # since we might match branches/hooks/info/objects or possible
294 294 # other things inside bare git repo
295 295 get_scm(os.path.dirname(full_path))
296 296 return False
297 297 except VCSError:
298 298 pass
299 299
300 300 # check if it's a valid path
301 301 if skip_path_check or os.path.isdir(full_path):
302 302 return True
303 303
304 304 return False
305 305
306 306
307 307 def ask_ok(prompt, retries=4, complaint='Yes or no please!'):
308 308 while True:
309 309 ok = raw_input(prompt)
310 310 if ok in ('y', 'ye', 'yes'):
311 311 return True
312 312 if ok in ('n', 'no', 'nop', 'nope'):
313 313 return False
314 314 retries = retries - 1
315 315 if retries < 0:
316 316 raise IOError
317 317 print complaint
318 318
319 319 #propagated from mercurial documentation
320 320 ui_sections = ['alias', 'auth',
321 321 'decode/encode', 'defaults',
322 322 'diff', 'email',
323 323 'extensions', 'format',
324 324 'merge-patterns', 'merge-tools',
325 325 'hooks', 'http_proxy',
326 326 'smtp', 'patch',
327 327 'paths', 'profiling',
328 328 'server', 'trusted',
329 329 'ui', 'web', ]
330 330
331 331
332 332 def make_ui(read_from='file', path=None, checkpaths=True, clear_session=True):
333 333 """
334 334 A function that will read python rc files or database
335 335 and make an mercurial ui object from read options
336 336
337 337 :param path: path to mercurial config file
338 338 :param checkpaths: check the path
339 339 :param read_from: read from 'file' or 'db'
340 340 """
341 341
342 342 baseui = ui.ui()
343 343
344 344 # clean the baseui object
345 345 baseui._ocfg = config.config()
346 346 baseui._ucfg = config.config()
347 347 baseui._tcfg = config.config()
348 348
349 349 if read_from == 'file':
350 350 if not os.path.isfile(path):
351 351 log.debug('hgrc file is not present at %s, skipping...', path)
352 352 return False
353 353 log.debug('reading hgrc from %s', path)
354 354 cfg = config.config()
355 355 cfg.read(path)
356 356 for section in ui_sections:
357 357 for k, v in cfg.items(section):
358 358 log.debug('settings ui from file: [%s] %s=%s', section, k, v)
359 359 baseui.setconfig(safe_str(section), safe_str(k), safe_str(v))
360 360
361 361 elif read_from == 'db':
362 362 sa = meta.Session()
363 363 ret = sa.query(Ui).all()
364 364
365 365 hg_ui = ret
366 366 for ui_ in hg_ui:
367 367 if ui_.ui_active:
368 368 ui_val = safe_str(ui_.ui_value)
369 369 if ui_.ui_section == 'hooks' and BRAND != 'kallithea' and ui_val.startswith('python:' + BRAND + '.lib.hooks.'):
370 370 ui_val = ui_val.replace('python:' + BRAND + '.lib.hooks.', 'python:kallithea.lib.hooks.')
371 371 log.debug('settings ui from db: [%s] %s=%s', ui_.ui_section,
372 372 ui_.ui_key, ui_val)
373 373 baseui.setconfig(safe_str(ui_.ui_section), safe_str(ui_.ui_key),
374 374 ui_val)
375 375 if ui_.ui_key == 'push_ssl':
376 376 # force set push_ssl requirement to False, kallithea
377 377 # handles that
378 378 baseui.setconfig(safe_str(ui_.ui_section), safe_str(ui_.ui_key),
379 379 False)
380 380 if clear_session:
381 381 meta.Session.remove()
382 382
383 383 # prevent interactive questions for ssh password / passphrase
384 384 ssh = baseui.config('ui', 'ssh', default='ssh')
385 385 baseui.setconfig('ui', 'ssh', '%s -oBatchMode=yes -oIdentitiesOnly=yes' % ssh)
386 386
387 387 return baseui
388 388
389 389
390 390 def set_app_settings(config):
391 391 """
392 392 Updates pylons config with new settings from database
393 393
394 394 :param config:
395 395 """
396 396 hgsettings = Setting.get_app_settings()
397 397
398 398 for k, v in hgsettings.items():
399 399 config[k] = v
400 400
401 401
402 402 def set_vcs_config(config):
403 403 """
404 404 Patch VCS config with some Kallithea specific stuff
405 405
406 406 :param config: kallithea.CONFIG
407 407 """
408 408 from kallithea.lib.vcs import conf
409 409 from kallithea.lib.utils2 import aslist
410 410 conf.settings.BACKENDS = {
411 411 'hg': 'kallithea.lib.vcs.backends.hg.MercurialRepository',
412 412 'git': 'kallithea.lib.vcs.backends.git.GitRepository',
413 413 }
414 414
415 415 conf.settings.GIT_EXECUTABLE_PATH = config.get('git_path', 'git')
416 416 conf.settings.GIT_REV_FILTER = config.get('git_rev_filter', '--all').strip()
417 417 conf.settings.DEFAULT_ENCODINGS = aslist(config.get('default_encoding',
418 418 'utf8'), sep=',')
419 419
420 420
421 def set_indexer_config(config):
422 """
423 Update Whoosh index mapping
424
425 :param config: kallithea.CONFIG
426 """
427 from kallithea.config import conf
428
429 log.debug('adding extra into INDEX_EXTENSIONS')
430 conf.INDEX_EXTENSIONS.extend(re.split('\s+', config.get('index.extensions', '')))
431
432 log.debug('adding extra into INDEX_FILENAMES')
433 conf.INDEX_FILENAMES.extend(re.split('\s+', config.get('index.filenames', '')))
434
435
421 436 def map_groups(path):
422 437 """
423 438 Given a full path to a repository, create all nested groups that this
424 439 repo is inside. This function creates parent-child relationships between
425 440 groups and creates default perms for all new groups.
426 441
427 442 :param paths: full path to repository
428 443 """
429 444 sa = meta.Session()
430 445 groups = path.split(Repository.url_sep())
431 446 parent = None
432 447 group = None
433 448
434 449 # last element is repo in nested groups structure
435 450 groups = groups[:-1]
436 451 rgm = RepoGroupModel(sa)
437 452 owner = User.get_first_admin()
438 453 for lvl, group_name in enumerate(groups):
439 454 group_name = '/'.join(groups[:lvl] + [group_name])
440 455 group = RepoGroup.get_by_group_name(group_name)
441 456 desc = '%s group' % group_name
442 457
443 458 # skip folders that are now removed repos
444 459 if REMOVED_REPO_PAT.match(group_name):
445 460 break
446 461
447 462 if group is None:
448 463 log.debug('creating group level: %s group_name: %s',
449 464 lvl, group_name)
450 465 group = RepoGroup(group_name, parent)
451 466 group.group_description = desc
452 467 group.user = owner
453 468 sa.add(group)
454 469 perm_obj = rgm._create_default_perms(group)
455 470 sa.add(perm_obj)
456 471 sa.flush()
457 472
458 473 parent = group
459 474 return group
460 475
461 476
462 477 def repo2db_mapper(initial_repo_list, remove_obsolete=False,
463 478 install_git_hooks=False, user=None, overwrite_git_hooks=False):
464 479 """
465 480 maps all repos given in initial_repo_list, non existing repositories
466 481 are created, if remove_obsolete is True it also check for db entries
467 482 that are not in initial_repo_list and removes them.
468 483
469 484 :param initial_repo_list: list of repositories found by scanning methods
470 485 :param remove_obsolete: check for obsolete entries in database
471 486 :param install_git_hooks: if this is True, also check and install git hook
472 487 for a repo if missing
473 488 :param overwrite_git_hooks: if this is True, overwrite any existing git hooks
474 489 that may be encountered (even if user-deployed)
475 490 """
476 491 from kallithea.model.repo import RepoModel
477 492 from kallithea.model.scm import ScmModel
478 493 sa = meta.Session()
479 494 repo_model = RepoModel()
480 495 if user is None:
481 496 user = User.get_first_admin()
482 497 added = []
483 498
484 499 ##creation defaults
485 500 defs = Setting.get_default_repo_settings(strip_prefix=True)
486 501 enable_statistics = defs.get('repo_enable_statistics')
487 502 enable_locking = defs.get('repo_enable_locking')
488 503 enable_downloads = defs.get('repo_enable_downloads')
489 504 private = defs.get('repo_private')
490 505
491 506 for name, repo in initial_repo_list.items():
492 507 group = map_groups(name)
493 508 unicode_name = safe_unicode(name)
494 509 db_repo = repo_model.get_by_repo_name(unicode_name)
495 510 # found repo that is on filesystem not in Kallithea database
496 511 if not db_repo:
497 512 log.info('repository %s not found, creating now', name)
498 513 added.append(name)
499 514 desc = (repo.description
500 515 if repo.description != 'unknown'
501 516 else '%s repository' % name)
502 517
503 518 new_repo = repo_model._create_repo(
504 519 repo_name=name,
505 520 repo_type=repo.alias,
506 521 description=desc,
507 522 repo_group=getattr(group, 'group_id', None),
508 523 owner=user,
509 524 enable_locking=enable_locking,
510 525 enable_downloads=enable_downloads,
511 526 enable_statistics=enable_statistics,
512 527 private=private,
513 528 state=Repository.STATE_CREATED
514 529 )
515 530 sa.commit()
516 531 # we added that repo just now, and make sure it has githook
517 532 # installed, and updated server info
518 533 if new_repo.repo_type == 'git':
519 534 git_repo = new_repo.scm_instance
520 535 ScmModel().install_git_hooks(git_repo)
521 536 # update repository server-info
522 537 log.debug('Running update server info')
523 538 git_repo._update_server_info()
524 539 new_repo.update_changeset_cache()
525 540 elif install_git_hooks:
526 541 if db_repo.repo_type == 'git':
527 542 ScmModel().install_git_hooks(db_repo.scm_instance, force_create=overwrite_git_hooks)
528 543
529 544 removed = []
530 545 # remove from database those repositories that are not in the filesystem
531 546 for repo in sa.query(Repository).all():
532 547 if repo.repo_name not in initial_repo_list.keys():
533 548 if remove_obsolete:
534 549 log.debug("Removing non-existing repository found in db `%s`",
535 550 repo.repo_name)
536 551 try:
537 552 RepoModel(sa).delete(repo, forks='detach', fs_remove=False)
538 553 sa.commit()
539 554 except Exception:
540 555 #don't hold further removals on error
541 556 log.error(traceback.format_exc())
542 557 sa.rollback()
543 558 removed.append(repo.repo_name)
544 559 return added, removed
545 560
546 561
547 562 # set cache regions for beaker so celery can utilise it
548 563 def add_cache(settings):
549 564 cache_settings = {'regions': None}
550 565 for key in settings.keys():
551 566 for prefix in ['beaker.cache.', 'cache.']:
552 567 if key.startswith(prefix):
553 568 name = key.split(prefix)[1].strip()
554 569 cache_settings[name] = settings[key].strip()
555 570 if cache_settings['regions']:
556 571 for region in cache_settings['regions'].split(','):
557 572 region = region.strip()
558 573 region_settings = {}
559 574 for key, value in cache_settings.items():
560 575 if key.startswith(region):
561 576 region_settings[key.split('.')[1]] = value
562 577 region_settings['expire'] = int(region_settings.get('expire',
563 578 60))
564 579 region_settings.setdefault('lock_dir',
565 580 cache_settings.get('lock_dir'))
566 581 region_settings.setdefault('data_dir',
567 582 cache_settings.get('data_dir'))
568 583
569 584 if 'type' not in region_settings:
570 585 region_settings['type'] = cache_settings.get('type',
571 586 'memory')
572 587 beaker.cache.cache_regions[region] = region_settings
573 588
574 589
575 590 def load_rcextensions(root_path):
576 591 import kallithea
577 592 from kallithea.config import conf
578 593
579 594 path = os.path.join(root_path, 'rcextensions', '__init__.py')
580 595 if os.path.isfile(path):
581 596 rcext = create_module('rc', path)
582 597 EXT = kallithea.EXTENSIONS = rcext
583 598 log.debug('Found rcextensions now loading %s...', rcext)
584 599
585 600 # Additional mappings that are not present in the pygments lexers
586 601 conf.LANGUAGES_EXTENSIONS_MAP.update(getattr(EXT, 'EXTRA_MAPPINGS', {}))
587 602
588 603 #OVERRIDE OUR EXTENSIONS FROM RC-EXTENSIONS (if present)
589 604
590 605 if getattr(EXT, 'INDEX_EXTENSIONS', []):
591 606 log.debug('settings custom INDEX_EXTENSIONS')
592 607 conf.INDEX_EXTENSIONS = getattr(EXT, 'INDEX_EXTENSIONS', [])
593 608
594 609 #ADDITIONAL MAPPINGS
595 610 log.debug('adding extra into INDEX_EXTENSIONS')
596 611 conf.INDEX_EXTENSIONS.extend(getattr(EXT, 'EXTRA_INDEX_EXTENSIONS', []))
597 612
598 613 # auto check if the module is not missing any data, set to default if is
599 614 # this will help autoupdate new feature of rcext module
600 615 #from kallithea.config import rcextensions
601 616 #for k in dir(rcextensions):
602 617 # if not k.startswith('_') and not hasattr(EXT, k):
603 618 # setattr(EXT, k, getattr(rcextensions, k))
604 619
605 620
606 621 def get_custom_lexer(extension):
607 622 """
608 623 returns a custom lexer if it's defined in rcextensions module, or None
609 624 if there's no custom lexer defined
610 625 """
611 626 import kallithea
612 627 from pygments import lexers
613 628 #check if we didn't define this extension as other lexer
614 629 if kallithea.EXTENSIONS and extension in kallithea.EXTENSIONS.EXTRA_LEXERS:
615 630 _lexer_name = kallithea.EXTENSIONS.EXTRA_LEXERS[extension]
616 631 return lexers.get_lexer_by_name(_lexer_name)
617 632
618 633
619 634 #==============================================================================
620 635 # TEST FUNCTIONS AND CREATORS
621 636 #==============================================================================
622 637 def create_test_index(repo_location, config, full_index):
623 638 """
624 639 Makes default test index
625 640
626 641 :param config: test config
627 642 :param full_index:
628 643 """
629 644
630 645 from kallithea.lib.indexers.daemon import WhooshIndexingDaemon
631 646 from kallithea.lib.pidlock import DaemonLock, LockHeld
632 647
633 648 repo_location = repo_location
634 649
635 650 index_location = os.path.join(config['app_conf']['index_dir'])
636 651 if not os.path.exists(index_location):
637 652 os.makedirs(index_location)
638 653
639 654 try:
640 655 l = DaemonLock(file_=jn(dn(index_location), 'make_index.lock'))
641 656 WhooshIndexingDaemon(index_location=index_location,
642 657 repo_location=repo_location)\
643 658 .run(full_index=full_index)
644 659 l.release()
645 660 except LockHeld:
646 661 pass
647 662
648 663
649 664 def create_test_env(repos_test_path, config):
650 665 """
651 666 Makes a fresh database and
652 667 install test repository into tmp dir
653 668 """
654 669 from kallithea.lib.db_manage import DbManage
655 670 from kallithea.tests import HG_REPO, GIT_REPO, TESTS_TMP_PATH
656 671
657 672 # PART ONE create db
658 673 dbconf = config['sqlalchemy.db1.url']
659 674 log.debug('making test db %s', dbconf)
660 675
661 676 # create test dir if it doesn't exist
662 677 if not os.path.isdir(repos_test_path):
663 678 log.debug('Creating testdir %s', repos_test_path)
664 679 os.makedirs(repos_test_path)
665 680
666 681 dbmanage = DbManage(log_sql=True, dbconf=dbconf, root=config['here'],
667 682 tests=True)
668 683 dbmanage.create_tables(override=True)
669 684 # for tests dynamically set new root paths based on generated content
670 685 dbmanage.create_settings(dbmanage.config_prompt(repos_test_path))
671 686 dbmanage.create_default_user()
672 687 dbmanage.admin_prompt()
673 688 dbmanage.create_permissions()
674 689 dbmanage.populate_default_permissions()
675 690 Session().commit()
676 691 # PART TWO make test repo
677 692 log.debug('making test vcs repositories')
678 693
679 694 idx_path = config['app_conf']['index_dir']
680 695 data_path = config['app_conf']['cache_dir']
681 696
682 697 #clean index and data
683 698 if idx_path and os.path.exists(idx_path):
684 699 log.debug('remove %s', idx_path)
685 700 shutil.rmtree(idx_path)
686 701
687 702 if data_path and os.path.exists(data_path):
688 703 log.debug('remove %s', data_path)
689 704 shutil.rmtree(data_path)
690 705
691 706 #CREATE DEFAULT TEST REPOS
692 707 cur_dir = dn(dn(abspath(__file__)))
693 708 tar = tarfile.open(jn(cur_dir, 'tests', 'fixtures', "vcs_test_hg.tar.gz"))
694 709 tar.extractall(jn(TESTS_TMP_PATH, HG_REPO))
695 710 tar.close()
696 711
697 712 cur_dir = dn(dn(abspath(__file__)))
698 713 tar = tarfile.open(jn(cur_dir, 'tests', 'fixtures', "vcs_test_git.tar.gz"))
699 714 tar.extractall(jn(TESTS_TMP_PATH, GIT_REPO))
700 715 tar.close()
701 716
702 717 #LOAD VCS test stuff
703 718 from kallithea.tests.vcs import setup_package
704 719 setup_package()
705 720
706 721
707 722 #==============================================================================
708 723 # PASTER COMMANDS
709 724 #==============================================================================
710 725 class BasePasterCommand(Command):
711 726 """
712 727 Abstract Base Class for paster commands.
713 728
714 729 The celery commands are somewhat aggressive about loading
715 730 celery.conf, and since our module sets the `CELERY_LOADER`
716 731 environment variable to our loader, we have to bootstrap a bit and
717 732 make sure we've had a chance to load the pylons config off of the
718 733 command line, otherwise everything fails.
719 734 """
720 735 min_args = 1
721 736 min_args_error = "Please provide a paster config file as an argument."
722 737 takes_config_file = 1
723 738 requires_config_file = True
724 739
725 740 def notify_msg(self, msg, log=False):
726 741 """Make a notification to user, additionally if logger is passed
727 742 it logs this action using given logger
728 743
729 744 :param msg: message that will be printed to user
730 745 :param log: logging instance, to use to additionally log this message
731 746
732 747 """
733 748 if log and isinstance(log, logging):
734 749 log(msg)
735 750
736 751 def run(self, args):
737 752 """
738 753 Overrides Command.run
739 754
740 755 Checks for a config file argument and loads it.
741 756 """
742 757 if len(args) < self.min_args:
743 758 raise BadCommand(
744 759 self.min_args_error % {'min_args': self.min_args,
745 760 'actual_args': len(args)})
746 761
747 762 # Decrement because we're going to lob off the first argument.
748 763 # @@ This is hacky
749 764 self.min_args -= 1
750 765 self.bootstrap_config(args[0])
751 766 self.update_parser()
752 767 return super(BasePasterCommand, self).run(args[1:])
753 768
754 769 def update_parser(self):
755 770 """
756 771 Abstract method. Allows for the class's parser to be updated
757 772 before the superclass's `run` method is called. Necessary to
758 773 allow options/arguments to be passed through to the underlying
759 774 celery command.
760 775 """
761 776 raise NotImplementedError("Abstract Method.")
762 777
763 778 def bootstrap_config(self, conf):
764 779 """
765 780 Loads the pylons configuration.
766 781 """
767 782 from pylons import config as pylonsconfig
768 783
769 784 self.path_to_ini_file = os.path.realpath(conf)
770 785 conf = paste.deploy.appconfig('config:' + self.path_to_ini_file)
771 786 pylonsconfig.init_app(conf.global_conf, conf.local_conf)
772 787
773 788 def _init_session(self):
774 789 """
775 790 Inits SqlAlchemy Session
776 791 """
777 792 logging.config.fileConfig(self.path_to_ini_file)
778 793 from pylons import config
779 794 from kallithea.model import init_model
780 795 from kallithea.lib.utils2 import engine_from_config
781 796
782 797 #get to remove repos !!
783 798 add_cache(config)
784 799 engine = engine_from_config(config, 'sqlalchemy.db1.')
785 800 init_model(engine)
786 801
787 802
788 803 def check_git_version():
789 804 """
790 805 Checks what version of git is installed in system, and issues a warning
791 806 if it's too old for Kallithea to work properly.
792 807 """
793 808 from kallithea import BACKENDS
794 809 from kallithea.lib.vcs.backends.git.repository import GitRepository
795 810 from kallithea.lib.vcs.conf import settings
796 811 from distutils.version import StrictVersion
797 812
798 813 if 'git' not in BACKENDS:
799 814 return None
800 815
801 816 stdout, stderr = GitRepository._run_git_command(['--version'], _bare=True,
802 817 _safe=True)
803 818
804 819 m = re.search("\d+.\d+.\d+", stdout)
805 820 if m:
806 821 ver = StrictVersion(m.group(0))
807 822 else:
808 823 ver = StrictVersion('0.0.0')
809 824
810 825 req_ver = StrictVersion('1.7.4')
811 826
812 827 log.debug('Git executable: "%s" version %s detected: %s',
813 828 settings.GIT_EXECUTABLE_PATH, ver, stdout)
814 829 if stderr:
815 830 log.warning('Error detecting git version: %r', stderr)
816 831 elif ver < req_ver:
817 832 log.warning('Kallithea detected git version %s, which is too old '
818 833 'for the system to function properly. '
819 834 'Please upgrade to version %s or later.' % (ver, req_ver))
820 835 return ver
821 836
822 837
823 838 @decorator.decorator
824 839 def jsonify(func, *args, **kwargs):
825 840 """Action decorator that formats output for JSON
826 841
827 842 Given a function that will return content, this decorator will turn
828 843 the result into JSON, with a content-type of 'application/json' and
829 844 output it.
830 845
831 846 """
832 847 from pylons.decorators.util import get_pylons
833 848 from kallithea.lib.compat import json
834 849 pylons = get_pylons(args)
835 850 pylons.response.headers['Content-Type'] = 'application/json; charset=utf-8'
836 851 data = func(*args, **kwargs)
837 852 if isinstance(data, (list, tuple)):
838 853 msg = "JSON responses with Array envelopes are susceptible to " \
839 854 "cross-site data leak attacks, see " \
840 855 "http://wiki.pylonshq.com/display/pylonsfaq/Warnings"
841 856 warnings.warn(msg, Warning, 2)
842 857 log.warning(msg)
843 858 log.debug("Returning JSON wrapped action output")
844 859 return json.dumps(data, encoding='utf-8')
845 860
846 861
847 862 def conditional_cache(region, prefix, condition, func):
848 863 """
849 864
850 865 Conditional caching function use like::
851 866 def _c(arg):
852 867 #heavy computation function
853 868 return data
854 869
855 870 # denpending from condition the compute is wrapped in cache or not
856 871 compute = conditional_cache('short_term', 'cache_desc', codnition=True, func=func)
857 872 return compute(arg)
858 873
859 874 :param region: name of cache region
860 875 :param prefix: cache region prefix
861 876 :param condition: condition for cache to be triggered, and return data cached
862 877 :param func: wrapped heavy function to compute
863 878
864 879 """
865 880 wrapped = func
866 881 if condition:
867 882 log.debug('conditional_cache: True, wrapping call of '
868 883 'func: %s into %s region cache' % (region, func))
869 884 wrapped = _cache_decorate((prefix,), None, None, region)(func)
870 885
871 886 return wrapped
@@ -1,588 +1,600 b''
1 1 ################################################################################
2 2 ################################################################################
3 3 # Kallithea - config for tests: #
4 4 # initial_repo_scan = true #
5 5 # vcs_full_cache = false #
6 6 # sqlalchemy and kallithea_test.sqlite #
7 7 # custom logging #
8 8 # #
9 9 # The %(here)s variable will be replaced with the parent directory of this file#
10 10 ################################################################################
11 11 ################################################################################
12 12
13 13 [DEFAULT]
14 14 debug = true
15 15 pdebug = false
16 16
17 17 ################################################################################
18 18 ## Email settings ##
19 19 ## ##
20 20 ## Refer to the documentation ("Email settings") for more details. ##
21 21 ## ##
22 22 ## It is recommended to use a valid sender address that passes access ##
23 23 ## validation and spam filtering in mail servers. ##
24 24 ################################################################################
25 25
26 26 ## 'From' header for application emails. You can optionally add a name.
27 27 ## Default:
28 28 #app_email_from = Kallithea
29 29 ## Examples:
30 30 #app_email_from = Kallithea <kallithea-noreply@example.com>
31 31 #app_email_from = kallithea-noreply@example.com
32 32
33 33 ## Subject prefix for application emails.
34 34 ## A space between this prefix and the real subject is automatically added.
35 35 ## Default:
36 36 #email_prefix =
37 37 ## Example:
38 38 #email_prefix = [Kallithea]
39 39
40 40 ## Recipients for error emails and fallback recipients of application mails.
41 41 ## Multiple addresses can be specified, space-separated.
42 42 ## Only addresses are allowed, do not add any name part.
43 43 ## Default:
44 44 #email_to =
45 45 ## Examples:
46 46 #email_to = admin@example.com
47 47 #email_to = admin@example.com another_admin@example.com
48 48
49 49 ## 'From' header for error emails. You can optionally add a name.
50 50 ## Default:
51 51 #error_email_from = pylons@yourapp.com
52 52 ## Examples:
53 53 #error_email_from = Kallithea Errors <kallithea-noreply@example.com>
54 54 #error_email_from = paste_error@example.com
55 55
56 56 ## SMTP server settings
57 57 ## Only smtp_server is mandatory. All other settings take the specified default
58 58 ## values.
59 59 #smtp_server = smtp.example.com
60 60 #smtp_username =
61 61 #smtp_password =
62 62 #smtp_port = 25
63 63 #smtp_use_tls = false
64 64 #smtp_use_ssl = false
65 65 ## SMTP authentication parameters to use (e.g. LOGIN PLAIN CRAM-MD5, etc.).
66 66 ## If empty, use any of the authentication parameters supported by the server.
67 67 #smtp_auth =
68 68
69 69 [server:main]
70 70 ## PASTE ##
71 71 #use = egg:Paste#http
72 72 ## nr of worker threads to spawn
73 73 #threadpool_workers = 5
74 74 ## max request before thread respawn
75 75 #threadpool_max_requests = 10
76 76 ## option to use threads of process
77 77 #use_threadpool = true
78 78
79 79 ## WAITRESS ##
80 80 use = egg:waitress#main
81 81 ## number of worker threads
82 82 threads = 5
83 83 ## MAX BODY SIZE 100GB
84 84 max_request_body_size = 107374182400
85 85 ## use poll instead of select, fixes fd limits, may not work on old
86 86 ## windows systems.
87 87 #asyncore_use_poll = True
88 88
89 89 ## GUNICORN ##
90 90 #use = egg:gunicorn#main
91 91 ## number of process workers. You must set `instance_id = *` when this option
92 92 ## is set to more than one worker
93 93 #workers = 1
94 94 ## process name
95 95 #proc_name = kallithea
96 96 ## type of worker class, one of sync, eventlet, gevent, tornado
97 97 ## recommended for bigger setup is using of of other than sync one
98 98 #worker_class = sync
99 99 #max_requests = 1000
100 100 ## ammount of time a worker can handle request before it gets killed and
101 101 ## restarted
102 102 #timeout = 3600
103 103
104 104 ## UWSGI ##
105 105 ## run with uwsgi --ini-paste-logged <inifile.ini>
106 106 #[uwsgi]
107 107 #socket = /tmp/uwsgi.sock
108 108 #master = true
109 109 #http = 127.0.0.1:5000
110 110
111 111 ## set as deamon and redirect all output to file
112 112 #daemonize = ./uwsgi_kallithea.log
113 113
114 114 ## master process PID
115 115 #pidfile = ./uwsgi_kallithea.pid
116 116
117 117 ## stats server with workers statistics, use uwsgitop
118 118 ## for monitoring, `uwsgitop 127.0.0.1:1717`
119 119 #stats = 127.0.0.1:1717
120 120 #memory-report = true
121 121
122 122 ## log 5XX errors
123 123 #log-5xx = true
124 124
125 125 ## Set the socket listen queue size.
126 126 #listen = 256
127 127
128 128 ## Gracefully Reload workers after the specified amount of managed requests
129 129 ## (avoid memory leaks).
130 130 #max-requests = 1000
131 131
132 132 ## enable large buffers
133 133 #buffer-size = 65535
134 134
135 135 ## socket and http timeouts ##
136 136 #http-timeout = 3600
137 137 #socket-timeout = 3600
138 138
139 139 ## Log requests slower than the specified number of milliseconds.
140 140 #log-slow = 10
141 141
142 142 ## Exit if no app can be loaded.
143 143 #need-app = true
144 144
145 145 ## Set lazy mode (load apps in workers instead of master).
146 146 #lazy = true
147 147
148 148 ## scaling ##
149 149 ## set cheaper algorithm to use, if not set default will be used
150 150 #cheaper-algo = spare
151 151
152 152 ## minimum number of workers to keep at all times
153 153 #cheaper = 1
154 154
155 155 ## number of workers to spawn at startup
156 156 #cheaper-initial = 1
157 157
158 158 ## maximum number of workers that can be spawned
159 159 #workers = 4
160 160
161 161 ## how many workers should be spawned at a time
162 162 #cheaper-step = 1
163 163
164 164 ## COMMON ##
165 165 host = 127.0.0.1
166 166 #port = 5000
167 167 port = 4999
168 168
169 169 ## middleware for hosting the WSGI application under a URL prefix
170 170 #[filter:proxy-prefix]
171 171 #use = egg:PasteDeploy#prefix
172 172 #prefix = /<your-prefix>
173 173
174 174 [app:main]
175 175 use = egg:kallithea
176 176 ## enable proxy prefix middleware
177 177 #filter-with = proxy-prefix
178 178
179 179 full_stack = true
180 180 static_files = true
181 181 ## Available Languages:
182 182 ## cs de fr hu ja nl_BE pl pt_BR ru sk zh_CN zh_TW
183 183 lang =
184 184 cache_dir = %(here)s/data
185 185 index_dir = %(here)s/data/index
186 186
187 187 ## perform a full repository scan on each server start, this should be
188 188 ## set to false after first startup, to allow faster server restarts.
189 189 #initial_repo_scan = false
190 190 initial_repo_scan = true
191 191
192 192 ## uncomment and set this path to use archive download cache
193 193 archive_cache_dir = %(here)s/tarballcache
194 194
195 195 ## change this to unique ID for security
196 196 app_instance_uuid = test
197 197
198 198 ## cut off limit for large diffs (size in bytes)
199 199 cut_off_limit = 256000
200 200
201 201 ## use cache version of scm repo everywhere
202 202 #vcs_full_cache = true
203 203 vcs_full_cache = false
204 204
205 205 ## force https in Kallithea, fixes https redirects, assumes it's always https
206 206 force_https = false
207 207
208 208 ## use Strict-Transport-Security headers
209 209 use_htsts = false
210 210
211 211 ## number of commits stats will parse on each iteration
212 212 commit_parse_limit = 25
213 213
214 214 ## path to git executable
215 215 git_path = git
216 216
217 217 ## git rev filter option, --all is the default filter, if you need to
218 218 ## hide all refs in changelog switch this to --branches --tags
219 219 #git_rev_filter = --branches --tags
220 220
221 221 ## RSS feed options
222 222 rss_cut_off_limit = 256000
223 223 rss_items_per_page = 10
224 224 rss_include_diff = false
225 225
226 226 ## options for showing and identifying changesets
227 227 show_sha_length = 12
228 228 #show_revision_number = false
229 229 show_revision_number = true
230 230
231 231 ## gist URL alias, used to create nicer urls for gist. This should be an
232 232 ## url that does rewrites to _admin/gists/<gistid>.
233 233 ## example: http://gist.example.com/{gistid}. Empty means use the internal
234 234 ## Kallithea url, ie. http[s]://kallithea.example.com/_admin/gists/<gistid>
235 235 gist_alias_url =
236 236
237 237 ## white list of API enabled controllers. This allows to add list of
238 238 ## controllers to which access will be enabled by api_key. eg: to enable
239 239 ## api access to raw_files put `FilesController:raw`, to enable access to patches
240 240 ## add `ChangesetController:changeset_patch`. This list should be "," separated
241 241 ## Syntax is <ControllerClass>:<function>. Check debug logs for generated names
242 242 ## Recommended settings below are commented out:
243 243 api_access_controllers_whitelist =
244 244 # ChangesetController:changeset_patch,
245 245 # ChangesetController:changeset_raw,
246 246 # FilesController:raw,
247 247 # FilesController:archivefile
248 248
249 249 ## default encoding used to convert from and to unicode
250 250 ## can be also a comma seperated list of encoding in case of mixed encodings
251 251 default_encoding = utf8
252 252
253 253 ## issue tracker for Kallithea (leave blank to disable, absent for default)
254 254 #bugtracker = https://bitbucket.org/conservancy/kallithea/issues
255 255
256 256 ## issue tracking mapping for commits messages
257 257 ## comment out issue_pat, issue_server, issue_prefix to enable
258 258
259 259 ## pattern to get the issues from commit messages
260 260 ## default one used here is #<numbers> with a regex passive group for `#`
261 261 ## {id} will be all groups matched from this pattern
262 262
263 263 issue_pat = (?:\s*#)(\d+)
264 264
265 265 ## server url to the issue, each {id} will be replaced with match
266 266 ## fetched from the regex and {repo} is replaced with full repository name
267 267 ## including groups {repo_name} is replaced with just name of repo
268 268
269 269 issue_server_link = https://issues.example.com/{repo}/issue/{id}
270 270
271 271 ## prefix to add to link to indicate it's an url
272 272 ## #314 will be replaced by <issue_prefix><id>
273 273
274 274 issue_prefix = #
275 275
276 276 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
277 277 ## multiple patterns, to other issues server, wiki or others
278 278 ## below an example how to create a wiki pattern
279 279 # wiki-some-id -> https://wiki.example.com/some-id
280 280
281 281 #issue_pat_wiki = (?:wiki-)(.+)
282 282 #issue_server_link_wiki = https://wiki.example.com/{id}
283 283 #issue_prefix_wiki = WIKI-
284 284
285 285 ## alternative return HTTP header for failed authentication. Default HTTP
286 286 ## response is 401 HTTPUnauthorized. Currently Mercurial clients have trouble with
287 287 ## handling that. Set this variable to 403 to return HTTPForbidden
288 288 auth_ret_code =
289 289
290 290 ## locking return code. When repository is locked return this HTTP code. 2XX
291 291 ## codes don't break the transactions while 4XX codes do
292 292 lock_ret_code = 423
293 293
294 294 ## allows to change the repository location in settings page
295 295 allow_repo_location_change = True
296 296
297 297 ## allows to setup custom hooks in settings page
298 298 allow_custom_hooks_settings = True
299 299
300 ## extra extensions for indexing, space separated and without the leading '.'.
301 # index.extensions =
302 # gemfile
303 # lock
304
305 ## extra filenames for indexing, space separated
306 # index.filenames =
307 # .dockerignore
308 # .editorconfig
309 # INSTALL
310 # CHANGELOG
311
300 312 ####################################
301 313 ### CELERY CONFIG ####
302 314 ####################################
303 315
304 316 use_celery = false
305 317 broker.host = localhost
306 318 broker.vhost = rabbitmqhost
307 319 broker.port = 5672
308 320 broker.user = rabbitmq
309 321 broker.password = qweqwe
310 322
311 323 celery.imports = kallithea.lib.celerylib.tasks
312 324
313 325 celery.result.backend = amqp
314 326 celery.result.dburi = amqp://
315 327 celery.result.serialier = json
316 328
317 329 #celery.send.task.error.emails = true
318 330 #celery.amqp.task.result.expires = 18000
319 331
320 332 celeryd.concurrency = 2
321 333 #celeryd.log.file = celeryd.log
322 334 celeryd.log.level = DEBUG
323 335 celeryd.max.tasks.per.child = 1
324 336
325 337 ## tasks will never be sent to the queue, but executed locally instead.
326 338 celery.always.eager = false
327 339
328 340 ####################################
329 341 ### BEAKER CACHE ####
330 342 ####################################
331 343
332 344 beaker.cache.data_dir = %(here)s/data/cache/data
333 345 beaker.cache.lock_dir = %(here)s/data/cache/lock
334 346
335 347 beaker.cache.regions = short_term,long_term,sql_cache_short
336 348
337 349 beaker.cache.short_term.type = memory
338 350 beaker.cache.short_term.expire = 60
339 351 beaker.cache.short_term.key_length = 256
340 352
341 353 beaker.cache.long_term.type = memory
342 354 beaker.cache.long_term.expire = 36000
343 355 beaker.cache.long_term.key_length = 256
344 356
345 357 beaker.cache.sql_cache_short.type = memory
346 358 #beaker.cache.sql_cache_short.expire = 10
347 359 beaker.cache.sql_cache_short.expire = 1
348 360 beaker.cache.sql_cache_short.key_length = 256
349 361
350 362 ####################################
351 363 ### BEAKER SESSION ####
352 364 ####################################
353 365
354 366 ## Name of session cookie. Should be unique for a given host and path, even when running
355 367 ## on different ports. Otherwise, cookie sessions will be shared and messed up.
356 368 beaker.session.key = kallithea
357 369 ## Sessions should always only be accessible by the browser, not directly by JavaScript.
358 370 beaker.session.httponly = true
359 371 ## Session lifetime. 2592000 seconds is 30 days.
360 372 beaker.session.timeout = 2592000
361 373
362 374 ## Server secret used with HMAC to ensure integrity of cookies.
363 375 beaker.session.secret = {74e0cd75-b339-478b-b129-07dd221def1f}
364 376 ## Further, encrypt the data with AES.
365 377 #beaker.session.encrypt_key = <key_for_encryption>
366 378 #beaker.session.validate_key = <validation_key>
367 379
368 380 ## Type of storage used for the session, current types are
369 381 ## dbm, file, memcached, database, and memory.
370 382
371 383 ## File system storage of session data. (default)
372 384 #beaker.session.type = file
373 385
374 386 ## Cookie only, store all session data inside the cookie. Requires secure secrets.
375 387 #beaker.session.type = cookie
376 388
377 389 ## Database storage of session data.
378 390 #beaker.session.type = ext:database
379 391 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/kallithea
380 392 #beaker.session.table_name = db_session
381 393
382 394 ############################
383 395 ## ERROR HANDLING SYSTEMS ##
384 396 ############################
385 397
386 398 ####################
387 399 ### [errormator] ###
388 400 ####################
389 401
390 402 ## Errormator is tailored to work with Kallithea, see
391 403 ## http://errormator.com for details how to obtain an account
392 404 ## you must install python package `errormator_client` to make it work
393 405
394 406 ## errormator enabled
395 407 errormator = false
396 408
397 409 errormator.server_url = https://api.errormator.com
398 410 errormator.api_key = YOUR_API_KEY
399 411
400 412 ## TWEAK AMOUNT OF INFO SENT HERE
401 413
402 414 ## enables 404 error logging (default False)
403 415 errormator.report_404 = false
404 416
405 417 ## time in seconds after request is considered being slow (default 1)
406 418 errormator.slow_request_time = 1
407 419
408 420 ## record slow requests in application
409 421 ## (needs to be enabled for slow datastore recording and time tracking)
410 422 errormator.slow_requests = true
411 423
412 424 ## enable hooking to application loggers
413 425 #errormator.logging = true
414 426
415 427 ## minimum log level for log capture
416 428 #errormator.logging.level = WARNING
417 429
418 430 ## send logs only from erroneous/slow requests
419 431 ## (saves API quota for intensive logging)
420 432 errormator.logging_on_error = false
421 433
422 434 ## list of additonal keywords that should be grabbed from environ object
423 435 ## can be string with comma separated list of words in lowercase
424 436 ## (by default client will always send following info:
425 437 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
426 438 ## start with HTTP* this list be extended with additional keywords here
427 439 errormator.environ_keys_whitelist =
428 440
429 441 ## list of keywords that should be blanked from request object
430 442 ## can be string with comma separated list of words in lowercase
431 443 ## (by default client will always blank keys that contain following words
432 444 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
433 445 ## this list be extended with additional keywords set here
434 446 errormator.request_keys_blacklist =
435 447
436 448 ## list of namespaces that should be ignores when gathering log entries
437 449 ## can be string with comma separated list of namespaces
438 450 ## (by default the client ignores own entries: errormator_client.client)
439 451 errormator.log_namespace_blacklist =
440 452
441 453 ################
442 454 ### [sentry] ###
443 455 ################
444 456
445 457 ## sentry is a alternative open source error aggregator
446 458 ## you must install python packages `sentry` and `raven` to enable
447 459
448 460 sentry.dsn = YOUR_DNS
449 461 sentry.servers =
450 462 sentry.name =
451 463 sentry.key =
452 464 sentry.public_key =
453 465 sentry.secret_key =
454 466 sentry.project =
455 467 sentry.site =
456 468 sentry.include_paths =
457 469 sentry.exclude_paths =
458 470
459 471 ################################################################################
460 472 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
461 473 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
462 474 ## execute malicious code after an exception is raised. ##
463 475 ################################################################################
464 476 set debug = false
465 477
466 478 ##################################
467 479 ### LOGVIEW CONFIG ###
468 480 ##################################
469 481
470 482 logview.sqlalchemy = #faa
471 483 logview.pylons.templating = #bfb
472 484 logview.pylons.util = #eee
473 485
474 486 #########################################################
475 487 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
476 488 #########################################################
477 489
478 490 # SQLITE [default]
479 491 #sqlalchemy.db1.url = sqlite:///%(here)s/kallithea.db?timeout=60
480 492 sqlalchemy.db1.url = sqlite:///%(here)s/kallithea_test.sqlite
481 493
482 494 # POSTGRESQL
483 495 #sqlalchemy.db1.url = postgresql://user:pass@localhost/kallithea
484 496
485 497 # MySQL
486 498 #sqlalchemy.db1.url = mysql://user:pass@localhost/kallithea
487 499
488 500 # see sqlalchemy docs for others
489 501
490 502 sqlalchemy.db1.echo = false
491 503 sqlalchemy.db1.pool_recycle = 3600
492 504 sqlalchemy.db1.convert_unicode = true
493 505
494 506 ################################
495 507 ### LOGGING CONFIGURATION ####
496 508 ################################
497 509
498 510 [loggers]
499 511 keys = root, routes, kallithea, sqlalchemy, beaker, templates, whoosh_indexer
500 512
501 513 [handlers]
502 514 keys = console, console_sql
503 515
504 516 [formatters]
505 517 keys = generic, color_formatter, color_formatter_sql
506 518
507 519 #############
508 520 ## LOGGERS ##
509 521 #############
510 522
511 523 [logger_root]
512 524 #level = NOTSET
513 525 level = DEBUG
514 526 handlers = console
515 527
516 528 [logger_routes]
517 529 level = DEBUG
518 530 handlers =
519 531 qualname = routes.middleware
520 532 ## "level = DEBUG" logs the route matched and routing variables.
521 533 propagate = 1
522 534
523 535 [logger_beaker]
524 536 level = DEBUG
525 537 handlers =
526 538 qualname = beaker.container
527 539 propagate = 1
528 540
529 541 [logger_templates]
530 542 level = INFO
531 543 handlers =
532 544 qualname = pylons.templating
533 545 propagate = 1
534 546
535 547 [logger_kallithea]
536 548 level = DEBUG
537 549 handlers =
538 550 qualname = kallithea
539 551 propagate = 1
540 552
541 553 [logger_sqlalchemy]
542 554 #level = INFO
543 555 level = ERROR
544 556 #handlers = console_sql
545 557 handlers = console
546 558 qualname = sqlalchemy.engine
547 559 propagate = 0
548 560
549 561 [logger_whoosh_indexer]
550 562 level = DEBUG
551 563 handlers =
552 564 qualname = whoosh_indexer
553 565 propagate = 1
554 566
555 567 ##############
556 568 ## HANDLERS ##
557 569 ##############
558 570
559 571 [handler_console]
560 572 class = StreamHandler
561 573 args = (sys.stderr,)
562 574 #level = INFO
563 575 level = NOTSET
564 576 formatter = generic
565 577
566 578 [handler_console_sql]
567 579 class = StreamHandler
568 580 args = (sys.stderr,)
569 581 level = WARN
570 582 formatter = generic
571 583
572 584 ################
573 585 ## FORMATTERS ##
574 586 ################
575 587
576 588 [formatter_generic]
577 589 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
578 590 datefmt = %Y-%m-%d %H:%M:%S
579 591
580 592 [formatter_color_formatter]
581 593 class = kallithea.lib.colored_formatter.ColorFormatter
582 594 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
583 595 datefmt = %Y-%m-%d %H:%M:%S
584 596
585 597 [formatter_color_formatter_sql]
586 598 class = kallithea.lib.colored_formatter.ColorFormatterSql
587 599 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
588 600 datefmt = %Y-%m-%d %H:%M:%S
General Comments 0
You need to be logged in to leave comments. Login now