##// END OF EJS Templates
config: major update for the code to make it be almost fully controllable via env for new docker based installer.
super-admin -
r4823:59ec40ea default
parent child Browse files
Show More
@@ -0,0 +1,98 b''
1 ; #####################
2 ; LOGGING CONFIGURATION
3 ; #####################
4 [loggers]
5 keys = root, sqlalchemy, beaker, celery, rhodecode, ssh_wrapper
6
7 [handlers]
8 keys = console, console_sql
9
10 [formatters]
11 keys = generic, json, color_formatter, color_formatter_sql
12
13 ; #######
14 ; LOGGERS
15 ; #######
16 [logger_root]
17 level = NOTSET
18 handlers = console
19
20 [logger_sqlalchemy]
21 level = $RC_LOGGING_LEVEL
22 handlers = console_sql
23 qualname = sqlalchemy.engine
24 propagate = 0
25
26 [logger_beaker]
27 level = $RC_LOGGING_LEVEL
28 handlers =
29 qualname = beaker.container
30 propagate = 1
31
32 [logger_rhodecode]
33 level = $RC_LOGGING_LEVEL
34 handlers =
35 qualname = rhodecode
36 propagate = 1
37
38 [logger_ssh_wrapper]
39 level = $RC_LOGGING_LEVEL
40 handlers =
41 qualname = ssh_wrapper
42 propagate = 1
43
44 [logger_celery]
45 level = $RC_LOGGING_LEVEL
46 handlers =
47 qualname = celery
48
49
50 ; ########
51 ; HANDLERS
52 ; ########
53
54 [handler_console]
55 class = StreamHandler
56 args = (sys.stderr, )
57 level = $RC_LOGGING_LEVEL
58 ; To enable JSON formatted logs replace generic with json
59 ; This allows sending properly formatted logs to grafana loki or elasticsearch
60 #formatter = json
61 #formatter = generic
62 formatter = $RC_LOGGING_FORMATTER
63
64 [handler_console_sql]
65 ; "level = DEBUG" logs SQL queries and results.
66 ; "level = INFO" logs SQL queries.
67 ; "level = WARN" logs neither. (Recommended for production systems.)
68 class = StreamHandler
69 args = (sys.stderr, )
70 level = WARN
71 ; To enable JSON formatted logs replace generic with json
72 ; This allows sending properly formatted logs to grafana loki or elasticsearch
73 #formatter = json
74 #formatter = generic
75 formatter = $RC_LOGGING_FORMATTER
76
77 ; ##########
78 ; FORMATTERS
79 ; ##########
80
81 [formatter_generic]
82 class = rhodecode.lib.logging_formatter.ExceptionAwareFormatter
83 format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s
84 datefmt = %Y-%m-%d %H:%M:%S
85
86 [formatter_color_formatter]
87 class = rhodecode.lib.logging_formatter.ColorFormatter
88 format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s
89 datefmt = %Y-%m-%d %H:%M:%S
90
91 [formatter_color_formatter_sql]
92 class = rhodecode.lib.logging_formatter.ColorFormatterSql
93 format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s
94 datefmt = %Y-%m-%d %H:%M:%S
95
96 [formatter_json]
97 format = %(message)s
98 class = rhodecode.lib._vendor.jsonlogger.JsonFormatter No newline at end of file
@@ -0,0 +1,182 b''
1 # -*- coding: utf-8 -*-
2
3 # Copyright (C) 2010-2020 RhodeCode GmbH
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
21 import os
22 import textwrap
23 import string
24 import functools
25 import logging
26 import tempfile
27 import logging.config
28 log = logging.getLogger(__name__)
29
30
31 def str2bool(_str):
32 """
33 returns True/False value from given string, it tries to translate the
34 string into boolean
35
36 :param _str: string value to translate into boolean
37 :rtype: boolean
38 :returns: boolean from given string
39 """
40 if _str is None:
41 return False
42 if _str in (True, False):
43 return _str
44 _str = str(_str).strip().lower()
45 return _str in ('t', 'true', 'y', 'yes', 'on', '1')
46
47
48 def aslist(obj, sep=None, strip=True):
49 """
50 Returns given string separated by sep as list
51
52 :param obj:
53 :param sep:
54 :param strip:
55 """
56 if isinstance(obj, (basestring,)):
57 if obj in ['', ""]:
58 return []
59
60 lst = obj.split(sep)
61 if strip:
62 lst = [v.strip() for v in lst]
63 return lst
64 elif isinstance(obj, (list, tuple)):
65 return obj
66 elif obj is None:
67 return []
68 else:
69 return [obj]
70
71
72 class SettingsMaker(object):
73
74 def __init__(self, app_settings):
75 self.settings = app_settings
76
77 @classmethod
78 def _bool_func(cls, input_val):
79 if isinstance(input_val, unicode):
80 input_val = input_val.encode('utf8')
81 return str2bool(input_val)
82
83 @classmethod
84 def _int_func(cls, input_val):
85 return int(input_val)
86
87 @classmethod
88 def _list_func(cls, input_val, sep=','):
89 return aslist(input_val, sep=sep)
90
91 @classmethod
92 def _string_func(cls, input_val, lower=True):
93 if lower:
94 input_val = input_val.lower()
95 return input_val
96
97 @classmethod
98 def _float_func(cls, input_val):
99 return float(input_val)
100
101 @classmethod
102 def _dir_func(cls, input_val, ensure_dir=False, mode=0o755):
103
104 # ensure we have our dir created
105 if not os.path.isdir(input_val) and ensure_dir:
106 os.makedirs(input_val, mode=mode)
107
108 if not os.path.isdir(input_val):
109 raise Exception('Dir at {} does not exist'.format(input_val))
110 return input_val
111
112 @classmethod
113 def _file_path_func(cls, input_val, ensure_dir=False, mode=0o755):
114 dirname = os.path.dirname(input_val)
115 cls._dir_func(dirname, ensure_dir=ensure_dir)
116 return input_val
117
118 @classmethod
119 def _key_transformator(cls, key):
120 return "{}_{}".format('RC'.upper(), key.upper().replace('.', '_').replace('-', '_'))
121
122 def enable_logging(self, logging_conf=None, level='INFO', formatter='generic'):
123 """
124 Helper to enable debug on running instance
125 :return:
126 """
127
128 if not str2bool(self.settings.get('logging.autoconfigure')):
129 log.info('logging configuration based on main .ini file')
130 return
131
132 if logging_conf is None:
133 logging_conf = self.settings.get('logging.logging_conf_file') or ''
134
135 if not os.path.isfile(logging_conf):
136 log.error('Unable to setup logging based on %s, file does not exist...', logging_conf)
137 return
138
139 with open(logging_conf, 'rb') as f:
140 ini_template = textwrap.dedent(f.read())
141 ini_template = string.Template(ini_template).safe_substitute(
142 RC_LOGGING_LEVEL=os.environ.get('RC_LOGGING_LEVEL', '') or level,
143 RC_LOGGING_FORMATTER=os.environ.get('RC_LOGGING_FORMATTER', '') or formatter
144 )
145
146 with tempfile.NamedTemporaryFile(prefix='rc_logging_', suffix='.ini', delete=False) as f:
147 log.info('Saved Temporary LOGGING config at %s', f.name)
148 f.write(ini_template)
149
150 logging.config.fileConfig(f.name)
151 os.remove(f.name)
152
153 def make_setting(self, key, default, lower=False, default_when_empty=False, parser=None):
154
155 input_val = self.settings.get(key, default)
156
157 if default_when_empty and not input_val:
158 # use default value when value is set in the config but it is empty
159 input_val = default
160
161 parser_func = {
162 'bool': self._bool_func,
163 'int': self._int_func,
164 'list': self._list_func,
165 'list:newline': functools.partial(self._list_func, sep='/n'),
166 'list:spacesep': functools.partial(self._list_func, sep=' '),
167 'string': functools.partial(self._string_func, lower=lower),
168 'dir': self._dir_func,
169 'dir:ensured': functools.partial(self._dir_func, ensure_dir=True),
170 'file': self._file_path_func,
171 'file:ensured': functools.partial(self._file_path_func, ensure_dir=True),
172 None: lambda i: i
173 }[parser]
174
175 # now maybe we have this KEY in env, search and use the value with higher priority.
176 transformed_key = self._key_transformator(key)
177 envvar_value = os.environ.get(transformed_key)
178 if envvar_value:
179 log.debug('using `%s` key instead of `%s` key for config', transformed_key, key)
180 input_val = envvar_value
181 self.settings[key] = parser_func(input_val)
182 return self.settings[key]
@@ -30,12 +30,12 b' worker_tmp_dir = None'
30 tmp_upload_dir = None
30 tmp_upload_dir = None
31
31
32 # Custom log format
32 # Custom log format
33 access_log_format = (
33 #access_log_format = (
34 '%(t)s %(p)s INFO [GNCRN] %(h)-15s rqt:%(L)s %(s)s %(b)-6s "%(m)s:%(U)s %(q)s" usr:%(u)s "%(f)s" "%(a)s"')
34 # '%(t)s %(p)s INFO [GNCRN] %(h)-15s rqt:%(L)s %(s)s %(b)-6s "%(m)s:%(U)s %(q)s" usr:%(u)s "%(f)s" "%(a)s"')
35
35
36 # loki format for easier parsing in grafana
36 # loki format for easier parsing in grafana
37 #access_log_format = (
37 access_log_format = (
38 # 'time="%(t)s" pid=%(p)s level="INFO" type="[GNCRN]" ip="%(h)-15s" rqt="%(L)s" response_code="%(s)s" response_bytes="%(b)-6s" uri="%(m)s:%(U)s %(q)s" user=":%(u)s" user_agent="%(a)s"')
38 'time="%(t)s" pid=%(p)s level="INFO" type="[GNCRN]" ip="%(h)-15s" rqt="%(L)s" response_code="%(s)s" response_bytes="%(b)-6s" uri="%(m)s:%(U)s %(q)s" user=":%(u)s" user_agent="%(a)s"')
39
39
40 # self adjust workers based on CPU count
40 # self adjust workers based on CPU count
41 # workers = get_workers()
41 # workers = get_workers()
@@ -97,9 +97,12 b' def post_fork(server, worker):'
97 if conf.has_option(section, 'memory_usage_recovery_threshold'):
97 if conf.has_option(section, 'memory_usage_recovery_threshold'):
98 _memory_usage_recovery_threshold = conf.getfloat(section, 'memory_usage_recovery_threshold')
98 _memory_usage_recovery_threshold = conf.getfloat(section, 'memory_usage_recovery_threshold')
99
99
100 worker._memory_max_usage = _memory_max_usage
100 worker._memory_max_usage = int(os.environ.get('RC_GUNICORN_MEMORY_MAX_USAGE', '')
101 worker._memory_usage_check_interval = _memory_usage_check_interval
101 or _memory_max_usage)
102 worker._memory_usage_recovery_threshold = _memory_usage_recovery_threshold
102 worker._memory_usage_check_interval = int(os.environ.get('RC_GUNICORN_MEMORY_USAGE_CHECK_INTERVAL', '')
103 or _memory_usage_check_interval)
104 worker._memory_usage_recovery_threshold = float(os.environ.get('RC_GUNICORN_MEMORY_USAGE_RECOVERY_THRESHOLD', '')
105 or _memory_usage_recovery_threshold)
103
106
104 # register memory last check time, with some random offset so we don't recycle all
107 # register memory last check time, with some random offset so we don't recycle all
105 # at once
108 # at once
@@ -124,10 +124,6 b' use = egg:PasteDeploy#prefix'
124 prefix = /
124 prefix = /
125
125
126 [app:main]
126 [app:main]
127 ; The %(here)s variable will be replaced with the absolute path of parent directory
128 ; of this file
129 ; In addition ENVIRONMENT variables usage is possible, e.g
130 ; sqlalchemy.db1.url = {ENV_RC_DB_URL}
131
127
132 use = egg:rhodecode-enterprise-ce
128 use = egg:rhodecode-enterprise-ce
133
129
@@ -330,6 +326,9 b' file_store.storage_path = %(here)s/data/'
330
326
331 use_celery = false
327 use_celery = false
332
328
329 ; path to store schedule database
330 #celerybeat-schedule.path =
331
333 ; connection url to the message broker (default redis)
332 ; connection url to the message broker (default redis)
334 celery.broker_url = redis://localhost:6379/8
333 celery.broker_url = redis://localhost:6379/8
335
334
@@ -575,6 +574,9 b' vcs.connection_timeout = 3600'
575 ; Legacy available options are: pre-1.4-compatible, pre-1.5-compatible, pre-1.6-compatible, pre-1.8-compatible, pre-1.9-compatible
574 ; Legacy available options are: pre-1.4-compatible, pre-1.5-compatible, pre-1.6-compatible, pre-1.8-compatible, pre-1.9-compatible
576 #vcs.svn.compatible_version = 1.8
575 #vcs.svn.compatible_version = 1.8
577
576
577 ; Cache flag to cache vcsserver remote calls locally
578 ; It uses cache_region `cache_repo`
579 vcs.methods.cache = true
578
580
579 ; ####################################################
581 ; ####################################################
580 ; Subversion proxy support (mod_dav_svn)
582 ; Subversion proxy support (mod_dav_svn)
@@ -657,55 +659,55 b' ssh.enable_ui_key_generator = true'
657 ; http://appenlight.rhodecode.com for details how to obtain an account
659 ; http://appenlight.rhodecode.com for details how to obtain an account
658
660
659 ; Appenlight integration enabled
661 ; Appenlight integration enabled
660 appenlight = false
662 #appenlight = false
661
663
662 appenlight.server_url = https://api.appenlight.com
664 #appenlight.server_url = https://api.appenlight.com
663 appenlight.api_key = YOUR_API_KEY
665 #appenlight.api_key = YOUR_API_KEY
664 #appenlight.transport_config = https://api.appenlight.com?threaded=1&timeout=5
666 #appenlight.transport_config = https://api.appenlight.com?threaded=1&timeout=5
665
667
666 ; used for JS client
668 ; used for JS client
667 appenlight.api_public_key = YOUR_API_PUBLIC_KEY
669 #appenlight.api_public_key = YOUR_API_PUBLIC_KEY
668
670
669 ; TWEAK AMOUNT OF INFO SENT HERE
671 ; TWEAK AMOUNT OF INFO SENT HERE
670
672
671 ; enables 404 error logging (default False)
673 ; enables 404 error logging (default False)
672 appenlight.report_404 = false
674 #appenlight.report_404 = false
673
675
674 ; time in seconds after request is considered being slow (default 1)
676 ; time in seconds after request is considered being slow (default 1)
675 appenlight.slow_request_time = 1
677 #appenlight.slow_request_time = 1
676
678
677 ; record slow requests in application
679 ; record slow requests in application
678 ; (needs to be enabled for slow datastore recording and time tracking)
680 ; (needs to be enabled for slow datastore recording and time tracking)
679 appenlight.slow_requests = true
681 #appenlight.slow_requests = true
680
682
681 ; enable hooking to application loggers
683 ; enable hooking to application loggers
682 appenlight.logging = true
684 #appenlight.logging = true
683
685
684 ; minimum log level for log capture
686 ; minimum log level for log capture
685 appenlight.logging.level = WARNING
687 #ppenlight.logging.level = WARNING
686
688
687 ; send logs only from erroneous/slow requests
689 ; send logs only from erroneous/slow requests
688 ; (saves API quota for intensive logging)
690 ; (saves API quota for intensive logging)
689 appenlight.logging_on_error = false
691 #appenlight.logging_on_error = false
690
692
691 ; list of additional keywords that should be grabbed from environ object
693 ; list of additional keywords that should be grabbed from environ object
692 ; can be string with comma separated list of words in lowercase
694 ; can be string with comma separated list of words in lowercase
693 ; (by default client will always send following info:
695 ; (by default client will always send following info:
694 ; 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
696 ; 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
695 ; start with HTTP* this list be extended with additional keywords here
697 ; start with HTTP* this list be extended with additional keywords here
696 appenlight.environ_keys_whitelist =
698 #appenlight.environ_keys_whitelist =
697
699
698 ; list of keywords that should be blanked from request object
700 ; list of keywords that should be blanked from request object
699 ; can be string with comma separated list of words in lowercase
701 ; can be string with comma separated list of words in lowercase
700 ; (by default client will always blank keys that contain following words
702 ; (by default client will always blank keys that contain following words
701 ; 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
703 ; 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
702 ; this list be extended with additional keywords set here
704 ; this list be extended with additional keywords set here
703 appenlight.request_keys_blacklist =
705 #appenlight.request_keys_blacklist =
704
706
705 ; list of namespaces that should be ignores when gathering log entries
707 ; list of namespaces that should be ignores when gathering log entries
706 ; can be string with comma separated list of namespaces
708 ; can be string with comma separated list of namespaces
707 ; (by default the client ignores own entries: appenlight_client.client)
709 ; (by default the client ignores own entries: appenlight_client.client)
708 appenlight.log_namespace_blacklist =
710 #appenlight.log_namespace_blacklist =
709
711
710 ; Statsd client config, this is used to send metrics to statsd
712 ; Statsd client config, this is used to send metrics to statsd
711 ; We recommend setting statsd_exported and scrape them using Promethues
713 ; We recommend setting statsd_exported and scrape them using Promethues
@@ -716,6 +718,13 b' appenlight.log_namespace_blacklist ='
716 #statsd.statsd_ipv6 = false
718 #statsd.statsd_ipv6 = false
717
719
718
720
721 ; configure logging automatically at server startup set to false
722 ; to use the below custom logging config.
723 #logging.autoconfigure = true
724
725 ; specify your own custom logging config file to configure logging
726 #logging.logging_conf_file = /path/to/custom_logging.ini
727
719 ; Dummy marker to add new entries after.
728 ; Dummy marker to add new entries after.
720 ; Add any custom entries below. Please don't remove this marker.
729 ; Add any custom entries below. Please don't remove this marker.
721 custom.conf = 1
730 custom.conf = 1
@@ -19,19 +19,20 b''
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 import os
20 import os
21 from rhodecode.apps.file_store import config_keys
21 from rhodecode.apps.file_store import config_keys
22 from rhodecode.config.middleware import _bool_setting, _string_setting
22 from rhodecode.config.settings_maker import SettingsMaker
23
23
24
24
25 def _sanitize_settings_and_apply_defaults(settings):
25 def _sanitize_settings_and_apply_defaults(settings):
26 """
26 """
27 Set defaults, convert to python types and validate settings.
27 Set defaults, convert to python types and validate settings.
28 """
28 """
29 _bool_setting(settings, config_keys.enabled, 'true')
29 settings_maker = SettingsMaker(settings)
30
30
31 _string_setting(settings, config_keys.backend, 'local')
31 settings_maker.make_setting(config_keys.enabled, True, parser='bool')
32 settings_maker.make_setting(config_keys.backend, 'local')
32
33
33 default_store = os.path.join(os.path.dirname(settings['__file__']), 'upload_store')
34 default_store = os.path.join(os.path.dirname(settings['__file__']), 'upload_store')
34 _string_setting(settings, config_keys.store_path, default_store)
35 settings_maker.make_setting(config_keys.store_path, default_store)
35
36
36
37
37 def includeme(config):
38 def includeme(config):
@@ -24,7 +24,7 b' from . import config_keys'
24 from .events import SshKeyFileChangeEvent
24 from .events import SshKeyFileChangeEvent
25 from .subscribers import generate_ssh_authorized_keys_file_subscriber
25 from .subscribers import generate_ssh_authorized_keys_file_subscriber
26
26
27 from rhodecode.config.middleware import _bool_setting, _string_setting
27 from rhodecode.config.settings_maker import SettingsMaker
28
28
29 log = logging.getLogger(__name__)
29 log = logging.getLogger(__name__)
30
30
@@ -33,28 +33,20 b' def _sanitize_settings_and_apply_default'
33 """
33 """
34 Set defaults, convert to python types and validate settings.
34 Set defaults, convert to python types and validate settings.
35 """
35 """
36 _bool_setting(settings, config_keys.generate_authorized_keyfile, 'false')
36 settings_maker = SettingsMaker(settings)
37 _bool_setting(settings, config_keys.wrapper_allow_shell, 'false')
37
38 _bool_setting(settings, config_keys.enable_debug_logging, 'false')
38 settings_maker.make_setting(config_keys.generate_authorized_keyfile, False, parser='bool')
39 _bool_setting(settings, config_keys.ssh_key_generator_enabled, 'true')
39 settings_maker.make_setting(config_keys.wrapper_allow_shell, False, parser='bool')
40 settings_maker.make_setting(config_keys.enable_debug_logging, False, parser='bool')
41 settings_maker.make_setting(config_keys.ssh_key_generator_enabled, True, parser='bool')
40
42
41 _string_setting(settings, config_keys.authorized_keys_file_path,
43 settings_maker.make_setting(config_keys.authorized_keys_file_path, '~/.ssh/authorized_keys_rhodecode')
42 '~/.ssh/authorized_keys_rhodecode',
44 settings_maker.make_setting(config_keys.wrapper_cmd, '')
43 lower=False)
45 settings_maker.make_setting(config_keys.authorized_keys_line_ssh_opts, '')
44 _string_setting(settings, config_keys.wrapper_cmd, '',
45 lower=False)
46 _string_setting(settings, config_keys.authorized_keys_line_ssh_opts, '',
47 lower=False)
48
46
49 _string_setting(settings, config_keys.ssh_hg_bin,
47 settings_maker.make_setting(config_keys.ssh_hg_bin, '~/.rccontrol/vcsserver-1/profile/bin/hg')
50 '~/.rccontrol/vcsserver-1/profile/bin/hg',
48 settings_maker.make_setting(config_keys.ssh_git_bin, '~/.rccontrol/vcsserver-1/profile/bin/git')
51 lower=False)
49 settings_maker.make_setting(config_keys.ssh_svn_bin, '~/.rccontrol/vcsserver-1/profile/bin/svnserve')
52 _string_setting(settings, config_keys.ssh_git_bin,
53 '~/.rccontrol/vcsserver-1/profile/bin/git',
54 lower=False)
55 _string_setting(settings, config_keys.ssh_svn_bin,
56 '~/.rccontrol/vcsserver-1/profile/bin/svnserve',
57 lower=False)
58
50
59
51
60 def includeme(config):
52 def includeme(config):
@@ -19,15 +19,13 b''
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 import os
20 import os
21 import logging
21 import logging
22 import shlex
23 from pyramid import compat
22 from pyramid import compat
24
23
25 # Do not use `from rhodecode import events` here, it will be overridden by the
24 # Do not use `from rhodecode import events` here, it will be overridden by the
26 # events module in this package due to pythons import mechanism.
25 # events module in this package due to pythons import mechanism.
27 from rhodecode.events import RepoGroupEvent
26 from rhodecode.events import RepoGroupEvent
28 from rhodecode.subscribers import AsyncSubprocessSubscriber
27 from rhodecode.subscribers import AsyncSubprocessSubscriber
29 from rhodecode.config.middleware import (
28 from rhodecode.config.settings_maker import SettingsMaker
30 _bool_setting, _string_setting, _int_setting)
31
29
32 from .events import ModDavSvnConfigChange
30 from .events import ModDavSvnConfigChange
33 from .subscribers import generate_config_subscriber
31 from .subscribers import generate_config_subscriber
@@ -41,13 +39,14 b' def _sanitize_settings_and_apply_default'
41 """
39 """
42 Set defaults, convert to python types and validate settings.
40 Set defaults, convert to python types and validate settings.
43 """
41 """
44 _bool_setting(settings, config_keys.generate_config, 'false')
42 settings_maker = SettingsMaker(settings)
45 _bool_setting(settings, config_keys.list_parent_path, 'true')
43 settings_maker.make_setting(config_keys.generate_config, False, parser='bool')
46 _int_setting(settings, config_keys.reload_timeout, 10)
44 settings_maker.make_setting(config_keys.list_parent_path, True, parser='bool')
47 _string_setting(settings, config_keys.config_file_path, '', lower=False)
45 settings_maker.make_setting(config_keys.reload_timeout, 10, parser='bool')
48 _string_setting(settings, config_keys.location_root, '/', lower=False)
46 settings_maker.make_setting(config_keys.config_file_path, '')
49 _string_setting(settings, config_keys.reload_command, '', lower=False)
47 settings_maker.make_setting(config_keys.location_root, '/')
50 _string_setting(settings, config_keys.template, '', lower=False)
48 settings_maker.make_setting(config_keys.reload_command, '')
49 settings_maker.make_setting(config_keys.template, '')
51
50
52 # Convert negative timeout values to zero.
51 # Convert negative timeout values to zero.
53 if settings[config_keys.reload_timeout] < 0:
52 if settings[config_keys.reload_timeout] < 0:
@@ -85,38 +85,3 b' def load_pyramid_environment(global_conf'
85
85
86 if vcs_server_enabled:
86 if vcs_server_enabled:
87 connect_vcs(vcs_server_uri, utils.get_vcs_server_protocol(settings))
87 connect_vcs(vcs_server_uri, utils.get_vcs_server_protocol(settings))
88
89
90 def get_rc_env_settings(prefix='ENV_{}'):
91 return {'ENV_{}'.format(key): value for key, value in os.environ.items()}
92
93
94 def substitute_values(mapping, substitutions):
95 result = {}
96
97 try:
98 for key, value in mapping.items():
99 # initialize without substitution first
100 result[key] = value
101
102 # Note: Cannot use regular replacements, since they would clash
103 # with the implementation of ConfigParser. Using "format" instead.
104 try:
105 result[key] = value.format(**substitutions)
106 except KeyError as e:
107 env_var = '{}'.format(e.args[0])
108
109 msg = 'Failed to substitute: `{key}={{{var}}}` with environment entry. ' \
110 'Make sure your environment has {var} set, or remove this ' \
111 'variable from config file'.format(key=key, var=env_var)
112
113 if env_var.startswith('ENV_'):
114 raise ValueError(msg)
115 else:
116 log.warning(msg)
117
118 except ValueError as e:
119 log.warning('Failed to substitute ENV variable: %s', e)
120 result = mapping
121
122 return result No newline at end of file
@@ -20,10 +20,10 b''
20
20
21 import os
21 import os
22 import sys
22 import sys
23 import logging
24 import collections
23 import collections
25 import tempfile
24 import tempfile
26 import time
25 import time
26 import logging.config
27
27
28 from paste.gzipper import make_gzip_middleware
28 from paste.gzipper import make_gzip_middleware
29 import pyramid.events
29 import pyramid.events
@@ -38,7 +38,8 b' from pyramid.renderers import render_to_'
38 from rhodecode.model import meta
38 from rhodecode.model import meta
39 from rhodecode.config import patches
39 from rhodecode.config import patches
40 from rhodecode.config import utils as config_utils
40 from rhodecode.config import utils as config_utils
41 from rhodecode.config.environment import load_pyramid_environment, substitute_values, get_rc_env_settings
41 from rhodecode.config.settings_maker import SettingsMaker
42 from rhodecode.config.environment import load_pyramid_environment
42
43
43 import rhodecode.events
44 import rhodecode.events
44 from rhodecode.lib.middleware.vcs import VCSMiddleware
45 from rhodecode.lib.middleware.vcs import VCSMiddleware
@@ -48,7 +49,7 b' from rhodecode.lib.exceptions import VCS'
48 from rhodecode.lib.middleware.appenlight import wrap_in_appenlight_if_enabled
49 from rhodecode.lib.middleware.appenlight import wrap_in_appenlight_if_enabled
49 from rhodecode.lib.middleware.https_fixup import HttpsFixup
50 from rhodecode.lib.middleware.https_fixup import HttpsFixup
50 from rhodecode.lib.plugins.utils import register_rhodecode_plugin
51 from rhodecode.lib.plugins.utils import register_rhodecode_plugin
51 from rhodecode.lib.utils2 import aslist as rhodecode_aslist, AttributeDict
52 from rhodecode.lib.utils2 import AttributeDict
52 from rhodecode.lib.exc_tracking import store_exception
53 from rhodecode.lib.exc_tracking import store_exception
53 from rhodecode.subscribers import (
54 from rhodecode.subscribers import (
54 scan_repositories_if_enabled, write_js_routes_if_enabled,
55 scan_repositories_if_enabled, write_js_routes_if_enabled,
@@ -87,24 +88,14 b' def make_pyramid_app(global_config, **se'
87 cases when these fragments are assembled from another place.
88 cases when these fragments are assembled from another place.
88
89
89 """
90 """
90
91 # Allows to use format style "{ENV_NAME}" placeholders in the configuration. It
92 # will be replaced by the value of the environment variable "NAME" in this case.
93 start_time = time.time()
91 start_time = time.time()
94 log.info('Pyramid app config starting')
92 log.info('Pyramid app config starting')
95
93
96 global_config = substitute_values(global_config, get_rc_env_settings())
94 sanitize_settings_and_apply_defaults(global_config, settings)
97 settings = substitute_values(settings, get_rc_env_settings())
98
95
99 # init and bootstrap StatsdClient
96 # init and bootstrap StatsdClient
100 StatsdClient.setup(settings)
97 StatsdClient.setup(settings)
101
98
102 debug = asbool(global_config.get('debug'))
103 if debug:
104 enable_debug()
105
106 sanitize_settings_and_apply_defaults(global_config, settings)
107
108 config = Configurator(settings=settings)
99 config = Configurator(settings=settings)
109 # Init our statsd at very start
100 # Init our statsd at very start
110 config.registry.statsd = StatsdClient.statsd
101 config.registry.statsd = StatsdClient.statsd
@@ -123,17 +114,62 b' def make_pyramid_app(global_config, **se'
123 pyramid_app = wrap_app_in_wsgi_middlewares(pyramid_app, config)
114 pyramid_app = wrap_app_in_wsgi_middlewares(pyramid_app, config)
124 pyramid_app.config = config
115 pyramid_app.config = config
125
116
126 config.configure_celery(global_config['__file__'])
117 celery_settings = get_celery_config(settings)
118 config.configure_celery(celery_settings)
127
119
128 # creating the app uses a connection - return it after we are done
120 # creating the app uses a connection - return it after we are done
129 meta.Session.remove()
121 meta.Session.remove()
130
122
131 total_time = time.time() - start_time
123 total_time = time.time() - start_time
132 log.info('Pyramid app `%s` created and configured in %.2fs',
124 log.info('Pyramid app `%s` created and configured in %.2fs',
133 pyramid_app.func_name, total_time)
125 getattr(pyramid_app, 'func_name', 'pyramid_app'), total_time)
134 return pyramid_app
126 return pyramid_app
135
127
136
128
129 def get_celery_config(settings):
130 """
131 Converts basic ini configuration into celery 4.X options
132 """
133
134 def key_converter(key_name):
135 pref = 'celery.'
136 if key_name.startswith(pref):
137 return key_name[len(pref):].replace('.', '_').lower()
138
139 def type_converter(parsed_key, value):
140 # cast to int
141 if value.isdigit():
142 return int(value)
143
144 # cast to bool
145 if value.lower() in ['true', 'false', 'True', 'False']:
146 return value.lower() == 'true'
147 return value
148
149 celery_config = {}
150 for k, v in settings.items():
151 pref = 'celery.'
152 if k.startswith(pref):
153 celery_config[key_converter(k)] = type_converter(key_converter(k), v)
154
155 # TODO:rethink if we want to support celerybeat based file config, probably NOT
156 # beat_config = {}
157 # for section in parser.sections():
158 # if section.startswith('celerybeat:'):
159 # name = section.split(':', 1)[1]
160 # beat_config[name] = get_beat_config(parser, section)
161
162 # final compose of settings
163 celery_settings = {}
164
165 if celery_config:
166 celery_settings.update(celery_config)
167 # if beat_config:
168 # celery_settings.update({'beat_schedule': beat_config})
169
170 return celery_settings
171
172
137 def not_found_view(request):
173 def not_found_view(request):
138 """
174 """
139 This creates the view which should be registered as not-found-view to
175 This creates the view which should be registered as not-found-view to
@@ -263,7 +299,7 b' def includeme(config, auth_resources=Non'
263
299
264 config.add_directive('configure_celery', configure_celery)
300 config.add_directive('configure_celery', configure_celery)
265
301
266 if asbool(settings.get('appenlight', 'false')):
302 if settings.get('appenlight', False):
267 config.include('appenlight_client.ext.pyramid_tween')
303 config.include('appenlight_client.ext.pyramid_tween')
268
304
269 load_all = should_load_all()
305 load_all = should_load_all()
@@ -435,8 +471,28 b' def sanitize_settings_and_apply_defaults'
435 function.
471 function.
436 """
472 """
437
473
438 settings.setdefault('rhodecode.edition', 'Community Edition')
474 global_settings_maker = SettingsMaker(global_config)
439 settings.setdefault('rhodecode.edition_id', 'CE')
475 global_settings_maker.make_setting('debug', default=False, parser='bool')
476 debug_enabled = asbool(global_config.get('debug'))
477
478 settings_maker = SettingsMaker(settings)
479
480 settings_maker.make_setting(
481 'logging.autoconfigure',
482 default=True,
483 parser='bool')
484
485 logging_conf = os.path.join(os.path.dirname(global_config.get('__file__')), 'logging.ini')
486 settings_maker.enable_logging(logging_conf, level='INFO' if debug_enabled else 'DEBUG')
487
488 # Default includes, possible to change as a user
489 pyramid_includes = settings_maker.make_setting('pyramid.includes', [], parser='list:newline')
490 log.debug(
491 "Using the following pyramid.includes: %s",
492 pyramid_includes)
493
494 settings_maker.make_setting('rhodecode.edition', 'Community Edition')
495 settings_maker.make_setting('rhodecode.edition_id', 'CE')
440
496
441 if 'mako.default_filters' not in settings:
497 if 'mako.default_filters' not in settings:
442 # set custom default filters if we don't have it defined
498 # set custom default filters if we don't have it defined
@@ -458,25 +514,41 b' def sanitize_settings_and_apply_defaults'
458 if not raw_url.startswith(('redis://', 'rediss://', 'unix://')):
514 if not raw_url.startswith(('redis://', 'rediss://', 'unix://')):
459 settings['beaker.session.url'] = 'redis://' + raw_url
515 settings['beaker.session.url'] = 'redis://' + raw_url
460
516
461 # Default includes, possible to change as a user
517 settings_maker.make_setting('__file__', global_config.get('__file__'))
462 pyramid_includes = settings.setdefault('pyramid.includes', [])
463 log.debug(
464 "Using the following pyramid.includes: %s",
465 pyramid_includes)
466
518
467 # TODO: johbo: Re-think this, usually the call to config.include
519 # TODO: johbo: Re-think this, usually the call to config.include
468 # should allow to pass in a prefix.
520 # should allow to pass in a prefix.
469 settings.setdefault('rhodecode.api.url', '/_admin/api')
521 settings_maker.make_setting('rhodecode.api.url', '/_admin/api')
470 settings.setdefault('__file__', global_config.get('__file__'))
471
522
472 # Sanitize generic settings.
523 # Sanitize generic settings.
473 _list_setting(settings, 'default_encoding', 'UTF-8')
524 settings_maker.make_setting('default_encoding', 'UTF-8', parser='list')
474 _bool_setting(settings, 'is_test', 'false')
525 settings_maker.make_setting('is_test', False, parser='bool')
475 _bool_setting(settings, 'gzip_responses', 'false')
526 settings_maker.make_setting('gzip_responses', False, parser='bool')
476
527
477 # Call split out functions that sanitize settings for each topic.
528 settings_maker.make_setting('vcs.svn.compatible_version', '')
478 _sanitize_appenlight_settings(settings)
529 settings_maker.make_setting('vcs.hooks.protocol', 'http')
479 _sanitize_vcs_settings(settings)
530 settings_maker.make_setting('vcs.hooks.host', '127.0.0.1')
531 settings_maker.make_setting('vcs.scm_app_implementation', 'http')
532 settings_maker.make_setting('vcs.server', '')
533 settings_maker.make_setting('vcs.server.protocol', 'http')
534 settings_maker.make_setting('startup.import_repos', 'false', parser='bool')
535 settings_maker.make_setting('vcs.hooks.direct_calls', 'false', parser='bool')
536 settings_maker.make_setting('vcs.server.enable', 'true', parser='bool')
537 settings_maker.make_setting('vcs.start_server', 'false', parser='bool')
538 settings_maker.make_setting('vcs.backends', 'hg, git, svn', parser='list')
539 settings_maker.make_setting('vcs.connection_timeout', 3600, parser='int')
540
541 settings_maker.make_setting('vcs.methods.cache', True, parser='bool')
542
543 # Support legacy values of vcs.scm_app_implementation. Legacy
544 # configurations may use 'rhodecode.lib.middleware.utils.scm_app_http', or
545 # disabled since 4.13 'vcsserver.scm_app' which is now mapped to 'http'.
546 scm_app_impl = settings['vcs.scm_app_implementation']
547 if scm_app_impl in ['rhodecode.lib.middleware.utils.scm_app_http', 'vcsserver.scm_app']:
548 settings['vcs.scm_app_implementation'] = 'http'
549
550 settings_maker.make_setting('appenlight', False, parser='bool')
551
480 _sanitize_cache_settings(settings)
552 _sanitize_cache_settings(settings)
481
553
482 # configure instance id
554 # configure instance id
@@ -485,277 +557,55 b' def sanitize_settings_and_apply_defaults'
485 return settings
557 return settings
486
558
487
559
488 def enable_debug():
560 def _sanitize_cache_settings(settings):
489 """
561 settings_maker = SettingsMaker(settings)
490 Helper to enable debug on running instance
491 :return:
492 """
493 import tempfile
494 import textwrap
495 import logging.config
496
497 ini_template = textwrap.dedent("""
498 #####################################
499 ### DEBUG LOGGING CONFIGURATION ####
500 #####################################
501 [loggers]
502 keys = root, sqlalchemy, beaker, celery, rhodecode, ssh_wrapper
503
504 [handlers]
505 keys = console, console_sql
506
507 [formatters]
508 keys = generic, color_formatter, color_formatter_sql
509
510 #############
511 ## LOGGERS ##
512 #############
513 [logger_root]
514 level = NOTSET
515 handlers = console
516
517 [logger_sqlalchemy]
518 level = INFO
519 handlers = console_sql
520 qualname = sqlalchemy.engine
521 propagate = 0
522
523 [logger_beaker]
524 level = DEBUG
525 handlers =
526 qualname = beaker.container
527 propagate = 1
528
529 [logger_rhodecode]
530 level = DEBUG
531 handlers =
532 qualname = rhodecode
533 propagate = 1
534
535 [logger_ssh_wrapper]
536 level = DEBUG
537 handlers =
538 qualname = ssh_wrapper
539 propagate = 1
540
541 [logger_celery]
542 level = DEBUG
543 handlers =
544 qualname = celery
545
546
547 ##############
548 ## HANDLERS ##
549 ##############
550
551 [handler_console]
552 class = StreamHandler
553 args = (sys.stderr, )
554 level = DEBUG
555 formatter = color_formatter
556
562
557 [handler_console_sql]
558 # "level = DEBUG" logs SQL queries and results.
559 # "level = INFO" logs SQL queries.
560 # "level = WARN" logs neither. (Recommended for production systems.)
561 class = StreamHandler
562 args = (sys.stderr, )
563 level = WARN
564 formatter = color_formatter_sql
565
566 ################
567 ## FORMATTERS ##
568 ################
569
570 [formatter_generic]
571 class = rhodecode.lib.logging_formatter.ExceptionAwareFormatter
572 format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s | %(req_id)s
573 datefmt = %Y-%m-%d %H:%M:%S
574
575 [formatter_color_formatter]
576 class = rhodecode.lib.logging_formatter.ColorRequestTrackingFormatter
577 format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s | %(req_id)s
578 datefmt = %Y-%m-%d %H:%M:%S
579
580 [formatter_color_formatter_sql]
581 class = rhodecode.lib.logging_formatter.ColorFormatterSql
582 format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s
583 datefmt = %Y-%m-%d %H:%M:%S
584 """)
585
586 with tempfile.NamedTemporaryFile(prefix='rc_debug_logging_', suffix='.ini',
587 delete=False) as f:
588 log.info('Saved Temporary DEBUG config at %s', f.name)
589 f.write(ini_template)
590
591 logging.config.fileConfig(f.name)
592 log.debug('DEBUG MODE ON')
593 os.remove(f.name)
594
595
596 def _sanitize_appenlight_settings(settings):
597 _bool_setting(settings, 'appenlight', 'false')
598
599
600 def _sanitize_vcs_settings(settings):
601 """
602 Applies settings defaults and does type conversion for all VCS related
603 settings.
604 """
605 _string_setting(settings, 'vcs.svn.compatible_version', '')
606 _string_setting(settings, 'vcs.hooks.protocol', 'http')
607 _string_setting(settings, 'vcs.hooks.host', '127.0.0.1')
608 _string_setting(settings, 'vcs.scm_app_implementation', 'http')
609 _string_setting(settings, 'vcs.server', '')
610 _string_setting(settings, 'vcs.server.protocol', 'http')
611 _bool_setting(settings, 'startup.import_repos', 'false')
612 _bool_setting(settings, 'vcs.hooks.direct_calls', 'false')
613 _bool_setting(settings, 'vcs.server.enable', 'true')
614 _bool_setting(settings, 'vcs.start_server', 'false')
615 _list_setting(settings, 'vcs.backends', 'hg, git, svn')
616 _int_setting(settings, 'vcs.connection_timeout', 3600)
617
618 # Support legacy values of vcs.scm_app_implementation. Legacy
619 # configurations may use 'rhodecode.lib.middleware.utils.scm_app_http', or
620 # disabled since 4.13 'vcsserver.scm_app' which is now mapped to 'http'.
621 scm_app_impl = settings['vcs.scm_app_implementation']
622 if scm_app_impl in ['rhodecode.lib.middleware.utils.scm_app_http', 'vcsserver.scm_app']:
623 settings['vcs.scm_app_implementation'] = 'http'
624
625
626 def _sanitize_cache_settings(settings):
627 temp_store = tempfile.gettempdir()
563 temp_store = tempfile.gettempdir()
628 default_cache_dir = os.path.join(temp_store, 'rc_cache')
564 default_cache_dir = os.path.join(temp_store, 'rc_cache')
629
565
630 # save default, cache dir, and use it for all backends later.
566 # save default, cache dir, and use it for all backends later.
631 default_cache_dir = _string_setting(
567 default_cache_dir = settings_maker.make_setting(
632 settings,
633 'cache_dir',
568 'cache_dir',
634 default_cache_dir, lower=False, default_when_empty=True)
569 default=default_cache_dir, default_when_empty=True,
635
570 parser='dir:ensured')
636 # ensure we have our dir created
637 if not os.path.isdir(default_cache_dir):
638 os.makedirs(default_cache_dir, mode=0o755)
639
571
640 # exception store cache
572 # exception store cache
641 _string_setting(
573 settings_maker.make_setting(
642 settings,
643 'exception_tracker.store_path',
574 'exception_tracker.store_path',
644 temp_store, lower=False, default_when_empty=True)
575 default=os.path.join(default_cache_dir, 'exc_store'), default_when_empty=True,
645 _bool_setting(
576 parser='dir:ensured'
646 settings,
577 )
647 'exception_tracker.send_email',
578
648 'false')
579 settings_maker.make_setting(
649 _string_setting(
580 'celerybeat-schedule.path',
650 settings,
581 default=os.path.join(default_cache_dir, 'celerybeat_schedule', 'celerybeat-schedule.db'), default_when_empty=True,
651 'exception_tracker.email_prefix',
582 parser='file:ensured'
652 '[RHODECODE ERROR]', lower=False, default_when_empty=True)
583 )
584
585 settings_maker.make_setting('exception_tracker.send_email', False, parser='bool')
586 settings_maker.make_setting('exception_tracker.email_prefix', '[RHODECODE ERROR]', default_when_empty=True)
653
587
654 # cache_perms
588 # cache_perms
655 _string_setting(
589 settings_maker.make_setting('rc_cache.cache_perms.backend', 'dogpile.cache.rc.file_namespace')
656 settings,
590 settings_maker.make_setting('rc_cache.cache_perms.expiration_time', 60, parser='int')
657 'rc_cache.cache_perms.backend',
591 settings_maker.make_setting('rc_cache.cache_perms.arguments.filename', os.path.join(default_cache_dir, 'rhodecode_cache_perms.db'))
658 'dogpile.cache.rc.file_namespace', lower=False)
659 _int_setting(
660 settings,
661 'rc_cache.cache_perms.expiration_time',
662 60)
663 _string_setting(
664 settings,
665 'rc_cache.cache_perms.arguments.filename',
666 os.path.join(default_cache_dir, 'rc_cache_1'), lower=False)
667
592
668 # cache_repo
593 # cache_repo
669 _string_setting(
594 settings_maker.make_setting('rc_cache.cache_repo.backend', 'dogpile.cache.rc.file_namespace')
670 settings,
595 settings_maker.make_setting('rc_cache.cache_repo.expiration_time', 60, parser='int')
671 'rc_cache.cache_repo.backend',
596 settings_maker.make_setting('rc_cache.cache_repo.arguments.filename', os.path.join(default_cache_dir, 'rhodecode_cache_repo.db'))
672 'dogpile.cache.rc.file_namespace', lower=False)
673 _int_setting(
674 settings,
675 'rc_cache.cache_repo.expiration_time',
676 60)
677 _string_setting(
678 settings,
679 'rc_cache.cache_repo.arguments.filename',
680 os.path.join(default_cache_dir, 'rc_cache_2'), lower=False)
681
597
682 # cache_license
598 # cache_license
683 _string_setting(
599 settings_maker.make_setting('rc_cache.cache_license.backend', 'dogpile.cache.rc.file_namespace')
684 settings,
600 settings_maker.make_setting('rc_cache.cache_license.expiration_time', 5*60, parser='int')
685 'rc_cache.cache_license.backend',
601 settings_maker.make_setting('rc_cache.cache_license.arguments.filename', os.path.join(default_cache_dir, 'rhodecode_cache_license.db'))
686 'dogpile.cache.rc.file_namespace', lower=False)
687 _int_setting(
688 settings,
689 'rc_cache.cache_license.expiration_time',
690 5*60)
691 _string_setting(
692 settings,
693 'rc_cache.cache_license.arguments.filename',
694 os.path.join(default_cache_dir, 'rc_cache_3'), lower=False)
695
602
696 # cache_repo_longterm memory, 96H
603 # cache_repo_longterm memory, 96H
697 _string_setting(
604 settings_maker.make_setting('rc_cache.cache_repo_longterm.backend', 'dogpile.cache.rc.memory_lru')
698 settings,
605 settings_maker.make_setting('rc_cache.cache_repo_longterm.expiration_time', 345600, parser='int')
699 'rc_cache.cache_repo_longterm.backend',
606 settings_maker.make_setting('rc_cache.cache_repo_longterm.max_size', 10000, parser='int')
700 'dogpile.cache.rc.memory_lru', lower=False)
701 _int_setting(
702 settings,
703 'rc_cache.cache_repo_longterm.expiration_time',
704 345600)
705 _int_setting(
706 settings,
707 'rc_cache.cache_repo_longterm.max_size',
708 10000)
709
607
710 # sql_cache_short
608 # sql_cache_short
711 _string_setting(
609 settings_maker.make_setting('rc_cache.sql_cache_short.backend', 'dogpile.cache.rc.memory_lru')
712 settings,
610 settings_maker.make_setting('rc_cache.sql_cache_short.expiration_time', 30, parser='int')
713 'rc_cache.sql_cache_short.backend',
611 settings_maker.make_setting('rc_cache.sql_cache_short.max_size', 10000, parser='int')
714 'dogpile.cache.rc.memory_lru', lower=False)
715 _int_setting(
716 settings,
717 'rc_cache.sql_cache_short.expiration_time',
718 30)
719 _int_setting(
720 settings,
721 'rc_cache.sql_cache_short.max_size',
722 10000)
723
724
725 def _int_setting(settings, name, default):
726 settings[name] = int(settings.get(name, default))
727 return settings[name]
728
729
730 def _bool_setting(settings, name, default):
731 input_val = settings.get(name, default)
732 if isinstance(input_val, unicode):
733 input_val = input_val.encode('utf8')
734 settings[name] = asbool(input_val)
735 return settings[name]
736
737
738 def _list_setting(settings, name, default):
739 raw_value = settings.get(name, default)
740
741 old_separator = ','
742 if old_separator in raw_value:
743 # If we get a comma separated list, pass it to our own function.
744 settings[name] = rhodecode_aslist(raw_value, sep=old_separator)
745 else:
746 # Otherwise we assume it uses pyramids space/newline separation.
747 settings[name] = aslist(raw_value)
748 return settings[name]
749
750
751 def _string_setting(settings, name, default, lower=True, default_when_empty=False):
752 value = settings.get(name, default)
753
754 if default_when_empty and not value:
755 # use default value when value is empty
756 value = default
757
758 if lower:
759 value = value.lower()
760 settings[name] = value
761 return settings[name]
@@ -371,7 +371,7 b' def attach_context_attributes(context, r'
371 config.get('license.hide_license_info', False))
371 config.get('license.hide_license_info', False))
372
372
373 # AppEnlight
373 # AppEnlight
374 context.appenlight_enabled = str2bool(config.get('appenlight', 'false'))
374 context.appenlight_enabled = config.get('appenlight', False)
375 context.appenlight_api_public_key = config.get(
375 context.appenlight_api_public_key = config.get(
376 'appenlight.api_public_key', '')
376 'appenlight.api_public_key', '')
377 context.appenlight_server_url = config.get('appenlight.server_url', '')
377 context.appenlight_server_url = config.get('appenlight.server_url', '')
@@ -40,7 +40,7 b' from pyramid.threadlocal import get_curr'
40 import rhodecode
40 import rhodecode
41
41
42 from rhodecode.lib.auth import AuthUser
42 from rhodecode.lib.auth import AuthUser
43 from rhodecode.lib.celerylib.utils import get_ini_config, parse_ini_vars, ping_db
43 from rhodecode.lib.celerylib.utils import parse_ini_vars, ping_db
44 from rhodecode.lib.ext_json import json
44 from rhodecode.lib.ext_json import json
45 from rhodecode.lib.pyramid_utils import bootstrap, setup_logging, prepare_request
45 from rhodecode.lib.pyramid_utils import bootstrap, setup_logging, prepare_request
46 from rhodecode.lib.utils2 import str2bool
46 from rhodecode.lib.utils2 import str2bool
@@ -116,6 +116,8 b' def setup_logging_callback(**kwargs):'
116
116
117 @signals.user_preload_options.connect
117 @signals.user_preload_options.connect
118 def on_preload_parsed(options, **kwargs):
118 def on_preload_parsed(options, **kwargs):
119 from rhodecode.config.middleware import get_celery_config
120
119 ini_location = options['ini']
121 ini_location = options['ini']
120 ini_vars = options['ini_var']
122 ini_vars = options['ini_var']
121 celery_app.conf['INI_PYRAMID'] = options['ini']
123 celery_app.conf['INI_PYRAMID'] = options['ini']
@@ -134,10 +136,11 b' def on_preload_parsed(options, **kwargs)'
134 log.debug('Bootstrapping RhodeCode application...')
136 log.debug('Bootstrapping RhodeCode application...')
135 env = bootstrap(ini_location, options=options)
137 env = bootstrap(ini_location, options=options)
136
138
139 celery_settings = get_celery_config(env['registry'].settings)
137 setup_celery_app(
140 setup_celery_app(
138 app=env['app'], root=env['root'], request=env['request'],
141 app=env['app'], root=env['root'], request=env['request'],
139 registry=env['registry'], closer=env['closer'],
142 registry=env['registry'], closer=env['closer'],
140 ini_location=ini_location)
143 celery_settings=celery_settings)
141
144
142 # fix the global flag even if it's disabled via .ini file because this
145 # fix the global flag even if it's disabled via .ini file because this
143 # is a worker code that doesn't need this to be disabled.
146 # is a worker code that doesn't need this to be disabled.
@@ -196,17 +199,15 b' def task_revoked_signal('
196 closer()
199 closer()
197
200
198
201
199 def setup_celery_app(app, root, request, registry, closer, ini_location):
202 def setup_celery_app(app, root, request, registry, closer, celery_settings):
200 ini_dir = os.path.dirname(os.path.abspath(ini_location))
203 log.debug('Got custom celery conf: %s', celery_settings)
201 celery_config = base_celery_config
204 celery_config = base_celery_config
202 celery_config.update({
205 celery_config.update({
203 # store celerybeat scheduler db where the .ini file is
206 # store celerybeat scheduler db where the .ini file is
204 'beat_schedule_filename': os.path.join(ini_dir, 'celerybeat-schedule'),
207 'beat_schedule_filename': registry.settings['celerybeat-schedule.path'],
205 })
208 })
206 ini_settings = get_ini_config(ini_location)
207 log.debug('Got custom celery conf: %s', ini_settings)
208
209
209 celery_config.update(ini_settings)
210 celery_config.update(celery_settings)
210 celery_app.config_from_object(celery_config)
211 celery_app.config_from_object(celery_config)
211
212
212 celery_app.conf.update({'PYRAMID_APP': app})
213 celery_app.conf.update({'PYRAMID_APP': app})
@@ -216,7 +217,7 b' def setup_celery_app(app, root, request,'
216 celery_app.conf.update({'PYRAMID_CLOSER': closer})
217 celery_app.conf.update({'PYRAMID_CLOSER': closer})
217
218
218
219
219 def configure_celery(config, ini_location):
220 def configure_celery(config, celery_settings):
220 """
221 """
221 Helper that is called from our application creation logic. It gives
222 Helper that is called from our application creation logic. It gives
222 connection info into running webapp and allows execution of tasks from
223 connection info into running webapp and allows execution of tasks from
@@ -226,10 +227,10 b' def configure_celery(config, ini_locatio'
226 rhodecode.CELERY_ENABLED = str2bool(
227 rhodecode.CELERY_ENABLED = str2bool(
227 config.registry.settings.get('use_celery'))
228 config.registry.settings.get('use_celery'))
228 if rhodecode.CELERY_ENABLED:
229 if rhodecode.CELERY_ENABLED:
229 log.info('Configuring celery based on `%s` file', ini_location)
230 log.info('Configuring celery based on `%s` settings', celery_settings)
230 setup_celery_app(
231 setup_celery_app(
231 app=None, root=None, request=None, registry=config.registry,
232 app=None, root=None, request=None, registry=config.registry,
232 closer=None, ini_location=ini_location)
233 closer=None, celery_settings=celery_settings)
233
234
234
235
235 def maybe_prepare_env(req):
236 def maybe_prepare_env(req):
@@ -238,7 +239,7 b' def maybe_prepare_env(req):'
238 environ.update({
239 environ.update({
239 'PATH_INFO': req.environ['PATH_INFO'],
240 'PATH_INFO': req.environ['PATH_INFO'],
240 'SCRIPT_NAME': req.environ['SCRIPT_NAME'],
241 'SCRIPT_NAME': req.environ['SCRIPT_NAME'],
241 'HTTP_HOST':req.environ.get('HTTP_HOST', req.environ['SERVER_NAME']),
242 'HTTP_HOST': req.environ.get('HTTP_HOST', req.environ['SERVER_NAME']),
242 'SERVER_NAME': req.environ['SERVER_NAME'],
243 'SERVER_NAME': req.environ['SERVER_NAME'],
243 'SERVER_PORT': req.environ['SERVER_PORT'],
244 'SERVER_PORT': req.environ['SERVER_PORT'],
244 'wsgi.url_scheme': req.environ['wsgi.url_scheme'],
245 'wsgi.url_scheme': req.environ['wsgi.url_scheme'],
@@ -115,52 +115,6 b' def get_beat_config(parser, section):'
115 return config
115 return config
116
116
117
117
118 def get_ini_config(ini_location):
119 """
120 Converts basic ini configuration into celery 4.X options
121 """
122 def key_converter(key_name):
123 pref = 'celery.'
124 if key_name.startswith(pref):
125 return key_name[len(pref):].replace('.', '_').lower()
126
127 def type_converter(parsed_key, value):
128 # cast to int
129 if value.isdigit():
130 return int(value)
131
132 # cast to bool
133 if value.lower() in ['true', 'false', 'True', 'False']:
134 return value.lower() == 'true'
135 return value
136
137 parser = configparser.SafeConfigParser(
138 defaults={'here': os.path.abspath(ini_location)})
139 parser.read(ini_location)
140
141 ini_config = {}
142 for k, v in parser.items('app:main'):
143 pref = 'celery.'
144 if k.startswith(pref):
145 ini_config[key_converter(k)] = type_converter(key_converter(k), v)
146
147 beat_config = {}
148 for section in parser.sections():
149 if section.startswith('celerybeat:'):
150 name = section.split(':', 1)[1]
151 beat_config[name] = get_beat_config(parser, section)
152
153 # final compose of settings
154 celery_settings = {}
155
156 if ini_config:
157 celery_settings.update(ini_config)
158 if beat_config:
159 celery_settings.update({'beat_schedule': beat_config})
160
161 return celery_settings
162
163
164 def parse_ini_vars(ini_vars):
118 def parse_ini_vars(ini_vars):
165 options = {}
119 options = {}
166 for pairs in ini_vars.split(','):
120 for pairs in ini_vars.split(','):
@@ -22,9 +22,8 b''
22 import pytest
22 import pytest
23
23
24 from rhodecode.tests import no_newline_id_generator
24 from rhodecode.tests import no_newline_id_generator
25 from rhodecode.config.middleware import (
25 from rhodecode.config.middleware import sanitize_settings_and_apply_defaults
26 _sanitize_vcs_settings, _bool_setting, _string_setting, _list_setting,
26 from rhodecode.config.settings_maker import SettingsMaker
27 _int_setting)
28
27
29
28
30 class TestHelperFunctions(object):
29 class TestHelperFunctions(object):
@@ -39,11 +38,9 b' class TestHelperFunctions(object):'
39 ('invalid-∫øø@-√Γ₯@¨€', False),
38 ('invalid-∫øø@-√Γ₯@¨€', False),
40 (u'invalid-∫øø@-√Γ₯@¨€', False),
39 (u'invalid-∫øø@-√Γ₯@¨€', False),
41 ])
40 ])
42 def test_bool_setting_helper(self, raw, expected):
41 def test_bool_func_helper(self, raw, expected):
43 key = 'dummy-key'
42 val = SettingsMaker._bool_func(raw)
44 settings = {key: raw}
43 assert val == expected
45 _bool_setting(settings, key, None)
46 assert settings[key] is expected
47
44
48 @pytest.mark.parametrize('raw, expected', [
45 @pytest.mark.parametrize('raw, expected', [
49 ('', ''),
46 ('', ''),
@@ -52,11 +49,9 b' class TestHelperFunctions(object):'
52 ('test-string-烩€', 'test-string-烩€'),
49 ('test-string-烩€', 'test-string-烩€'),
53 (u'test-string-烩€', u'test-string-烩€'),
50 (u'test-string-烩€', u'test-string-烩€'),
54 ])
51 ])
55 def test_string_setting_helper(self, raw, expected):
52 def test_string_func_helper(self, raw, expected):
56 key = 'dummy-key'
53 val = SettingsMaker._string_func(raw)
57 settings = {key: raw}
54 assert val == expected
58 _string_setting(settings, key, None)
59 assert settings[key] == expected
60
55
61 @pytest.mark.parametrize('raw, expected', [
56 @pytest.mark.parametrize('raw, expected', [
62 ('', []),
57 ('', []),
@@ -64,19 +59,30 b' class TestHelperFunctions(object):'
64 ('CaSe-TeSt', ['CaSe-TeSt']),
59 ('CaSe-TeSt', ['CaSe-TeSt']),
65 ('test-string-烩€', ['test-string-烩€']),
60 ('test-string-烩€', ['test-string-烩€']),
66 (u'test-string-烩€', [u'test-string-烩€']),
61 (u'test-string-烩€', [u'test-string-烩€']),
67 ('hg git svn', ['hg', 'git', 'svn']),
68 ('hg,git,svn', ['hg', 'git', 'svn']),
62 ('hg,git,svn', ['hg', 'git', 'svn']),
69 ('hg, git, svn', ['hg', 'git', 'svn']),
63 ('hg, git, svn', ['hg', 'git', 'svn']),
70 ('hg\ngit\nsvn', ['hg', 'git', 'svn']),
64
71 (' hg\n git\n svn ', ['hg', 'git', 'svn']),
72 (', hg , git , svn , ', ['', 'hg', 'git', 'svn', '']),
65 (', hg , git , svn , ', ['', 'hg', 'git', 'svn', '']),
73 ('cheese,free node,other', ['cheese', 'free node', 'other']),
66 ('cheese,free node,other', ['cheese', 'free node', 'other']),
74 ], ids=no_newline_id_generator)
67 ], ids=no_newline_id_generator)
75 def test_list_setting_helper(self, raw, expected):
68 def test_list_setting_helper(self, raw, expected):
76 key = 'dummy-key'
69 val = SettingsMaker._list_func(raw)
77 settings = {key: raw}
70 assert val == expected
78 _list_setting(settings, key, None)
71
79 assert settings[key] == expected
72 @pytest.mark.parametrize('raw, expected', [
73 ('hg git svn', ['hg', 'git', 'svn']),
74 ], ids=no_newline_id_generator)
75 def test_list_setting_spaces_helper(self, raw, expected):
76 val = SettingsMaker._list_func(raw, sep=' ')
77 assert val == expected
78
79 @pytest.mark.parametrize('raw, expected', [
80 ('hg\ngit\nsvn', ['hg', 'git', 'svn']),
81 (' hg\n git\n svn ', ['hg', 'git', 'svn']),
82 ], ids=no_newline_id_generator)
83 def test_list_setting_newlines_helper(self, raw, expected):
84 val = SettingsMaker._list_func(raw, sep='\n')
85 assert val == expected
80
86
81 @pytest.mark.parametrize('raw, expected', [
87 @pytest.mark.parametrize('raw, expected', [
82 ('0', 0),
88 ('0', 0),
@@ -86,10 +92,8 b' class TestHelperFunctions(object):'
86 (u'-12345', -12345),
92 (u'-12345', -12345),
87 ])
93 ])
88 def test_int_setting_helper(self, raw, expected):
94 def test_int_setting_helper(self, raw, expected):
89 key = 'dummy-key'
95 val = SettingsMaker._int_func(raw)
90 settings = {key: raw}
96 assert val == expected
91 _int_setting(settings, key, None)
92 assert settings[key] == expected
93
97
94 @pytest.mark.parametrize('raw', [
98 @pytest.mark.parametrize('raw', [
95 ('0xff'),
99 ('0xff'),
@@ -99,21 +103,19 b' class TestHelperFunctions(object):'
99 (u'invalid-⁄~†'),
103 (u'invalid-⁄~†'),
100 ])
104 ])
101 def test_int_setting_helper_invalid_input(self, raw):
105 def test_int_setting_helper_invalid_input(self, raw):
102 key = 'dummy-key'
103 settings = {key: raw}
104 with pytest.raises(Exception):
106 with pytest.raises(Exception):
105 _int_setting(settings, key, None)
107 SettingsMaker._int_func(raw)
106
108
107
109
108 class TestSanitizeVcsSettings(object):
110 class TestSanitizeVcsSettings(object):
109 _bool_settings = [
111 _bool_funcs = [
110 ('vcs.hooks.direct_calls', False),
112 ('vcs.hooks.direct_calls', False),
111 ('vcs.server.enable', True),
113 ('vcs.server.enable', True),
112 ('vcs.start_server', False),
114 ('vcs.start_server', False),
113 ('startup.import_repos', False),
115 ('startup.import_repos', False),
114 ]
116 ]
115
117
116 _string_settings = [
118 _string_funcs = [
117 ('vcs.svn.compatible_version', ''),
119 ('vcs.svn.compatible_version', ''),
118 ('vcs.hooks.protocol', 'http'),
120 ('vcs.hooks.protocol', 'http'),
119 ('vcs.hooks.host', '127.0.0.1'),
121 ('vcs.hooks.host', '127.0.0.1'),
@@ -126,28 +128,28 b' class TestSanitizeVcsSettings(object):'
126 ('vcs.backends', 'hg git'),
128 ('vcs.backends', 'hg git'),
127 ]
129 ]
128
130
129 @pytest.mark.parametrize('key, default', _list_settings)
131 # @pytest.mark.parametrize('key, default', _list_settings)
130 def test_list_setting_spacesep_list(self, key, default):
132 # def test_list_setting_spacesep_list(self, key, default):
131 test_list = ['test', 'list', 'values', 'for', key]
133 # test_list = ['test', 'list', 'values', 'for', key]
132 input_value = ' '.join(test_list)
134 # input_value = ' '.join(test_list)
133 settings = {key: input_value}
135 # settings = {key: input_value}
134 _sanitize_vcs_settings(settings)
136 # sanitize_settings_and_apply_defaults({'__file__': ''}, settings)
135 assert settings[key] == test_list
137 # assert settings[key] == test_list
136
138 #
137 @pytest.mark.parametrize('key, default', _list_settings)
139 # @pytest.mark.parametrize('key, default', _list_settings)
138 def test_list_setting_newlinesep_list(self, key, default):
140 # def test_list_setting_newlinesep_list(self, key, default):
139 test_list = ['test', 'list', 'values', 'for', key]
141 # test_list = ['test', 'list', 'values', 'for', key]
140 input_value = '\n'.join(test_list)
142 # input_value = '\n'.join(test_list)
141 settings = {key: input_value}
143 # settings = {key: input_value}
142 _sanitize_vcs_settings(settings)
144 # sanitize_settings_and_apply_defaults({'__file__': ''}, settings)
143 assert settings[key] == test_list
145 # assert settings[key] == test_list
144
146
145 @pytest.mark.parametrize('key, default', _list_settings)
147 @pytest.mark.parametrize('key, default', _list_settings)
146 def test_list_setting_commasep_list(self, key, default):
148 def test_list_setting_commasep_list(self, key, default):
147 test_list = ['test', 'list', 'values', 'for', key]
149 test_list = ['test', 'list', 'values', 'for', key]
148 input_value = ','.join(test_list)
150 input_value = ','.join(test_list)
149 settings = {key: input_value}
151 settings = {key: input_value}
150 _sanitize_vcs_settings(settings)
152 sanitize_settings_and_apply_defaults({'__file__': ''}, settings)
151 assert settings[key] == test_list
153 assert settings[key] == test_list
152
154
153 @pytest.mark.parametrize('key, default', _list_settings)
155 @pytest.mark.parametrize('key, default', _list_settings)
@@ -155,49 +157,49 b' class TestSanitizeVcsSettings(object):'
155 test_list = ['test', 'list', 'values', 'for', key]
157 test_list = ['test', 'list', 'values', 'for', key]
156 input_value = ', '.join(test_list)
158 input_value = ', '.join(test_list)
157 settings = {key: input_value}
159 settings = {key: input_value}
158 _sanitize_vcs_settings(settings)
160 sanitize_settings_and_apply_defaults({'__file__': ''}, settings)
159 assert settings[key] == test_list
161 assert settings[key] == test_list
160
162
161 @pytest.mark.parametrize('key, default', _string_settings)
163 @pytest.mark.parametrize('key, default', _string_funcs)
162 def test_string_setting_string(self, key, default):
164 def test_string_func_string(self, key, default):
163 test_value = 'test-string-for-{}'.format(key)
165 test_value = 'test-string-for-{}'.format(key)
164 settings = {key: test_value}
166 settings = {key: test_value}
165 _sanitize_vcs_settings(settings)
167 sanitize_settings_and_apply_defaults({'__file__': ''}, settings)
166 assert settings[key] == test_value
168 assert settings[key] == test_value
167
169
168 @pytest.mark.parametrize('key, default', _string_settings)
170 @pytest.mark.parametrize('key, default', _string_funcs)
169 def test_string_setting_default(self, key, default):
171 def test_string_func_default(self, key, default):
170 settings = {}
172 settings = {}
171 _sanitize_vcs_settings(settings)
173 sanitize_settings_and_apply_defaults({'__file__': ''}, settings)
172 assert settings[key] == default
174 assert settings[key] == default
173
175
174 @pytest.mark.parametrize('key, default', _string_settings)
176 # @pytest.mark.parametrize('key, default', _string_funcs)
175 def test_string_setting_lowercase(self, key, default):
177 # def test_string_func_lowercase(self, key, default):
176 test_value = 'Test-String-For-{}'.format(key)
178 # test_value = 'Test-String-For-{}'.format(key)
177 settings = {key: test_value}
179 # settings = {key: test_value}
178 _sanitize_vcs_settings(settings)
180 # sanitize_settings_and_apply_defaults({'__file__': ''}, settings)
179 assert settings[key] == test_value.lower()
181 # assert settings[key] == test_value.lower()
180
182
181 @pytest.mark.parametrize('key, default', _bool_settings)
183 @pytest.mark.parametrize('key, default', _bool_funcs)
182 def test_bool_setting_true(self, key, default):
184 def test_bool_func_true(self, key, default):
183 settings = {key: 'true'}
185 settings = {key: 'true'}
184 _sanitize_vcs_settings(settings)
186 sanitize_settings_and_apply_defaults({'__file__': ''}, settings)
185 assert settings[key] is True
187 assert settings[key] is True
186
188
187 @pytest.mark.parametrize('key, default', _bool_settings)
189 @pytest.mark.parametrize('key, default', _bool_funcs)
188 def test_bool_setting_false(self, key, default):
190 def test_bool_func_false(self, key, default):
189 settings = {key: 'false'}
191 settings = {key: 'false'}
190 _sanitize_vcs_settings(settings)
192 sanitize_settings_and_apply_defaults({'__file__': ''}, settings)
191 assert settings[key] is False
193 assert settings[key] is False
192
194
193 @pytest.mark.parametrize('key, default', _bool_settings)
195 @pytest.mark.parametrize('key, default', _bool_funcs)
194 def test_bool_setting_invalid_string(self, key, default):
196 def test_bool_func_invalid_string(self, key, default):
195 settings = {key: 'no-bool-val-string'}
197 settings = {key: 'no-bool-val-string'}
196 _sanitize_vcs_settings(settings)
198 sanitize_settings_and_apply_defaults({'__file__': ''}, settings)
197 assert settings[key] is False
199 assert settings[key] is False
198
200
199 @pytest.mark.parametrize('key, default', _bool_settings)
201 @pytest.mark.parametrize('key, default', _bool_funcs)
200 def test_bool_setting_default(self, key, default):
202 def test_bool_func_default(self, key, default):
201 settings = {}
203 settings = {}
202 _sanitize_vcs_settings(settings)
204 sanitize_settings_and_apply_defaults({'__file__': ''}, settings)
203 assert settings[key] is default
205 assert settings[key] is default
This diff has been collapsed as it changes many lines, (572 lines changed) Show them Hide them
@@ -1,30 +1,23 b''
1
1
2
2 ; #########################################
3 ################################################################################
3 ; RHODECODE COMMUNITY EDITION CONFIGURATION
4 ## RHODECODE COMMUNITY EDITION CONFIGURATION ##
4 ; #########################################
5 # The %(here)s variable will be replaced with the parent directory of this file#
6 ################################################################################
7
5
8 [DEFAULT]
6 [DEFAULT]
7 ; Debug flag sets all loggers to debug, and enables request tracking
9 debug = true
8 debug = true
10
9
11 ################################################################################
10 ; ########################################################################
12 ## EMAIL CONFIGURATION ##
11 ; EMAIL CONFIGURATION
13 ## Uncomment and replace with the email address which should receive ##
12 ; These settings will be used by the RhodeCode mailing system
14 ## any error reports after an application crash ##
13 ; ########################################################################
15 ## Additionally these settings will be used by the RhodeCode mailing system ##
16 ################################################################################
17
14
18 ## prefix all emails subjects with given prefix, helps filtering out emails
15 ; prefix all emails subjects with given prefix, helps filtering out emails
19 #email_prefix = [RhodeCode]
16 #email_prefix = [RhodeCode]
20
17
21 ## email FROM address all mails will be sent
18 ; email FROM address all mails will be sent
22 #app_email_from = rhodecode-noreply@localhost
19 #app_email_from = rhodecode-noreply@localhost
23
20
24 ## Uncomment and replace with the address which should receive any error report
25 ## note: using appenlight for error handling doesn't need this to be uncommented
26 #email_to = admin@localhost
27
28 #smtp_server = mail.server.com
21 #smtp_server = mail.server.com
29 #smtp_username =
22 #smtp_username =
30 #smtp_password =
23 #smtp_password =
@@ -33,16 +26,20 b' debug = true'
33 #smtp_use_ssl = true
26 #smtp_use_ssl = true
34
27
35 [server:main]
28 [server:main]
36 ## COMMON ##
29 ; COMMON HOST/IP CONFIG
37 host = 0.0.0.0
30 host = 0.0.0.0
38 port = 5000
31 port = 5000
39
32
40 ##########################
33
41 ## GUNICORN WSGI SERVER ##
34 ; ###########################
42 ##########################
35 ; GUNICORN APPLICATION SERVER
43 ## run with gunicorn --log-config rhodecode.ini --paste rhodecode.ini
36 ; ###########################
44
37
38 ; run with gunicorn --log-config rhodecode.ini --paste rhodecode.ini
39
40 ; Module to use, this setting shouldn't be changed
45 use = egg:gunicorn#main
41 use = egg:gunicorn#main
42
46 ## Sets the number of process workers. You must set `instance_id = *`
43 ## Sets the number of process workers. You must set `instance_id = *`
47 ## when this option is set to more than one worker, recommended
44 ## when this option is set to more than one worker, recommended
48 ## value is (2 * NUMBER_OF_CPUS + 1), eg 2CPU = 5 workers
45 ## value is (2 * NUMBER_OF_CPUS + 1), eg 2CPU = 5 workers
@@ -81,7 +78,7 b' prefix = /'
81 is_test = True
78 is_test = True
82 use = egg:rhodecode-enterprise-ce
79 use = egg:rhodecode-enterprise-ce
83
80
84 ## enable proxy prefix middleware, defined above
81 ; enable proxy prefix middleware, defined above
85 #filter-with = proxy-prefix
82 #filter-with = proxy-prefix
86
83
87
84
@@ -99,64 +96,69 b' rhodecode.api.url = /_admin/api'
99 ## `beaker.session.secret`
96 ## `beaker.session.secret`
100 #rhodecode.encrypted_values.secret =
97 #rhodecode.encrypted_values.secret =
101
98
102 ## decryption strict mode (enabled by default). It controls if decryption raises
99 ; decryption strict mode (enabled by default). It controls if decryption raises
103 ## `SignatureVerificationError` in case of wrong key, or damaged encryption data.
100 ; `SignatureVerificationError` in case of wrong key, or damaged encryption data.
104 #rhodecode.encrypted_values.strict = false
101 #rhodecode.encrypted_values.strict = false
105
102
106 ## return gzipped responses from Rhodecode (static files/application)
103 ; Pick algorithm for encryption. Either fernet (more secure) or aes (default)
104 ; fernet is safer, and we strongly recommend switching to it.
105 ; Due to backward compatibility aes is used as default.
106 #rhodecode.encrypted_values.algorithm = fernet
107
108 ; Return gzipped responses from RhodeCode (static files/application)
107 gzip_responses = false
109 gzip_responses = false
108
110
109 ## autogenerate javascript routes file on startup
111 ; Auto-generate javascript routes file on startup
110 generate_js_files = false
112 generate_js_files = false
111
113
112 ## Optional Languages
114 ; System global default language.
113 ## en(default), be, de, es, fr, it, ja, pl, pt, ru, zh
115 ; All available languages: en (default), be, de, es, fr, it, ja, pl, pt, ru, zh
114 lang = en
116 lang = en
115
117
116 ## perform a full repository scan on each server start, this should be
118 ## perform a full repository scan on each server start, this should be
117 ## set to false after first startup, to allow faster server restarts.
119 ## set to false after first startup, to allow faster server restarts.
118 startup.import_repos = true
120 startup.import_repos = true
119
121
120 ## Uncomment and set this path to use archive download cache.
122 ; Uncomment and set this path to use archive download cache.
121 ## Once enabled, generated archives will be cached at this location
123 ; Once enabled, generated archives will be cached at this location
122 ## and served from the cache during subsequent requests for the same archive of
124 ; and served from the cache during subsequent requests for the same archive of
123 ## the repository.
125 ; the repository.
124 #archive_cache_dir = /tmp/tarballcache
126 #archive_cache_dir = /tmp/tarballcache
125
127
126 ## URL at which the application is running. This is used for bootstraping
128 ; URL at which the application is running. This is used for Bootstrapping
127 ## requests in context when no web request is available. Used in ishell, or
129 ; requests in context when no web request is available. Used in ishell, or
128 ## SSH calls. Set this for events to receive proper url for SSH calls.
130 ; SSH calls. Set this for events to receive proper url for SSH calls.
129 app.base_url = http://rhodecode.local
131 app.base_url = http://rhodecode.local
130
132
131 ## change this to unique ID for security
133 ; Unique application ID. Should be a random unique string for security.
132 app_instance_uuid = rc-production
134 app_instance_uuid = rc-production
133
135
134 ## cut off limit for large diffs (size in bytes)
136 ## cut off limit for large diffs (size in bytes)
135 cut_off_limit_diff = 1024000
137 cut_off_limit_diff = 1024000
136 cut_off_limit_file = 256000
138 cut_off_limit_file = 256000
137
139
138 ## use cache version of scm repo everywhere
140 ; Use cached version of vcs repositories everywhere. Recommended to be `true`
139 vcs_full_cache = false
141 vcs_full_cache = false
140
142
141 ## force https in RhodeCode, fixes https redirects, assumes it's always https
143 ; Force https in RhodeCode, fixes https redirects, assumes it's always https.
142 ## Normally this is controlled by proper http flags sent from http server
144 ; Normally this is controlled by proper flags sent from http server such as Nginx or Apache
143 force_https = false
145 force_https = false
144
146
145 ## use Strict-Transport-Security headers
147 ; use Strict-Transport-Security headers
146 use_htsts = false
148 use_htsts = false
147
149
148 # Set to true if your repos are exposed using the dumb protocol
150 ; Set to true if your repos are exposed using the dumb protocol
149 git_update_server_info = false
151 git_update_server_info = false
150
152
151 ## RSS/ATOM feed options
153 ; RSS/ATOM feed options
152 rss_cut_off_limit = 256000
154 rss_cut_off_limit = 256000
153 rss_items_per_page = 10
155 rss_items_per_page = 10
154 rss_include_diff = false
156 rss_include_diff = false
155
157
156 ## gist URL alias, used to create nicer urls for gist. This should be an
158 ; gist URL alias, used to create nicer urls for gist. This should be an
157 ## url that does rewrites to _admin/gists/{gistid}.
159 ; url that does rewrites to _admin/gists/{gistid}.
158 ## example: http://gist.rhodecode.org/{gistid}. Empty means use the internal
160 ; example: http://gist.rhodecode.org/{gistid}. Empty means use the internal
159 ## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/{gistid}
161 ; RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/{gistid}
160 gist_alias_url =
162 gist_alias_url =
161
163
162 ## List of views (using glob pattern syntax) that AUTH TOKENS could be
164 ## List of views (using glob pattern syntax) that AUTH TOKENS could be
@@ -181,36 +183,39 b' gist_alias_url ='
181 # GistView:*
183 # GistView:*
182 api_access_controllers_whitelist =
184 api_access_controllers_whitelist =
183
185
184 ## default encoding used to convert from and to unicode
186 ; Default encoding used to convert from and to unicode
185 ## can be also a comma separated list of encoding in case of mixed encodings
187 ; can be also a comma separated list of encoding in case of mixed encodings
186 default_encoding = UTF-8
188 default_encoding = UTF-8
187
189
188 ## instance-id prefix
190 ; instance-id prefix
189 ## a prefix key for this instance used for cache invalidation when running
191 ; a prefix key for this instance used for cache invalidation when running
190 ## multiple instances of rhodecode, make sure it's globally unique for
192 ; multiple instances of RhodeCode, make sure it's globally unique for
191 ## all running rhodecode instances. Leave empty if you don't use it
193 ; all running RhodeCode instances. Leave empty if you don't use it
192 instance_id =
194 instance_id =
193
195
194 ## Fallback authentication plugin. Set this to a plugin ID to force the usage
196 ; Fallback authentication plugin. Set this to a plugin ID to force the usage
195 ## of an authentication plugin also if it is disabled by it's settings.
197 ; of an authentication plugin also if it is disabled by it's settings.
196 ## This could be useful if you are unable to log in to the system due to broken
198 ; This could be useful if you are unable to log in to the system due to broken
197 ## authentication settings. Then you can enable e.g. the internal rhodecode auth
199 ; authentication settings. Then you can enable e.g. the internal RhodeCode auth
198 ## module to log in again and fix the settings.
200 ; module to log in again and fix the settings.
199 ##
201 ; Available builtin plugin IDs (hash is part of the ID):
200 ## Available builtin plugin IDs (hash is part of the ID):
202 ; egg:rhodecode-enterprise-ce#rhodecode
201 ## egg:rhodecode-enterprise-ce#rhodecode
203 ; egg:rhodecode-enterprise-ce#pam
202 ## egg:rhodecode-enterprise-ce#pam
204 ; egg:rhodecode-enterprise-ce#ldap
203 ## egg:rhodecode-enterprise-ce#ldap
205 ; egg:rhodecode-enterprise-ce#jasig_cas
204 ## egg:rhodecode-enterprise-ce#jasig_cas
206 ; egg:rhodecode-enterprise-ce#headers
205 ## egg:rhodecode-enterprise-ce#headers
207 ; egg:rhodecode-enterprise-ce#crowd
206 ## egg:rhodecode-enterprise-ce#crowd
208
207 #rhodecode.auth_plugin_fallback = egg:rhodecode-enterprise-ce#rhodecode
209 #rhodecode.auth_plugin_fallback = egg:rhodecode-enterprise-ce#rhodecode
208
210
209 ## alternative return HTTP header for failed authentication. Default HTTP
211 ; Flag to control loading of legacy plugins in py:/path format
210 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
212 auth_plugin.import_legacy_plugins = true
211 ## handling that causing a series of failed authentication calls.
213
212 ## Set this variable to 403 to return HTTPForbidden, or any other HTTP code
214 ; alternative return HTTP header for failed authentication. Default HTTP
213 ## This will be served instead of default 401 on bad authnetication
215 ; response is 401 HTTPUnauthorized. Currently HG clients have troubles with
216 ; handling that causing a series of failed authentication calls.
217 ; Set this variable to 403 to return HTTPForbidden, or any other HTTP code
218 ; This will be served instead of default 401 on bad authentication
214 auth_ret_code =
219 auth_ret_code =
215
220
216 ## use special detection method when serving auth_ret_code, instead of serving
221 ## use special detection method when serving auth_ret_code, instead of serving
@@ -240,38 +245,35 b' supervisor.group_id = dev'
240 ## Display extended labs settings
245 ## Display extended labs settings
241 labs_settings_active = true
246 labs_settings_active = true
242
247
243 ####################################
248 ; #############
244 ### CELERY CONFIG ####
249 ; CELERY CONFIG
245 ####################################
250 ; #############
251
252 ; manually run celery: /path/to/celery worker -E --beat --app rhodecode.lib.celerylib.loader --scheduler rhodecode.lib.celerylib.scheduler.RcScheduler --loglevel DEBUG --ini /path/to/rhodecode.ini
253
246 use_celery = false
254 use_celery = false
247 broker.host = localhost
248 broker.vhost = rabbitmqhost
249 broker.port = 5672
250 broker.user = rabbitmq
251 broker.password = qweqwe
252
255
253 celery.imports = rhodecode.lib.celerylib.tasks
256 ; path to store schedule database
257 #celerybeat-schedule.path =
254
258
255 celery.result.backend = amqp
259 ; connection url to the message broker (default redis)
256 celery.result.dburi = amqp://
260 celery.broker_url = redis://localhost:6379/8
257 celery.result.serialier = json
258
261
259 #celery.send.task.error.emails = true
262 ; rabbitmq example
260 #celery.amqp.task.result.expires = 18000
263 #celery.broker_url = amqp://rabbitmq:qweqwe@localhost:5672/rabbitmqhost
261
264
262 celeryd.concurrency = 2
265 ; maximum tasks to execute before worker restart
263 #celeryd.log.file = celeryd.log
266 celery.max_tasks_per_child = 100
264 celeryd.log.level = debug
265 celeryd.max.tasks.per.child = 1
266
267
267 ## tasks will never be sent to the queue, but executed locally instead.
268 ; tasks will never be sent to the queue, but executed locally instead.
268 celery.always.eager = false
269 celery.task_always_eager = false
269
270
270 ####################################
271 ; #############
271 ### BEAKER CACHE ####
272 ; DOGPILE CACHE
272 ####################################
273 ; #############
273 # default cache dir for templates. Putting this into a ramdisk
274
274 ## can boost performance, eg. %(here)s/data_ramdisk
275 ; Default cache dir for caches. Putting this into a ramdisk can boost performance.
276 ; eg. /tmpfs/data_ramdisk, however this directory might require large amount of space
275 cache_dir = %(here)s/data
277 cache_dir = %(here)s/data
276
278
277 ## locking and default file storage for Beaker. Putting this into a ramdisk
279 ## locking and default file storage for Beaker. Putting this into a ramdisk
@@ -301,16 +303,21 b' rc_cache.sql_cache_short.backend = dogpi'
301 rc_cache.sql_cache_short.expiration_time = 0
303 rc_cache.sql_cache_short.expiration_time = 0
302
304
303
305
304 ####################################
306 ; ##############
305 ### BEAKER SESSION ####
307 ; BEAKER SESSION
306 ####################################
308 ; ##############
307
309
308 ## .session.type is type of storage options for the session, current allowed
310 ; beaker.session.type is type of storage options for the logged users sessions. Current allowed
309 ## types are file, ext:memcached, ext:database, and memory (default).
311 ; types are file, ext:redis, ext:database, ext:memcached, and memory (default if not specified).
312 ; Fastest ones are Redis and ext:database
310 beaker.session.type = file
313 beaker.session.type = file
311 beaker.session.data_dir = %(here)s/rc/data/sessions/data
314 beaker.session.data_dir = %(here)s/rc/data/sessions/data
312
315
313 ## db based session, fast, and allows easy management over logged in users
316 ; Redis based sessions
317 #beaker.session.type = ext:redis
318 #beaker.session.url = redis://127.0.0.1:6379/2
319
320 ; DB based session, fast, and allows easy management over logged in users
314 #beaker.session.type = ext:database
321 #beaker.session.type = ext:database
315 #beaker.session.table_name = db_session
322 #beaker.session.table_name = db_session
316 #beaker.session.sa.url = postgresql://postgres:secret@localhost/rhodecode
323 #beaker.session.sa.url = postgresql://postgres:secret@localhost/rhodecode
@@ -322,19 +329,20 b' beaker.session.key = rhodecode'
322 beaker.session.secret = test-rc-uytcxaz
329 beaker.session.secret = test-rc-uytcxaz
323 beaker.session.lock_dir = %(here)s/rc/data/sessions/lock
330 beaker.session.lock_dir = %(here)s/rc/data/sessions/lock
324
331
325 ## Secure encrypted cookie. Requires AES and AES python libraries
332 ; Secure encrypted cookie. Requires AES and AES python libraries
326 ## you must disable beaker.session.secret to use this
333 ; you must disable beaker.session.secret to use this
327 #beaker.session.encrypt_key = key_for_encryption
334 #beaker.session.encrypt_key = key_for_encryption
328 #beaker.session.validate_key = validation_key
335 #beaker.session.validate_key = validation_key
329
336
330 ## sets session as invalid(also logging out user) if it haven not been
337 ; Sets session as invalid (also logging out user) if it haven not been
331 ## accessed for given amount of time in seconds
338 ; accessed for given amount of time in seconds
332 beaker.session.timeout = 2592000
339 beaker.session.timeout = 2592000
333 beaker.session.httponly = true
340 beaker.session.httponly = true
334 ## Path to use for the cookie. Set to prefix if you use prefix middleware
341
342 ; Path to use for the cookie. Set to prefix if you use prefix middleware
335 #beaker.session.cookie_path = /custom_prefix
343 #beaker.session.cookie_path = /custom_prefix
336
344
337 ## uncomment for https secure cookie
345 ; Set https secure cookie
338 beaker.session.secure = false
346 beaker.session.secure = false
339
347
340 ## auto save the session to not to use .save()
348 ## auto save the session to not to use .save()
@@ -344,242 +352,213 b' beaker.session.auto = false'
344 ## at browser close
352 ## at browser close
345 #beaker.session.cookie_expires = 3600
353 #beaker.session.cookie_expires = 3600
346
354
347 ###################################
355 ; #############################
348 ## SEARCH INDEXING CONFIGURATION ##
356 ; SEARCH INDEXING CONFIGURATION
349 ###################################
357 ; #############################
350 ## Full text search indexer is available in rhodecode-tools under
351 ## `rhodecode-tools index` command
352
358
353 ## WHOOSH Backend, doesn't require additional services to run
359 ## WHOOSH Backend, doesn't require additional services to run
354 ## it works good with few dozen repos
360 ## it works good with few dozen repos
355 search.module = rhodecode.lib.index.whoosh
361 search.module = rhodecode.lib.index.whoosh
356 search.location = %(here)s/data/index
362 search.location = %(here)s/data/index
357
363
358 ########################################
364 ; ####################
359 ### CHANNELSTREAM CONFIG ####
365 ; CHANNELSTREAM CONFIG
360 ########################################
366 ; ####################
361 ## channelstream enables persistent connections and live notification
367
362 ## in the system. It's also used by the chat system
368 ; channelstream enables persistent connections and live notification
369 ; in the system. It's also used by the chat system
363
370
364 channelstream.enabled = false
371 channelstream.enabled = false
365
372
366 ## server address for channelstream server on the backend
373 ; server address for channelstream server on the backend
367 channelstream.server = 127.0.0.1:9800
374 channelstream.server = 127.0.0.1:9800
368 ## location of the channelstream server from outside world
375
369 ## use ws:// for http or wss:// for https. This address needs to be handled
376 ; location of the channelstream server from outside world
370 ## by external HTTP server such as Nginx or Apache
377 ; use ws:// for http or wss:// for https. This address needs to be handled
371 ## see nginx/apache configuration examples in our docs
378 ; by external HTTP server such as Nginx or Apache
379 ; see Nginx/Apache configuration examples in our docs
372 channelstream.ws_url = ws://rhodecode.yourserver.com/_channelstream
380 channelstream.ws_url = ws://rhodecode.yourserver.com/_channelstream
373 channelstream.secret = secret
381 channelstream.secret = secret
374 channelstream.history.location = %(here)s/channelstream_history
382 channelstream.history.location = %(here)s/channelstream_history
375
383
376 ## Internal application path that Javascript uses to connect into.
384 ; Internal application path that Javascript uses to connect into.
377 ## If you use proxy-prefix the prefix should be added before /_channelstream
385 ; If you use proxy-prefix the prefix should be added before /_channelstream
378 channelstream.proxy_path = /_channelstream
386 channelstream.proxy_path = /_channelstream
379
387
380
388
381 ###################################
389 ; ##############################
382 ## APPENLIGHT CONFIG ##
390 ; MAIN RHODECODE DATABASE CONFIG
383 ###################################
391 ; ##############################
384
385 ## Appenlight is tailored to work with RhodeCode, see
386 ## http://appenlight.com for details how to obtain an account
387
388 ## appenlight integration enabled
389 appenlight = false
390
391 appenlight.server_url = https://api.appenlight.com
392 appenlight.api_key = YOUR_API_KEY
393 #appenlight.transport_config = https://api.appenlight.com?threaded=1&timeout=5
394
395 # used for JS client
396 appenlight.api_public_key = YOUR_API_PUBLIC_KEY
397
398 ## TWEAK AMOUNT OF INFO SENT HERE
399
400 ## enables 404 error logging (default False)
401 appenlight.report_404 = false
402
403 ## time in seconds after request is considered being slow (default 1)
404 appenlight.slow_request_time = 1
405
406 ## record slow requests in application
407 ## (needs to be enabled for slow datastore recording and time tracking)
408 appenlight.slow_requests = true
409
410 ## enable hooking to application loggers
411 appenlight.logging = true
412
413 ## minimum log level for log capture
414 appenlight.logging.level = WARNING
415
416 ## send logs only from erroneous/slow requests
417 ## (saves API quota for intensive logging)
418 appenlight.logging_on_error = false
419
392
420 ## list of additonal keywords that should be grabbed from environ object
393 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db?timeout=30
421 ## can be string with comma separated list of words in lowercase
394 #sqlalchemy.db1.url = postgresql://postgres:qweqwe@localhost/rhodecode
422 ## (by default client will always send following info:
395 #sqlalchemy.db1.url = mysql://root:qweqwe@localhost/rhodecode?charset=utf8
423 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
396 ; pymysql is an alternative driver for MySQL, use in case of problems with default one
424 ## start with HTTP* this list be extended with additional keywords here
397 #sqlalchemy.db1.url = mysql+pymysql://root:qweqwe@localhost/rhodecode
425 appenlight.environ_keys_whitelist =
426
427 ## list of keywords that should be blanked from request object
428 ## can be string with comma separated list of words in lowercase
429 ## (by default client will always blank keys that contain following words
430 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
431 ## this list be extended with additional keywords set here
432 appenlight.request_keys_blacklist =
433
434 ## list of namespaces that should be ignores when gathering log entries
435 ## can be string with comma separated list of namespaces
436 ## (by default the client ignores own entries: appenlight_client.client)
437 appenlight.log_namespace_blacklist =
438
439
398
440 ################################################################################
441 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
442 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
443 ## execute malicious code after an exception is raised. ##
444 ################################################################################
445 set debug = false
446
447
448 ##############
449 ## STYLING ##
450 ##############
451 debug_style = false
452
453 ###########################################
454 ### MAIN RHODECODE DATABASE CONFIG ###
455 ###########################################
456 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode_test.db?timeout=30
457 #sqlalchemy.db1.url = postgresql://postgres:qweqwe@localhost/rhodecode_test
458 #sqlalchemy.db1.url = mysql://root:qweqwe@localhost/rhodecode_test
459 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode_test.db?timeout=30
399 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode_test.db?timeout=30
460
400
461 # see sqlalchemy docs for other advanced settings
401 ; see sqlalchemy docs for other advanced settings
462
402 ; print the sql statements to output
463 ## print the sql statements to output
464 sqlalchemy.db1.echo = false
403 sqlalchemy.db1.echo = false
465 ## recycle the connections after this amount of seconds
466 sqlalchemy.db1.pool_recycle = 3600
467
404
468 ## the number of connections to keep open inside the connection pool.
405 ; recycle the connections after this amount of seconds
469 ## 0 indicates no limit
406 sqlalchemy.db1.pool_recycle = 3600
407 sqlalchemy.db1.convert_unicode = true
408
409 ; the number of connections to keep open inside the connection pool.
410 ; 0 indicates no limit
470 #sqlalchemy.db1.pool_size = 5
411 #sqlalchemy.db1.pool_size = 5
471
412
472 ## the number of connections to allow in connection pool "overflow", that is
413 ; The number of connections to allow in connection pool "overflow", that is
473 ## connections that can be opened above and beyond the pool_size setting,
414 ; connections that can be opened above and beyond the pool_size setting,
474 ## which defaults to five.
415 ; which defaults to five.
475 #sqlalchemy.db1.max_overflow = 10
416 #sqlalchemy.db1.max_overflow = 10
476
417
418 ; Connection check ping, used to detect broken database connections
419 ; could be enabled to better handle cases if MySQL has gone away errors
420 #sqlalchemy.db1.ping_connection = true
477
421
478 ##################
422 ; ##########
479 ### VCS CONFIG ###
423 ; VCS CONFIG
480 ##################
424 ; ##########
481 vcs.server.enable = true
425 vcs.server.enable = true
482 vcs.server = localhost:9901
426 vcs.server = localhost:9901
483
427
484 ## Web server connectivity protocol, responsible for web based VCS operatations
428 ; Web server connectivity protocol, responsible for web based VCS operations
485 ## Available protocols are:
429 ; Available protocols are:
486 ## `http` - use http-rpc backend (default)
430 ; `http` - use http-rpc backend (default)
487 vcs.server.protocol = http
431 vcs.server.protocol = http
488
432
489 ## Push/Pull operations protocol, available options are:
433 ; Push/Pull operations protocol, available options are:
490 ## `http` - use http-rpc backend (default)
434 ; `http` - use http-rpc backend (default)
491 ## `vcsserver.scm_app` - internal app (EE only)
492 vcs.scm_app_implementation = http
435 vcs.scm_app_implementation = http
493
436
494 ## Push/Pull operations hooks protocol, available options are:
437 ; Push/Pull operations hooks protocol, available options are:
495 ## `http` - use http-rpc backend (default)
438 ; `http` - use http-rpc backend (default)
496 vcs.hooks.protocol = http
439 vcs.hooks.protocol = http
440
441 ; Host on which this instance is listening for hooks. If vcsserver is in other location
442 ; this should be adjusted.
497 vcs.hooks.host = 127.0.0.1
443 vcs.hooks.host = 127.0.0.1
498
444
499
445 ; Start VCSServer with this instance as a subprocess, useful for development
500 ## Start VCSServer with this instance as a subprocess, Useful for development
501 vcs.start_server = false
446 vcs.start_server = false
502
447
503 ## List of enabled VCS backends, available options are:
448 ; List of enabled VCS backends, available options are:
504 ## `hg` - mercurial
449 ; `hg` - mercurial
505 ## `git` - git
450 ; `git` - git
506 ## `svn` - subversion
451 ; `svn` - subversion
507 vcs.backends = hg, git, svn
452 vcs.backends = hg, git, svn
508
453
454 ; Wait this number of seconds before killing connection to the vcsserver
509 vcs.connection_timeout = 3600
455 vcs.connection_timeout = 3600
510 ## Compatibility version when creating SVN repositories. Defaults to newest version when commented out.
511 ## Available options are: pre-1.4-compatible, pre-1.5-compatible, pre-1.6-compatible, pre-1.8-compatible, pre-1.9-compatible
512 #vcs.svn.compatible_version = pre-1.8-compatible
513
456
457 ; Compatibility version when creating SVN repositories. Defaults to newest version when commented out.
458 ; Set a numeric version for your current SVN e.g 1.8, or 1.12
459 ; Legacy available options are: pre-1.4-compatible, pre-1.5-compatible, pre-1.6-compatible, pre-1.8-compatible, pre-1.9-compatible
460 #vcs.svn.compatible_version = 1.8
514
461
515 ############################################################
462 ; Cache flag to cache vcsserver remote calls locally
516 ### Subversion proxy support (mod_dav_svn) ###
463 ; It uses cache_region `cache_repo`
517 ### Maps RhodeCode repo groups into SVN paths for Apache ###
464 vcs.methods.cache = false
518 ############################################################
465
519 ## Enable or disable the config file generation.
466 ; ####################################################
467 ; Subversion proxy support (mod_dav_svn)
468 ; Maps RhodeCode repo groups into SVN paths for Apache
469 ; ####################################################
470
471 ; Enable or disable the config file generation.
520 svn.proxy.generate_config = false
472 svn.proxy.generate_config = false
521 ## Generate config file with `SVNListParentPath` set to `On`.
473
474 ; Generate config file with `SVNListParentPath` set to `On`.
522 svn.proxy.list_parent_path = true
475 svn.proxy.list_parent_path = true
523 ## Set location and file name of generated config file.
476
477 ; Set location and file name of generated config file.
524 svn.proxy.config_file_path = %(here)s/mod_dav_svn.conf
478 svn.proxy.config_file_path = %(here)s/mod_dav_svn.conf
525 ## Used as a prefix to the `Location` block in the generated config file.
479
526 ## In most cases it should be set to `/`.
480 ; alternative mod_dav config template. This needs to be a valid mako template
481 ; Example template can be found in the source code:
482 ; rhodecode/apps/svn_support/templates/mod-dav-svn.conf.mako
483 #svn.proxy.config_template = ~/.rccontrol/enterprise-1/custom_svn_conf.mako
484
485 ; Used as a prefix to the `Location` block in the generated config file.
486 ; In most cases it should be set to `/`.
527 svn.proxy.location_root = /
487 svn.proxy.location_root = /
528 ## Command to reload the mod dav svn configuration on change.
488
529 ## Example: `/etc/init.d/apache2 reload`
489 ; Command to reload the mod dav svn configuration on change.
490 ; Example: `/etc/init.d/apache2 reload` or /home/USER/apache_reload.sh
491 ; Make sure user who runs RhodeCode process is allowed to reload Apache
530 #svn.proxy.reload_cmd = /etc/init.d/apache2 reload
492 #svn.proxy.reload_cmd = /etc/init.d/apache2 reload
531 ## If the timeout expires before the reload command finishes, the command will
493
532 ## be killed. Setting it to zero means no timeout. Defaults to 10 seconds.
494 ; If the timeout expires before the reload command finishes, the command will
495 ; be killed. Setting it to zero means no timeout. Defaults to 10 seconds.
533 #svn.proxy.reload_timeout = 10
496 #svn.proxy.reload_timeout = 10
534
497
535 ############################################################
498 ; ####################
536 ### SSH Support Settings ###
499 ; SSH Support Settings
537 ############################################################
500 ; ####################
538
501
539 ## Defines if the authorized_keys file should be written on any change of
502 ; Defines if a custom authorized_keys file should be created and written on
540 ## user ssh keys, setting this to false also disables posibility of adding
503 ; any change user ssh keys. Setting this to false also disables possibility
541 ## ssh keys for users from web interface.
504 ; of adding SSH keys by users from web interface. Super admins can still
505 ; manage SSH Keys.
542 ssh.generate_authorized_keyfile = true
506 ssh.generate_authorized_keyfile = true
543
507
544 ## Options for ssh, default is `no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding`
508 ; Options for ssh, default is `no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding`
545 # ssh.authorized_keys_ssh_opts =
509 # ssh.authorized_keys_ssh_opts =
546
510
547 ## File to generate the authorized keys together with options
511 ; Path to the authorized_keys file where the generate entries are placed.
548 ## It is possible to have multiple key files specified in `sshd_config` e.g.
512 ; It is possible to have multiple key files specified in `sshd_config` e.g.
549 ## AuthorizedKeysFile %h/.ssh/authorized_keys %h/.ssh/authorized_keys_rhodecode
513 ; AuthorizedKeysFile %h/.ssh/authorized_keys %h/.ssh/authorized_keys_rhodecode
550 ssh.authorized_keys_file_path = %(here)s/rc/authorized_keys_rhodecode
514 ssh.authorized_keys_file_path = %(here)s/rc/authorized_keys_rhodecode
551
515
552 ## Command to execute the SSH wrapper. The binary is available in the
516 ; Command to execute the SSH wrapper. The binary is available in the
553 ## rhodecode installation directory.
517 ; RhodeCode installation directory.
554 ## e.g ~/.rccontrol/community-1/profile/bin/rc-ssh-wrapper
518 ; e.g ~/.rccontrol/community-1/profile/bin/rc-ssh-wrapper
555 ssh.wrapper_cmd = ~/.rccontrol/community-1/rc-ssh-wrapper
519 ssh.wrapper_cmd = ~/.rccontrol/community-1/rc-ssh-wrapper
556
520
557 ## Allow shell when executing the ssh-wrapper command
521 ; Allow shell when executing the ssh-wrapper command
558 ssh.wrapper_cmd_allow_shell = false
522 ssh.wrapper_cmd_allow_shell = false
559
523
560 ## Enables logging, and detailed output send back to the client. Useful for
524 ; Enables logging, and detailed output send back to the client during SSH
561 ## debugging, shouldn't be used in production.
525 ; operations. Useful for debugging, shouldn't be used in production.
562 ssh.enable_debug_logging = false
526 ssh.enable_debug_logging = false
563
527
564 ## Paths to binary executrables, by default they are the names, but we can
528 ; Paths to binary executable, by default they are the names, but we can
565 ## override them if we want to use a custom one
529 ; override them if we want to use a custom one
566 ssh.executable.hg = ~/.rccontrol/vcsserver-1/profile/bin/hg
530 ssh.executable.hg = ~/.rccontrol/vcsserver-1/profile/bin/hg
567 ssh.executable.git = ~/.rccontrol/vcsserver-1/profile/bin/git
531 ssh.executable.git = ~/.rccontrol/vcsserver-1/profile/bin/git
568 ssh.executable.svn = ~/.rccontrol/vcsserver-1/profile/bin/svnserve
532 ssh.executable.svn = ~/.rccontrol/vcsserver-1/profile/bin/svnserve
569
533
570 ## Enables SSH key generator web interface. Disabling this still allows users
534 ; Enables SSH key generator web interface. Disabling this still allows users
571 ## to add their own keys.
535 ; to add their own keys.
572 ssh.enable_ui_key_generator = true
536 ssh.enable_ui_key_generator = true
573
537
538 ; Statsd client config, this is used to send metrics to statsd
539 ; We recommend setting statsd_exported and scrape them using Promethues
540 #statsd.enabled = false
541 #statsd.statsd_host = 0.0.0.0
542 #statsd.statsd_port = 8125
543 #statsd.statsd_prefix =
544 #statsd.statsd_ipv6 = false
574
545
575 ## Dummy marker to add new entries after.
546
576 ## Add any custom entries below. Please don't remove.
547 ; configure logging automatically at server startup set to false
548 ; to use the below custom logging config.
549 logging.autoconfigure = false
550
551 ; specify your own custom logging config file to configure logging
552 #logging.logging_conf_file = /path/to/custom_logging.ini
553
554 ; Dummy marker to add new entries after.
555 ; Add any custom entries below. Please don't remove this marker.
577 custom.conf = 1
556 custom.conf = 1
578
557
579
558
580 ################################
559 ; #####################
581 ### LOGGING CONFIGURATION ####
560 ; LOGGING CONFIGURATION
582 ################################
561 ; #####################
583 [loggers]
562 [loggers]
584 keys = root, sqlalchemy, beaker, rhodecode, ssh_wrapper
563 keys = root, sqlalchemy, beaker, rhodecode, ssh_wrapper
585
564
@@ -589,9 +568,9 b' keys = console, console_sql'
589 [formatters]
568 [formatters]
590 keys = generic, color_formatter, color_formatter_sql
569 keys = generic, color_formatter, color_formatter_sql
591
570
592 #############
571 ; #######
593 ## LOGGERS ##
572 ; LOGGERS
594 #############
573 ; #######
595 [logger_root]
574 [logger_root]
596 level = NOTSET
575 level = NOTSET
597 handlers = console
576 handlers = console
@@ -603,6 +582,12 b' qualname = routes.middleware'
603 ## "level = DEBUG" logs the route matched and routing variables.
582 ## "level = DEBUG" logs the route matched and routing variables.
604 propagate = 1
583 propagate = 1
605
584
585 [logger_sqlalchemy]
586 level = INFO
587 handlers = console_sql
588 qualname = sqlalchemy.engine
589 propagate = 0
590
606 [logger_beaker]
591 [logger_beaker]
607 level = DEBUG
592 level = DEBUG
608 handlers =
593 handlers =
@@ -615,50 +600,59 b' handlers ='
615 qualname = rhodecode
600 qualname = rhodecode
616 propagate = 1
601 propagate = 1
617
602
618 [logger_sqlalchemy]
619 level = ERROR
620 handlers = console_sql
621 qualname = sqlalchemy.engine
622 propagate = 0
623
624 [logger_ssh_wrapper]
603 [logger_ssh_wrapper]
625 level = DEBUG
604 level = DEBUG
626 handlers =
605 handlers =
627 qualname = ssh_wrapper
606 qualname = ssh_wrapper
628 propagate = 1
607 propagate = 1
629
608
609 [logger_celery]
610 level = DEBUG
611 handlers =
612 qualname = celery
630
613
631 ##############
614
632 ## HANDLERS ##
615 ; ########
633 ##############
616 ; HANDLERS
617 ; ########
634
618
635 [handler_console]
619 [handler_console]
636 class = StreamHandler
620 class = StreamHandler
637 args = (sys.stderr,)
621 args = (sys.stderr, )
638 level = DEBUG
622 level = DEBUG
639 formatter = generic
623 formatter = generic
624 ; To enable JSON formatted logs replace generic with json
625 ; This allows sending properly formatted logs to grafana loki or elasticsearch
626 #formatter = json
640
627
641 [handler_console_sql]
628 [handler_console_sql]
629 ; "level = DEBUG" logs SQL queries and results.
630 ; "level = INFO" logs SQL queries.
631 ; "level = WARN" logs neither. (Recommended for production systems.)
642 class = StreamHandler
632 class = StreamHandler
643 args = (sys.stderr,)
633 args = (sys.stderr, )
644 level = WARN
634 level = WARN
645 formatter = generic
635 formatter = generic
646
636
647 ################
637 ; ##########
648 ## FORMATTERS ##
638 ; FORMATTERS
649 ################
639 ; ##########
650
640
651 [formatter_generic]
641 [formatter_generic]
652 class = rhodecode.lib.logging_formatter.ExceptionAwareFormatter
642 class = rhodecode.lib.logging_formatter.ExceptionAwareFormatter
653 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
643 format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s
654 datefmt = %Y-%m-%d %H:%M:%S
644 datefmt = %Y-%m-%d %H:%M:%S
655
645
656 [formatter_color_formatter]
646 [formatter_color_formatter]
657 class = rhodecode.lib.logging_formatter.ColorFormatter
647 class = rhodecode.lib.logging_formatter.ColorFormatter
658 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
648 format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s
659 datefmt = %Y-%m-%d %H:%M:%S
649 datefmt = %Y-%m-%d %H:%M:%S
660
650
661 [formatter_color_formatter_sql]
651 [formatter_color_formatter_sql]
662 class = rhodecode.lib.logging_formatter.ColorFormatterSql
652 class = rhodecode.lib.logging_formatter.ColorFormatterSql
663 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
653 format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s
664 datefmt = %Y-%m-%d %H:%M:%S
654 datefmt = %Y-%m-%d %H:%M:%S
655
656 [formatter_json]
657 format = %(message)s
658 class = rhodecode.lib._vendor.jsonlogger.JsonFormatter No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now