##// END OF EJS Templates
Add ini option to controll custom advanced hooks settings
marcink -
r4045:9b4ba12e default
parent child Browse files
Show More
@@ -1,517 +1,522 b''
1 ################################################################################
1 ################################################################################
2 ################################################################################
2 ################################################################################
3 # RhodeCode - Pylons environment configuration #
3 # RhodeCode - Pylons environment configuration #
4 # #
4 # #
5 # The %(here)s variable will be replaced with the parent directory of this file#
5 # The %(here)s variable will be replaced with the parent directory of this file#
6 ################################################################################
6 ################################################################################
7
7
8 [DEFAULT]
8 [DEFAULT]
9 debug = true
9 debug = true
10 pdebug = false
10 pdebug = false
11 ################################################################################
11 ################################################################################
12 ## Uncomment and replace with the address which should receive ##
12 ## Uncomment and replace with the address which should receive ##
13 ## any error reports after application crash ##
13 ## any error reports after application crash ##
14 ## Additionally those settings will be used by RhodeCode mailing system ##
14 ## Additionally those settings will be used by RhodeCode mailing system ##
15 ################################################################################
15 ################################################################################
16 #email_to = admin@localhost
16 #email_to = admin@localhost
17 #error_email_from = paste_error@localhost
17 #error_email_from = paste_error@localhost
18 #app_email_from = rhodecode-noreply@localhost
18 #app_email_from = rhodecode-noreply@localhost
19 #error_message =
19 #error_message =
20 #email_prefix = [RhodeCode]
20 #email_prefix = [RhodeCode]
21
21
22 #smtp_server = mail.server.com
22 #smtp_server = mail.server.com
23 #smtp_username =
23 #smtp_username =
24 #smtp_password =
24 #smtp_password =
25 #smtp_port =
25 #smtp_port =
26 #smtp_use_tls = false
26 #smtp_use_tls = false
27 #smtp_use_ssl = true
27 #smtp_use_ssl = true
28 ## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.)
28 ## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.)
29 #smtp_auth =
29 #smtp_auth =
30
30
31 [server:main]
31 [server:main]
32 ## PASTE ##
32 ## PASTE ##
33 #use = egg:Paste#http
33 #use = egg:Paste#http
34 ## nr of worker threads to spawn
34 ## nr of worker threads to spawn
35 #threadpool_workers = 5
35 #threadpool_workers = 5
36 ## max request before thread respawn
36 ## max request before thread respawn
37 #threadpool_max_requests = 10
37 #threadpool_max_requests = 10
38 ## option to use threads of process
38 ## option to use threads of process
39 #use_threadpool = true
39 #use_threadpool = true
40
40
41 ## WAITRESS ##
41 ## WAITRESS ##
42 use = egg:waitress#main
42 use = egg:waitress#main
43 ## number of worker threads
43 ## number of worker threads
44 threads = 5
44 threads = 5
45 ## MAX BODY SIZE 100GB
45 ## MAX BODY SIZE 100GB
46 max_request_body_size = 107374182400
46 max_request_body_size = 107374182400
47 ## use poll instead of select, fixes fd limits, may not work on old
47 ## use poll instead of select, fixes fd limits, may not work on old
48 ## windows systems.
48 ## windows systems.
49 #asyncore_use_poll = True
49 #asyncore_use_poll = True
50
50
51 ## GUNICORN ##
51 ## GUNICORN ##
52 #use = egg:gunicorn#main
52 #use = egg:gunicorn#main
53 ## number of process workers. You must set `instance_id = *` when this option
53 ## number of process workers. You must set `instance_id = *` when this option
54 ## is set to more than one worker
54 ## is set to more than one worker
55 #workers = 1
55 #workers = 1
56 ## process name
56 ## process name
57 #proc_name = rhodecode
57 #proc_name = rhodecode
58 ## type of worker class, one of sync, eventlet, gevent, tornado
58 ## type of worker class, one of sync, eventlet, gevent, tornado
59 ## recommended for bigger setup is using of of other than sync one
59 ## recommended for bigger setup is using of of other than sync one
60 #worker_class = sync
60 #worker_class = sync
61 #max_requests = 5
61 #max_requests = 5
62 ## ammount of time a worker can handle request before it get's killed and
62 ## ammount of time a worker can handle request before it get's killed and
63 ## restarted
63 ## restarted
64 #timeout = 3600
64 #timeout = 3600
65
65
66 ## COMMON ##
66 ## COMMON ##
67 host = 0.0.0.0
67 host = 0.0.0.0
68 port = 5000
68 port = 5000
69
69
70 ## prefix middleware for rc
70 ## prefix middleware for rc
71 #[filter:proxy-prefix]
71 #[filter:proxy-prefix]
72 #use = egg:PasteDeploy#prefix
72 #use = egg:PasteDeploy#prefix
73 #prefix = /<your-prefix>
73 #prefix = /<your-prefix>
74
74
75 [app:main]
75 [app:main]
76 use = egg:rhodecode
76 use = egg:rhodecode
77 ## enable proxy prefix middleware
77 ## enable proxy prefix middleware
78 #filter-with = proxy-prefix
78 #filter-with = proxy-prefix
79
79
80 full_stack = true
80 full_stack = true
81 static_files = true
81 static_files = true
82 ## Optional Languages
82 ## Optional Languages
83 ## en, fr, ja, pt_BR, zh_CN, zh_TW, pl
83 ## en, fr, ja, pt_BR, zh_CN, zh_TW, pl
84 lang = en
84 lang = en
85 cache_dir = %(here)s/data
85 cache_dir = %(here)s/data
86 index_dir = %(here)s/data/index
86 index_dir = %(here)s/data/index
87
87
88 ## perform a full repository scan on each server start, this should be
88 ## perform a full repository scan on each server start, this should be
89 ## set to false after first startup, to allow faster server restarts.
89 ## set to false after first startup, to allow faster server restarts.
90 initial_repo_scan = true
90 initial_repo_scan = true
91
91
92 ## uncomment and set this path to use archive download cache
92 ## uncomment and set this path to use archive download cache
93 #archive_cache_dir = /tmp/tarballcache
93 #archive_cache_dir = /tmp/tarballcache
94
94
95 ## change this to unique ID for security
95 ## change this to unique ID for security
96 app_instance_uuid = rc-production
96 app_instance_uuid = rc-production
97
97
98 ## cut off limit for large diffs (size in bytes)
98 ## cut off limit for large diffs (size in bytes)
99 cut_off_limit = 256000
99 cut_off_limit = 256000
100
100
101 ## use cache version of scm repo everywhere
101 ## use cache version of scm repo everywhere
102 vcs_full_cache = true
102 vcs_full_cache = true
103
103
104 ## force https in RhodeCode, fixes https redirects, assumes it's always https
104 ## force https in RhodeCode, fixes https redirects, assumes it's always https
105 force_https = false
105 force_https = false
106
106
107 ## use Strict-Transport-Security headers
107 ## use Strict-Transport-Security headers
108 use_htsts = false
108 use_htsts = false
109
109
110 ## number of commits stats will parse on each iteration
110 ## number of commits stats will parse on each iteration
111 commit_parse_limit = 25
111 commit_parse_limit = 25
112
112
113 ## use gravatar service to display avatars
113 ## use gravatar service to display avatars
114 use_gravatar = true
114 use_gravatar = true
115
115
116 ## path to git executable
116 ## path to git executable
117 git_path = git
117 git_path = git
118
118
119 ## git rev filter option, --all is the default filter, if you need to
119 ## git rev filter option, --all is the default filter, if you need to
120 ## hide all refs in changelog switch this to --branches --tags
120 ## hide all refs in changelog switch this to --branches --tags
121 git_rev_filter=--all
121 git_rev_filter=--all
122
122
123 ## RSS feed options
123 ## RSS feed options
124 rss_cut_off_limit = 256000
124 rss_cut_off_limit = 256000
125 rss_items_per_page = 10
125 rss_items_per_page = 10
126 rss_include_diff = false
126 rss_include_diff = false
127
127
128 ## options for showing and identifying changesets
128 ## options for showing and identifying changesets
129 show_sha_length = 12
129 show_sha_length = 12
130 show_revision_number = true
130 show_revision_number = true
131
131
132 ## gist URL alias, used to create nicer urls for gist. This should be an
132 ## gist URL alias, used to create nicer urls for gist. This should be an
133 ## url that does rewrites to _admin/gists/<gistid>.
133 ## url that does rewrites to _admin/gists/<gistid>.
134 ## example: http://gist.rhodecode.org/{gistid}. Empty means use the internal
134 ## example: http://gist.rhodecode.org/{gistid}. Empty means use the internal
135 ## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/<gistid>
135 ## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/<gistid>
136 gist_alias_url =
136 gist_alias_url =
137
137
138 ## white list of API enabled controllers. This allows to add list of
138 ## white list of API enabled controllers. This allows to add list of
139 ## controllers to which access will be enabled by api_key. eg: to enable
139 ## controllers to which access will be enabled by api_key. eg: to enable
140 ## api access to raw_files put `FilesController:raw`, to enable access to patches
140 ## api access to raw_files put `FilesController:raw`, to enable access to patches
141 ## add `ChangesetController:changeset_patch`. This list should be "," separated
141 ## add `ChangesetController:changeset_patch`. This list should be "," separated
142 ## Syntax is <ControllerClass>:<function>. Check debug logs for generated names
142 ## Syntax is <ControllerClass>:<function>. Check debug logs for generated names
143 api_access_controllers_whitelist =
143 api_access_controllers_whitelist =
144
144
145 ## alternative_gravatar_url allows you to use your own avatar server application
145 ## alternative_gravatar_url allows you to use your own avatar server application
146 ## the following parts of the URL will be replaced
146 ## the following parts of the URL will be replaced
147 ## {email} user email
147 ## {email} user email
148 ## {md5email} md5 hash of the user email (like at gravatar.com)
148 ## {md5email} md5 hash of the user email (like at gravatar.com)
149 ## {size} size of the image that is expected from the server application
149 ## {size} size of the image that is expected from the server application
150 ## {scheme} http/https from RhodeCode server
150 ## {scheme} http/https from RhodeCode server
151 ## {netloc} network location from RhodeCode server
151 ## {netloc} network location from RhodeCode server
152 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
152 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
153 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
153 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
154
154
155
155
156 ## container auth options
156 ## container auth options
157 container_auth_enabled = false
157 container_auth_enabled = false
158 proxypass_auth_enabled = false
158 proxypass_auth_enabled = false
159
159
160 ## default encoding used to convert from and to unicode
160 ## default encoding used to convert from and to unicode
161 ## can be also a comma seperated list of encoding in case of mixed encodings
161 ## can be also a comma seperated list of encoding in case of mixed encodings
162 default_encoding = utf8
162 default_encoding = utf8
163
163
164 ## overwrite schema of clone url
164 ## overwrite schema of clone url
165 ## available vars:
165 ## available vars:
166 ## scheme - http/https
166 ## scheme - http/https
167 ## user - current user
167 ## user - current user
168 ## pass - password
168 ## pass - password
169 ## netloc - network location
169 ## netloc - network location
170 ## path - usually repo_name
170 ## path - usually repo_name
171
171
172 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
172 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
173
173
174 ## issue tracker RhodeCode (leave blank to disable, absent for default)
174 ## issue tracker for RhodeCode (leave blank to disable, absent for default)
175 #bugtracker = http://bitbucket.org/marcinkuzminski/rhodecode/issues
175 #bugtracker = http://bitbucket.org/marcinkuzminski/rhodecode/issues
176
176
177 ## issue tracking mapping for commits messages
177 ## issue tracking mapping for commits messages
178 ## comment out issue_pat, issue_server, issue_prefix to enable
178 ## comment out issue_pat, issue_server, issue_prefix to enable
179
179
180 ## pattern to get the issues from commit messages
180 ## pattern to get the issues from commit messages
181 ## default one used here is #<numbers> with a regex passive group for `#`
181 ## default one used here is #<numbers> with a regex passive group for `#`
182 ## {id} will be all groups matched from this pattern
182 ## {id} will be all groups matched from this pattern
183
183
184 issue_pat = (?:\s*#)(\d+)
184 issue_pat = (?:\s*#)(\d+)
185
185
186 ## server url to the issue, each {id} will be replaced with match
186 ## server url to the issue, each {id} will be replaced with match
187 ## fetched from the regex and {repo} is replaced with full repository name
187 ## fetched from the regex and {repo} is replaced with full repository name
188 ## including groups {repo_name} is replaced with just name of repo
188 ## including groups {repo_name} is replaced with just name of repo
189
189
190 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
190 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
191
191
192 ## prefix to add to link to indicate it's an url
192 ## prefix to add to link to indicate it's an url
193 ## #314 will be replaced by <issue_prefix><id>
193 ## #314 will be replaced by <issue_prefix><id>
194
194
195 issue_prefix = #
195 issue_prefix = #
196
196
197 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
197 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
198 ## multiple patterns, to other issues server, wiki or others
198 ## multiple patterns, to other issues server, wiki or others
199 ## below an example how to create a wiki pattern
199 ## below an example how to create a wiki pattern
200 # #wiki-some-id -> https://mywiki.com/some-id
200 # #wiki-some-id -> https://mywiki.com/some-id
201
201
202 #issue_pat_wiki = (?:wiki-)(.+)
202 #issue_pat_wiki = (?:wiki-)(.+)
203 #issue_server_link_wiki = https://mywiki.com/{id}
203 #issue_server_link_wiki = https://mywiki.com/{id}
204 #issue_prefix_wiki = WIKI-
204 #issue_prefix_wiki = WIKI-
205
205
206
206
207 ## instance-id prefix
207 ## instance-id prefix
208 ## a prefix key for this instance used for cache invalidation when running
208 ## a prefix key for this instance used for cache invalidation when running
209 ## multiple instances of rhodecode, make sure it's globally unique for
209 ## multiple instances of rhodecode, make sure it's globally unique for
210 ## all running rhodecode instances. Leave empty if you don't use it
210 ## all running rhodecode instances. Leave empty if you don't use it
211 instance_id =
211 instance_id =
212
212
213 ## alternative return HTTP header for failed authentication. Default HTTP
213 ## alternative return HTTP header for failed authentication. Default HTTP
214 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
214 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
215 ## handling that. Set this variable to 403 to return HTTPForbidden
215 ## handling that. Set this variable to 403 to return HTTPForbidden
216 auth_ret_code =
216 auth_ret_code =
217
217
218 ## locking return code. When repository is locked return this HTTP code. 2XX
218 ## locking return code. When repository is locked return this HTTP code. 2XX
219 ## codes don't break the transactions while 4XX codes do
219 ## codes don't break the transactions while 4XX codes do
220 lock_ret_code = 423
220 lock_ret_code = 423
221
221
222 ## allows to change the repository location in settings page
222 allow_repo_location_change = True
223 allow_repo_location_change = True
223
224
225 ## allows to setup custom hooks in settings page
226 allow_custom_hooks_settings = True
227
228
224 ####################################
229 ####################################
225 ### CELERY CONFIG ####
230 ### CELERY CONFIG ####
226 ####################################
231 ####################################
227 use_celery = false
232 use_celery = false
228 broker.host = localhost
233 broker.host = localhost
229 broker.vhost = rabbitmqhost
234 broker.vhost = rabbitmqhost
230 broker.port = 5672
235 broker.port = 5672
231 broker.user = rabbitmq
236 broker.user = rabbitmq
232 broker.password = qweqwe
237 broker.password = qweqwe
233
238
234 celery.imports = rhodecode.lib.celerylib.tasks
239 celery.imports = rhodecode.lib.celerylib.tasks
235
240
236 celery.result.backend = amqp
241 celery.result.backend = amqp
237 celery.result.dburi = amqp://
242 celery.result.dburi = amqp://
238 celery.result.serialier = json
243 celery.result.serialier = json
239
244
240 #celery.send.task.error.emails = true
245 #celery.send.task.error.emails = true
241 #celery.amqp.task.result.expires = 18000
246 #celery.amqp.task.result.expires = 18000
242
247
243 celeryd.concurrency = 2
248 celeryd.concurrency = 2
244 #celeryd.log.file = celeryd.log
249 #celeryd.log.file = celeryd.log
245 celeryd.log.level = debug
250 celeryd.log.level = debug
246 celeryd.max.tasks.per.child = 1
251 celeryd.max.tasks.per.child = 1
247
252
248 ## tasks will never be sent to the queue, but executed locally instead.
253 ## tasks will never be sent to the queue, but executed locally instead.
249 celery.always.eager = false
254 celery.always.eager = false
250
255
251 ####################################
256 ####################################
252 ### BEAKER CACHE ####
257 ### BEAKER CACHE ####
253 ####################################
258 ####################################
254 beaker.cache.data_dir=%(here)s/data/cache/data
259 beaker.cache.data_dir=%(here)s/data/cache/data
255 beaker.cache.lock_dir=%(here)s/data/cache/lock
260 beaker.cache.lock_dir=%(here)s/data/cache/lock
256
261
257 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
262 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
258
263
259 beaker.cache.super_short_term.type=memory
264 beaker.cache.super_short_term.type=memory
260 beaker.cache.super_short_term.expire=10
265 beaker.cache.super_short_term.expire=10
261 beaker.cache.super_short_term.key_length = 256
266 beaker.cache.super_short_term.key_length = 256
262
267
263 beaker.cache.short_term.type=memory
268 beaker.cache.short_term.type=memory
264 beaker.cache.short_term.expire=60
269 beaker.cache.short_term.expire=60
265 beaker.cache.short_term.key_length = 256
270 beaker.cache.short_term.key_length = 256
266
271
267 beaker.cache.long_term.type=memory
272 beaker.cache.long_term.type=memory
268 beaker.cache.long_term.expire=36000
273 beaker.cache.long_term.expire=36000
269 beaker.cache.long_term.key_length = 256
274 beaker.cache.long_term.key_length = 256
270
275
271 beaker.cache.sql_cache_short.type=memory
276 beaker.cache.sql_cache_short.type=memory
272 beaker.cache.sql_cache_short.expire=10
277 beaker.cache.sql_cache_short.expire=10
273 beaker.cache.sql_cache_short.key_length = 256
278 beaker.cache.sql_cache_short.key_length = 256
274
279
275 beaker.cache.sql_cache_med.type=memory
280 beaker.cache.sql_cache_med.type=memory
276 beaker.cache.sql_cache_med.expire=360
281 beaker.cache.sql_cache_med.expire=360
277 beaker.cache.sql_cache_med.key_length = 256
282 beaker.cache.sql_cache_med.key_length = 256
278
283
279 beaker.cache.sql_cache_long.type=file
284 beaker.cache.sql_cache_long.type=file
280 beaker.cache.sql_cache_long.expire=3600
285 beaker.cache.sql_cache_long.expire=3600
281 beaker.cache.sql_cache_long.key_length = 256
286 beaker.cache.sql_cache_long.key_length = 256
282
287
283 ####################################
288 ####################################
284 ### BEAKER SESSION ####
289 ### BEAKER SESSION ####
285 ####################################
290 ####################################
286 ## Type of storage used for the session, current types are
291 ## Type of storage used for the session, current types are
287 ## dbm, file, memcached, database, and memory.
292 ## dbm, file, memcached, database, and memory.
288 ## The storage uses the Container API
293 ## The storage uses the Container API
289 ## that is also used by the cache system.
294 ## that is also used by the cache system.
290
295
291 ## db session ##
296 ## db session ##
292 #beaker.session.type = ext:database
297 #beaker.session.type = ext:database
293 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
298 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
294 #beaker.session.table_name = db_session
299 #beaker.session.table_name = db_session
295
300
296 ## encrypted cookie client side session, good for many instances ##
301 ## encrypted cookie client side session, good for many instances ##
297 #beaker.session.type = cookie
302 #beaker.session.type = cookie
298
303
299 ## file based cookies (default) ##
304 ## file based cookies (default) ##
300 #beaker.session.type = file
305 #beaker.session.type = file
301
306
302 beaker.session.key = rhodecode
307 beaker.session.key = rhodecode
303 beaker.session.secret = ${app_instance_uuid}
308 beaker.session.secret = ${app_instance_uuid}
304
309
305 ## Secure encrypted cookie. Requires AES and AES python libraries
310 ## Secure encrypted cookie. Requires AES and AES python libraries
306 ## you must disable beaker.session.secret to use this
311 ## you must disable beaker.session.secret to use this
307 #beaker.session.encrypt_key = <key_for_encryption>
312 #beaker.session.encrypt_key = <key_for_encryption>
308 #beaker.session.validate_key = <validation_key>
313 #beaker.session.validate_key = <validation_key>
309
314
310 ## sets session as invalid if it haven't been accessed for given amount of time
315 ## sets session as invalid if it haven't been accessed for given amount of time
311 beaker.session.timeout = 2592000
316 beaker.session.timeout = 2592000
312 beaker.session.httponly = true
317 beaker.session.httponly = true
313 #beaker.session.cookie_path = /<your-prefix>
318 #beaker.session.cookie_path = /<your-prefix>
314
319
315 ## uncomment for https secure cookie
320 ## uncomment for https secure cookie
316 beaker.session.secure = false
321 beaker.session.secure = false
317
322
318 ## auto save the session to not to use .save()
323 ## auto save the session to not to use .save()
319 beaker.session.auto = False
324 beaker.session.auto = False
320
325
321 ## default cookie expiration time in seconds `true` expire at browser close ##
326 ## default cookie expiration time in seconds `true` expire at browser close ##
322 #beaker.session.cookie_expires = 3600
327 #beaker.session.cookie_expires = 3600
323
328
324
329
325 ############################
330 ############################
326 ## ERROR HANDLING SYSTEMS ##
331 ## ERROR HANDLING SYSTEMS ##
327 ############################
332 ############################
328
333
329 ####################
334 ####################
330 ### [errormator] ###
335 ### [errormator] ###
331 ####################
336 ####################
332
337
333 ## Errormator is tailored to work with RhodeCode, see
338 ## Errormator is tailored to work with RhodeCode, see
334 ## http://errormator.com for details how to obtain an account
339 ## http://errormator.com for details how to obtain an account
335 ## you must install python package `errormator_client` to make it work
340 ## you must install python package `errormator_client` to make it work
336
341
337 ## errormator enabled
342 ## errormator enabled
338 errormator = false
343 errormator = false
339
344
340 errormator.server_url = https://api.errormator.com
345 errormator.server_url = https://api.errormator.com
341 errormator.api_key = YOUR_API_KEY
346 errormator.api_key = YOUR_API_KEY
342
347
343 ## TWEAK AMOUNT OF INFO SENT HERE
348 ## TWEAK AMOUNT OF INFO SENT HERE
344
349
345 ## enables 404 error logging (default False)
350 ## enables 404 error logging (default False)
346 errormator.report_404 = false
351 errormator.report_404 = false
347
352
348 ## time in seconds after request is considered being slow (default 1)
353 ## time in seconds after request is considered being slow (default 1)
349 errormator.slow_request_time = 1
354 errormator.slow_request_time = 1
350
355
351 ## record slow requests in application
356 ## record slow requests in application
352 ## (needs to be enabled for slow datastore recording and time tracking)
357 ## (needs to be enabled for slow datastore recording and time tracking)
353 errormator.slow_requests = true
358 errormator.slow_requests = true
354
359
355 ## enable hooking to application loggers
360 ## enable hooking to application loggers
356 # errormator.logging = true
361 # errormator.logging = true
357
362
358 ## minimum log level for log capture
363 ## minimum log level for log capture
359 # errormator.logging.level = WARNING
364 # errormator.logging.level = WARNING
360
365
361 ## send logs only from erroneous/slow requests
366 ## send logs only from erroneous/slow requests
362 ## (saves API quota for intensive logging)
367 ## (saves API quota for intensive logging)
363 errormator.logging_on_error = false
368 errormator.logging_on_error = false
364
369
365 ## list of additonal keywords that should be grabbed from environ object
370 ## list of additonal keywords that should be grabbed from environ object
366 ## can be string with comma separated list of words in lowercase
371 ## can be string with comma separated list of words in lowercase
367 ## (by default client will always send following info:
372 ## (by default client will always send following info:
368 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
373 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
369 ## start with HTTP* this list be extended with additional keywords here
374 ## start with HTTP* this list be extended with additional keywords here
370 errormator.environ_keys_whitelist =
375 errormator.environ_keys_whitelist =
371
376
372
377
373 ## list of keywords that should be blanked from request object
378 ## list of keywords that should be blanked from request object
374 ## can be string with comma separated list of words in lowercase
379 ## can be string with comma separated list of words in lowercase
375 ## (by default client will always blank keys that contain following words
380 ## (by default client will always blank keys that contain following words
376 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
381 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
377 ## this list be extended with additional keywords set here
382 ## this list be extended with additional keywords set here
378 errormator.request_keys_blacklist =
383 errormator.request_keys_blacklist =
379
384
380
385
381 ## list of namespaces that should be ignores when gathering log entries
386 ## list of namespaces that should be ignores when gathering log entries
382 ## can be string with comma separated list of namespaces
387 ## can be string with comma separated list of namespaces
383 ## (by default the client ignores own entries: errormator_client.client)
388 ## (by default the client ignores own entries: errormator_client.client)
384 errormator.log_namespace_blacklist =
389 errormator.log_namespace_blacklist =
385
390
386
391
387 ################
392 ################
388 ### [sentry] ###
393 ### [sentry] ###
389 ################
394 ################
390
395
391 ## sentry is a alternative open source error aggregator
396 ## sentry is a alternative open source error aggregator
392 ## you must install python packages `sentry` and `raven` to enable
397 ## you must install python packages `sentry` and `raven` to enable
393
398
394 sentry.dsn = YOUR_DNS
399 sentry.dsn = YOUR_DNS
395 sentry.servers =
400 sentry.servers =
396 sentry.name =
401 sentry.name =
397 sentry.key =
402 sentry.key =
398 sentry.public_key =
403 sentry.public_key =
399 sentry.secret_key =
404 sentry.secret_key =
400 sentry.project =
405 sentry.project =
401 sentry.site =
406 sentry.site =
402 sentry.include_paths =
407 sentry.include_paths =
403 sentry.exclude_paths =
408 sentry.exclude_paths =
404
409
405
410
406 ################################################################################
411 ################################################################################
407 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
412 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
408 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
413 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
409 ## execute malicious code after an exception is raised. ##
414 ## execute malicious code after an exception is raised. ##
410 ################################################################################
415 ################################################################################
411 #set debug = false
416 #set debug = false
412
417
413 ##################################
418 ##################################
414 ### LOGVIEW CONFIG ###
419 ### LOGVIEW CONFIG ###
415 ##################################
420 ##################################
416 logview.sqlalchemy = #faa
421 logview.sqlalchemy = #faa
417 logview.pylons.templating = #bfb
422 logview.pylons.templating = #bfb
418 logview.pylons.util = #eee
423 logview.pylons.util = #eee
419
424
420 #########################################################
425 #########################################################
421 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
426 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
422 #########################################################
427 #########################################################
423 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
428 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
424 sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode
429 sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode
425 sqlalchemy.db1.echo = false
430 sqlalchemy.db1.echo = false
426 sqlalchemy.db1.pool_recycle = 3600
431 sqlalchemy.db1.pool_recycle = 3600
427 sqlalchemy.db1.convert_unicode = true
432 sqlalchemy.db1.convert_unicode = true
428
433
429 ################################
434 ################################
430 ### LOGGING CONFIGURATION ####
435 ### LOGGING CONFIGURATION ####
431 ################################
436 ################################
432 [loggers]
437 [loggers]
433 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
438 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
434
439
435 [handlers]
440 [handlers]
436 keys = console, console_sql
441 keys = console, console_sql
437
442
438 [formatters]
443 [formatters]
439 keys = generic, color_formatter, color_formatter_sql
444 keys = generic, color_formatter, color_formatter_sql
440
445
441 #############
446 #############
442 ## LOGGERS ##
447 ## LOGGERS ##
443 #############
448 #############
444 [logger_root]
449 [logger_root]
445 level = NOTSET
450 level = NOTSET
446 handlers = console
451 handlers = console
447
452
448 [logger_routes]
453 [logger_routes]
449 level = DEBUG
454 level = DEBUG
450 handlers =
455 handlers =
451 qualname = routes.middleware
456 qualname = routes.middleware
452 ## "level = DEBUG" logs the route matched and routing variables.
457 ## "level = DEBUG" logs the route matched and routing variables.
453 propagate = 1
458 propagate = 1
454
459
455 [logger_beaker]
460 [logger_beaker]
456 level = DEBUG
461 level = DEBUG
457 handlers =
462 handlers =
458 qualname = beaker.container
463 qualname = beaker.container
459 propagate = 1
464 propagate = 1
460
465
461 [logger_templates]
466 [logger_templates]
462 level = INFO
467 level = INFO
463 handlers =
468 handlers =
464 qualname = pylons.templating
469 qualname = pylons.templating
465 propagate = 1
470 propagate = 1
466
471
467 [logger_rhodecode]
472 [logger_rhodecode]
468 level = DEBUG
473 level = DEBUG
469 handlers =
474 handlers =
470 qualname = rhodecode
475 qualname = rhodecode
471 propagate = 1
476 propagate = 1
472
477
473 [logger_sqlalchemy]
478 [logger_sqlalchemy]
474 level = INFO
479 level = INFO
475 handlers = console_sql
480 handlers = console_sql
476 qualname = sqlalchemy.engine
481 qualname = sqlalchemy.engine
477 propagate = 0
482 propagate = 0
478
483
479 [logger_whoosh_indexer]
484 [logger_whoosh_indexer]
480 level = DEBUG
485 level = DEBUG
481 handlers =
486 handlers =
482 qualname = whoosh_indexer
487 qualname = whoosh_indexer
483 propagate = 1
488 propagate = 1
484
489
485 ##############
490 ##############
486 ## HANDLERS ##
491 ## HANDLERS ##
487 ##############
492 ##############
488
493
489 [handler_console]
494 [handler_console]
490 class = StreamHandler
495 class = StreamHandler
491 args = (sys.stderr,)
496 args = (sys.stderr,)
492 level = DEBUG
497 level = DEBUG
493 formatter = color_formatter
498 formatter = color_formatter
494
499
495 [handler_console_sql]
500 [handler_console_sql]
496 class = StreamHandler
501 class = StreamHandler
497 args = (sys.stderr,)
502 args = (sys.stderr,)
498 level = DEBUG
503 level = DEBUG
499 formatter = color_formatter_sql
504 formatter = color_formatter_sql
500
505
501 ################
506 ################
502 ## FORMATTERS ##
507 ## FORMATTERS ##
503 ################
508 ################
504
509
505 [formatter_generic]
510 [formatter_generic]
506 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
511 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
507 datefmt = %Y-%m-%d %H:%M:%S
512 datefmt = %Y-%m-%d %H:%M:%S
508
513
509 [formatter_color_formatter]
514 [formatter_color_formatter]
510 class=rhodecode.lib.colored_formatter.ColorFormatter
515 class=rhodecode.lib.colored_formatter.ColorFormatter
511 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
516 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
512 datefmt = %Y-%m-%d %H:%M:%S
517 datefmt = %Y-%m-%d %H:%M:%S
513
518
514 [formatter_color_formatter_sql]
519 [formatter_color_formatter_sql]
515 class=rhodecode.lib.colored_formatter.ColorFormatterSql
520 class=rhodecode.lib.colored_formatter.ColorFormatterSql
516 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
521 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
517 datefmt = %Y-%m-%d %H:%M:%S
522 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,517 +1,522 b''
1 ################################################################################
1 ################################################################################
2 ################################################################################
2 ################################################################################
3 # RhodeCode - Pylons environment configuration #
3 # RhodeCode - Pylons environment configuration #
4 # #
4 # #
5 # The %(here)s variable will be replaced with the parent directory of this file#
5 # The %(here)s variable will be replaced with the parent directory of this file#
6 ################################################################################
6 ################################################################################
7
7
8 [DEFAULT]
8 [DEFAULT]
9 debug = true
9 debug = true
10 pdebug = false
10 pdebug = false
11 ################################################################################
11 ################################################################################
12 ## Uncomment and replace with the address which should receive ##
12 ## Uncomment and replace with the address which should receive ##
13 ## any error reports after application crash ##
13 ## any error reports after application crash ##
14 ## Additionally those settings will be used by RhodeCode mailing system ##
14 ## Additionally those settings will be used by RhodeCode mailing system ##
15 ################################################################################
15 ################################################################################
16 #email_to = admin@localhost
16 #email_to = admin@localhost
17 #error_email_from = paste_error@localhost
17 #error_email_from = paste_error@localhost
18 #app_email_from = rhodecode-noreply@localhost
18 #app_email_from = rhodecode-noreply@localhost
19 #error_message =
19 #error_message =
20 #email_prefix = [RhodeCode]
20 #email_prefix = [RhodeCode]
21
21
22 #smtp_server = mail.server.com
22 #smtp_server = mail.server.com
23 #smtp_username =
23 #smtp_username =
24 #smtp_password =
24 #smtp_password =
25 #smtp_port =
25 #smtp_port =
26 #smtp_use_tls = false
26 #smtp_use_tls = false
27 #smtp_use_ssl = true
27 #smtp_use_ssl = true
28 ## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.)
28 ## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.)
29 #smtp_auth =
29 #smtp_auth =
30
30
31 [server:main]
31 [server:main]
32 ## PASTE ##
32 ## PASTE ##
33 #use = egg:Paste#http
33 #use = egg:Paste#http
34 ## nr of worker threads to spawn
34 ## nr of worker threads to spawn
35 #threadpool_workers = 5
35 #threadpool_workers = 5
36 ## max request before thread respawn
36 ## max request before thread respawn
37 #threadpool_max_requests = 10
37 #threadpool_max_requests = 10
38 ## option to use threads of process
38 ## option to use threads of process
39 #use_threadpool = true
39 #use_threadpool = true
40
40
41 ## WAITRESS ##
41 ## WAITRESS ##
42 use = egg:waitress#main
42 use = egg:waitress#main
43 ## number of worker threads
43 ## number of worker threads
44 threads = 5
44 threads = 5
45 ## MAX BODY SIZE 100GB
45 ## MAX BODY SIZE 100GB
46 max_request_body_size = 107374182400
46 max_request_body_size = 107374182400
47 ## use poll instead of select, fixes fd limits, may not work on old
47 ## use poll instead of select, fixes fd limits, may not work on old
48 ## windows systems.
48 ## windows systems.
49 #asyncore_use_poll = True
49 #asyncore_use_poll = True
50
50
51 ## GUNICORN ##
51 ## GUNICORN ##
52 #use = egg:gunicorn#main
52 #use = egg:gunicorn#main
53 ## number of process workers. You must set `instance_id = *` when this option
53 ## number of process workers. You must set `instance_id = *` when this option
54 ## is set to more than one worker
54 ## is set to more than one worker
55 #workers = 1
55 #workers = 1
56 ## process name
56 ## process name
57 #proc_name = rhodecode
57 #proc_name = rhodecode
58 ## type of worker class, one of sync, eventlet, gevent, tornado
58 ## type of worker class, one of sync, eventlet, gevent, tornado
59 ## recommended for bigger setup is using of of other than sync one
59 ## recommended for bigger setup is using of of other than sync one
60 #worker_class = sync
60 #worker_class = sync
61 #max_requests = 5
61 #max_requests = 5
62 ## ammount of time a worker can handle request before it get's killed and
62 ## ammount of time a worker can handle request before it get's killed and
63 ## restarted
63 ## restarted
64 #timeout = 3600
64 #timeout = 3600
65
65
66 ## COMMON ##
66 ## COMMON ##
67 host = 127.0.0.1
67 host = 127.0.0.1
68 port = 5000
68 port = 5000
69
69
70 ## prefix middleware for rc
70 ## prefix middleware for rc
71 #[filter:proxy-prefix]
71 #[filter:proxy-prefix]
72 #use = egg:PasteDeploy#prefix
72 #use = egg:PasteDeploy#prefix
73 #prefix = /<your-prefix>
73 #prefix = /<your-prefix>
74
74
75 [app:main]
75 [app:main]
76 use = egg:rhodecode
76 use = egg:rhodecode
77 ## enable proxy prefix middleware
77 ## enable proxy prefix middleware
78 #filter-with = proxy-prefix
78 #filter-with = proxy-prefix
79
79
80 full_stack = true
80 full_stack = true
81 static_files = true
81 static_files = true
82 ## Optional Languages
82 ## Optional Languages
83 ## en, fr, ja, pt_BR, zh_CN, zh_TW, pl
83 ## en, fr, ja, pt_BR, zh_CN, zh_TW, pl
84 lang = en
84 lang = en
85 cache_dir = %(here)s/data
85 cache_dir = %(here)s/data
86 index_dir = %(here)s/data/index
86 index_dir = %(here)s/data/index
87
87
88 ## perform a full repository scan on each server start, this should be
88 ## perform a full repository scan on each server start, this should be
89 ## set to false after first startup, to allow faster server restarts.
89 ## set to false after first startup, to allow faster server restarts.
90 initial_repo_scan = true
90 initial_repo_scan = true
91
91
92 ## uncomment and set this path to use archive download cache
92 ## uncomment and set this path to use archive download cache
93 #archive_cache_dir = /tmp/tarballcache
93 #archive_cache_dir = /tmp/tarballcache
94
94
95 ## change this to unique ID for security
95 ## change this to unique ID for security
96 app_instance_uuid = rc-production
96 app_instance_uuid = rc-production
97
97
98 ## cut off limit for large diffs (size in bytes)
98 ## cut off limit for large diffs (size in bytes)
99 cut_off_limit = 256000
99 cut_off_limit = 256000
100
100
101 ## use cache version of scm repo everywhere
101 ## use cache version of scm repo everywhere
102 vcs_full_cache = true
102 vcs_full_cache = true
103
103
104 ## force https in RhodeCode, fixes https redirects, assumes it's always https
104 ## force https in RhodeCode, fixes https redirects, assumes it's always https
105 force_https = false
105 force_https = false
106
106
107 ## use Strict-Transport-Security headers
107 ## use Strict-Transport-Security headers
108 use_htsts = false
108 use_htsts = false
109
109
110 ## number of commits stats will parse on each iteration
110 ## number of commits stats will parse on each iteration
111 commit_parse_limit = 25
111 commit_parse_limit = 25
112
112
113 ## use gravatar service to display avatars
113 ## use gravatar service to display avatars
114 use_gravatar = true
114 use_gravatar = true
115
115
116 ## path to git executable
116 ## path to git executable
117 git_path = git
117 git_path = git
118
118
119 ## git rev filter option, --all is the default filter, if you need to
119 ## git rev filter option, --all is the default filter, if you need to
120 ## hide all refs in changelog switch this to --branches --tags
120 ## hide all refs in changelog switch this to --branches --tags
121 git_rev_filter=--all
121 git_rev_filter=--all
122
122
123 ## RSS feed options
123 ## RSS feed options
124 rss_cut_off_limit = 256000
124 rss_cut_off_limit = 256000
125 rss_items_per_page = 10
125 rss_items_per_page = 10
126 rss_include_diff = false
126 rss_include_diff = false
127
127
128 ## options for showing and identifying changesets
128 ## options for showing and identifying changesets
129 show_sha_length = 12
129 show_sha_length = 12
130 show_revision_number = true
130 show_revision_number = true
131
131
132 ## gist URL alias, used to create nicer urls for gist. This should be an
132 ## gist URL alias, used to create nicer urls for gist. This should be an
133 ## url that does rewrites to _admin/gists/<gistid>.
133 ## url that does rewrites to _admin/gists/<gistid>.
134 ## example: http://gist.rhodecode.org/{gistid}. Empty means use the internal
134 ## example: http://gist.rhodecode.org/{gistid}. Empty means use the internal
135 ## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/<gistid>
135 ## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/<gistid>
136 gist_alias_url =
136 gist_alias_url =
137
137
138 ## white list of API enabled controllers. This allows to add list of
138 ## white list of API enabled controllers. This allows to add list of
139 ## controllers to which access will be enabled by api_key. eg: to enable
139 ## controllers to which access will be enabled by api_key. eg: to enable
140 ## api access to raw_files put `FilesController:raw`, to enable access to patches
140 ## api access to raw_files put `FilesController:raw`, to enable access to patches
141 ## add `ChangesetController:changeset_patch`. This list should be "," separated
141 ## add `ChangesetController:changeset_patch`. This list should be "," separated
142 ## Syntax is <ControllerClass>:<function>. Check debug logs for generated names
142 ## Syntax is <ControllerClass>:<function>. Check debug logs for generated names
143 api_access_controllers_whitelist =
143 api_access_controllers_whitelist =
144
144
145 ## alternative_gravatar_url allows you to use your own avatar server application
145 ## alternative_gravatar_url allows you to use your own avatar server application
146 ## the following parts of the URL will be replaced
146 ## the following parts of the URL will be replaced
147 ## {email} user email
147 ## {email} user email
148 ## {md5email} md5 hash of the user email (like at gravatar.com)
148 ## {md5email} md5 hash of the user email (like at gravatar.com)
149 ## {size} size of the image that is expected from the server application
149 ## {size} size of the image that is expected from the server application
150 ## {scheme} http/https from RhodeCode server
150 ## {scheme} http/https from RhodeCode server
151 ## {netloc} network location from RhodeCode server
151 ## {netloc} network location from RhodeCode server
152 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
152 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
153 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
153 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
154
154
155
155
156 ## container auth options
156 ## container auth options
157 container_auth_enabled = false
157 container_auth_enabled = false
158 proxypass_auth_enabled = false
158 proxypass_auth_enabled = false
159
159
160 ## default encoding used to convert from and to unicode
160 ## default encoding used to convert from and to unicode
161 ## can be also a comma seperated list of encoding in case of mixed encodings
161 ## can be also a comma seperated list of encoding in case of mixed encodings
162 default_encoding = utf8
162 default_encoding = utf8
163
163
164 ## overwrite schema of clone url
164 ## overwrite schema of clone url
165 ## available vars:
165 ## available vars:
166 ## scheme - http/https
166 ## scheme - http/https
167 ## user - current user
167 ## user - current user
168 ## pass - password
168 ## pass - password
169 ## netloc - network location
169 ## netloc - network location
170 ## path - usually repo_name
170 ## path - usually repo_name
171
171
172 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
172 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
173
173
174 ## issue tracker for RhodeCode (leave blank to disable, absent for default)
174 ## issue tracker for RhodeCode (leave blank to disable, absent for default)
175 #bugtracker = http://bitbucket.org/marcinkuzminski/rhodecode/issues
175 #bugtracker = http://bitbucket.org/marcinkuzminski/rhodecode/issues
176
176
177 ## issue tracking mapping for commits messages
177 ## issue tracking mapping for commits messages
178 ## comment out issue_pat, issue_server, issue_prefix to enable
178 ## comment out issue_pat, issue_server, issue_prefix to enable
179
179
180 ## pattern to get the issues from commit messages
180 ## pattern to get the issues from commit messages
181 ## default one used here is #<numbers> with a regex passive group for `#`
181 ## default one used here is #<numbers> with a regex passive group for `#`
182 ## {id} will be all groups matched from this pattern
182 ## {id} will be all groups matched from this pattern
183
183
184 issue_pat = (?:\s*#)(\d+)
184 issue_pat = (?:\s*#)(\d+)
185
185
186 ## server url to the issue, each {id} will be replaced with match
186 ## server url to the issue, each {id} will be replaced with match
187 ## fetched from the regex and {repo} is replaced with full repository name
187 ## fetched from the regex and {repo} is replaced with full repository name
188 ## including groups {repo_name} is replaced with just name of repo
188 ## including groups {repo_name} is replaced with just name of repo
189
189
190 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
190 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
191
191
192 ## prefix to add to link to indicate it's an url
192 ## prefix to add to link to indicate it's an url
193 ## #314 will be replaced by <issue_prefix><id>
193 ## #314 will be replaced by <issue_prefix><id>
194
194
195 issue_prefix = #
195 issue_prefix = #
196
196
197 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
197 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
198 ## multiple patterns, to other issues server, wiki or others
198 ## multiple patterns, to other issues server, wiki or others
199 ## below an example how to create a wiki pattern
199 ## below an example how to create a wiki pattern
200 # #wiki-some-id -> https://mywiki.com/some-id
200 # #wiki-some-id -> https://mywiki.com/some-id
201
201
202 #issue_pat_wiki = (?:wiki-)(.+)
202 #issue_pat_wiki = (?:wiki-)(.+)
203 #issue_server_link_wiki = https://mywiki.com/{id}
203 #issue_server_link_wiki = https://mywiki.com/{id}
204 #issue_prefix_wiki = WIKI-
204 #issue_prefix_wiki = WIKI-
205
205
206
206
207 ## instance-id prefix
207 ## instance-id prefix
208 ## a prefix key for this instance used for cache invalidation when running
208 ## a prefix key for this instance used for cache invalidation when running
209 ## multiple instances of rhodecode, make sure it's globally unique for
209 ## multiple instances of rhodecode, make sure it's globally unique for
210 ## all running rhodecode instances. Leave empty if you don't use it
210 ## all running rhodecode instances. Leave empty if you don't use it
211 instance_id =
211 instance_id =
212
212
213 ## alternative return HTTP header for failed authentication. Default HTTP
213 ## alternative return HTTP header for failed authentication. Default HTTP
214 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
214 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
215 ## handling that. Set this variable to 403 to return HTTPForbidden
215 ## handling that. Set this variable to 403 to return HTTPForbidden
216 auth_ret_code =
216 auth_ret_code =
217
217
218 ## locking return code. When repository is locked return this HTTP code. 2XX
218 ## locking return code. When repository is locked return this HTTP code. 2XX
219 ## codes don't break the transactions while 4XX codes do
219 ## codes don't break the transactions while 4XX codes do
220 lock_ret_code = 423
220 lock_ret_code = 423
221
221
222 ## allows to change the repository location in settings page
222 allow_repo_location_change = True
223 allow_repo_location_change = True
223
224
225 ## allows to setup custom hooks in settings page
226 allow_custom_hooks_settings = True
227
228
224 ####################################
229 ####################################
225 ### CELERY CONFIG ####
230 ### CELERY CONFIG ####
226 ####################################
231 ####################################
227 use_celery = false
232 use_celery = false
228 broker.host = localhost
233 broker.host = localhost
229 broker.vhost = rabbitmqhost
234 broker.vhost = rabbitmqhost
230 broker.port = 5672
235 broker.port = 5672
231 broker.user = rabbitmq
236 broker.user = rabbitmq
232 broker.password = qweqwe
237 broker.password = qweqwe
233
238
234 celery.imports = rhodecode.lib.celerylib.tasks
239 celery.imports = rhodecode.lib.celerylib.tasks
235
240
236 celery.result.backend = amqp
241 celery.result.backend = amqp
237 celery.result.dburi = amqp://
242 celery.result.dburi = amqp://
238 celery.result.serialier = json
243 celery.result.serialier = json
239
244
240 #celery.send.task.error.emails = true
245 #celery.send.task.error.emails = true
241 #celery.amqp.task.result.expires = 18000
246 #celery.amqp.task.result.expires = 18000
242
247
243 celeryd.concurrency = 2
248 celeryd.concurrency = 2
244 #celeryd.log.file = celeryd.log
249 #celeryd.log.file = celeryd.log
245 celeryd.log.level = debug
250 celeryd.log.level = debug
246 celeryd.max.tasks.per.child = 1
251 celeryd.max.tasks.per.child = 1
247
252
248 ## tasks will never be sent to the queue, but executed locally instead.
253 ## tasks will never be sent to the queue, but executed locally instead.
249 celery.always.eager = false
254 celery.always.eager = false
250
255
251 ####################################
256 ####################################
252 ### BEAKER CACHE ####
257 ### BEAKER CACHE ####
253 ####################################
258 ####################################
254 beaker.cache.data_dir=%(here)s/data/cache/data
259 beaker.cache.data_dir=%(here)s/data/cache/data
255 beaker.cache.lock_dir=%(here)s/data/cache/lock
260 beaker.cache.lock_dir=%(here)s/data/cache/lock
256
261
257 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
262 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
258
263
259 beaker.cache.super_short_term.type=memory
264 beaker.cache.super_short_term.type=memory
260 beaker.cache.super_short_term.expire=10
265 beaker.cache.super_short_term.expire=10
261 beaker.cache.super_short_term.key_length = 256
266 beaker.cache.super_short_term.key_length = 256
262
267
263 beaker.cache.short_term.type=memory
268 beaker.cache.short_term.type=memory
264 beaker.cache.short_term.expire=60
269 beaker.cache.short_term.expire=60
265 beaker.cache.short_term.key_length = 256
270 beaker.cache.short_term.key_length = 256
266
271
267 beaker.cache.long_term.type=memory
272 beaker.cache.long_term.type=memory
268 beaker.cache.long_term.expire=36000
273 beaker.cache.long_term.expire=36000
269 beaker.cache.long_term.key_length = 256
274 beaker.cache.long_term.key_length = 256
270
275
271 beaker.cache.sql_cache_short.type=memory
276 beaker.cache.sql_cache_short.type=memory
272 beaker.cache.sql_cache_short.expire=10
277 beaker.cache.sql_cache_short.expire=10
273 beaker.cache.sql_cache_short.key_length = 256
278 beaker.cache.sql_cache_short.key_length = 256
274
279
275 beaker.cache.sql_cache_med.type=memory
280 beaker.cache.sql_cache_med.type=memory
276 beaker.cache.sql_cache_med.expire=360
281 beaker.cache.sql_cache_med.expire=360
277 beaker.cache.sql_cache_med.key_length = 256
282 beaker.cache.sql_cache_med.key_length = 256
278
283
279 beaker.cache.sql_cache_long.type=file
284 beaker.cache.sql_cache_long.type=file
280 beaker.cache.sql_cache_long.expire=3600
285 beaker.cache.sql_cache_long.expire=3600
281 beaker.cache.sql_cache_long.key_length = 256
286 beaker.cache.sql_cache_long.key_length = 256
282
287
283 ####################################
288 ####################################
284 ### BEAKER SESSION ####
289 ### BEAKER SESSION ####
285 ####################################
290 ####################################
286 ## Type of storage used for the session, current types are
291 ## Type of storage used for the session, current types are
287 ## dbm, file, memcached, database, and memory.
292 ## dbm, file, memcached, database, and memory.
288 ## The storage uses the Container API
293 ## The storage uses the Container API
289 ## that is also used by the cache system.
294 ## that is also used by the cache system.
290
295
291 ## db session ##
296 ## db session ##
292 #beaker.session.type = ext:database
297 #beaker.session.type = ext:database
293 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
298 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
294 #beaker.session.table_name = db_session
299 #beaker.session.table_name = db_session
295
300
296 ## encrypted cookie client side session, good for many instances ##
301 ## encrypted cookie client side session, good for many instances ##
297 #beaker.session.type = cookie
302 #beaker.session.type = cookie
298
303
299 ## file based cookies (default) ##
304 ## file based cookies (default) ##
300 #beaker.session.type = file
305 #beaker.session.type = file
301
306
302 beaker.session.key = rhodecode
307 beaker.session.key = rhodecode
303 beaker.session.secret = ${app_instance_uuid}
308 beaker.session.secret = ${app_instance_uuid}
304
309
305 ## Secure encrypted cookie. Requires AES and AES python libraries
310 ## Secure encrypted cookie. Requires AES and AES python libraries
306 ## you must disable beaker.session.secret to use this
311 ## you must disable beaker.session.secret to use this
307 #beaker.session.encrypt_key = <key_for_encryption>
312 #beaker.session.encrypt_key = <key_for_encryption>
308 #beaker.session.validate_key = <validation_key>
313 #beaker.session.validate_key = <validation_key>
309
314
310 ## sets session as invalid if it haven't been accessed for given amount of time
315 ## sets session as invalid if it haven't been accessed for given amount of time
311 beaker.session.timeout = 2592000
316 beaker.session.timeout = 2592000
312 beaker.session.httponly = true
317 beaker.session.httponly = true
313 #beaker.session.cookie_path = /<your-prefix>
318 #beaker.session.cookie_path = /<your-prefix>
314
319
315 ## uncomment for https secure cookie
320 ## uncomment for https secure cookie
316 beaker.session.secure = false
321 beaker.session.secure = false
317
322
318 ## auto save the session to not to use .save()
323 ## auto save the session to not to use .save()
319 beaker.session.auto = False
324 beaker.session.auto = False
320
325
321 ## default cookie expiration time in seconds `true` expire at browser close ##
326 ## default cookie expiration time in seconds `true` expire at browser close ##
322 #beaker.session.cookie_expires = 3600
327 #beaker.session.cookie_expires = 3600
323
328
324
329
325 ############################
330 ############################
326 ## ERROR HANDLING SYSTEMS ##
331 ## ERROR HANDLING SYSTEMS ##
327 ############################
332 ############################
328
333
329 ####################
334 ####################
330 ### [errormator] ###
335 ### [errormator] ###
331 ####################
336 ####################
332
337
333 ## Errormator is tailored to work with RhodeCode, see
338 ## Errormator is tailored to work with RhodeCode, see
334 ## http://errormator.com for details how to obtain an account
339 ## http://errormator.com for details how to obtain an account
335 ## you must install python package `errormator_client` to make it work
340 ## you must install python package `errormator_client` to make it work
336
341
337 ## errormator enabled
342 ## errormator enabled
338 errormator = false
343 errormator = false
339
344
340 errormator.server_url = https://api.errormator.com
345 errormator.server_url = https://api.errormator.com
341 errormator.api_key = YOUR_API_KEY
346 errormator.api_key = YOUR_API_KEY
342
347
343 ## TWEAK AMOUNT OF INFO SENT HERE
348 ## TWEAK AMOUNT OF INFO SENT HERE
344
349
345 ## enables 404 error logging (default False)
350 ## enables 404 error logging (default False)
346 errormator.report_404 = false
351 errormator.report_404 = false
347
352
348 ## time in seconds after request is considered being slow (default 1)
353 ## time in seconds after request is considered being slow (default 1)
349 errormator.slow_request_time = 1
354 errormator.slow_request_time = 1
350
355
351 ## record slow requests in application
356 ## record slow requests in application
352 ## (needs to be enabled for slow datastore recording and time tracking)
357 ## (needs to be enabled for slow datastore recording and time tracking)
353 errormator.slow_requests = true
358 errormator.slow_requests = true
354
359
355 ## enable hooking to application loggers
360 ## enable hooking to application loggers
356 # errormator.logging = true
361 # errormator.logging = true
357
362
358 ## minimum log level for log capture
363 ## minimum log level for log capture
359 # errormator.logging.level = WARNING
364 # errormator.logging.level = WARNING
360
365
361 ## send logs only from erroneous/slow requests
366 ## send logs only from erroneous/slow requests
362 ## (saves API quota for intensive logging)
367 ## (saves API quota for intensive logging)
363 errormator.logging_on_error = false
368 errormator.logging_on_error = false
364
369
365 ## list of additonal keywords that should be grabbed from environ object
370 ## list of additonal keywords that should be grabbed from environ object
366 ## can be string with comma separated list of words in lowercase
371 ## can be string with comma separated list of words in lowercase
367 ## (by default client will always send following info:
372 ## (by default client will always send following info:
368 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
373 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
369 ## start with HTTP* this list be extended with additional keywords here
374 ## start with HTTP* this list be extended with additional keywords here
370 errormator.environ_keys_whitelist =
375 errormator.environ_keys_whitelist =
371
376
372
377
373 ## list of keywords that should be blanked from request object
378 ## list of keywords that should be blanked from request object
374 ## can be string with comma separated list of words in lowercase
379 ## can be string with comma separated list of words in lowercase
375 ## (by default client will always blank keys that contain following words
380 ## (by default client will always blank keys that contain following words
376 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
381 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
377 ## this list be extended with additional keywords set here
382 ## this list be extended with additional keywords set here
378 errormator.request_keys_blacklist =
383 errormator.request_keys_blacklist =
379
384
380
385
381 ## list of namespaces that should be ignores when gathering log entries
386 ## list of namespaces that should be ignores when gathering log entries
382 ## can be string with comma separated list of namespaces
387 ## can be string with comma separated list of namespaces
383 ## (by default the client ignores own entries: errormator_client.client)
388 ## (by default the client ignores own entries: errormator_client.client)
384 errormator.log_namespace_blacklist =
389 errormator.log_namespace_blacklist =
385
390
386
391
387 ################
392 ################
388 ### [sentry] ###
393 ### [sentry] ###
389 ################
394 ################
390
395
391 ## sentry is a alternative open source error aggregator
396 ## sentry is a alternative open source error aggregator
392 ## you must install python packages `sentry` and `raven` to enable
397 ## you must install python packages `sentry` and `raven` to enable
393
398
394 sentry.dsn = YOUR_DNS
399 sentry.dsn = YOUR_DNS
395 sentry.servers =
400 sentry.servers =
396 sentry.name =
401 sentry.name =
397 sentry.key =
402 sentry.key =
398 sentry.public_key =
403 sentry.public_key =
399 sentry.secret_key =
404 sentry.secret_key =
400 sentry.project =
405 sentry.project =
401 sentry.site =
406 sentry.site =
402 sentry.include_paths =
407 sentry.include_paths =
403 sentry.exclude_paths =
408 sentry.exclude_paths =
404
409
405
410
406 ################################################################################
411 ################################################################################
407 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
412 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
408 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
413 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
409 ## execute malicious code after an exception is raised. ##
414 ## execute malicious code after an exception is raised. ##
410 ################################################################################
415 ################################################################################
411 set debug = false
416 set debug = false
412
417
413 ##################################
418 ##################################
414 ### LOGVIEW CONFIG ###
419 ### LOGVIEW CONFIG ###
415 ##################################
420 ##################################
416 logview.sqlalchemy = #faa
421 logview.sqlalchemy = #faa
417 logview.pylons.templating = #bfb
422 logview.pylons.templating = #bfb
418 logview.pylons.util = #eee
423 logview.pylons.util = #eee
419
424
420 #########################################################
425 #########################################################
421 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
426 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
422 #########################################################
427 #########################################################
423 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
428 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
424 sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode
429 sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode
425 sqlalchemy.db1.echo = false
430 sqlalchemy.db1.echo = false
426 sqlalchemy.db1.pool_recycle = 3600
431 sqlalchemy.db1.pool_recycle = 3600
427 sqlalchemy.db1.convert_unicode = true
432 sqlalchemy.db1.convert_unicode = true
428
433
429 ################################
434 ################################
430 ### LOGGING CONFIGURATION ####
435 ### LOGGING CONFIGURATION ####
431 ################################
436 ################################
432 [loggers]
437 [loggers]
433 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
438 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
434
439
435 [handlers]
440 [handlers]
436 keys = console, console_sql
441 keys = console, console_sql
437
442
438 [formatters]
443 [formatters]
439 keys = generic, color_formatter, color_formatter_sql
444 keys = generic, color_formatter, color_formatter_sql
440
445
441 #############
446 #############
442 ## LOGGERS ##
447 ## LOGGERS ##
443 #############
448 #############
444 [logger_root]
449 [logger_root]
445 level = NOTSET
450 level = NOTSET
446 handlers = console
451 handlers = console
447
452
448 [logger_routes]
453 [logger_routes]
449 level = DEBUG
454 level = DEBUG
450 handlers =
455 handlers =
451 qualname = routes.middleware
456 qualname = routes.middleware
452 ## "level = DEBUG" logs the route matched and routing variables.
457 ## "level = DEBUG" logs the route matched and routing variables.
453 propagate = 1
458 propagate = 1
454
459
455 [logger_beaker]
460 [logger_beaker]
456 level = DEBUG
461 level = DEBUG
457 handlers =
462 handlers =
458 qualname = beaker.container
463 qualname = beaker.container
459 propagate = 1
464 propagate = 1
460
465
461 [logger_templates]
466 [logger_templates]
462 level = INFO
467 level = INFO
463 handlers =
468 handlers =
464 qualname = pylons.templating
469 qualname = pylons.templating
465 propagate = 1
470 propagate = 1
466
471
467 [logger_rhodecode]
472 [logger_rhodecode]
468 level = DEBUG
473 level = DEBUG
469 handlers =
474 handlers =
470 qualname = rhodecode
475 qualname = rhodecode
471 propagate = 1
476 propagate = 1
472
477
473 [logger_sqlalchemy]
478 [logger_sqlalchemy]
474 level = INFO
479 level = INFO
475 handlers = console_sql
480 handlers = console_sql
476 qualname = sqlalchemy.engine
481 qualname = sqlalchemy.engine
477 propagate = 0
482 propagate = 0
478
483
479 [logger_whoosh_indexer]
484 [logger_whoosh_indexer]
480 level = DEBUG
485 level = DEBUG
481 handlers =
486 handlers =
482 qualname = whoosh_indexer
487 qualname = whoosh_indexer
483 propagate = 1
488 propagate = 1
484
489
485 ##############
490 ##############
486 ## HANDLERS ##
491 ## HANDLERS ##
487 ##############
492 ##############
488
493
489 [handler_console]
494 [handler_console]
490 class = StreamHandler
495 class = StreamHandler
491 args = (sys.stderr,)
496 args = (sys.stderr,)
492 level = INFO
497 level = INFO
493 formatter = generic
498 formatter = generic
494
499
495 [handler_console_sql]
500 [handler_console_sql]
496 class = StreamHandler
501 class = StreamHandler
497 args = (sys.stderr,)
502 args = (sys.stderr,)
498 level = WARN
503 level = WARN
499 formatter = generic
504 formatter = generic
500
505
501 ################
506 ################
502 ## FORMATTERS ##
507 ## FORMATTERS ##
503 ################
508 ################
504
509
505 [formatter_generic]
510 [formatter_generic]
506 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
511 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
507 datefmt = %Y-%m-%d %H:%M:%S
512 datefmt = %Y-%m-%d %H:%M:%S
508
513
509 [formatter_color_formatter]
514 [formatter_color_formatter]
510 class=rhodecode.lib.colored_formatter.ColorFormatter
515 class=rhodecode.lib.colored_formatter.ColorFormatter
511 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
516 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
512 datefmt = %Y-%m-%d %H:%M:%S
517 datefmt = %Y-%m-%d %H:%M:%S
513
518
514 [formatter_color_formatter_sql]
519 [formatter_color_formatter_sql]
515 class=rhodecode.lib.colored_formatter.ColorFormatterSql
520 class=rhodecode.lib.colored_formatter.ColorFormatterSql
516 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
521 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
517 datefmt = %Y-%m-%d %H:%M:%S
522 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,545 +1,548 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%text>
2 <%text>
3 ################################################################################
3 ################################################################################
4 ################################################################################
4 ################################################################################
5 # RhodeCode - Example config #
5 # RhodeCode - Example config #
6 # Built-in functions and variables #
6 # Built-in functions and variables #
7 # The ${here} variable will be replaced with the parent directory of this file #
7 # The ${here} variable will be replaced with the parent directory of this file #
8 # ${uuid()} function will generate a unique hash #
8 # ${uuid()} function will generate a unique hash #
9 ################################################################################
9 ################################################################################
10 </%text>
10 </%text>
11 [DEFAULT]
11 [DEFAULT]
12 debug = true
12 debug = true
13 pdebug = false
13 pdebug = false
14 <%text>
14 <%text>
15 ################################################################################
15 ################################################################################
16 ## Uncomment and replace with the address which should receive ##
16 ## Uncomment and replace with the address which should receive ##
17 ## any error reports after application crash ##
17 ## any error reports after application crash ##
18 ## Additionally those settings will be used by RhodeCode mailing system ##
18 ## Additionally those settings will be used by RhodeCode mailing system ##
19 ################################################################################
19 ################################################################################
20 </%text>
20 </%text>
21 #email_to = admin@localhost
21 #email_to = admin@localhost
22 #error_email_from = paste_error@localhost
22 #error_email_from = paste_error@localhost
23 #app_email_from = rhodecode-noreply@localhost
23 #app_email_from = rhodecode-noreply@localhost
24 #error_message =
24 #error_message =
25 #email_prefix = [RhodeCode]
25 #email_prefix = [RhodeCode]
26
26
27 #smtp_server = mail.server.com
27 #smtp_server = mail.server.com
28 #smtp_username =
28 #smtp_username =
29 #smtp_password =
29 #smtp_password =
30 #smtp_port =
30 #smtp_port =
31 #smtp_use_tls = false
31 #smtp_use_tls = false
32 #smtp_use_ssl = true
32 #smtp_use_ssl = true
33 <%text>## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.)</%text>
33 <%text>## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.)</%text>
34 #smtp_auth =
34 #smtp_auth =
35
35
36 [server:main]
36 [server:main]
37 %if http_server == 'paste':
37 %if http_server == 'paste':
38 <%text>## PASTE ##</%text>
38 <%text>## PASTE ##</%text>
39 use = egg:Paste#http
39 use = egg:Paste#http
40 <%text>## nr of worker threads to spawn</%text>
40 <%text>## nr of worker threads to spawn</%text>
41 threadpool_workers = 5
41 threadpool_workers = 5
42 <%text>## max request before thread respawn</%text>
42 <%text>## max request before thread respawn</%text>
43 threadpool_max_requests = 10
43 threadpool_max_requests = 10
44 <%text>## option to use threads of process</%text>
44 <%text>## option to use threads of process</%text>
45 use_threadpool = true
45 use_threadpool = true
46 %endif
46 %endif
47 %if http_server == 'waitress':
47 %if http_server == 'waitress':
48 <%text>## WAITRESS ##</%text>
48 <%text>## WAITRESS ##</%text>
49 use = egg:waitress#main
49 use = egg:waitress#main
50 <%text>## number of worker threads</%text>
50 <%text>## number of worker threads</%text>
51 threads = 5
51 threads = 5
52 <%text>## MAX BODY SIZE 100GB</%text>
52 <%text>## MAX BODY SIZE 100GB</%text>
53 max_request_body_size = 107374182400
53 max_request_body_size = 107374182400
54 <%text>## use poll instead of select, fixes fd limits, may not work on old</%text>
54 <%text>## use poll instead of select, fixes fd limits, may not work on old</%text>
55 <%text>## windows systems.</%text>
55 <%text>## windows systems.</%text>
56 #asyncore_use_poll = True
56 #asyncore_use_poll = True
57 %endif
57 %endif
58 %if http_server == 'gunicorn':
58 %if http_server == 'gunicorn':
59 <%text>## GUNICORN ##</%text>
59 <%text>## GUNICORN ##</%text>
60 use = egg:gunicorn#main
60 use = egg:gunicorn#main
61 <%text>## number of process workers. You must set `instance_id = *` when this option</%text>
61 <%text>## number of process workers. You must set `instance_id = *` when this option</%text>
62 <%text>## is set to more than one worker</%text>
62 <%text>## is set to more than one worker</%text>
63 workers = 1
63 workers = 1
64 <%text>## process name</%text>
64 <%text>## process name</%text>
65 proc_name = rhodecode
65 proc_name = rhodecode
66 <%text>## type of worker class, one of sync, eventlet, gevent, tornado</%text>
66 <%text>## type of worker class, one of sync, eventlet, gevent, tornado</%text>
67 <%text>## recommended for bigger setup is using of of other than sync one</%text>
67 <%text>## recommended for bigger setup is using of of other than sync one</%text>
68 worker_class = sync
68 worker_class = sync
69 max_requests = 1000
69 max_requests = 1000
70 <%text>## ammount of time a worker can handle request before it get's killed and</%text>
70 <%text>## ammount of time a worker can handle request before it get's killed and</%text>
71 <%text>## restarted</%text>
71 <%text>## restarted</%text>
72 timeout = 3600
72 timeout = 3600
73 %endif
73 %endif
74 <%text>## COMMON ##</%text>
74 <%text>## COMMON ##</%text>
75 host = ${host}
75 host = ${host}
76 port = ${port}
76 port = ${port}
77
77
78 <%text>## prefix middleware for rc</%text>
78 <%text>## prefix middleware for rc</%text>
79 #[filter:proxy-prefix]
79 #[filter:proxy-prefix]
80 #use = egg:PasteDeploy#prefix
80 #use = egg:PasteDeploy#prefix
81 #prefix = /<your-prefix>
81 #prefix = /<your-prefix>
82
82
83 [app:main]
83 [app:main]
84 use = egg:rhodecode
84 use = egg:rhodecode
85 <%text>## enable proxy prefix middleware</%text>
85 <%text>## enable proxy prefix middleware</%text>
86 #filter-with = proxy-prefix
86 #filter-with = proxy-prefix
87
87
88 full_stack = true
88 full_stack = true
89 static_files = true
89 static_files = true
90 <%text>## Optional Languages</%text>
90 <%text>## Optional Languages</%text>
91 <%text>## en, fr, ja, pt_BR, zh_CN, zh_TW, pl, ru</%text>
91 <%text>## en, fr, ja, pt_BR, zh_CN, zh_TW, pl, ru</%text>
92 lang = ${lang}
92 lang = ${lang}
93 cache_dir = ${here}/data
93 cache_dir = ${here}/data
94 index_dir = ${here}/data/index
94 index_dir = ${here}/data/index
95
95
96 <%text>## perform a full repository scan on each server start, this should be</%text>
96 <%text>## perform a full repository scan on each server start, this should be</%text>
97 <%text>## set to false after first startup, to allow faster server restarts.</%text>
97 <%text>## set to false after first startup, to allow faster server restarts.</%text>
98 initial_repo_scan = false
98 initial_repo_scan = false
99
99
100 <%text>## uncomment and set this path to use archive download cache</%text>
100 <%text>## uncomment and set this path to use archive download cache</%text>
101 archive_cache_dir = ${here}/tarballcache
101 archive_cache_dir = ${here}/tarballcache
102
102
103 <%text>## change this to unique ID for security</%text>
103 <%text>## change this to unique ID for security</%text>
104 app_instance_uuid = ${uuid()}
104 app_instance_uuid = ${uuid()}
105
105
106 <%text>## cut off limit for large diffs (size in bytes)</%text>
106 <%text>## cut off limit for large diffs (size in bytes)</%text>
107 cut_off_limit = 256000
107 cut_off_limit = 256000
108
108
109 <%text>## use cache version of scm repo everywhere</%text>
109 <%text>## use cache version of scm repo everywhere</%text>
110 vcs_full_cache = true
110 vcs_full_cache = true
111
111
112 <%text>## force https in RhodeCode, fixes https redirects, assumes it's always https</%text>
112 <%text>## force https in RhodeCode, fixes https redirects, assumes it's always https</%text>
113 force_https = false
113 force_https = false
114
114
115 <%text>## use Strict-Transport-Security headers</%text>
115 <%text>## use Strict-Transport-Security headers</%text>
116 use_htsts = false
116 use_htsts = false
117
117
118 <%text>## number of commits stats will parse on each iteration</%text>
118 <%text>## number of commits stats will parse on each iteration</%text>
119 commit_parse_limit = 25
119 commit_parse_limit = 25
120
120
121 <%text>## use gravatar service to display avatars</%text>
121 <%text>## use gravatar service to display avatars</%text>
122 use_gravatar = true
122 use_gravatar = true
123
123
124 <%text>## path to git executable</%text>
124 <%text>## path to git executable</%text>
125 git_path = git
125 git_path = git
126
126
127 <%text>## git rev filter option, --all is the default filter, if you need to</%text>
127 <%text>## git rev filter option, --all is the default filter, if you need to</%text>
128 <%text>## hide all refs in changelog switch this to --branches --tags</%text>
128 <%text>## hide all refs in changelog switch this to --branches --tags</%text>
129 git_rev_filter=--branches --tags
129 git_rev_filter=--branches --tags
130
130
131 <%text>## RSS feed options</%text>
131 <%text>## RSS feed options</%text>
132 rss_cut_off_limit = 256000
132 rss_cut_off_limit = 256000
133 rss_items_per_page = 10
133 rss_items_per_page = 10
134 rss_include_diff = false
134 rss_include_diff = false
135
135
136 <%text>## options for showing and identifying changesets</%text>
136 <%text>## options for showing and identifying changesets</%text>
137 show_sha_length = 12
137 show_sha_length = 12
138 show_revision_number = true
138 show_revision_number = true
139
139
140 <%text>## gist URL alias, used to create nicer urls for gist. This should be an</%text>
140 <%text>## gist URL alias, used to create nicer urls for gist. This should be an</%text>
141 <%text>## url that does rewrites to _admin/gists/<gistid>.</%text>
141 <%text>## url that does rewrites to _admin/gists/<gistid>.</%text>
142 <%text>## example: http://gist.rhodecode.org/{gistid}. Empty means use the internal</%text>
142 <%text>## example: http://gist.rhodecode.org/{gistid}. Empty means use the internal</%text>
143 <%text>## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/<gistid></%text>
143 <%text>## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/<gistid></%text>
144 gist_alias_url =
144 gist_alias_url =
145
145
146 <%text>## white list of API enabled controllers. This allows to add list of</%text>
146 <%text>## white list of API enabled controllers. This allows to add list of</%text>
147 <%text>## controllers to which access will be enabled by api_key. eg: to enable</%text>
147 <%text>## controllers to which access will be enabled by api_key. eg: to enable</%text>
148 <%text>## api access to raw_files put `FilesController:raw`, to enable access to patches</%text>
148 <%text>## api access to raw_files put `FilesController:raw`, to enable access to patches</%text>
149 <%text>## add `ChangesetController:changeset_patch`. This list should be "," separated</%text>
149 <%text>## add `ChangesetController:changeset_patch`. This list should be "," separated</%text>
150 <%text>## Syntax is <ControllerClass>:<function>. Check debug logs for generated names</%text>
150 <%text>## Syntax is <ControllerClass>:<function>. Check debug logs for generated names</%text>
151 api_access_controllers_whitelist =
151 api_access_controllers_whitelist =
152
152
153 <%text>## alternative_gravatar_url allows you to use your own avatar server application</%text>
153 <%text>## alternative_gravatar_url allows you to use your own avatar server application</%text>
154 <%text>## the following parts of the URL will be replaced</%text>
154 <%text>## the following parts of the URL will be replaced</%text>
155 <%text>## {email} user email</%text>
155 <%text>## {email} user email</%text>
156 <%text>## {md5email} md5 hash of the user email (like at gravatar.com)</%text>
156 <%text>## {md5email} md5 hash of the user email (like at gravatar.com)</%text>
157 <%text>## {size} size of the image that is expected from the server application</%text>
157 <%text>## {size} size of the image that is expected from the server application</%text>
158 <%text>## {scheme} http/https from RhodeCode server</%text>
158 <%text>## {scheme} http/https from RhodeCode server</%text>
159 <%text>## {netloc} network location from RhodeCode server</%text>
159 <%text>## {netloc} network location from RhodeCode server</%text>
160 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
160 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
161 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
161 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
162
162
163
163
164 <%text>## container auth options</%text>
164 <%text>## container auth options</%text>
165 container_auth_enabled = false
165 container_auth_enabled = false
166 proxypass_auth_enabled = false
166 proxypass_auth_enabled = false
167
167
168 <%text>## default encoding used to convert from and to unicode</%text>
168 <%text>## default encoding used to convert from and to unicode</%text>
169 <%text>## can be also a comma seperated list of encoding in case of mixed encodings</%text>
169 <%text>## can be also a comma seperated list of encoding in case of mixed encodings</%text>
170 default_encoding = utf8
170 default_encoding = utf8
171
171
172 <%text>## overwrite schema of clone url</%text>
172 <%text>## overwrite schema of clone url</%text>
173 <%text>## available vars:</%text>
173 <%text>## available vars:</%text>
174 <%text>## scheme - http/https</%text>
174 <%text>## scheme - http/https</%text>
175 <%text>## user - current user</%text>
175 <%text>## user - current user</%text>
176 <%text>## pass - password</%text>
176 <%text>## pass - password</%text>
177 <%text>## netloc - network location</%text>
177 <%text>## netloc - network location</%text>
178 <%text>## path - usually repo_name</%text>
178 <%text>## path - usually repo_name</%text>
179
179
180 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
180 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
181
181
182 <%text>## issue tracker for RhodeCode (leave blank to disable, absent for default)</%text>
182 <%text>## issue tracker for RhodeCode (leave blank to disable, absent for default)</%text>
183 #bugtracker = http://bitbucket.org/marcinkuzminski/rhodecode/issues
183 #bugtracker = http://bitbucket.org/marcinkuzminski/rhodecode/issues
184
184
185 <%text>## issue tracking mapping for commits messages</%text>
185 <%text>## issue tracking mapping for commits messages</%text>
186 <%text>## comment out issue_pat, issue_server, issue_prefix to enable</%text>
186 <%text>## comment out issue_pat, issue_server, issue_prefix to enable</%text>
187
187
188 <%text>## pattern to get the issues from commit messages</%text>
188 <%text>## pattern to get the issues from commit messages</%text>
189 <%text>## default one used here is #<numbers> with a regex passive group for `#`</%text>
189 <%text>## default one used here is #<numbers> with a regex passive group for `#`</%text>
190 <%text>## {id} will be all groups matched from this pattern</%text>
190 <%text>## {id} will be all groups matched from this pattern</%text>
191
191
192 issue_pat = (?:\s*#)(\d+)
192 issue_pat = (?:\s*#)(\d+)
193
193
194 <%text>## server url to the issue, each {id} will be replaced with match</%text>
194 <%text>## server url to the issue, each {id} will be replaced with match</%text>
195 <%text>## fetched from the regex and {repo} is replaced with full repository name</%text>
195 <%text>## fetched from the regex and {repo} is replaced with full repository name</%text>
196 <%text>## including groups {repo_name} is replaced with just name of repo</%text>
196 <%text>## including groups {repo_name} is replaced with just name of repo</%text>
197
197
198 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
198 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
199
199
200 <%text>## prefix to add to link to indicate it's an url</%text>
200 <%text>## prefix to add to link to indicate it's an url</%text>
201 <%text>## #314 will be replaced by <issue_prefix><id></%text>
201 <%text>## #314 will be replaced by <issue_prefix><id></%text>
202
202
203 issue_prefix = #
203 issue_prefix = #
204
204
205 <%text>## issue_pat, issue_server_link, issue_prefix can have suffixes to specify</%text>
205 <%text>## issue_pat, issue_server_link, issue_prefix can have suffixes to specify</%text>
206 <%text>## multiple patterns, to other issues server, wiki or others</%text>
206 <%text>## multiple patterns, to other issues server, wiki or others</%text>
207 <%text>## below an example how to create a wiki pattern</%text>
207 <%text>## below an example how to create a wiki pattern</%text>
208 <%text>## wiki-some-id -> https://mywiki.com/some-id</%text>
208 <%text>## wiki-some-id -> https://mywiki.com/some-id</%text>
209
209
210 #issue_pat_wiki = (?:wiki-)(.+)
210 #issue_pat_wiki = (?:wiki-)(.+)
211 #issue_server_link_wiki = https://mywiki.com/{id}
211 #issue_server_link_wiki = https://mywiki.com/{id}
212 #issue_prefix_wiki = WIKI-
212 #issue_prefix_wiki = WIKI-
213
213
214
214
215 <%text>## instance-id prefix</%text>
215 <%text>## instance-id prefix</%text>
216 <%text>## a prefix key for this instance used for cache invalidation when running</%text>
216 <%text>## a prefix key for this instance used for cache invalidation when running</%text>
217 <%text>## multiple instances of rhodecode, make sure it's globally unique for</%text>
217 <%text>## multiple instances of rhodecode, make sure it's globally unique for</%text>
218 <%text>## all running rhodecode instances. Leave empty if you don't use it</%text>
218 <%text>## all running rhodecode instances. Leave empty if you don't use it</%text>
219 instance_id =
219 instance_id =
220
220
221 <%text>## alternative return HTTP header for failed authentication. Default HTTP</%text>
221 <%text>## alternative return HTTP header for failed authentication. Default HTTP</%text>
222 <%text>## response is 401 HTTPUnauthorized. Currently HG clients have troubles with</%text>
222 <%text>## response is 401 HTTPUnauthorized. Currently HG clients have troubles with</%text>
223 <%text>## handling that. Set this variable to 403 to return HTTPForbidden</%text>
223 <%text>## handling that. Set this variable to 403 to return HTTPForbidden</%text>
224 auth_ret_code =
224 auth_ret_code =
225
225
226 <%text>## locking return code. When repository is locked return this HTTP code. 2XX</%text>
226 <%text>## locking return code. When repository is locked return this HTTP code. 2XX</%text>
227 <%text>## codes don't break the transactions while 4XX codes do</%text>
227 <%text>## codes don't break the transactions while 4XX codes do</%text>
228 lock_ret_code = 423
228 lock_ret_code = 423
229
229
230 <%text>## allow chaning the repository store location from web interface</%text>
230 <%text>## allows to change the repository location in settings page</%text>
231 allow_repo_location_change = True
231 allow_repo_location_change = True
232
232
233 <%text>## allows to setup custom hooks in settings page</%text>
234 allow_custom_hooks_settings = True
235
233 <%text>
236 <%text>
234 ####################################
237 ####################################
235 ### CELERY CONFIG ####
238 ### CELERY CONFIG ####
236 ####################################
239 ####################################
237 </%text>
240 </%text>
238 use_celery = false
241 use_celery = false
239 broker.host = localhost
242 broker.host = localhost
240 broker.vhost = rabbitmqhost
243 broker.vhost = rabbitmqhost
241 broker.port = 5672
244 broker.port = 5672
242 broker.user = rabbitmq
245 broker.user = rabbitmq
243 broker.password = qweqwe
246 broker.password = qweqwe
244
247
245 celery.imports = rhodecode.lib.celerylib.tasks
248 celery.imports = rhodecode.lib.celerylib.tasks
246
249
247 celery.result.backend = amqp
250 celery.result.backend = amqp
248 celery.result.dburi = amqp://
251 celery.result.dburi = amqp://
249 celery.result.serialier = json
252 celery.result.serialier = json
250
253
251 #celery.send.task.error.emails = true
254 #celery.send.task.error.emails = true
252 #celery.amqp.task.result.expires = 18000
255 #celery.amqp.task.result.expires = 18000
253
256
254 celeryd.concurrency = 2
257 celeryd.concurrency = 2
255 #celeryd.log.file = celeryd.log
258 #celeryd.log.file = celeryd.log
256 celeryd.log.level = debug
259 celeryd.log.level = debug
257 celeryd.max.tasks.per.child = 1
260 celeryd.max.tasks.per.child = 1
258
261
259 <%text>## tasks will never be sent to the queue, but executed locally instead.</%text>
262 <%text>## tasks will never be sent to the queue, but executed locally instead.</%text>
260 celery.always.eager = false
263 celery.always.eager = false
261 <%text>
264 <%text>
262 ####################################
265 ####################################
263 ### BEAKER CACHE ####
266 ### BEAKER CACHE ####
264 ####################################
267 ####################################
265 </%text>
268 </%text>
266 beaker.cache.data_dir=${here}/data/cache/data
269 beaker.cache.data_dir=${here}/data/cache/data
267 beaker.cache.lock_dir=${here}/data/cache/lock
270 beaker.cache.lock_dir=${here}/data/cache/lock
268
271
269 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
272 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
270
273
271 beaker.cache.super_short_term.type=memory
274 beaker.cache.super_short_term.type=memory
272 beaker.cache.super_short_term.expire=10
275 beaker.cache.super_short_term.expire=10
273 beaker.cache.super_short_term.key_length = 256
276 beaker.cache.super_short_term.key_length = 256
274
277
275 beaker.cache.short_term.type=memory
278 beaker.cache.short_term.type=memory
276 beaker.cache.short_term.expire=60
279 beaker.cache.short_term.expire=60
277 beaker.cache.short_term.key_length = 256
280 beaker.cache.short_term.key_length = 256
278
281
279 beaker.cache.long_term.type=memory
282 beaker.cache.long_term.type=memory
280 beaker.cache.long_term.expire=36000
283 beaker.cache.long_term.expire=36000
281 beaker.cache.long_term.key_length = 256
284 beaker.cache.long_term.key_length = 256
282
285
283 beaker.cache.sql_cache_short.type=memory
286 beaker.cache.sql_cache_short.type=memory
284 beaker.cache.sql_cache_short.expire=10
287 beaker.cache.sql_cache_short.expire=10
285 beaker.cache.sql_cache_short.key_length = 256
288 beaker.cache.sql_cache_short.key_length = 256
286
289
287 beaker.cache.sql_cache_med.type=memory
290 beaker.cache.sql_cache_med.type=memory
288 beaker.cache.sql_cache_med.expire=360
291 beaker.cache.sql_cache_med.expire=360
289 beaker.cache.sql_cache_med.key_length = 256
292 beaker.cache.sql_cache_med.key_length = 256
290
293
291 beaker.cache.sql_cache_long.type=file
294 beaker.cache.sql_cache_long.type=file
292 beaker.cache.sql_cache_long.expire=3600
295 beaker.cache.sql_cache_long.expire=3600
293 beaker.cache.sql_cache_long.key_length = 256
296 beaker.cache.sql_cache_long.key_length = 256
294 <%text>
297 <%text>
295 ####################################
298 ####################################
296 ### BEAKER SESSION ####
299 ### BEAKER SESSION ####
297 ####################################
300 ####################################
298 ## Type of storage used for the session, current types are
301 ## Type of storage used for the session, current types are
299 ## dbm, file, memcached, database, and memory.
302 ## dbm, file, memcached, database, and memory.
300 ## The storage uses the Container API
303 ## The storage uses the Container API
301 ## that is also used by the cache system.
304 ## that is also used by the cache system.
302 </%text>
305 </%text>
303 <%text>## db session ##</%text>
306 <%text>## db session ##</%text>
304 #beaker.session.type = ext:database
307 #beaker.session.type = ext:database
305 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
308 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
306 #beaker.session.table_name = db_session
309 #beaker.session.table_name = db_session
307
310
308 <%text>## encrypted cookie client side session, good for many instances ##</%text>
311 <%text>## encrypted cookie client side session, good for many instances ##</%text>
309 #beaker.session.type = cookie
312 #beaker.session.type = cookie
310
313
311 <%text>## file based cookies (default) ##</%text>
314 <%text>## file based cookies (default) ##</%text>
312 #beaker.session.type = file
315 #beaker.session.type = file
313
316
314 beaker.session.key = rhodecode
317 beaker.session.key = rhodecode
315 beaker.session.secret = ${uuid()}
318 beaker.session.secret = ${uuid()}
316
319
317 <%text>## Secure encrypted cookie. Requires AES and AES python libraries</%text>
320 <%text>## Secure encrypted cookie. Requires AES and AES python libraries</%text>
318 <%text>## you must disable beaker.session.secret to use this</%text>
321 <%text>## you must disable beaker.session.secret to use this</%text>
319 #beaker.session.encrypt_key = <key_for_encryption>
322 #beaker.session.encrypt_key = <key_for_encryption>
320 #beaker.session.validate_key = <validation_key>
323 #beaker.session.validate_key = <validation_key>
321
324
322 <%text>## sets session as invalid if it haven't been accessed for given amount of time</%text>
325 <%text>## sets session as invalid if it haven't been accessed for given amount of time</%text>
323 beaker.session.timeout = 2592000
326 beaker.session.timeout = 2592000
324 beaker.session.httponly = true
327 beaker.session.httponly = true
325 #beaker.session.cookie_path = /<your-prefix>
328 #beaker.session.cookie_path = /<your-prefix>
326
329
327 <%text>## uncomment for https secure cookie</%text>
330 <%text>## uncomment for https secure cookie</%text>
328 beaker.session.secure = false
331 beaker.session.secure = false
329
332
330 <%text>## auto save the session to not to use .save()</%text>
333 <%text>## auto save the session to not to use .save()</%text>
331 beaker.session.auto = False
334 beaker.session.auto = False
332
335
333 <%text>## default cookie expiration time in seconds `true` expire at browser close ##</%text>
336 <%text>## default cookie expiration time in seconds `true` expire at browser close ##</%text>
334 #beaker.session.cookie_expires = 3600
337 #beaker.session.cookie_expires = 3600
335
338
336 %if error_aggregation_service == 'errormator':
339 %if error_aggregation_service == 'errormator':
337 <%text>
340 <%text>
338 ############################
341 ############################
339 ## ERROR HANDLING SYSTEMS ##
342 ## ERROR HANDLING SYSTEMS ##
340 ############################
343 ############################
341
344
342 ####################
345 ####################
343 ### [errormator] ###
346 ### [errormator] ###
344 ####################
347 ####################
345
348
346 ## Errormator is tailored to work with RhodeCode, see
349 ## Errormator is tailored to work with RhodeCode, see
347 ## http://errormator.com for details how to obtain an account
350 ## http://errormator.com for details how to obtain an account
348 ## you must install python package `errormator_client` to make it work
351 ## you must install python package `errormator_client` to make it work
349 </%text>
352 </%text>
350 <%text>## errormator enabled</%text>
353 <%text>## errormator enabled</%text>
351 errormator = false
354 errormator = false
352
355
353 errormator.server_url = https://api.errormator.com
356 errormator.server_url = https://api.errormator.com
354 errormator.api_key = YOUR_API_KEY
357 errormator.api_key = YOUR_API_KEY
355
358
356 <%text>## TWEAK AMOUNT OF INFO SENT HERE</%text>
359 <%text>## TWEAK AMOUNT OF INFO SENT HERE</%text>
357
360
358 <%text>## enables 404 error logging (default False)</%text>
361 <%text>## enables 404 error logging (default False)</%text>
359 errormator.report_404 = false
362 errormator.report_404 = false
360
363
361 <%text>## time in seconds after request is considered being slow (default 1)</%text>
364 <%text>## time in seconds after request is considered being slow (default 1)</%text>
362 errormator.slow_request_time = 1
365 errormator.slow_request_time = 1
363
366
364 <%text>## record slow requests in application</%text>
367 <%text>## record slow requests in application</%text>
365 <%text>## (needs to be enabled for slow datastore recording and time tracking)</%text>
368 <%text>## (needs to be enabled for slow datastore recording and time tracking)</%text>
366 errormator.slow_requests = true
369 errormator.slow_requests = true
367
370
368 <%text>## enable hooking to application loggers</%text>
371 <%text>## enable hooking to application loggers</%text>
369 # errormator.logging = true
372 # errormator.logging = true
370
373
371 <%text>## minimum log level for log capture</%text>
374 <%text>## minimum log level for log capture</%text>
372 # errormator.logging.level = WARNING
375 # errormator.logging.level = WARNING
373
376
374 <%text>## send logs only from erroneous/slow requests</%text>
377 <%text>## send logs only from erroneous/slow requests</%text>
375 <%text>## (saves API quota for intensive logging)</%text>
378 <%text>## (saves API quota for intensive logging)</%text>
376 errormator.logging_on_error = false
379 errormator.logging_on_error = false
377
380
378 <%text>## list of additonal keywords that should be grabbed from environ object</%text>
381 <%text>## list of additonal keywords that should be grabbed from environ object</%text>
379 <%text>## can be string with comma separated list of words in lowercase</%text>
382 <%text>## can be string with comma separated list of words in lowercase</%text>
380 <%text>## (by default client will always send following info:</%text>
383 <%text>## (by default client will always send following info:</%text>
381 <%text>## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that</%text>
384 <%text>## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that</%text>
382 <%text>## start with HTTP* this list be extended with additional keywords here</%text>
385 <%text>## start with HTTP* this list be extended with additional keywords here</%text>
383 errormator.environ_keys_whitelist =
386 errormator.environ_keys_whitelist =
384
387
385
388
386 <%text>## list of keywords that should be blanked from request object</%text>
389 <%text>## list of keywords that should be blanked from request object</%text>
387 <%text>## can be string with comma separated list of words in lowercase</%text>
390 <%text>## can be string with comma separated list of words in lowercase</%text>
388 <%text>## (by default client will always blank keys that contain following words</%text>
391 <%text>## (by default client will always blank keys that contain following words</%text>
389 <%text>## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'</%text>
392 <%text>## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'</%text>
390 <%text>## this list be extended with additional keywords set here</%text>
393 <%text>## this list be extended with additional keywords set here</%text>
391 errormator.request_keys_blacklist =
394 errormator.request_keys_blacklist =
392
395
393
396
394 <%text>## list of namespaces that should be ignores when gathering log entries</%text>
397 <%text>## list of namespaces that should be ignores when gathering log entries</%text>
395 <%text>## can be string with comma separated list of namespaces</%text>
398 <%text>## can be string with comma separated list of namespaces</%text>
396 <%text>## (by default the client ignores own entries: errormator_client.client)</%text>
399 <%text>## (by default the client ignores own entries: errormator_client.client)</%text>
397 errormator.log_namespace_blacklist =
400 errormator.log_namespace_blacklist =
398 %elif error_aggregation_service == 'sentry':
401 %elif error_aggregation_service == 'sentry':
399 <%text>
402 <%text>
400 ################
403 ################
401 ### [sentry] ###
404 ### [sentry] ###
402 ################
405 ################
403
406
404 ## sentry is a alternative open source error aggregator
407 ## sentry is a alternative open source error aggregator
405 ## you must install python packages `sentry` and `raven` to enable
408 ## you must install python packages `sentry` and `raven` to enable
406 </%text>
409 </%text>
407 sentry.dsn = YOUR_DNS
410 sentry.dsn = YOUR_DNS
408 sentry.servers =
411 sentry.servers =
409 sentry.name =
412 sentry.name =
410 sentry.key =
413 sentry.key =
411 sentry.public_key =
414 sentry.public_key =
412 sentry.secret_key =
415 sentry.secret_key =
413 sentry.project =
416 sentry.project =
414 sentry.site =
417 sentry.site =
415 sentry.include_paths =
418 sentry.include_paths =
416 sentry.exclude_paths =
419 sentry.exclude_paths =
417 %endif
420 %endif
418 <%text>
421 <%text>
419 ################################################################################
422 ################################################################################
420 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
423 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
421 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
424 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
422 ## execute malicious code after an exception is raised. ##
425 ## execute malicious code after an exception is raised. ##
423 ################################################################################
426 ################################################################################
424 </%text>
427 </%text>
425 set debug = false
428 set debug = false
426 <%text>
429 <%text>
427 ##################################
430 ##################################
428 ### LOGVIEW CONFIG ###
431 ### LOGVIEW CONFIG ###
429 ##################################
432 ##################################
430 </%text>
433 </%text>
431 logview.sqlalchemy = #faa
434 logview.sqlalchemy = #faa
432 logview.pylons.templating = #bfb
435 logview.pylons.templating = #bfb
433 logview.pylons.util = #eee
436 logview.pylons.util = #eee
434 <%text>
437 <%text>
435 #########################################################
438 #########################################################
436 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
439 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
437 #########################################################
440 #########################################################
438 </%text>
441 </%text>
439 %if database_engine == 'sqlite':
442 %if database_engine == 'sqlite':
440 # SQLITE [default]
443 # SQLITE [default]
441 sqlalchemy.db1.url = sqlite:///${here}/rhodecode.db?timeout=60
444 sqlalchemy.db1.url = sqlite:///${here}/rhodecode.db?timeout=60
442 %elif database_engine == 'postgres':
445 %elif database_engine == 'postgres':
443 # POSTGRESQL
446 # POSTGRESQL
444 sqlalchemy.db1.url = postgresql://user:pass@localhost/rhodecode
447 sqlalchemy.db1.url = postgresql://user:pass@localhost/rhodecode
445 %elif database_engine == 'mysql':
448 %elif database_engine == 'mysql':
446 # MySQL
449 # MySQL
447 sqlalchemy.db1.url = mysql://user:pass@localhost/rhodecode
450 sqlalchemy.db1.url = mysql://user:pass@localhost/rhodecode
448 %endif
451 %endif
449 # see sqlalchemy docs for others
452 # see sqlalchemy docs for others
450
453
451 sqlalchemy.db1.echo = false
454 sqlalchemy.db1.echo = false
452 sqlalchemy.db1.pool_recycle = 3600
455 sqlalchemy.db1.pool_recycle = 3600
453 sqlalchemy.db1.convert_unicode = true
456 sqlalchemy.db1.convert_unicode = true
454 <%text>
457 <%text>
455 ################################
458 ################################
456 ### LOGGING CONFIGURATION ####
459 ### LOGGING CONFIGURATION ####
457 ################################
460 ################################
458 </%text>
461 </%text>
459 [loggers]
462 [loggers]
460 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
463 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
461
464
462 [handlers]
465 [handlers]
463 keys = console, console_sql
466 keys = console, console_sql
464
467
465 [formatters]
468 [formatters]
466 keys = generic, color_formatter, color_formatter_sql
469 keys = generic, color_formatter, color_formatter_sql
467 <%text>
470 <%text>
468 #############
471 #############
469 ## LOGGERS ##
472 ## LOGGERS ##
470 #############
473 #############
471 </%text>
474 </%text>
472 [logger_root]
475 [logger_root]
473 level = NOTSET
476 level = NOTSET
474 handlers = console
477 handlers = console
475
478
476 [logger_routes]
479 [logger_routes]
477 level = DEBUG
480 level = DEBUG
478 handlers =
481 handlers =
479 qualname = routes.middleware
482 qualname = routes.middleware
480 <%text>## "level = DEBUG" logs the route matched and routing variables.</%text>
483 <%text>## "level = DEBUG" logs the route matched and routing variables.</%text>
481 propagate = 1
484 propagate = 1
482
485
483 [logger_beaker]
486 [logger_beaker]
484 level = DEBUG
487 level = DEBUG
485 handlers =
488 handlers =
486 qualname = beaker.container
489 qualname = beaker.container
487 propagate = 1
490 propagate = 1
488
491
489 [logger_templates]
492 [logger_templates]
490 level = INFO
493 level = INFO
491 handlers =
494 handlers =
492 qualname = pylons.templating
495 qualname = pylons.templating
493 propagate = 1
496 propagate = 1
494
497
495 [logger_rhodecode]
498 [logger_rhodecode]
496 level = DEBUG
499 level = DEBUG
497 handlers =
500 handlers =
498 qualname = rhodecode
501 qualname = rhodecode
499 propagate = 1
502 propagate = 1
500
503
501 [logger_sqlalchemy]
504 [logger_sqlalchemy]
502 level = INFO
505 level = INFO
503 handlers = console_sql
506 handlers = console_sql
504 qualname = sqlalchemy.engine
507 qualname = sqlalchemy.engine
505 propagate = 0
508 propagate = 0
506
509
507 [logger_whoosh_indexer]
510 [logger_whoosh_indexer]
508 level = DEBUG
511 level = DEBUG
509 handlers =
512 handlers =
510 qualname = whoosh_indexer
513 qualname = whoosh_indexer
511 propagate = 1
514 propagate = 1
512 <%text>
515 <%text>
513 ##############
516 ##############
514 ## HANDLERS ##
517 ## HANDLERS ##
515 ##############
518 ##############
516 </%text>
519 </%text>
517 [handler_console]
520 [handler_console]
518 class = StreamHandler
521 class = StreamHandler
519 args = (sys.stderr,)
522 args = (sys.stderr,)
520 level = INFO
523 level = INFO
521 formatter = generic
524 formatter = generic
522
525
523 [handler_console_sql]
526 [handler_console_sql]
524 class = StreamHandler
527 class = StreamHandler
525 args = (sys.stderr,)
528 args = (sys.stderr,)
526 level = WARN
529 level = WARN
527 formatter = generic
530 formatter = generic
528 <%text>
531 <%text>
529 ################
532 ################
530 ## FORMATTERS ##
533 ## FORMATTERS ##
531 ################
534 ################
532 </%text>
535 </%text>
533 [formatter_generic]
536 [formatter_generic]
534 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
537 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
535 datefmt = %Y-%m-%d %H:%M:%S
538 datefmt = %Y-%m-%d %H:%M:%S
536
539
537 [formatter_color_formatter]
540 [formatter_color_formatter]
538 class=rhodecode.lib.colored_formatter.ColorFormatter
541 class=rhodecode.lib.colored_formatter.ColorFormatter
539 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
542 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
540 datefmt = %Y-%m-%d %H:%M:%S
543 datefmt = %Y-%m-%d %H:%M:%S
541
544
542 [formatter_color_formatter_sql]
545 [formatter_color_formatter_sql]
543 class=rhodecode.lib.colored_formatter.ColorFormatterSql
546 class=rhodecode.lib.colored_formatter.ColorFormatterSql
544 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
547 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
545 datefmt = %Y-%m-%d %H:%M:%S
548 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,527 +1,532 b''
1 ################################################################################
1 ################################################################################
2 ################################################################################
2 ################################################################################
3 # RhodeCode - Pylons environment configuration #
3 # RhodeCode - Pylons environment configuration #
4 # #
4 # #
5 # The %(here)s variable will be replaced with the parent directory of this file#
5 # The %(here)s variable will be replaced with the parent directory of this file#
6 ################################################################################
6 ################################################################################
7
7
8 [DEFAULT]
8 [DEFAULT]
9 debug = true
9 debug = true
10 pdebug = false
10 pdebug = false
11 ################################################################################
11 ################################################################################
12 ## Uncomment and replace with the address which should receive ##
12 ## Uncomment and replace with the address which should receive ##
13 ## any error reports after application crash ##
13 ## any error reports after application crash ##
14 ## Additionally those settings will be used by RhodeCode mailing system ##
14 ## Additionally those settings will be used by RhodeCode mailing system ##
15 ################################################################################
15 ################################################################################
16 #email_to = admin@localhost
16 #email_to = admin@localhost
17 #error_email_from = paste_error@localhost
17 #error_email_from = paste_error@localhost
18 #app_email_from = rhodecode-noreply@localhost
18 #app_email_from = rhodecode-noreply@localhost
19 #error_message =
19 #error_message =
20 #email_prefix = [RhodeCode]
20 #email_prefix = [RhodeCode]
21
21
22 #smtp_server = mail.server.com
22 #smtp_server = mail.server.com
23 #smtp_username =
23 #smtp_username =
24 #smtp_password =
24 #smtp_password =
25 #smtp_port =
25 #smtp_port =
26 #smtp_use_tls = false
26 #smtp_use_tls = false
27 #smtp_use_ssl = true
27 #smtp_use_ssl = true
28 ## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.)
28 ## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.)
29 #smtp_auth =
29 #smtp_auth =
30
30
31 [server:main]
31 [server:main]
32 ## PASTE ##
32 ## PASTE ##
33 #use = egg:Paste#http
33 #use = egg:Paste#http
34 ## nr of worker threads to spawn
34 ## nr of worker threads to spawn
35 #threadpool_workers = 5
35 #threadpool_workers = 5
36 ## max request before thread respawn
36 ## max request before thread respawn
37 #threadpool_max_requests = 10
37 #threadpool_max_requests = 10
38 ## option to use threads of process
38 ## option to use threads of process
39 #use_threadpool = true
39 #use_threadpool = true
40
40
41 ## WAITRESS ##
41 ## WAITRESS ##
42 use = egg:waitress#main
42 use = egg:waitress#main
43 ## number of worker threads
43 ## number of worker threads
44 threads = 5
44 threads = 5
45 ## MAX BODY SIZE 100GB
45 ## MAX BODY SIZE 100GB
46 max_request_body_size = 107374182400
46 max_request_body_size = 107374182400
47 ## use poll instead of select, fixes fd limits, may not work on old
47 ## use poll instead of select, fixes fd limits, may not work on old
48 ## windows systems.
48 ## windows systems.
49 #asyncore_use_poll = True
49 #asyncore_use_poll = True
50
50
51 ## GUNICORN ##
51 ## GUNICORN ##
52 #use = egg:gunicorn#main
52 #use = egg:gunicorn#main
53 ## number of process workers. You must set `instance_id = *` when this option
53 ## number of process workers. You must set `instance_id = *` when this option
54 ## is set to more than one worker
54 ## is set to more than one worker
55 #workers = 1
55 #workers = 1
56 ## process name
56 ## process name
57 #proc_name = rhodecode
57 #proc_name = rhodecode
58 ## type of worker class, one of sync, eventlet, gevent, tornado
58 ## type of worker class, one of sync, eventlet, gevent, tornado
59 ## recommended for bigger setup is using of of other than sync one
59 ## recommended for bigger setup is using of of other than sync one
60 #worker_class = sync
60 #worker_class = sync
61 #max_requests = 5
61 #max_requests = 5
62 ## ammount of time a worker can handle request before it get's killed and
62 ## ammount of time a worker can handle request before it get's killed and
63 ## restarted
63 ## restarted
64 #timeout = 3600
64 #timeout = 3600
65
65
66 ## COMMON ##
66 ## COMMON ##
67 host = 127.0.0.1
67 host = 127.0.0.1
68 port = 5000
68 port = 5000
69
69
70 ## prefix middleware for rc
70 ## prefix middleware for rc
71 #[filter:proxy-prefix]
71 #[filter:proxy-prefix]
72 #use = egg:PasteDeploy#prefix
72 #use = egg:PasteDeploy#prefix
73 #prefix = /<your-prefix>
73 #prefix = /<your-prefix>
74
74
75 [app:main]
75 [app:main]
76 use = egg:rhodecode
76 use = egg:rhodecode
77 ## enable proxy prefix middleware
77 ## enable proxy prefix middleware
78 #filter-with = proxy-prefix
78 #filter-with = proxy-prefix
79
79
80 full_stack = true
80 full_stack = true
81 static_files = true
81 static_files = true
82 ## Optional Languages
82 ## Optional Languages
83 ## en, fr, ja, pt_BR, zh_CN, zh_TW, pl
83 ## en, fr, ja, pt_BR, zh_CN, zh_TW, pl
84 lang = en
84 lang = en
85 cache_dir = %(here)s/data
85 cache_dir = %(here)s/data
86 index_dir = %(here)s/data/index
86 index_dir = %(here)s/data/index
87
87
88 ## perform a full repository scan on each server start, this should be
88 ## perform a full repository scan on each server start, this should be
89 ## set to false after first startup, to allow faster server restarts.
89 ## set to false after first startup, to allow faster server restarts.
90 initial_repo_scan = true
90 initial_repo_scan = true
91
91
92 ## uncomment and set this path to use archive download cache
92 ## uncomment and set this path to use archive download cache
93 #archive_cache_dir = /tmp/tarballcache
93 #archive_cache_dir = /tmp/tarballcache
94
94
95 ## change this to unique ID for security
95 ## change this to unique ID for security
96 app_instance_uuid = ${app_instance_uuid}
96 app_instance_uuid = ${app_instance_uuid}
97
97
98 ## cut off limit for large diffs (size in bytes)
98 ## cut off limit for large diffs (size in bytes)
99 cut_off_limit = 256000
99 cut_off_limit = 256000
100
100
101 ## use cache version of scm repo everywhere
101 ## use cache version of scm repo everywhere
102 vcs_full_cache = true
102 vcs_full_cache = true
103
103
104 ## force https in RhodeCode, fixes https redirects, assumes it's always https
104 ## force https in RhodeCode, fixes https redirects, assumes it's always https
105 force_https = false
105 force_https = false
106
106
107 ## use Strict-Transport-Security headers
107 ## use Strict-Transport-Security headers
108 use_htsts = false
108 use_htsts = false
109
109
110 ## number of commits stats will parse on each iteration
110 ## number of commits stats will parse on each iteration
111 commit_parse_limit = 25
111 commit_parse_limit = 25
112
112
113 ## use gravatar service to display avatars
113 ## use gravatar service to display avatars
114 use_gravatar = true
114 use_gravatar = true
115
115
116 ## path to git executable
116 ## path to git executable
117 git_path = git
117 git_path = git
118
118
119 ## git rev filter option, --all is the default filter, if you need to
119 ## git rev filter option, --all is the default filter, if you need to
120 ## hide all refs in changelog switch this to --branches --tags
120 ## hide all refs in changelog switch this to --branches --tags
121 git_rev_filter=--all
121 git_rev_filter=--all
122
122
123 ## RSS feed options
123 ## RSS feed options
124 rss_cut_off_limit = 256000
124 rss_cut_off_limit = 256000
125 rss_items_per_page = 10
125 rss_items_per_page = 10
126 rss_include_diff = false
126 rss_include_diff = false
127
127
128 ## options for showing and identifying changesets
128 ## options for showing and identifying changesets
129 show_sha_length = 12
129 show_sha_length = 12
130 show_revision_number = true
130 show_revision_number = true
131
131
132 ## gist URL alias, used to create nicer urls for gist. This should be an
132 ## gist URL alias, used to create nicer urls for gist. This should be an
133 ## url that does rewrites to _admin/gists/<gistid>.
133 ## url that does rewrites to _admin/gists/<gistid>.
134 ## example: http://gist.rhodecode.org/{gistid}. Empty means use the internal
134 ## example: http://gist.rhodecode.org/{gistid}. Empty means use the internal
135 ## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/<gistid>
135 ## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/<gistid>
136 gist_alias_url =
136 gist_alias_url =
137
137
138 ## white list of API enabled controllers. This allows to add list of
138 ## white list of API enabled controllers. This allows to add list of
139 ## controllers to which access will be enabled by api_key. eg: to enable
139 ## controllers to which access will be enabled by api_key. eg: to enable
140 ## api access to raw_files put `FilesController:raw`, to enable access to patches
140 ## api access to raw_files put `FilesController:raw`, to enable access to patches
141 ## add `ChangesetController:changeset_patch`. This list should be "," separated
141 ## add `ChangesetController:changeset_patch`. This list should be "," separated
142 ## Syntax is <ControllerClass>:<function>. Check debug logs for generated names
142 ## Syntax is <ControllerClass>:<function>. Check debug logs for generated names
143 api_access_controllers_whitelist =
143 api_access_controllers_whitelist =
144
144
145 ## alternative_gravatar_url allows you to use your own avatar server application
145 ## alternative_gravatar_url allows you to use your own avatar server application
146 ## the following parts of the URL will be replaced
146 ## the following parts of the URL will be replaced
147 ## {email} user email
147 ## {email} user email
148 ## {md5email} md5 hash of the user email (like at gravatar.com)
148 ## {md5email} md5 hash of the user email (like at gravatar.com)
149 ## {size} size of the image that is expected from the server application
149 ## {size} size of the image that is expected from the server application
150 ## {scheme} http/https from RhodeCode server
150 ## {scheme} http/https from RhodeCode server
151 ## {netloc} network location from RhodeCode server
151 ## {netloc} network location from RhodeCode server
152 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
152 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
153 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
153 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
154
154
155
155
156 ## container auth options
156 ## container auth options
157 container_auth_enabled = false
157 container_auth_enabled = false
158 proxypass_auth_enabled = false
158 proxypass_auth_enabled = false
159
159
160 ## default encoding used to convert from and to unicode
160 ## default encoding used to convert from and to unicode
161 ## can be also a comma seperated list of encoding in case of mixed encodings
161 ## can be also a comma seperated list of encoding in case of mixed encodings
162 default_encoding = utf8
162 default_encoding = utf8
163
163
164 ## overwrite schema of clone url
164 ## overwrite schema of clone url
165 ## available vars:
165 ## available vars:
166 ## scheme - http/https
166 ## scheme - http/https
167 ## user - current user
167 ## user - current user
168 ## pass - password
168 ## pass - password
169 ## netloc - network location
169 ## netloc - network location
170 ## path - usually repo_name
170 ## path - usually repo_name
171
171
172 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
172 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
173
173
174 ## issue tracker for RhodeCode (leave blank to disable, absent for default)
174 ## issue tracker for RhodeCode (leave blank to disable, absent for default)
175 #bugtracker = http://bitbucket.org/marcinkuzminski/rhodecode/issues
175 #bugtracker = http://bitbucket.org/marcinkuzminski/rhodecode/issues
176
176
177 ## issue tracking mapping for commits messages
177 ## issue tracking mapping for commits messages
178 ## comment out issue_pat, issue_server, issue_prefix to enable
178 ## comment out issue_pat, issue_server, issue_prefix to enable
179
179
180 ## pattern to get the issues from commit messages
180 ## pattern to get the issues from commit messages
181 ## default one used here is #<numbers> with a regex passive group for `#`
181 ## default one used here is #<numbers> with a regex passive group for `#`
182 ## {id} will be all groups matched from this pattern
182 ## {id} will be all groups matched from this pattern
183
183
184 issue_pat = (?:\s*#)(\d+)
184 issue_pat = (?:\s*#)(\d+)
185
185
186 ## server url to the issue, each {id} will be replaced with match
186 ## server url to the issue, each {id} will be replaced with match
187 ## fetched from the regex and {repo} is replaced with full repository name
187 ## fetched from the regex and {repo} is replaced with full repository name
188 ## including groups {repo_name} is replaced with just name of repo
188 ## including groups {repo_name} is replaced with just name of repo
189
189
190 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
190 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
191
191
192 ## prefix to add to link to indicate it's an url
192 ## prefix to add to link to indicate it's an url
193 ## #314 will be replaced by <issue_prefix><id>
193 ## #314 will be replaced by <issue_prefix><id>
194
194
195 issue_prefix = #
195 issue_prefix = #
196
196
197 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
197 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
198 ## multiple patterns, to other issues server, wiki or others
198 ## multiple patterns, to other issues server, wiki or others
199 ## below an example how to create a wiki pattern
199 ## below an example how to create a wiki pattern
200 # #wiki-some-id -> https://mywiki.com/some-id
200 # #wiki-some-id -> https://mywiki.com/some-id
201
201
202 #issue_pat_wiki = (?:wiki-)(.+)
202 #issue_pat_wiki = (?:wiki-)(.+)
203 #issue_server_link_wiki = https://mywiki.com/{id}
203 #issue_server_link_wiki = https://mywiki.com/{id}
204 #issue_prefix_wiki = WIKI-
204 #issue_prefix_wiki = WIKI-
205
205
206
206
207 ## instance-id prefix
207 ## instance-id prefix
208 ## a prefix key for this instance used for cache invalidation when running
208 ## a prefix key for this instance used for cache invalidation when running
209 ## multiple instances of rhodecode, make sure it's globally unique for
209 ## multiple instances of rhodecode, make sure it's globally unique for
210 ## all running rhodecode instances. Leave empty if you don't use it
210 ## all running rhodecode instances. Leave empty if you don't use it
211 instance_id =
211 instance_id =
212
212
213 ## alternative return HTTP header for failed authentication. Default HTTP
213 ## alternative return HTTP header for failed authentication. Default HTTP
214 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
214 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
215 ## handling that. Set this variable to 403 to return HTTPForbidden
215 ## handling that. Set this variable to 403 to return HTTPForbidden
216 auth_ret_code =
216 auth_ret_code =
217
217
218 ## locking return code. When repository is locked return this HTTP code. 2XX
218 ## locking return code. When repository is locked return this HTTP code. 2XX
219 ## codes don't break the transactions while 4XX codes do
219 ## codes don't break the transactions while 4XX codes do
220 lock_ret_code = 423
220 lock_ret_code = 423
221
221
222 ## allows to change the repository location in settings page
222 allow_repo_location_change = True
223 allow_repo_location_change = True
223
224
225 ## allows to setup custom hooks in settings page
226 allow_custom_hooks_settings = True
227
228
224 ####################################
229 ####################################
225 ### CELERY CONFIG ####
230 ### CELERY CONFIG ####
226 ####################################
231 ####################################
227 use_celery = false
232 use_celery = false
228 broker.host = localhost
233 broker.host = localhost
229 broker.vhost = rabbitmqhost
234 broker.vhost = rabbitmqhost
230 broker.port = 5672
235 broker.port = 5672
231 broker.user = rabbitmq
236 broker.user = rabbitmq
232 broker.password = qweqwe
237 broker.password = qweqwe
233
238
234 celery.imports = rhodecode.lib.celerylib.tasks
239 celery.imports = rhodecode.lib.celerylib.tasks
235
240
236 celery.result.backend = amqp
241 celery.result.backend = amqp
237 celery.result.dburi = amqp://
242 celery.result.dburi = amqp://
238 celery.result.serialier = json
243 celery.result.serialier = json
239
244
240 #celery.send.task.error.emails = true
245 #celery.send.task.error.emails = true
241 #celery.amqp.task.result.expires = 18000
246 #celery.amqp.task.result.expires = 18000
242
247
243 celeryd.concurrency = 2
248 celeryd.concurrency = 2
244 #celeryd.log.file = celeryd.log
249 #celeryd.log.file = celeryd.log
245 celeryd.log.level = debug
250 celeryd.log.level = debug
246 celeryd.max.tasks.per.child = 1
251 celeryd.max.tasks.per.child = 1
247
252
248 ## tasks will never be sent to the queue, but executed locally instead.
253 ## tasks will never be sent to the queue, but executed locally instead.
249 celery.always.eager = false
254 celery.always.eager = false
250
255
251 ####################################
256 ####################################
252 ### BEAKER CACHE ####
257 ### BEAKER CACHE ####
253 ####################################
258 ####################################
254 beaker.cache.data_dir=%(here)s/data/cache/data
259 beaker.cache.data_dir=%(here)s/data/cache/data
255 beaker.cache.lock_dir=%(here)s/data/cache/lock
260 beaker.cache.lock_dir=%(here)s/data/cache/lock
256
261
257 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
262 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
258
263
259 beaker.cache.super_short_term.type=memory
264 beaker.cache.super_short_term.type=memory
260 beaker.cache.super_short_term.expire=10
265 beaker.cache.super_short_term.expire=10
261 beaker.cache.super_short_term.key_length = 256
266 beaker.cache.super_short_term.key_length = 256
262
267
263 beaker.cache.short_term.type=memory
268 beaker.cache.short_term.type=memory
264 beaker.cache.short_term.expire=60
269 beaker.cache.short_term.expire=60
265 beaker.cache.short_term.key_length = 256
270 beaker.cache.short_term.key_length = 256
266
271
267 beaker.cache.long_term.type=memory
272 beaker.cache.long_term.type=memory
268 beaker.cache.long_term.expire=36000
273 beaker.cache.long_term.expire=36000
269 beaker.cache.long_term.key_length = 256
274 beaker.cache.long_term.key_length = 256
270
275
271 beaker.cache.sql_cache_short.type=memory
276 beaker.cache.sql_cache_short.type=memory
272 beaker.cache.sql_cache_short.expire=10
277 beaker.cache.sql_cache_short.expire=10
273 beaker.cache.sql_cache_short.key_length = 256
278 beaker.cache.sql_cache_short.key_length = 256
274
279
275 beaker.cache.sql_cache_med.type=memory
280 beaker.cache.sql_cache_med.type=memory
276 beaker.cache.sql_cache_med.expire=360
281 beaker.cache.sql_cache_med.expire=360
277 beaker.cache.sql_cache_med.key_length = 256
282 beaker.cache.sql_cache_med.key_length = 256
278
283
279 beaker.cache.sql_cache_long.type=file
284 beaker.cache.sql_cache_long.type=file
280 beaker.cache.sql_cache_long.expire=3600
285 beaker.cache.sql_cache_long.expire=3600
281 beaker.cache.sql_cache_long.key_length = 256
286 beaker.cache.sql_cache_long.key_length = 256
282
287
283 ####################################
288 ####################################
284 ### BEAKER SESSION ####
289 ### BEAKER SESSION ####
285 ####################################
290 ####################################
286 ## Type of storage used for the session, current types are
291 ## Type of storage used for the session, current types are
287 ## dbm, file, memcached, database, and memory.
292 ## dbm, file, memcached, database, and memory.
288 ## The storage uses the Container API
293 ## The storage uses the Container API
289 ## that is also used by the cache system.
294 ## that is also used by the cache system.
290
295
291 ## db session ##
296 ## db session ##
292 #beaker.session.type = ext:database
297 #beaker.session.type = ext:database
293 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
298 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
294 #beaker.session.table_name = db_session
299 #beaker.session.table_name = db_session
295
300
296 ## encrypted cookie client side session, good for many instances ##
301 ## encrypted cookie client side session, good for many instances ##
297 #beaker.session.type = cookie
302 #beaker.session.type = cookie
298
303
299 ## file based cookies (default) ##
304 ## file based cookies (default) ##
300 #beaker.session.type = file
305 #beaker.session.type = file
301
306
302 beaker.session.key = rhodecode
307 beaker.session.key = rhodecode
303 beaker.session.secret = ${app_instance_uuid}
308 beaker.session.secret = ${app_instance_uuid}
304
309
305 ## Secure encrypted cookie. Requires AES and AES python libraries
310 ## Secure encrypted cookie. Requires AES and AES python libraries
306 ## you must disable beaker.session.secret to use this
311 ## you must disable beaker.session.secret to use this
307 #beaker.session.encrypt_key = <key_for_encryption>
312 #beaker.session.encrypt_key = <key_for_encryption>
308 #beaker.session.validate_key = <validation_key>
313 #beaker.session.validate_key = <validation_key>
309
314
310 ## sets session as invalid if it haven't been accessed for given amount of time
315 ## sets session as invalid if it haven't been accessed for given amount of time
311 beaker.session.timeout = 2592000
316 beaker.session.timeout = 2592000
312 beaker.session.httponly = true
317 beaker.session.httponly = true
313 #beaker.session.cookie_path = /<your-prefix>
318 #beaker.session.cookie_path = /<your-prefix>
314
319
315 ## uncomment for https secure cookie
320 ## uncomment for https secure cookie
316 beaker.session.secure = false
321 beaker.session.secure = false
317
322
318 ## auto save the session to not to use .save()
323 ## auto save the session to not to use .save()
319 beaker.session.auto = False
324 beaker.session.auto = False
320
325
321 ## default cookie expiration time in seconds `true` expire at browser close ##
326 ## default cookie expiration time in seconds `true` expire at browser close ##
322 #beaker.session.cookie_expires = 3600
327 #beaker.session.cookie_expires = 3600
323
328
324
329
325 ############################
330 ############################
326 ## ERROR HANDLING SYSTEMS ##
331 ## ERROR HANDLING SYSTEMS ##
327 ############################
332 ############################
328
333
329 ####################
334 ####################
330 ### [errormator] ###
335 ### [errormator] ###
331 ####################
336 ####################
332
337
333 ## Errormator is tailored to work with RhodeCode, see
338 ## Errormator is tailored to work with RhodeCode, see
334 ## http://errormator.com for details how to obtain an account
339 ## http://errormator.com for details how to obtain an account
335 ## you must install python package `errormator_client` to make it work
340 ## you must install python package `errormator_client` to make it work
336
341
337 ## errormator enabled
342 ## errormator enabled
338 errormator = false
343 errormator = false
339
344
340 errormator.server_url = https://api.errormator.com
345 errormator.server_url = https://api.errormator.com
341 errormator.api_key = YOUR_API_KEY
346 errormator.api_key = YOUR_API_KEY
342
347
343 ## TWEAK AMOUNT OF INFO SENT HERE
348 ## TWEAK AMOUNT OF INFO SENT HERE
344
349
345 ## enables 404 error logging (default False)
350 ## enables 404 error logging (default False)
346 errormator.report_404 = false
351 errormator.report_404 = false
347
352
348 ## time in seconds after request is considered being slow (default 1)
353 ## time in seconds after request is considered being slow (default 1)
349 errormator.slow_request_time = 1
354 errormator.slow_request_time = 1
350
355
351 ## record slow requests in application
356 ## record slow requests in application
352 ## (needs to be enabled for slow datastore recording and time tracking)
357 ## (needs to be enabled for slow datastore recording and time tracking)
353 errormator.slow_requests = true
358 errormator.slow_requests = true
354
359
355 ## enable hooking to application loggers
360 ## enable hooking to application loggers
356 # errormator.logging = true
361 # errormator.logging = true
357
362
358 ## minimum log level for log capture
363 ## minimum log level for log capture
359 # errormator.logging.level = WARNING
364 # errormator.logging.level = WARNING
360
365
361 ## send logs only from erroneous/slow requests
366 ## send logs only from erroneous/slow requests
362 ## (saves API quota for intensive logging)
367 ## (saves API quota for intensive logging)
363 errormator.logging_on_error = false
368 errormator.logging_on_error = false
364
369
365 ## list of additonal keywords that should be grabbed from environ object
370 ## list of additonal keywords that should be grabbed from environ object
366 ## can be string with comma separated list of words in lowercase
371 ## can be string with comma separated list of words in lowercase
367 ## (by default client will always send following info:
372 ## (by default client will always send following info:
368 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
373 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
369 ## start with HTTP* this list be extended with additional keywords here
374 ## start with HTTP* this list be extended with additional keywords here
370 errormator.environ_keys_whitelist =
375 errormator.environ_keys_whitelist =
371
376
372
377
373 ## list of keywords that should be blanked from request object
378 ## list of keywords that should be blanked from request object
374 ## can be string with comma separated list of words in lowercase
379 ## can be string with comma separated list of words in lowercase
375 ## (by default client will always blank keys that contain following words
380 ## (by default client will always blank keys that contain following words
376 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
381 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
377 ## this list be extended with additional keywords set here
382 ## this list be extended with additional keywords set here
378 errormator.request_keys_blacklist =
383 errormator.request_keys_blacklist =
379
384
380
385
381 ## list of namespaces that should be ignores when gathering log entries
386 ## list of namespaces that should be ignores when gathering log entries
382 ## can be string with comma separated list of namespaces
387 ## can be string with comma separated list of namespaces
383 ## (by default the client ignores own entries: errormator_client.client)
388 ## (by default the client ignores own entries: errormator_client.client)
384 errormator.log_namespace_blacklist =
389 errormator.log_namespace_blacklist =
385
390
386
391
387 ################
392 ################
388 ### [sentry] ###
393 ### [sentry] ###
389 ################
394 ################
390
395
391 ## sentry is a alternative open source error aggregator
396 ## sentry is a alternative open source error aggregator
392 ## you must install python packages `sentry` and `raven` to enable
397 ## you must install python packages `sentry` and `raven` to enable
393
398
394 sentry.dsn = YOUR_DNS
399 sentry.dsn = YOUR_DNS
395 sentry.servers =
400 sentry.servers =
396 sentry.name =
401 sentry.name =
397 sentry.key =
402 sentry.key =
398 sentry.public_key =
403 sentry.public_key =
399 sentry.secret_key =
404 sentry.secret_key =
400 sentry.project =
405 sentry.project =
401 sentry.site =
406 sentry.site =
402 sentry.include_paths =
407 sentry.include_paths =
403 sentry.exclude_paths =
408 sentry.exclude_paths =
404
409
405
410
406 ################################################################################
411 ################################################################################
407 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
412 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
408 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
413 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
409 ## execute malicious code after an exception is raised. ##
414 ## execute malicious code after an exception is raised. ##
410 ################################################################################
415 ################################################################################
411 set debug = false
416 set debug = false
412
417
413 ##################################
418 ##################################
414 ### LOGVIEW CONFIG ###
419 ### LOGVIEW CONFIG ###
415 ##################################
420 ##################################
416 logview.sqlalchemy = #faa
421 logview.sqlalchemy = #faa
417 logview.pylons.templating = #bfb
422 logview.pylons.templating = #bfb
418 logview.pylons.util = #eee
423 logview.pylons.util = #eee
419
424
420 #########################################################
425 #########################################################
421 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
426 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
422 #########################################################
427 #########################################################
423
428
424 # SQLITE [default]
429 # SQLITE [default]
425 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
430 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
426
431
427 # POSTGRESQL
432 # POSTGRESQL
428 # sqlalchemy.db1.url = postgresql://user:pass@localhost/rhodecode
433 # sqlalchemy.db1.url = postgresql://user:pass@localhost/rhodecode
429
434
430 # MySQL
435 # MySQL
431 # sqlalchemy.db1.url = mysql://user:pass@localhost/rhodecode
436 # sqlalchemy.db1.url = mysql://user:pass@localhost/rhodecode
432
437
433 # see sqlalchemy docs for others
438 # see sqlalchemy docs for others
434
439
435 sqlalchemy.db1.echo = false
440 sqlalchemy.db1.echo = false
436 sqlalchemy.db1.pool_recycle = 3600
441 sqlalchemy.db1.pool_recycle = 3600
437 sqlalchemy.db1.convert_unicode = true
442 sqlalchemy.db1.convert_unicode = true
438
443
439 ################################
444 ################################
440 ### LOGGING CONFIGURATION ####
445 ### LOGGING CONFIGURATION ####
441 ################################
446 ################################
442 [loggers]
447 [loggers]
443 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
448 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
444
449
445 [handlers]
450 [handlers]
446 keys = console, console_sql
451 keys = console, console_sql
447
452
448 [formatters]
453 [formatters]
449 keys = generic, color_formatter, color_formatter_sql
454 keys = generic, color_formatter, color_formatter_sql
450
455
451 #############
456 #############
452 ## LOGGERS ##
457 ## LOGGERS ##
453 #############
458 #############
454 [logger_root]
459 [logger_root]
455 level = NOTSET
460 level = NOTSET
456 handlers = console
461 handlers = console
457
462
458 [logger_routes]
463 [logger_routes]
459 level = DEBUG
464 level = DEBUG
460 handlers =
465 handlers =
461 qualname = routes.middleware
466 qualname = routes.middleware
462 ## "level = DEBUG" logs the route matched and routing variables.
467 ## "level = DEBUG" logs the route matched and routing variables.
463 propagate = 1
468 propagate = 1
464
469
465 [logger_beaker]
470 [logger_beaker]
466 level = DEBUG
471 level = DEBUG
467 handlers =
472 handlers =
468 qualname = beaker.container
473 qualname = beaker.container
469 propagate = 1
474 propagate = 1
470
475
471 [logger_templates]
476 [logger_templates]
472 level = INFO
477 level = INFO
473 handlers =
478 handlers =
474 qualname = pylons.templating
479 qualname = pylons.templating
475 propagate = 1
480 propagate = 1
476
481
477 [logger_rhodecode]
482 [logger_rhodecode]
478 level = DEBUG
483 level = DEBUG
479 handlers =
484 handlers =
480 qualname = rhodecode
485 qualname = rhodecode
481 propagate = 1
486 propagate = 1
482
487
483 [logger_sqlalchemy]
488 [logger_sqlalchemy]
484 level = INFO
489 level = INFO
485 handlers = console_sql
490 handlers = console_sql
486 qualname = sqlalchemy.engine
491 qualname = sqlalchemy.engine
487 propagate = 0
492 propagate = 0
488
493
489 [logger_whoosh_indexer]
494 [logger_whoosh_indexer]
490 level = DEBUG
495 level = DEBUG
491 handlers =
496 handlers =
492 qualname = whoosh_indexer
497 qualname = whoosh_indexer
493 propagate = 1
498 propagate = 1
494
499
495 ##############
500 ##############
496 ## HANDLERS ##
501 ## HANDLERS ##
497 ##############
502 ##############
498
503
499 [handler_console]
504 [handler_console]
500 class = StreamHandler
505 class = StreamHandler
501 args = (sys.stderr,)
506 args = (sys.stderr,)
502 level = INFO
507 level = INFO
503 formatter = generic
508 formatter = generic
504
509
505 [handler_console_sql]
510 [handler_console_sql]
506 class = StreamHandler
511 class = StreamHandler
507 args = (sys.stderr,)
512 args = (sys.stderr,)
508 level = WARN
513 level = WARN
509 formatter = generic
514 formatter = generic
510
515
511 ################
516 ################
512 ## FORMATTERS ##
517 ## FORMATTERS ##
513 ################
518 ################
514
519
515 [formatter_generic]
520 [formatter_generic]
516 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
521 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
517 datefmt = %Y-%m-%d %H:%M:%S
522 datefmt = %Y-%m-%d %H:%M:%S
518
523
519 [formatter_color_formatter]
524 [formatter_color_formatter]
520 class=rhodecode.lib.colored_formatter.ColorFormatter
525 class=rhodecode.lib.colored_formatter.ColorFormatter
521 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
526 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
522 datefmt = %Y-%m-%d %H:%M:%S
527 datefmt = %Y-%m-%d %H:%M:%S
523
528
524 [formatter_color_formatter_sql]
529 [formatter_color_formatter_sql]
525 class=rhodecode.lib.colored_formatter.ColorFormatterSql
530 class=rhodecode.lib.colored_formatter.ColorFormatterSql
526 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
531 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
527 datefmt = %Y-%m-%d %H:%M:%S
532 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,523 +1,524 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.admin.settings
3 rhodecode.controllers.admin.settings
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 settings controller for rhodecode admin
6 settings controller for rhodecode admin
7
7
8 :created_on: Jul 14, 2010
8 :created_on: Jul 14, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 import logging
26 import logging
27 import traceback
27 import traceback
28 import formencode
28 import formencode
29 import pkg_resources
29 import pkg_resources
30 import platform
30 import platform
31
31
32 from sqlalchemy import func
32 from sqlalchemy import func
33 from formencode import htmlfill
33 from formencode import htmlfill
34 from pylons import request, session, tmpl_context as c, url, config
34 from pylons import request, session, tmpl_context as c, url, config
35 from pylons.controllers.util import abort, redirect
35 from pylons.controllers.util import abort, redirect
36 from pylons.i18n.translation import _
36 from pylons.i18n.translation import _
37
37
38 from rhodecode.lib import helpers as h
38 from rhodecode.lib import helpers as h
39 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \
39 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \
40 HasPermissionAnyDecorator, NotAnonymous, HasPermissionAny,\
40 HasPermissionAnyDecorator, NotAnonymous, HasPermissionAny,\
41 HasReposGroupPermissionAll, HasReposGroupPermissionAny, AuthUser
41 HasReposGroupPermissionAll, HasReposGroupPermissionAny, AuthUser
42 from rhodecode.lib.base import BaseController, render
42 from rhodecode.lib.base import BaseController, render
43 from rhodecode.lib.celerylib import tasks, run_task
43 from rhodecode.lib.celerylib import tasks, run_task
44 from rhodecode.lib.utils import repo2db_mapper, set_rhodecode_config, \
44 from rhodecode.lib.utils import repo2db_mapper, set_rhodecode_config, \
45 check_git_version
45 check_git_version
46 from rhodecode.model.db import RhodeCodeUi, Repository, RepoGroup, \
46 from rhodecode.model.db import RhodeCodeUi, Repository, RepoGroup, \
47 RhodeCodeSetting, PullRequest, PullRequestReviewers
47 RhodeCodeSetting, PullRequest, PullRequestReviewers
48 from rhodecode.model.forms import UserForm, ApplicationSettingsForm, \
48 from rhodecode.model.forms import UserForm, ApplicationSettingsForm, \
49 ApplicationUiSettingsForm, ApplicationVisualisationForm
49 ApplicationUiSettingsForm, ApplicationVisualisationForm
50 from rhodecode.model.scm import ScmModel, RepoGroupList
50 from rhodecode.model.scm import ScmModel, RepoGroupList
51 from rhodecode.model.user import UserModel
51 from rhodecode.model.user import UserModel
52 from rhodecode.model.repo import RepoModel
52 from rhodecode.model.repo import RepoModel
53 from rhodecode.model.db import User
53 from rhodecode.model.db import User
54 from rhodecode.model.notification import EmailNotificationModel
54 from rhodecode.model.notification import EmailNotificationModel
55 from rhodecode.model.meta import Session
55 from rhodecode.model.meta import Session
56 from rhodecode.lib.utils2 import str2bool, safe_unicode
56 from rhodecode.lib.utils2 import str2bool, safe_unicode
57 from rhodecode.lib.compat import json
57 from rhodecode.lib.compat import json
58 log = logging.getLogger(__name__)
58 log = logging.getLogger(__name__)
59
59
60
60
61 class SettingsController(BaseController):
61 class SettingsController(BaseController):
62 """REST Controller styled on the Atom Publishing Protocol"""
62 """REST Controller styled on the Atom Publishing Protocol"""
63 # To properly map this controller, ensure your config/routing.py
63 # To properly map this controller, ensure your config/routing.py
64 # file has a resource setup:
64 # file has a resource setup:
65 # map.resource('setting', 'settings', controller='admin/settings',
65 # map.resource('setting', 'settings', controller='admin/settings',
66 # path_prefix='/admin', name_prefix='admin_')
66 # path_prefix='/admin', name_prefix='admin_')
67
67
68 @LoginRequired()
68 @LoginRequired()
69 def __before__(self):
69 def __before__(self):
70 super(SettingsController, self).__before__()
70 super(SettingsController, self).__before__()
71 c.modules = sorted([(p.project_name, p.version)
71 c.modules = sorted([(p.project_name, p.version)
72 for p in pkg_resources.working_set]
72 for p in pkg_resources.working_set]
73 + [('git', check_git_version())],
73 + [('git', check_git_version())],
74 key=lambda k: k[0].lower())
74 key=lambda k: k[0].lower())
75 c.py_version = platform.python_version()
75 c.py_version = platform.python_version()
76 c.platform = platform.platform()
76 c.platform = platform.platform()
77
77
78 @HasPermissionAllDecorator('hg.admin')
78 @HasPermissionAllDecorator('hg.admin')
79 def index(self, format='html'):
79 def index(self, format='html'):
80 """GET /admin/settings: All items in the collection"""
80 """GET /admin/settings: All items in the collection"""
81 # url('admin_settings')
81 # url('admin_settings')
82
82
83 defaults = RhodeCodeSetting.get_app_settings()
83 defaults = RhodeCodeSetting.get_app_settings()
84 defaults.update(self._get_hg_ui_settings())
84 defaults.update(self._get_hg_ui_settings())
85
85
86 return htmlfill.render(
86 return htmlfill.render(
87 render('admin/settings/settings.html'),
87 render('admin/settings/settings.html'),
88 defaults=defaults,
88 defaults=defaults,
89 encoding="UTF-8",
89 encoding="UTF-8",
90 force_defaults=False
90 force_defaults=False
91 )
91 )
92
92
93 @HasPermissionAllDecorator('hg.admin')
93 @HasPermissionAllDecorator('hg.admin')
94 def create(self):
94 def create(self):
95 """POST /admin/settings: Create a new item"""
95 """POST /admin/settings: Create a new item"""
96 # url('admin_settings')
96 # url('admin_settings')
97
97
98 @HasPermissionAllDecorator('hg.admin')
98 @HasPermissionAllDecorator('hg.admin')
99 def new(self, format='html'):
99 def new(self, format='html'):
100 """GET /admin/settings/new: Form to create a new item"""
100 """GET /admin/settings/new: Form to create a new item"""
101 # url('admin_new_setting')
101 # url('admin_new_setting')
102
102
103 @HasPermissionAllDecorator('hg.admin')
103 @HasPermissionAllDecorator('hg.admin')
104 def update(self, setting_id):
104 def update(self, setting_id):
105 """PUT /admin/settings/setting_id: Update an existing item"""
105 """PUT /admin/settings/setting_id: Update an existing item"""
106 # Forms posted to this method should contain a hidden field:
106 # Forms posted to this method should contain a hidden field:
107 # <input type="hidden" name="_method" value="PUT" />
107 # <input type="hidden" name="_method" value="PUT" />
108 # Or using helpers:
108 # Or using helpers:
109 # h.form(url('admin_setting', setting_id=ID),
109 # h.form(url('admin_setting', setting_id=ID),
110 # method='put')
110 # method='put')
111 # url('admin_setting', setting_id=ID)
111 # url('admin_setting', setting_id=ID)
112
112
113 if setting_id == 'mapping':
113 if setting_id == 'mapping':
114 rm_obsolete = request.POST.get('destroy', False)
114 rm_obsolete = request.POST.get('destroy', False)
115 invalidate_cache = request.POST.get('invalidate', False)
115 invalidate_cache = request.POST.get('invalidate', False)
116 log.debug('rescanning repo location with destroy obsolete=%s'
116 log.debug('rescanning repo location with destroy obsolete=%s'
117 % (rm_obsolete,))
117 % (rm_obsolete,))
118
118
119 if invalidate_cache:
119 if invalidate_cache:
120 log.debug('invalidating all repositories cache')
120 log.debug('invalidating all repositories cache')
121 for repo in Repository.get_all():
121 for repo in Repository.get_all():
122 ScmModel().mark_for_invalidation(repo.repo_name)
122 ScmModel().mark_for_invalidation(repo.repo_name)
123
123
124 filesystem_repos = ScmModel().repo_scan()
124 filesystem_repos = ScmModel().repo_scan()
125 added, removed = repo2db_mapper(filesystem_repos, rm_obsolete)
125 added, removed = repo2db_mapper(filesystem_repos, rm_obsolete)
126 _repr = lambda l: ', '.join(map(safe_unicode, l)) or '-'
126 _repr = lambda l: ', '.join(map(safe_unicode, l)) or '-'
127 h.flash(_('Repositories successfully '
127 h.flash(_('Repositories successfully '
128 'rescanned added: %s ; removed: %s') %
128 'rescanned added: %s ; removed: %s') %
129 (_repr(added), _repr(removed)),
129 (_repr(added), _repr(removed)),
130 category='success')
130 category='success')
131
131
132 if setting_id == 'whoosh':
132 if setting_id == 'whoosh':
133 repo_location = self._get_hg_ui_settings()['paths_root_path']
133 repo_location = self._get_hg_ui_settings()['paths_root_path']
134 full_index = request.POST.get('full_index', False)
134 full_index = request.POST.get('full_index', False)
135 run_task(tasks.whoosh_index, repo_location, full_index)
135 run_task(tasks.whoosh_index, repo_location, full_index)
136 h.flash(_('Whoosh reindex task scheduled'), category='success')
136 h.flash(_('Whoosh reindex task scheduled'), category='success')
137
137
138 if setting_id == 'global':
138 if setting_id == 'global':
139
139
140 application_form = ApplicationSettingsForm()()
140 application_form = ApplicationSettingsForm()()
141 try:
141 try:
142 form_result = application_form.to_python(dict(request.POST))
142 form_result = application_form.to_python(dict(request.POST))
143 except formencode.Invalid, errors:
143 except formencode.Invalid, errors:
144 return htmlfill.render(
144 return htmlfill.render(
145 render('admin/settings/settings.html'),
145 render('admin/settings/settings.html'),
146 defaults=errors.value,
146 defaults=errors.value,
147 errors=errors.error_dict or {},
147 errors=errors.error_dict or {},
148 prefix_error=False,
148 prefix_error=False,
149 encoding="UTF-8"
149 encoding="UTF-8"
150 )
150 )
151
151
152 try:
152 try:
153 sett1 = RhodeCodeSetting.get_by_name_or_create('title')
153 sett1 = RhodeCodeSetting.get_by_name_or_create('title')
154 sett1.app_settings_value = form_result['rhodecode_title']
154 sett1.app_settings_value = form_result['rhodecode_title']
155 Session().add(sett1)
155 Session().add(sett1)
156
156
157 sett2 = RhodeCodeSetting.get_by_name_or_create('realm')
157 sett2 = RhodeCodeSetting.get_by_name_or_create('realm')
158 sett2.app_settings_value = form_result['rhodecode_realm']
158 sett2.app_settings_value = form_result['rhodecode_realm']
159 Session().add(sett2)
159 Session().add(sett2)
160
160
161 sett3 = RhodeCodeSetting.get_by_name_or_create('ga_code')
161 sett3 = RhodeCodeSetting.get_by_name_or_create('ga_code')
162 sett3.app_settings_value = form_result['rhodecode_ga_code']
162 sett3.app_settings_value = form_result['rhodecode_ga_code']
163 Session().add(sett3)
163 Session().add(sett3)
164
164
165 Session().commit()
165 Session().commit()
166 set_rhodecode_config(config)
166 set_rhodecode_config(config)
167 h.flash(_('Updated application settings'), category='success')
167 h.flash(_('Updated application settings'), category='success')
168
168
169 except Exception:
169 except Exception:
170 log.error(traceback.format_exc())
170 log.error(traceback.format_exc())
171 h.flash(_('Error occurred during updating '
171 h.flash(_('Error occurred during updating '
172 'application settings'),
172 'application settings'),
173 category='error')
173 category='error')
174
174
175 if setting_id == 'visual':
175 if setting_id == 'visual':
176
176
177 application_form = ApplicationVisualisationForm()()
177 application_form = ApplicationVisualisationForm()()
178 try:
178 try:
179 form_result = application_form.to_python(dict(request.POST))
179 form_result = application_form.to_python(dict(request.POST))
180 except formencode.Invalid, errors:
180 except formencode.Invalid, errors:
181 return htmlfill.render(
181 return htmlfill.render(
182 render('admin/settings/settings.html'),
182 render('admin/settings/settings.html'),
183 defaults=errors.value,
183 defaults=errors.value,
184 errors=errors.error_dict or {},
184 errors=errors.error_dict or {},
185 prefix_error=False,
185 prefix_error=False,
186 encoding="UTF-8"
186 encoding="UTF-8"
187 )
187 )
188
188
189 try:
189 try:
190 #TODO: rewrite this to something less ugly
190 #TODO: rewrite this to something less ugly
191 sett1 = RhodeCodeSetting.get_by_name_or_create('show_public_icon')
191 sett1 = RhodeCodeSetting.get_by_name_or_create('show_public_icon')
192 sett1.app_settings_value = \
192 sett1.app_settings_value = \
193 form_result['rhodecode_show_public_icon']
193 form_result['rhodecode_show_public_icon']
194 Session().add(sett1)
194 Session().add(sett1)
195
195
196 sett2 = RhodeCodeSetting.get_by_name_or_create('show_private_icon')
196 sett2 = RhodeCodeSetting.get_by_name_or_create('show_private_icon')
197 sett2.app_settings_value = \
197 sett2.app_settings_value = \
198 form_result['rhodecode_show_private_icon']
198 form_result['rhodecode_show_private_icon']
199 Session().add(sett2)
199 Session().add(sett2)
200
200
201 sett3 = RhodeCodeSetting.get_by_name_or_create('stylify_metatags')
201 sett3 = RhodeCodeSetting.get_by_name_or_create('stylify_metatags')
202 sett3.app_settings_value = \
202 sett3.app_settings_value = \
203 form_result['rhodecode_stylify_metatags']
203 form_result['rhodecode_stylify_metatags']
204 Session().add(sett3)
204 Session().add(sett3)
205
205
206 sett4 = RhodeCodeSetting.get_by_name_or_create('repository_fields')
206 sett4 = RhodeCodeSetting.get_by_name_or_create('repository_fields')
207 sett4.app_settings_value = \
207 sett4.app_settings_value = \
208 form_result['rhodecode_repository_fields']
208 form_result['rhodecode_repository_fields']
209 Session().add(sett4)
209 Session().add(sett4)
210
210
211 sett5 = RhodeCodeSetting.get_by_name_or_create('dashboard_items')
211 sett5 = RhodeCodeSetting.get_by_name_or_create('dashboard_items')
212 sett5.app_settings_value = \
212 sett5.app_settings_value = \
213 form_result['rhodecode_dashboard_items']
213 form_result['rhodecode_dashboard_items']
214 Session().add(sett5)
214 Session().add(sett5)
215
215
216 sett6 = RhodeCodeSetting.get_by_name_or_create('show_version')
216 sett6 = RhodeCodeSetting.get_by_name_or_create('show_version')
217 sett6.app_settings_value = \
217 sett6.app_settings_value = \
218 form_result['rhodecode_show_version']
218 form_result['rhodecode_show_version']
219 Session().add(sett6)
219 Session().add(sett6)
220
220
221 Session().commit()
221 Session().commit()
222 set_rhodecode_config(config)
222 set_rhodecode_config(config)
223 h.flash(_('Updated visualisation settings'),
223 h.flash(_('Updated visualisation settings'),
224 category='success')
224 category='success')
225
225
226 except Exception:
226 except Exception:
227 log.error(traceback.format_exc())
227 log.error(traceback.format_exc())
228 h.flash(_('Error occurred during updating '
228 h.flash(_('Error occurred during updating '
229 'visualisation settings'),
229 'visualisation settings'),
230 category='error')
230 category='error')
231
231
232 if setting_id == 'vcs':
232 if setting_id == 'vcs':
233 application_form = ApplicationUiSettingsForm()()
233 application_form = ApplicationUiSettingsForm()()
234 try:
234 try:
235 form_result = application_form.to_python(dict(request.POST))
235 form_result = application_form.to_python(dict(request.POST))
236 except formencode.Invalid, errors:
236 except formencode.Invalid, errors:
237 return htmlfill.render(
237 return htmlfill.render(
238 render('admin/settings/settings.html'),
238 render('admin/settings/settings.html'),
239 defaults=errors.value,
239 defaults=errors.value,
240 errors=errors.error_dict or {},
240 errors=errors.error_dict or {},
241 prefix_error=False,
241 prefix_error=False,
242 encoding="UTF-8"
242 encoding="UTF-8"
243 )
243 )
244
244
245 try:
245 try:
246 sett = RhodeCodeUi.get_by_key('push_ssl')
246 sett = RhodeCodeUi.get_by_key('push_ssl')
247 sett.ui_value = form_result['web_push_ssl']
247 sett.ui_value = form_result['web_push_ssl']
248 Session().add(sett)
248 Session().add(sett)
249 if c.visual.allow_repo_location_change:
249 if c.visual.allow_repo_location_change:
250 sett = RhodeCodeUi.get_by_key('/')
250 sett = RhodeCodeUi.get_by_key('/')
251 sett.ui_value = form_result['paths_root_path']
251 sett.ui_value = form_result['paths_root_path']
252 Session().add(sett)
252 Session().add(sett)
253
253
254 #HOOKS
254 #HOOKS
255 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_UPDATE)
255 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_UPDATE)
256 sett.ui_active = form_result['hooks_changegroup_update']
256 sett.ui_active = form_result['hooks_changegroup_update']
257 Session().add(sett)
257 Session().add(sett)
258
258
259 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_REPO_SIZE)
259 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_REPO_SIZE)
260 sett.ui_active = form_result['hooks_changegroup_repo_size']
260 sett.ui_active = form_result['hooks_changegroup_repo_size']
261 Session().add(sett)
261 Session().add(sett)
262
262
263 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_PUSH)
263 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_PUSH)
264 sett.ui_active = form_result['hooks_changegroup_push_logger']
264 sett.ui_active = form_result['hooks_changegroup_push_logger']
265 Session().add(sett)
265 Session().add(sett)
266
266
267 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_PULL)
267 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_PULL)
268 sett.ui_active = form_result['hooks_outgoing_pull_logger']
268 sett.ui_active = form_result['hooks_outgoing_pull_logger']
269
269
270 Session().add(sett)
270 Session().add(sett)
271
271
272 ## EXTENSIONS
272 ## EXTENSIONS
273 sett = RhodeCodeUi.get_by_key('largefiles')
273 sett = RhodeCodeUi.get_by_key('largefiles')
274 if not sett:
274 if not sett:
275 #make one if it's not there !
275 #make one if it's not there !
276 sett = RhodeCodeUi()
276 sett = RhodeCodeUi()
277 sett.ui_key = 'largefiles'
277 sett.ui_key = 'largefiles'
278 sett.ui_section = 'extensions'
278 sett.ui_section = 'extensions'
279 sett.ui_active = form_result['extensions_largefiles']
279 sett.ui_active = form_result['extensions_largefiles']
280 Session().add(sett)
280 Session().add(sett)
281
281
282 sett = RhodeCodeUi.get_by_key('hgsubversion')
282 sett = RhodeCodeUi.get_by_key('hgsubversion')
283 if not sett:
283 if not sett:
284 #make one if it's not there !
284 #make one if it's not there !
285 sett = RhodeCodeUi()
285 sett = RhodeCodeUi()
286 sett.ui_key = 'hgsubversion'
286 sett.ui_key = 'hgsubversion'
287 sett.ui_section = 'extensions'
287 sett.ui_section = 'extensions'
288
288
289 sett.ui_active = form_result['extensions_hgsubversion']
289 sett.ui_active = form_result['extensions_hgsubversion']
290 Session().add(sett)
290 Session().add(sett)
291
291
292 # sett = RhodeCodeUi.get_by_key('hggit')
292 # sett = RhodeCodeUi.get_by_key('hggit')
293 # if not sett:
293 # if not sett:
294 # #make one if it's not there !
294 # #make one if it's not there !
295 # sett = RhodeCodeUi()
295 # sett = RhodeCodeUi()
296 # sett.ui_key = 'hggit'
296 # sett.ui_key = 'hggit'
297 # sett.ui_section = 'extensions'
297 # sett.ui_section = 'extensions'
298 #
298 #
299 # sett.ui_active = form_result['extensions_hggit']
299 # sett.ui_active = form_result['extensions_hggit']
300 # Session().add(sett)
300 # Session().add(sett)
301
301
302 Session().commit()
302 Session().commit()
303
303
304 h.flash(_('Updated VCS settings'), category='success')
304 h.flash(_('Updated VCS settings'), category='success')
305
305
306 except Exception:
306 except Exception:
307 log.error(traceback.format_exc())
307 log.error(traceback.format_exc())
308 h.flash(_('Error occurred during updating '
308 h.flash(_('Error occurred during updating '
309 'application settings'), category='error')
309 'application settings'), category='error')
310
310
311 if setting_id == 'hooks':
311 if setting_id == 'hooks':
312 ui_key = request.POST.get('new_hook_ui_key')
312 if c.visual.allow_custom_hooks_settings:
313 ui_value = request.POST.get('new_hook_ui_value')
313 ui_key = request.POST.get('new_hook_ui_key')
314 try:
314 ui_value = request.POST.get('new_hook_ui_value')
315 try:
315
316
316 if ui_value and ui_key:
317 if ui_value and ui_key:
317 RhodeCodeUi.create_or_update_hook(ui_key, ui_value)
318 RhodeCodeUi.create_or_update_hook(ui_key, ui_value)
318 h.flash(_('Added new hook'),
319 h.flash(_('Added new hook'),
319 category='success')
320 category='success')
320
321
321 # check for edits
322 # check for edits
322 update = False
323 update = False
323 _d = request.POST.dict_of_lists()
324 _d = request.POST.dict_of_lists()
324 for k, v in zip(_d.get('hook_ui_key', []),
325 for k, v in zip(_d.get('hook_ui_key', []),
325 _d.get('hook_ui_value_new', [])):
326 _d.get('hook_ui_value_new', [])):
326 RhodeCodeUi.create_or_update_hook(k, v)
327 RhodeCodeUi.create_or_update_hook(k, v)
327 update = True
328 update = True
328
329
329 if update:
330 if update:
330 h.flash(_('Updated hooks'), category='success')
331 h.flash(_('Updated hooks'), category='success')
331 Session().commit()
332 Session().commit()
332 except Exception:
333 except Exception:
333 log.error(traceback.format_exc())
334 log.error(traceback.format_exc())
334 h.flash(_('Error occurred during hook creation'),
335 h.flash(_('Error occurred during hook creation'),
335 category='error')
336 category='error')
336
337
337 return redirect(url('admin_edit_setting', setting_id='hooks'))
338 return redirect(url('admin_edit_setting', setting_id='hooks'))
338
339
339 if setting_id == 'email':
340 if setting_id == 'email':
340 test_email = request.POST.get('test_email')
341 test_email = request.POST.get('test_email')
341 test_email_subj = 'RhodeCode TestEmail'
342 test_email_subj = 'RhodeCode TestEmail'
342 test_email_body = 'RhodeCode Email test'
343 test_email_body = 'RhodeCode Email test'
343
344
344 test_email_html_body = EmailNotificationModel()\
345 test_email_html_body = EmailNotificationModel()\
345 .get_email_tmpl(EmailNotificationModel.TYPE_DEFAULT,
346 .get_email_tmpl(EmailNotificationModel.TYPE_DEFAULT,
346 body=test_email_body)
347 body=test_email_body)
347
348
348 recipients = [test_email] if test_email else None
349 recipients = [test_email] if test_email else None
349
350
350 run_task(tasks.send_email, recipients, test_email_subj,
351 run_task(tasks.send_email, recipients, test_email_subj,
351 test_email_body, test_email_html_body)
352 test_email_body, test_email_html_body)
352
353
353 h.flash(_('Email task created'), category='success')
354 h.flash(_('Email task created'), category='success')
354 return redirect(url('admin_settings'))
355 return redirect(url('admin_settings'))
355
356
356 @HasPermissionAllDecorator('hg.admin')
357 @HasPermissionAllDecorator('hg.admin')
357 def delete(self, setting_id):
358 def delete(self, setting_id):
358 """DELETE /admin/settings/setting_id: Delete an existing item"""
359 """DELETE /admin/settings/setting_id: Delete an existing item"""
359 # Forms posted to this method should contain a hidden field:
360 # Forms posted to this method should contain a hidden field:
360 # <input type="hidden" name="_method" value="DELETE" />
361 # <input type="hidden" name="_method" value="DELETE" />
361 # Or using helpers:
362 # Or using helpers:
362 # h.form(url('admin_setting', setting_id=ID),
363 # h.form(url('admin_setting', setting_id=ID),
363 # method='delete')
364 # method='delete')
364 # url('admin_setting', setting_id=ID)
365 # url('admin_setting', setting_id=ID)
365 if setting_id == 'hooks':
366 if setting_id == 'hooks':
366 hook_id = request.POST.get('hook_id')
367 hook_id = request.POST.get('hook_id')
367 RhodeCodeUi.delete(hook_id)
368 RhodeCodeUi.delete(hook_id)
368 Session().commit()
369 Session().commit()
369
370
370 @HasPermissionAllDecorator('hg.admin')
371 @HasPermissionAllDecorator('hg.admin')
371 def show(self, setting_id, format='html'):
372 def show(self, setting_id, format='html'):
372 """
373 """
373 GET /admin/settings/setting_id: Show a specific item"""
374 GET /admin/settings/setting_id: Show a specific item"""
374 # url('admin_setting', setting_id=ID)
375 # url('admin_setting', setting_id=ID)
375
376
376 @HasPermissionAllDecorator('hg.admin')
377 @HasPermissionAllDecorator('hg.admin')
377 def edit(self, setting_id, format='html'):
378 def edit(self, setting_id, format='html'):
378 """
379 """
379 GET /admin/settings/setting_id/edit: Form to
380 GET /admin/settings/setting_id/edit: Form to
380 edit an existing item"""
381 edit an existing item"""
381 # url('admin_edit_setting', setting_id=ID)
382 # url('admin_edit_setting', setting_id=ID)
382
383
383 c.hooks = RhodeCodeUi.get_builtin_hooks()
384 c.hooks = RhodeCodeUi.get_builtin_hooks()
384 c.custom_hooks = RhodeCodeUi.get_custom_hooks()
385 c.custom_hooks = RhodeCodeUi.get_custom_hooks()
385
386
386 return htmlfill.render(
387 return htmlfill.render(
387 render('admin/settings/hooks.html'),
388 render('admin/settings/hooks.html'),
388 defaults={},
389 defaults={},
389 encoding="UTF-8",
390 encoding="UTF-8",
390 force_defaults=False
391 force_defaults=False
391 )
392 )
392
393
393 def _load_my_repos_data(self):
394 def _load_my_repos_data(self):
394 repos_list = Session().query(Repository)\
395 repos_list = Session().query(Repository)\
395 .filter(Repository.user_id ==
396 .filter(Repository.user_id ==
396 self.rhodecode_user.user_id)\
397 self.rhodecode_user.user_id)\
397 .order_by(func.lower(Repository.repo_name)).all()
398 .order_by(func.lower(Repository.repo_name)).all()
398
399
399 repos_data = RepoModel().get_repos_as_dict(repos_list=repos_list,
400 repos_data = RepoModel().get_repos_as_dict(repos_list=repos_list,
400 admin=True)
401 admin=True)
401 #json used to render the grid
402 #json used to render the grid
402 return json.dumps(repos_data)
403 return json.dumps(repos_data)
403
404
404 @NotAnonymous()
405 @NotAnonymous()
405 def my_account(self):
406 def my_account(self):
406 """
407 """
407 GET /_admin/my_account Displays info about my account
408 GET /_admin/my_account Displays info about my account
408 """
409 """
409 # url('admin_settings_my_account')
410 # url('admin_settings_my_account')
410
411
411 c.user = User.get(self.rhodecode_user.user_id)
412 c.user = User.get(self.rhodecode_user.user_id)
412 c.perm_user = AuthUser(user_id=self.rhodecode_user.user_id,
413 c.perm_user = AuthUser(user_id=self.rhodecode_user.user_id,
413 ip_addr=self.ip_addr)
414 ip_addr=self.ip_addr)
414 c.ldap_dn = c.user.ldap_dn
415 c.ldap_dn = c.user.ldap_dn
415
416
416 if c.user.username == 'default':
417 if c.user.username == 'default':
417 h.flash(_("You can't edit this user since it's"
418 h.flash(_("You can't edit this user since it's"
418 " crucial for entire application"), category='warning')
419 " crucial for entire application"), category='warning')
419 return redirect(url('users'))
420 return redirect(url('users'))
420
421
421 #json used to render the grid
422 #json used to render the grid
422 c.data = self._load_my_repos_data()
423 c.data = self._load_my_repos_data()
423
424
424 defaults = c.user.get_dict()
425 defaults = c.user.get_dict()
425
426
426 c.form = htmlfill.render(
427 c.form = htmlfill.render(
427 render('admin/users/user_edit_my_account_form.html'),
428 render('admin/users/user_edit_my_account_form.html'),
428 defaults=defaults,
429 defaults=defaults,
429 encoding="UTF-8",
430 encoding="UTF-8",
430 force_defaults=False
431 force_defaults=False
431 )
432 )
432 return render('admin/users/user_edit_my_account.html')
433 return render('admin/users/user_edit_my_account.html')
433
434
434 @NotAnonymous()
435 @NotAnonymous()
435 def my_account_update(self):
436 def my_account_update(self):
436 """PUT /_admin/my_account_update: Update an existing item"""
437 """PUT /_admin/my_account_update: Update an existing item"""
437 # Forms posted to this method should contain a hidden field:
438 # Forms posted to this method should contain a hidden field:
438 # <input type="hidden" name="_method" value="PUT" />
439 # <input type="hidden" name="_method" value="PUT" />
439 # Or using helpers:
440 # Or using helpers:
440 # h.form(url('admin_settings_my_account_update'),
441 # h.form(url('admin_settings_my_account_update'),
441 # method='put')
442 # method='put')
442 # url('admin_settings_my_account_update', id=ID)
443 # url('admin_settings_my_account_update', id=ID)
443 uid = self.rhodecode_user.user_id
444 uid = self.rhodecode_user.user_id
444 c.user = User.get(self.rhodecode_user.user_id)
445 c.user = User.get(self.rhodecode_user.user_id)
445 c.perm_user = AuthUser(user_id=self.rhodecode_user.user_id,
446 c.perm_user = AuthUser(user_id=self.rhodecode_user.user_id,
446 ip_addr=self.ip_addr)
447 ip_addr=self.ip_addr)
447 c.ldap_dn = c.user.ldap_dn
448 c.ldap_dn = c.user.ldap_dn
448 email = self.rhodecode_user.email
449 email = self.rhodecode_user.email
449 _form = UserForm(edit=True,
450 _form = UserForm(edit=True,
450 old_data={'user_id': uid, 'email': email})()
451 old_data={'user_id': uid, 'email': email})()
451 form_result = {}
452 form_result = {}
452 try:
453 try:
453 form_result = _form.to_python(dict(request.POST))
454 form_result = _form.to_python(dict(request.POST))
454 skip_attrs = ['admin', 'active'] # skip attr for my account
455 skip_attrs = ['admin', 'active'] # skip attr for my account
455 if c.ldap_dn:
456 if c.ldap_dn:
456 #forbid updating username for ldap accounts
457 #forbid updating username for ldap accounts
457 skip_attrs.append('username')
458 skip_attrs.append('username')
458 UserModel().update(uid, form_result, skip_attrs=skip_attrs)
459 UserModel().update(uid, form_result, skip_attrs=skip_attrs)
459 h.flash(_('Your account was updated successfully'),
460 h.flash(_('Your account was updated successfully'),
460 category='success')
461 category='success')
461 Session().commit()
462 Session().commit()
462 except formencode.Invalid, errors:
463 except formencode.Invalid, errors:
463 #json used to render the grid
464 #json used to render the grid
464 c.data = self._load_my_repos_data()
465 c.data = self._load_my_repos_data()
465 c.form = htmlfill.render(
466 c.form = htmlfill.render(
466 render('admin/users/user_edit_my_account_form.html'),
467 render('admin/users/user_edit_my_account_form.html'),
467 defaults=errors.value,
468 defaults=errors.value,
468 errors=errors.error_dict or {},
469 errors=errors.error_dict or {},
469 prefix_error=False,
470 prefix_error=False,
470 encoding="UTF-8")
471 encoding="UTF-8")
471 return render('admin/users/user_edit_my_account.html')
472 return render('admin/users/user_edit_my_account.html')
472 except Exception:
473 except Exception:
473 log.error(traceback.format_exc())
474 log.error(traceback.format_exc())
474 h.flash(_('Error occurred during update of user %s') \
475 h.flash(_('Error occurred during update of user %s') \
475 % form_result.get('username'), category='error')
476 % form_result.get('username'), category='error')
476
477
477 return redirect(url('my_account'))
478 return redirect(url('my_account'))
478
479
479 @NotAnonymous()
480 @NotAnonymous()
480 def my_account_my_pullrequests(self):
481 def my_account_my_pullrequests(self):
481 c.show_closed = request.GET.get('pr_show_closed')
482 c.show_closed = request.GET.get('pr_show_closed')
482
483
483 def _filter(pr):
484 def _filter(pr):
484 s = sorted(pr, key=lambda o: o.created_on, reverse=True)
485 s = sorted(pr, key=lambda o: o.created_on, reverse=True)
485 if not c.show_closed:
486 if not c.show_closed:
486 s = filter(lambda p: p.status != PullRequest.STATUS_CLOSED, s)
487 s = filter(lambda p: p.status != PullRequest.STATUS_CLOSED, s)
487 return s
488 return s
488
489
489 c.my_pull_requests = _filter(PullRequest.query()\
490 c.my_pull_requests = _filter(PullRequest.query()\
490 .filter(PullRequest.user_id ==
491 .filter(PullRequest.user_id ==
491 self.rhodecode_user.user_id)\
492 self.rhodecode_user.user_id)\
492 .all())
493 .all())
493
494
494 c.participate_in_pull_requests = _filter([
495 c.participate_in_pull_requests = _filter([
495 x.pull_request for x in PullRequestReviewers.query()\
496 x.pull_request for x in PullRequestReviewers.query()\
496 .filter(PullRequestReviewers.user_id ==
497 .filter(PullRequestReviewers.user_id ==
497 self.rhodecode_user.user_id).all()])
498 self.rhodecode_user.user_id).all()])
498
499
499 return render('admin/users/user_edit_my_account_pullrequests.html')
500 return render('admin/users/user_edit_my_account_pullrequests.html')
500
501
501 def _get_hg_ui_settings(self):
502 def _get_hg_ui_settings(self):
502 ret = RhodeCodeUi.query().all()
503 ret = RhodeCodeUi.query().all()
503
504
504 if not ret:
505 if not ret:
505 raise Exception('Could not get application ui settings !')
506 raise Exception('Could not get application ui settings !')
506 settings = {}
507 settings = {}
507 for each in ret:
508 for each in ret:
508 k = each.ui_key
509 k = each.ui_key
509 v = each.ui_value
510 v = each.ui_value
510 if k == '/':
511 if k == '/':
511 k = 'root_path'
512 k = 'root_path'
512
513
513 if k == 'push_ssl':
514 if k == 'push_ssl':
514 v = str2bool(v)
515 v = str2bool(v)
515
516
516 if k.find('.') != -1:
517 if k.find('.') != -1:
517 k = k.replace('.', '_')
518 k = k.replace('.', '_')
518
519
519 if each.ui_section in ['hooks', 'extensions']:
520 if each.ui_section in ['hooks', 'extensions']:
520 v = each.ui_active
521 v = each.ui_active
521
522
522 settings[each.ui_section + '_' + k] = v
523 settings[each.ui_section + '_' + k] = v
523 return settings
524 return settings
@@ -1,349 +1,350 b''
1 """The base Controller API
1 """The base Controller API
2
2
3 Provides the BaseController class for subclassing.
3 Provides the BaseController class for subclassing.
4 """
4 """
5 import logging
5 import logging
6 import time
6 import time
7 import traceback
7 import traceback
8
8
9 from paste.auth.basic import AuthBasicAuthenticator
9 from paste.auth.basic import AuthBasicAuthenticator
10 from paste.httpexceptions import HTTPUnauthorized, HTTPForbidden
10 from paste.httpexceptions import HTTPUnauthorized, HTTPForbidden
11 from paste.httpheaders import WWW_AUTHENTICATE, AUTHORIZATION
11 from paste.httpheaders import WWW_AUTHENTICATE, AUTHORIZATION
12
12
13 from pylons import config, tmpl_context as c, request, session, url
13 from pylons import config, tmpl_context as c, request, session, url
14 from pylons.controllers import WSGIController
14 from pylons.controllers import WSGIController
15 from pylons.controllers.util import redirect
15 from pylons.controllers.util import redirect
16 from pylons.templating import render_mako as render
16 from pylons.templating import render_mako as render
17
17
18 from rhodecode import __version__, BACKENDS
18 from rhodecode import __version__, BACKENDS
19
19
20 from rhodecode.lib.utils2 import str2bool, safe_unicode, AttributeDict,\
20 from rhodecode.lib.utils2 import str2bool, safe_unicode, AttributeDict,\
21 safe_str, safe_int
21 safe_str, safe_int
22 from rhodecode.lib.auth import AuthUser, get_container_username, authfunc,\
22 from rhodecode.lib.auth import AuthUser, get_container_username, authfunc,\
23 HasPermissionAnyMiddleware, CookieStoreWrapper
23 HasPermissionAnyMiddleware, CookieStoreWrapper
24 from rhodecode.lib.utils import get_repo_slug
24 from rhodecode.lib.utils import get_repo_slug
25 from rhodecode.model import meta
25 from rhodecode.model import meta
26
26
27 from rhodecode.model.db import Repository, RhodeCodeUi, User, RhodeCodeSetting
27 from rhodecode.model.db import Repository, RhodeCodeUi, User, RhodeCodeSetting
28 from rhodecode.model.notification import NotificationModel
28 from rhodecode.model.notification import NotificationModel
29 from rhodecode.model.scm import ScmModel
29 from rhodecode.model.scm import ScmModel
30 from rhodecode.model.meta import Session
30 from rhodecode.model.meta import Session
31
31
32 log = logging.getLogger(__name__)
32 log = logging.getLogger(__name__)
33
33
34
34
35 def _filter_proxy(ip):
35 def _filter_proxy(ip):
36 """
36 """
37 HEADERS can have multiple ips inside the left-most being the original
37 HEADERS can have multiple ips inside the left-most being the original
38 client, and each successive proxy that passed the request adding the IP
38 client, and each successive proxy that passed the request adding the IP
39 address where it received the request from.
39 address where it received the request from.
40
40
41 :param ip:
41 :param ip:
42 """
42 """
43 if ',' in ip:
43 if ',' in ip:
44 _ips = ip.split(',')
44 _ips = ip.split(',')
45 _first_ip = _ips[0].strip()
45 _first_ip = _ips[0].strip()
46 log.debug('Got multiple IPs %s, using %s' % (','.join(_ips), _first_ip))
46 log.debug('Got multiple IPs %s, using %s' % (','.join(_ips), _first_ip))
47 return _first_ip
47 return _first_ip
48 return ip
48 return ip
49
49
50
50
51 def _get_ip_addr(environ):
51 def _get_ip_addr(environ):
52 proxy_key = 'HTTP_X_REAL_IP'
52 proxy_key = 'HTTP_X_REAL_IP'
53 proxy_key2 = 'HTTP_X_FORWARDED_FOR'
53 proxy_key2 = 'HTTP_X_FORWARDED_FOR'
54 def_key = 'REMOTE_ADDR'
54 def_key = 'REMOTE_ADDR'
55
55
56 ip = environ.get(proxy_key)
56 ip = environ.get(proxy_key)
57 if ip:
57 if ip:
58 return _filter_proxy(ip)
58 return _filter_proxy(ip)
59
59
60 ip = environ.get(proxy_key2)
60 ip = environ.get(proxy_key2)
61 if ip:
61 if ip:
62 return _filter_proxy(ip)
62 return _filter_proxy(ip)
63
63
64 ip = environ.get(def_key, '0.0.0.0')
64 ip = environ.get(def_key, '0.0.0.0')
65 return _filter_proxy(ip)
65 return _filter_proxy(ip)
66
66
67
67
68 def _get_access_path(environ):
68 def _get_access_path(environ):
69 path = environ.get('PATH_INFO')
69 path = environ.get('PATH_INFO')
70 org_req = environ.get('pylons.original_request')
70 org_req = environ.get('pylons.original_request')
71 if org_req:
71 if org_req:
72 path = org_req.environ.get('PATH_INFO')
72 path = org_req.environ.get('PATH_INFO')
73 return path
73 return path
74
74
75
75
76 class BasicAuth(AuthBasicAuthenticator):
76 class BasicAuth(AuthBasicAuthenticator):
77
77
78 def __init__(self, realm, authfunc, auth_http_code=None):
78 def __init__(self, realm, authfunc, auth_http_code=None):
79 self.realm = realm
79 self.realm = realm
80 self.authfunc = authfunc
80 self.authfunc = authfunc
81 self._rc_auth_http_code = auth_http_code
81 self._rc_auth_http_code = auth_http_code
82
82
83 def build_authentication(self):
83 def build_authentication(self):
84 head = WWW_AUTHENTICATE.tuples('Basic realm="%s"' % self.realm)
84 head = WWW_AUTHENTICATE.tuples('Basic realm="%s"' % self.realm)
85 if self._rc_auth_http_code and self._rc_auth_http_code == '403':
85 if self._rc_auth_http_code and self._rc_auth_http_code == '403':
86 # return 403 if alternative http return code is specified in
86 # return 403 if alternative http return code is specified in
87 # RhodeCode config
87 # RhodeCode config
88 return HTTPForbidden(headers=head)
88 return HTTPForbidden(headers=head)
89 return HTTPUnauthorized(headers=head)
89 return HTTPUnauthorized(headers=head)
90
90
91 def authenticate(self, environ):
91 def authenticate(self, environ):
92 authorization = AUTHORIZATION(environ)
92 authorization = AUTHORIZATION(environ)
93 if not authorization:
93 if not authorization:
94 return self.build_authentication()
94 return self.build_authentication()
95 (authmeth, auth) = authorization.split(' ', 1)
95 (authmeth, auth) = authorization.split(' ', 1)
96 if 'basic' != authmeth.lower():
96 if 'basic' != authmeth.lower():
97 return self.build_authentication()
97 return self.build_authentication()
98 auth = auth.strip().decode('base64')
98 auth = auth.strip().decode('base64')
99 _parts = auth.split(':', 1)
99 _parts = auth.split(':', 1)
100 if len(_parts) == 2:
100 if len(_parts) == 2:
101 username, password = _parts
101 username, password = _parts
102 if self.authfunc(environ, username, password):
102 if self.authfunc(environ, username, password):
103 return username
103 return username
104 return self.build_authentication()
104 return self.build_authentication()
105
105
106 __call__ = authenticate
106 __call__ = authenticate
107
107
108
108
109 class BaseVCSController(object):
109 class BaseVCSController(object):
110
110
111 def __init__(self, application, config):
111 def __init__(self, application, config):
112 self.application = application
112 self.application = application
113 self.config = config
113 self.config = config
114 # base path of repo locations
114 # base path of repo locations
115 self.basepath = self.config['base_path']
115 self.basepath = self.config['base_path']
116 #authenticate this mercurial request using authfunc
116 #authenticate this mercurial request using authfunc
117 self.authenticate = BasicAuth('', authfunc,
117 self.authenticate = BasicAuth('', authfunc,
118 config.get('auth_ret_code'))
118 config.get('auth_ret_code'))
119 self.ip_addr = '0.0.0.0'
119 self.ip_addr = '0.0.0.0'
120
120
121 def _handle_request(self, environ, start_response):
121 def _handle_request(self, environ, start_response):
122 raise NotImplementedError()
122 raise NotImplementedError()
123
123
124 def _get_by_id(self, repo_name):
124 def _get_by_id(self, repo_name):
125 """
125 """
126 Get's a special pattern _<ID> from clone url and tries to replace it
126 Get's a special pattern _<ID> from clone url and tries to replace it
127 with a repository_name for support of _<ID> non changable urls
127 with a repository_name for support of _<ID> non changable urls
128
128
129 :param repo_name:
129 :param repo_name:
130 """
130 """
131 try:
131 try:
132 data = repo_name.split('/')
132 data = repo_name.split('/')
133 if len(data) >= 2:
133 if len(data) >= 2:
134 by_id = data[1].split('_')
134 by_id = data[1].split('_')
135 if len(by_id) == 2 and by_id[1].isdigit():
135 if len(by_id) == 2 and by_id[1].isdigit():
136 _repo_name = Repository.get(by_id[1]).repo_name
136 _repo_name = Repository.get(by_id[1]).repo_name
137 data[1] = _repo_name
137 data[1] = _repo_name
138 except Exception:
138 except Exception:
139 log.debug('Failed to extract repo_name from id %s' % (
139 log.debug('Failed to extract repo_name from id %s' % (
140 traceback.format_exc()
140 traceback.format_exc()
141 )
141 )
142 )
142 )
143
143
144 return '/'.join(data)
144 return '/'.join(data)
145
145
146 def _invalidate_cache(self, repo_name):
146 def _invalidate_cache(self, repo_name):
147 """
147 """
148 Set's cache for this repository for invalidation on next access
148 Set's cache for this repository for invalidation on next access
149
149
150 :param repo_name: full repo name, also a cache key
150 :param repo_name: full repo name, also a cache key
151 """
151 """
152 ScmModel().mark_for_invalidation(repo_name)
152 ScmModel().mark_for_invalidation(repo_name)
153
153
154 def _check_permission(self, action, user, repo_name, ip_addr=None):
154 def _check_permission(self, action, user, repo_name, ip_addr=None):
155 """
155 """
156 Checks permissions using action (push/pull) user and repository
156 Checks permissions using action (push/pull) user and repository
157 name
157 name
158
158
159 :param action: push or pull action
159 :param action: push or pull action
160 :param user: user instance
160 :param user: user instance
161 :param repo_name: repository name
161 :param repo_name: repository name
162 """
162 """
163 #check IP
163 #check IP
164 authuser = AuthUser(user_id=user.user_id, ip_addr=ip_addr)
164 authuser = AuthUser(user_id=user.user_id, ip_addr=ip_addr)
165 if not authuser.ip_allowed:
165 if not authuser.ip_allowed:
166 return False
166 return False
167 else:
167 else:
168 log.info('Access for IP:%s allowed' % (ip_addr))
168 log.info('Access for IP:%s allowed' % (ip_addr))
169 if action == 'push':
169 if action == 'push':
170 if not HasPermissionAnyMiddleware('repository.write',
170 if not HasPermissionAnyMiddleware('repository.write',
171 'repository.admin')(user,
171 'repository.admin')(user,
172 repo_name):
172 repo_name):
173 return False
173 return False
174
174
175 else:
175 else:
176 #any other action need at least read permission
176 #any other action need at least read permission
177 if not HasPermissionAnyMiddleware('repository.read',
177 if not HasPermissionAnyMiddleware('repository.read',
178 'repository.write',
178 'repository.write',
179 'repository.admin')(user,
179 'repository.admin')(user,
180 repo_name):
180 repo_name):
181 return False
181 return False
182
182
183 return True
183 return True
184
184
185 def _get_ip_addr(self, environ):
185 def _get_ip_addr(self, environ):
186 return _get_ip_addr(environ)
186 return _get_ip_addr(environ)
187
187
188 def _check_ssl(self, environ, start_response):
188 def _check_ssl(self, environ, start_response):
189 """
189 """
190 Checks the SSL check flag and returns False if SSL is not present
190 Checks the SSL check flag and returns False if SSL is not present
191 and required True otherwise
191 and required True otherwise
192 """
192 """
193 org_proto = environ['wsgi._org_proto']
193 org_proto = environ['wsgi._org_proto']
194 #check if we have SSL required ! if not it's a bad request !
194 #check if we have SSL required ! if not it's a bad request !
195 require_ssl = str2bool(RhodeCodeUi.get_by_key('push_ssl').ui_value)
195 require_ssl = str2bool(RhodeCodeUi.get_by_key('push_ssl').ui_value)
196 if require_ssl and org_proto == 'http':
196 if require_ssl and org_proto == 'http':
197 log.debug('proto is %s and SSL is required BAD REQUEST !'
197 log.debug('proto is %s and SSL is required BAD REQUEST !'
198 % org_proto)
198 % org_proto)
199 return False
199 return False
200 return True
200 return True
201
201
202 def _check_locking_state(self, environ, action, repo, user_id):
202 def _check_locking_state(self, environ, action, repo, user_id):
203 """
203 """
204 Checks locking on this repository, if locking is enabled and lock is
204 Checks locking on this repository, if locking is enabled and lock is
205 present returns a tuple of make_lock, locked, locked_by.
205 present returns a tuple of make_lock, locked, locked_by.
206 make_lock can have 3 states None (do nothing) True, make lock
206 make_lock can have 3 states None (do nothing) True, make lock
207 False release lock, This value is later propagated to hooks, which
207 False release lock, This value is later propagated to hooks, which
208 do the locking. Think about this as signals passed to hooks what to do.
208 do the locking. Think about this as signals passed to hooks what to do.
209
209
210 """
210 """
211 locked = False # defines that locked error should be thrown to user
211 locked = False # defines that locked error should be thrown to user
212 make_lock = None
212 make_lock = None
213 repo = Repository.get_by_repo_name(repo)
213 repo = Repository.get_by_repo_name(repo)
214 user = User.get(user_id)
214 user = User.get(user_id)
215
215
216 # this is kind of hacky, but due to how mercurial handles client-server
216 # this is kind of hacky, but due to how mercurial handles client-server
217 # server see all operation on changeset; bookmarks, phases and
217 # server see all operation on changeset; bookmarks, phases and
218 # obsolescence marker in different transaction, we don't want to check
218 # obsolescence marker in different transaction, we don't want to check
219 # locking on those
219 # locking on those
220 obsolete_call = environ['QUERY_STRING'] in ['cmd=listkeys',]
220 obsolete_call = environ['QUERY_STRING'] in ['cmd=listkeys',]
221 locked_by = repo.locked
221 locked_by = repo.locked
222 if repo and repo.enable_locking and not obsolete_call:
222 if repo and repo.enable_locking and not obsolete_call:
223 if action == 'push':
223 if action == 'push':
224 #check if it's already locked !, if it is compare users
224 #check if it's already locked !, if it is compare users
225 user_id, _date = repo.locked
225 user_id, _date = repo.locked
226 if user.user_id == user_id:
226 if user.user_id == user_id:
227 log.debug('Got push from user %s, now unlocking' % (user))
227 log.debug('Got push from user %s, now unlocking' % (user))
228 # unlock if we have push from user who locked
228 # unlock if we have push from user who locked
229 make_lock = False
229 make_lock = False
230 else:
230 else:
231 # we're not the same user who locked, ban with 423 !
231 # we're not the same user who locked, ban with 423 !
232 locked = True
232 locked = True
233 if action == 'pull':
233 if action == 'pull':
234 if repo.locked[0] and repo.locked[1]:
234 if repo.locked[0] and repo.locked[1]:
235 locked = True
235 locked = True
236 else:
236 else:
237 log.debug('Setting lock on repo %s by %s' % (repo, user))
237 log.debug('Setting lock on repo %s by %s' % (repo, user))
238 make_lock = True
238 make_lock = True
239
239
240 else:
240 else:
241 log.debug('Repository %s do not have locking enabled' % (repo))
241 log.debug('Repository %s do not have locking enabled' % (repo))
242 log.debug('FINAL locking values make_lock:%s,locked:%s,locked_by:%s'
242 log.debug('FINAL locking values make_lock:%s,locked:%s,locked_by:%s'
243 % (make_lock, locked, locked_by))
243 % (make_lock, locked, locked_by))
244 return make_lock, locked, locked_by
244 return make_lock, locked, locked_by
245
245
246 def __call__(self, environ, start_response):
246 def __call__(self, environ, start_response):
247 start = time.time()
247 start = time.time()
248 try:
248 try:
249 return self._handle_request(environ, start_response)
249 return self._handle_request(environ, start_response)
250 finally:
250 finally:
251 log = logging.getLogger('rhodecode.' + self.__class__.__name__)
251 log = logging.getLogger('rhodecode.' + self.__class__.__name__)
252 log.debug('Request time: %.3fs' % (time.time() - start))
252 log.debug('Request time: %.3fs' % (time.time() - start))
253 meta.Session.remove()
253 meta.Session.remove()
254
254
255
255
256 class BaseController(WSGIController):
256 class BaseController(WSGIController):
257
257
258 def __before__(self):
258 def __before__(self):
259 """
259 """
260 __before__ is called before controller methods and after __call__
260 __before__ is called before controller methods and after __call__
261 """
261 """
262 c.rhodecode_version = __version__
262 c.rhodecode_version = __version__
263 c.rhodecode_instanceid = config.get('instance_id')
263 c.rhodecode_instanceid = config.get('instance_id')
264 c.rhodecode_name = config.get('rhodecode_title')
264 c.rhodecode_name = config.get('rhodecode_title')
265 c.rhodecode_bugtracker = config.get('bugtracker', 'http://bitbucket.org/marcinkuzminski/rhodecode/issues')
265 c.rhodecode_bugtracker = config.get('bugtracker', 'http://bitbucket.org/marcinkuzminski/rhodecode/issues')
266 c.use_gravatar = str2bool(config.get('use_gravatar'))
266 c.use_gravatar = str2bool(config.get('use_gravatar'))
267 c.ga_code = config.get('rhodecode_ga_code')
267 c.ga_code = config.get('rhodecode_ga_code')
268 # Visual options
268 # Visual options
269 c.visual = AttributeDict({})
269 c.visual = AttributeDict({})
270 rc_config = RhodeCodeSetting.get_app_settings()
270 rc_config = RhodeCodeSetting.get_app_settings()
271 ## DB stored
271 ## DB stored
272 c.visual.show_public_icon = str2bool(rc_config.get('rhodecode_show_public_icon'))
272 c.visual.show_public_icon = str2bool(rc_config.get('rhodecode_show_public_icon'))
273 c.visual.show_private_icon = str2bool(rc_config.get('rhodecode_show_private_icon'))
273 c.visual.show_private_icon = str2bool(rc_config.get('rhodecode_show_private_icon'))
274 c.visual.stylify_metatags = str2bool(rc_config.get('rhodecode_stylify_metatags'))
274 c.visual.stylify_metatags = str2bool(rc_config.get('rhodecode_stylify_metatags'))
275 c.visual.dashboard_items = safe_int(rc_config.get('rhodecode_dashboard_items', 100))
275 c.visual.dashboard_items = safe_int(rc_config.get('rhodecode_dashboard_items', 100))
276 c.visual.repository_fields = str2bool(rc_config.get('rhodecode_repository_fields'))
276 c.visual.repository_fields = str2bool(rc_config.get('rhodecode_repository_fields'))
277 c.visual.show_version = str2bool(rc_config.get('rhodecode_show_version'))
277 c.visual.show_version = str2bool(rc_config.get('rhodecode_show_version'))
278
278
279 ## INI stored
279 ## INI stored
280 self.cut_off_limit = int(config.get('cut_off_limit'))
280 self.cut_off_limit = int(config.get('cut_off_limit'))
281 c.visual.allow_repo_location_change = str2bool(config.get('allow_repo_location_change', True))
281 c.visual.allow_repo_location_change = str2bool(config.get('allow_repo_location_change', True))
282 c.visual.allow_custom_hooks_settings = str2bool(config.get('allow_custom_hooks_settings', True))
282
283
283 c.repo_name = get_repo_slug(request) # can be empty
284 c.repo_name = get_repo_slug(request) # can be empty
284 c.backends = BACKENDS.keys()
285 c.backends = BACKENDS.keys()
285 c.unread_notifications = NotificationModel()\
286 c.unread_notifications = NotificationModel()\
286 .get_unread_cnt_for_user(c.rhodecode_user.user_id)
287 .get_unread_cnt_for_user(c.rhodecode_user.user_id)
287 self.sa = meta.Session
288 self.sa = meta.Session
288 self.scm_model = ScmModel(self.sa)
289 self.scm_model = ScmModel(self.sa)
289
290
290 def __call__(self, environ, start_response):
291 def __call__(self, environ, start_response):
291 """Invoke the Controller"""
292 """Invoke the Controller"""
292 # WSGIController.__call__ dispatches to the Controller method
293 # WSGIController.__call__ dispatches to the Controller method
293 # the request is routed to. This routing information is
294 # the request is routed to. This routing information is
294 # available in environ['pylons.routes_dict']
295 # available in environ['pylons.routes_dict']
295 try:
296 try:
296 self.ip_addr = _get_ip_addr(environ)
297 self.ip_addr = _get_ip_addr(environ)
297 # make sure that we update permissions each time we call controller
298 # make sure that we update permissions each time we call controller
298 api_key = request.GET.get('api_key')
299 api_key = request.GET.get('api_key')
299 cookie_store = CookieStoreWrapper(session.get('rhodecode_user'))
300 cookie_store = CookieStoreWrapper(session.get('rhodecode_user'))
300 user_id = cookie_store.get('user_id', None)
301 user_id = cookie_store.get('user_id', None)
301 username = get_container_username(environ, config)
302 username = get_container_username(environ, config)
302 auth_user = AuthUser(user_id, api_key, username, self.ip_addr)
303 auth_user = AuthUser(user_id, api_key, username, self.ip_addr)
303 request.user = auth_user
304 request.user = auth_user
304 self.rhodecode_user = c.rhodecode_user = auth_user
305 self.rhodecode_user = c.rhodecode_user = auth_user
305 if not self.rhodecode_user.is_authenticated and \
306 if not self.rhodecode_user.is_authenticated and \
306 self.rhodecode_user.user_id is not None:
307 self.rhodecode_user.user_id is not None:
307 self.rhodecode_user.set_authenticated(
308 self.rhodecode_user.set_authenticated(
308 cookie_store.get('is_authenticated')
309 cookie_store.get('is_authenticated')
309 )
310 )
310 log.info('IP: %s User: %s accessed %s' % (
311 log.info('IP: %s User: %s accessed %s' % (
311 self.ip_addr, auth_user, safe_unicode(_get_access_path(environ)))
312 self.ip_addr, auth_user, safe_unicode(_get_access_path(environ)))
312 )
313 )
313 return WSGIController.__call__(self, environ, start_response)
314 return WSGIController.__call__(self, environ, start_response)
314 finally:
315 finally:
315 meta.Session.remove()
316 meta.Session.remove()
316
317
317
318
318 class BaseRepoController(BaseController):
319 class BaseRepoController(BaseController):
319 """
320 """
320 Base class for controllers responsible for loading all needed data for
321 Base class for controllers responsible for loading all needed data for
321 repository loaded items are
322 repository loaded items are
322
323
323 c.rhodecode_repo: instance of scm repository
324 c.rhodecode_repo: instance of scm repository
324 c.rhodecode_db_repo: instance of db
325 c.rhodecode_db_repo: instance of db
325 c.repository_followers: number of followers
326 c.repository_followers: number of followers
326 c.repository_forks: number of forks
327 c.repository_forks: number of forks
327 c.repository_following: weather the current user is following the current repo
328 c.repository_following: weather the current user is following the current repo
328 """
329 """
329
330
330 def __before__(self):
331 def __before__(self):
331 super(BaseRepoController, self).__before__()
332 super(BaseRepoController, self).__before__()
332 if c.repo_name:
333 if c.repo_name:
333
334
334 dbr = c.rhodecode_db_repo = Repository.get_by_repo_name(c.repo_name)
335 dbr = c.rhodecode_db_repo = Repository.get_by_repo_name(c.repo_name)
335 c.rhodecode_repo = c.rhodecode_db_repo.scm_instance
336 c.rhodecode_repo = c.rhodecode_db_repo.scm_instance
336 # update last change according to VCS data
337 # update last change according to VCS data
337 dbr.update_changeset_cache(dbr.get_changeset())
338 dbr.update_changeset_cache(dbr.get_changeset())
338 if c.rhodecode_repo is None:
339 if c.rhodecode_repo is None:
339 log.error('%s this repository is present in database but it '
340 log.error('%s this repository is present in database but it '
340 'cannot be created as an scm instance', c.repo_name)
341 'cannot be created as an scm instance', c.repo_name)
341
342
342 redirect(url('home'))
343 redirect(url('home'))
343
344
344 # some globals counter for menu
345 # some globals counter for menu
345 c.repository_followers = self.scm_model.get_followers(dbr)
346 c.repository_followers = self.scm_model.get_followers(dbr)
346 c.repository_forks = self.scm_model.get_forks(dbr)
347 c.repository_forks = self.scm_model.get_forks(dbr)
347 c.repository_pull_requests = self.scm_model.get_pull_requests(dbr)
348 c.repository_pull_requests = self.scm_model.get_pull_requests(dbr)
348 c.repository_following = self.scm_model.is_following_repo(c.repo_name,
349 c.repository_following = self.scm_model.is_following_repo(c.repo_name,
349 self.rhodecode_user.user_id)
350 self.rhodecode_user.user_id)
@@ -1,96 +1,97 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="/base/base.html"/>
2 <%inherit file="/base/base.html"/>
3
3
4 <%def name="title()">
4 <%def name="title()">
5 ${_('Settings administration')} &middot; ${c.rhodecode_name}
5 ${_('Settings administration')} &middot; ${c.rhodecode_name}
6 </%def>
6 </%def>
7
7
8 <%def name="breadcrumbs_links()">
8 <%def name="breadcrumbs_links()">
9 ${h.link_to(_('Admin'),h.url('admin_home'))} &raquo; ${_('Settings')}
9 ${h.link_to(_('Admin'),h.url('admin_home'))} &raquo; ${_('Settings')}
10 </%def>
10 </%def>
11
11
12 <%def name="page_nav()">
12 <%def name="page_nav()">
13 ${self.menu('admin')}
13 ${self.menu('admin')}
14 </%def>
14 </%def>
15
15
16 <%def name="main()">
16 <%def name="main()">
17 <div class="box">
17 <div class="box">
18 <!-- box / title -->
18 <!-- box / title -->
19 <div class="title">
19 <div class="title">
20 ${self.breadcrumbs()}
20 ${self.breadcrumbs()}
21 </div>
21 </div>
22 <!-- end box / title -->
22 <!-- end box / title -->
23
23
24 <h3>${_('Built in hooks - read only')}</h3>
24 <h3>${_('Built in hooks - read only')}</h3>
25 <div class="form">
25 <div class="form">
26 <div class="fields">
26 <div class="fields">
27 % for hook in c.hooks:
27 % for hook in c.hooks:
28 <div class="field">
28 <div class="field">
29 <div class="label label">
29 <div class="label label">
30 <label for="${hook.ui_key}">${hook.ui_key}</label>
30 <label for="${hook.ui_key}">${hook.ui_key}</label>
31 </div>
31 </div>
32 <div class="input" style="margin-left:280px">
32 <div class="input" style="margin-left:280px">
33 ${h.text(hook.ui_key,hook.ui_value,size=60,readonly="readonly")}
33 ${h.text(hook.ui_key,hook.ui_value,size=60,readonly="readonly")}
34 </div>
34 </div>
35 </div>
35 </div>
36 % endfor
36 % endfor
37 </div>
37 </div>
38 </div>
38 </div>
39
39 % if c.visual.allow_custom_hooks_settings:
40 <h3>${_('Custom hooks')}</h3>
40 <h3>${_('Custom hooks')}</h3>
41 ${h.form(url('admin_setting', setting_id='hooks'),method='put')}
41 ${h.form(url('admin_setting', setting_id='hooks'),method='put')}
42 <div class="form">
42 <div class="form">
43 <div class="fields">
43 <div class="fields">
44
44
45 % for hook in c.custom_hooks:
45 % for hook in c.custom_hooks:
46 <div class="field" id="${'id%s' % hook.ui_id }">
46 <div class="field" id="${'id%s' % hook.ui_id }">
47 <div class="label label">
47 <div class="label label">
48 <label for="${hook.ui_key}">${hook.ui_key}</label>
48 <label for="${hook.ui_key}">${hook.ui_key}</label>
49 </div>
49 </div>
50 <div class="input" style="margin-left:280px">
50 <div class="input" style="margin-left:280px">
51 ${h.hidden('hook_ui_key',hook.ui_key)}
51 ${h.hidden('hook_ui_key',hook.ui_key)}
52 ${h.hidden('hook_ui_value',hook.ui_value)}
52 ${h.hidden('hook_ui_value',hook.ui_value)}
53 ${h.text('hook_ui_value_new',hook.ui_value,size=60)}
53 ${h.text('hook_ui_value_new',hook.ui_value,size=60)}
54 <span class="delete_icon action_button"
54 <span class="delete_icon action_button"
55 onclick="ajaxActionHook(${hook.ui_id},'${'id%s' % hook.ui_id }')">
55 onclick="ajaxActionHook(${hook.ui_id},'${'id%s' % hook.ui_id }')">
56 ${_('remove')}
56 ${_('remove')}
57 </span>
57 </span>
58 </div>
58 </div>
59 </div>
59 </div>
60 % endfor
60 % endfor
61
61
62 <div class="field">
62 <div class="field">
63 <div class="input" style="margin-left:-180px;position: absolute;">
63 <div class="input" style="margin-left:-180px;position: absolute;">
64 <div class="input">
64 <div class="input">
65 ${h.text('new_hook_ui_key',size=30)}
65 ${h.text('new_hook_ui_key',size=30)}
66 </div>
66 </div>
67 </div>
67 </div>
68 <div class="input" style="margin-left:280px">
68 <div class="input" style="margin-left:280px">
69 ${h.text('new_hook_ui_value',size=60)}
69 ${h.text('new_hook_ui_value',size=60)}
70 </div>
70 </div>
71 </div>
71 </div>
72 <div class="buttons" style="margin-left:280px">
72 <div class="buttons" style="margin-left:280px">
73 ${h.submit('save',_('Save'),class_="ui-btn large")}
73 ${h.submit('save',_('Save'),class_="ui-btn large")}
74 </div>
74 </div>
75 </div>
75 </div>
76 </div>
76 </div>
77 ${h.end_form()}
77 ${h.end_form()}
78 % endif
78 </div>
79 </div>
79 <script type="text/javascript">
80 <script type="text/javascript">
80 function ajaxActionHook(hook_id,field_id) {
81 function ajaxActionHook(hook_id,field_id) {
81 var sUrl = "${h.url('admin_setting', setting_id='hooks')}";
82 var sUrl = "${h.url('admin_setting', setting_id='hooks')}";
82 var callback = {
83 var callback = {
83 success: function (o) {
84 success: function (o) {
84 var elem = YUD.get(""+field_id);
85 var elem = YUD.get(""+field_id);
85 elem.parentNode.removeChild(elem);
86 elem.parentNode.removeChild(elem);
86 },
87 },
87 failure: function (o) {
88 failure: function (o) {
88 alert("${_('Failed to remove hook')}");
89 alert("${_('Failed to remove hook')}");
89 },
90 },
90 };
91 };
91 var postData = '_method=delete&hook_id=' + hook_id;
92 var postData = '_method=delete&hook_id=' + hook_id;
92 var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData);
93 var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData);
93 };
94 };
94 </script>
95 </script>
95
96
96 </%def>
97 </%def>
General Comments 0
You need to be logged in to leave comments. Login now