##// END OF EJS Templates
configs: removed utf8 markers
super-admin -
r5058:fa2cd01c default
parent child Browse files
Show More
@@ -1,20 +1,19 b''
1 # -*- coding: utf-8 -*-
2
1
3 # Copyright (C) 2010-2020 RhodeCode GmbH
2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 #
3 #
5 # This program is free software: you can redistribute it and/or modify
4 # 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
5 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
6 # (only), as published by the Free Software Foundation.
8 #
7 #
9 # This program is distributed in the hope that it will be useful,
8 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
11 # GNU General Public License for more details.
13 #
12 #
14 # You should have received a copy of the GNU Affero General Public License
13 # 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/>.
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
15 #
17 # This program is dual-licensed. If you wish to learn more about the
16 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
19
@@ -1,39 +1,39 b''
1 # -*- coding: utf-8 -*-
1
2
2
3 # Copyright (C) 2013-2020 RhodeCode GmbH
3 # Copyright (C) 2013-2020 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
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
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
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/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 """
21 """
22 Various config settings for RhodeCode
22 Various config settings for RhodeCode
23 """
23 """
24 from rhodecode import EXTENSIONS
24 from rhodecode import EXTENSIONS
25
25
26 from rhodecode.lib.utils2 import __get_lem
26 from rhodecode.lib.utils2 import __get_lem
27
27
28
28
29 # language map is also used by whoosh indexer, which for those specified
29 # language map is also used by whoosh indexer, which for those specified
30 # extensions will index it's content
30 # extensions will index it's content
31 # custom extensions to lexers, format is 'ext': 'LexerClass'
31 # custom extensions to lexers, format is 'ext': 'LexerClass'
32 extra = {
32 extra = {
33 'vbs': 'VbNet'
33 'vbs': 'VbNet'
34 }
34 }
35 LANGUAGES_EXTENSIONS_MAP = __get_lem(extra)
35 LANGUAGES_EXTENSIONS_MAP = __get_lem(extra)
36
36
37 DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S"
37 DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S"
38
38
39 DATE_FORMAT = "%Y-%m-%d"
39 DATE_FORMAT = "%Y-%m-%d"
@@ -1,90 +1,89 b''
1 # -*- coding: utf-8 -*-
2
1
3 # Copyright (C) 2010-2020 RhodeCode GmbH
2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 #
3 #
5 # This program is free software: you can redistribute it and/or modify
4 # 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
5 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
6 # (only), as published by the Free Software Foundation.
8 #
7 #
9 # This program is distributed in the hope that it will be useful,
8 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
11 # GNU General Public License for more details.
13 #
12 #
14 # You should have received a copy of the GNU Affero General Public License
13 # 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/>.
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
15 #
17 # This program is dual-licensed. If you wish to learn more about the
16 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
19
21 import os
20 import os
22 import logging
21 import logging
23 import rhodecode
22 import rhodecode
24 import collections
23 import collections
25
24
26 from rhodecode.config import utils
25 from rhodecode.config import utils
27
26
28 from rhodecode.lib.utils import load_rcextensions
27 from rhodecode.lib.utils import load_rcextensions
29 from rhodecode.lib.utils2 import str2bool
28 from rhodecode.lib.utils2 import str2bool
30 from rhodecode.lib.vcs import connect_vcs
29 from rhodecode.lib.vcs import connect_vcs
31
30
32 log = logging.getLogger(__name__)
31 log = logging.getLogger(__name__)
33
32
34
33
35 def load_pyramid_environment(global_config, settings):
34 def load_pyramid_environment(global_config, settings):
36 # Some parts of the code expect a merge of global and app settings.
35 # Some parts of the code expect a merge of global and app settings.
37 settings_merged = global_config.copy()
36 settings_merged = global_config.copy()
38 settings_merged.update(settings)
37 settings_merged.update(settings)
39
38
40 # TODO(marcink): probably not required anymore
39 # TODO(marcink): probably not required anymore
41 # configure channelstream,
40 # configure channelstream,
42 settings_merged['channelstream_config'] = {
41 settings_merged['channelstream_config'] = {
43 'enabled': str2bool(settings_merged.get('channelstream.enabled', False)),
42 'enabled': str2bool(settings_merged.get('channelstream.enabled', False)),
44 'server': settings_merged.get('channelstream.server'),
43 'server': settings_merged.get('channelstream.server'),
45 'secret': settings_merged.get('channelstream.secret')
44 'secret': settings_merged.get('channelstream.secret')
46 }
45 }
47
46
48 # If this is a test run we prepare the test environment like
47 # If this is a test run we prepare the test environment like
49 # creating a test database, test search index and test repositories.
48 # creating a test database, test search index and test repositories.
50 # This has to be done before the database connection is initialized.
49 # This has to be done before the database connection is initialized.
51 if settings['is_test']:
50 if settings['is_test']:
52 rhodecode.is_test = True
51 rhodecode.is_test = True
53 rhodecode.disable_error_handler = True
52 rhodecode.disable_error_handler = True
54 from rhodecode import authentication
53 from rhodecode import authentication
55 authentication.plugin_default_auth_ttl = 0
54 authentication.plugin_default_auth_ttl = 0
56
55
57 utils.initialize_test_environment(settings_merged)
56 utils.initialize_test_environment(settings_merged)
58
57
59 # Initialize the database connection.
58 # Initialize the database connection.
60 utils.initialize_database(settings_merged)
59 utils.initialize_database(settings_merged)
61
60
62 load_rcextensions(root_path=settings_merged['here'])
61 load_rcextensions(root_path=settings_merged['here'])
63
62
64 # Limit backends to `vcs.backends` from configuration, and preserve the order
63 # Limit backends to `vcs.backends` from configuration, and preserve the order
65 for alias in rhodecode.BACKENDS.keys():
64 for alias in rhodecode.BACKENDS.keys():
66 if alias not in settings['vcs.backends']:
65 if alias not in settings['vcs.backends']:
67 del rhodecode.BACKENDS[alias]
66 del rhodecode.BACKENDS[alias]
68
67
69 _sorted_backend = sorted(rhodecode.BACKENDS.items(),
68 _sorted_backend = sorted(rhodecode.BACKENDS.items(),
70 key=lambda item: settings['vcs.backends'].index(item[0]))
69 key=lambda item: settings['vcs.backends'].index(item[0]))
71 rhodecode.BACKENDS = collections.OrderedDict(_sorted_backend)
70 rhodecode.BACKENDS = collections.OrderedDict(_sorted_backend)
72
71
73 log.info('Enabled VCS backends: %s', rhodecode.BACKENDS.keys())
72 log.info('Enabled VCS backends: %s', rhodecode.BACKENDS.keys())
74
73
75 # initialize vcs client and optionally run the server if enabled
74 # initialize vcs client and optionally run the server if enabled
76 vcs_server_uri = settings['vcs.server']
75 vcs_server_uri = settings['vcs.server']
77 vcs_server_enabled = settings['vcs.server.enable']
76 vcs_server_enabled = settings['vcs.server.enable']
78
77
79 utils.configure_vcs(settings)
78 utils.configure_vcs(settings)
80
79
81 # Store the settings to make them available to other modules.
80 # Store the settings to make them available to other modules.
82
81
83 rhodecode.PYRAMID_SETTINGS = settings_merged
82 rhodecode.PYRAMID_SETTINGS = settings_merged
84 rhodecode.CONFIG = settings_merged
83 rhodecode.CONFIG = settings_merged
85 rhodecode.CONFIG['default_user_id'] = utils.get_default_user_id()
84 rhodecode.CONFIG['default_user_id'] = utils.get_default_user_id()
86
85
87 if vcs_server_enabled:
86 if vcs_server_enabled:
88 connect_vcs(vcs_server_uri, utils.get_vcs_server_protocol(settings))
87 connect_vcs(vcs_server_uri, utils.get_vcs_server_protocol(settings))
89 else:
88 else:
90 log.warning('vcs-server not enabled, vcs connection unavailable')
89 log.warning('vcs-server not enabled, vcs connection unavailable')
@@ -1,43 +1,42 b''
1 # -*- coding: utf-8 -*-
2
1
3 # Copyright (C) 2010-2020 RhodeCode GmbH
2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 #
3 #
5 # This program is free software: you can redistribute it and/or modify
4 # 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
5 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
6 # (only), as published by the Free Software Foundation.
8 #
7 #
9 # This program is distributed in the hope that it will be useful,
8 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
11 # GNU General Public License for more details.
13 #
12 #
14 # You should have received a copy of the GNU Affero General Public License
13 # 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/>.
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
15 #
17 # This program is dual-licensed. If you wish to learn more about the
16 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
19
21 def generate_jsroutes_content(jsroutes):
20 def generate_jsroutes_content(jsroutes):
22 statements = []
21 statements = []
23 for url_name, url, fields in sorted(jsroutes):
22 for url_name, url, fields in sorted(jsroutes):
24 statements.append(
23 statements.append(
25 "pyroutes.register('%s', '%s', %s);" % (url_name, url, fields))
24 "pyroutes.register('%s', '%s', %s);" % (url_name, url, fields))
26 return u'''
25 return u'''
27 /******************************************************************************
26 /******************************************************************************
28 * *
27 * *
29 * DO NOT CHANGE THIS FILE MANUALLY *
28 * DO NOT CHANGE THIS FILE MANUALLY *
30 * *
29 * *
31 * *
30 * *
32 * This file is automatically generated when the app starts up with *
31 * This file is automatically generated when the app starts up with *
33 * generate_js_files = true *
32 * generate_js_files = true *
34 * *
33 * *
35 * To add a route here pass jsroute=True to the route definition in the app *
34 * To add a route here pass jsroute=True to the route definition in the app *
36 * *
35 * *
37 ******************************************************************************/
36 ******************************************************************************/
38 function registerRCRoutes() {
37 function registerRCRoutes() {
39 // routes registration
38 // routes registration
40 %s
39 %s
41 }
40 }
42 ''' % '\n '.join(statements)
41 ''' % '\n '.join(statements)
43
42
@@ -1,617 +1,616 b''
1 # -*- coding: utf-8 -*-
2
1
3 # Copyright (C) 2010-2020 RhodeCode GmbH
2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 #
3 #
5 # This program is free software: you can redistribute it and/or modify
4 # 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
5 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
6 # (only), as published by the Free Software Foundation.
8 #
7 #
9 # This program is distributed in the hope that it will be useful,
8 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
11 # GNU General Public License for more details.
13 #
12 #
14 # You should have received a copy of the GNU Affero General Public License
13 # 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/>.
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
15 #
17 # This program is dual-licensed. If you wish to learn more about the
16 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
19
21 import os
20 import os
22 import sys
21 import sys
23 import collections
22 import collections
24 import tempfile
23 import tempfile
25 import time
24 import time
26 import logging.config
25 import logging.config
27
26
28 from paste.gzipper import make_gzip_middleware
27 from paste.gzipper import make_gzip_middleware
29 import pyramid.events
28 import pyramid.events
30 from pyramid.wsgi import wsgiapp
29 from pyramid.wsgi import wsgiapp
31 from pyramid.authorization import ACLAuthorizationPolicy
30 from pyramid.authorization import ACLAuthorizationPolicy
32 from pyramid.config import Configurator
31 from pyramid.config import Configurator
33 from pyramid.settings import asbool, aslist
32 from pyramid.settings import asbool, aslist
34 from pyramid.httpexceptions import (
33 from pyramid.httpexceptions import (
35 HTTPException, HTTPError, HTTPInternalServerError, HTTPFound, HTTPNotFound)
34 HTTPException, HTTPError, HTTPInternalServerError, HTTPFound, HTTPNotFound)
36 from pyramid.renderers import render_to_response
35 from pyramid.renderers import render_to_response
37
36
38 from rhodecode.model import meta
37 from rhodecode.model import meta
39 from rhodecode.config import patches
38 from rhodecode.config import patches
40 from rhodecode.config import utils as config_utils
39 from rhodecode.config import utils as config_utils
41 from rhodecode.config.settings_maker import SettingsMaker
40 from rhodecode.config.settings_maker import SettingsMaker
42 from rhodecode.config.environment import load_pyramid_environment
41 from rhodecode.config.environment import load_pyramid_environment
43
42
44 import rhodecode.events
43 import rhodecode.events
45 from rhodecode.lib.middleware.vcs import VCSMiddleware
44 from rhodecode.lib.middleware.vcs import VCSMiddleware
46 from rhodecode.lib.request import Request
45 from rhodecode.lib.request import Request
47 from rhodecode.lib.vcs import VCSCommunicationError
46 from rhodecode.lib.vcs import VCSCommunicationError
48 from rhodecode.lib.exceptions import VCSServerUnavailable
47 from rhodecode.lib.exceptions import VCSServerUnavailable
49 from rhodecode.lib.middleware.appenlight import wrap_in_appenlight_if_enabled
48 from rhodecode.lib.middleware.appenlight import wrap_in_appenlight_if_enabled
50 from rhodecode.lib.middleware.https_fixup import HttpsFixup
49 from rhodecode.lib.middleware.https_fixup import HttpsFixup
51 from rhodecode.lib.plugins.utils import register_rhodecode_plugin
50 from rhodecode.lib.plugins.utils import register_rhodecode_plugin
52 from rhodecode.lib.utils2 import AttributeDict
51 from rhodecode.lib.utils2 import AttributeDict
53 from rhodecode.lib.exc_tracking import store_exception
52 from rhodecode.lib.exc_tracking import store_exception
54 from rhodecode.subscribers import (
53 from rhodecode.subscribers import (
55 scan_repositories_if_enabled, write_js_routes_if_enabled,
54 scan_repositories_if_enabled, write_js_routes_if_enabled,
56 write_metadata_if_needed, write_usage_data)
55 write_metadata_if_needed, write_usage_data)
57 from rhodecode.lib.statsd_client import StatsdClient
56 from rhodecode.lib.statsd_client import StatsdClient
58
57
59 log = logging.getLogger(__name__)
58 log = logging.getLogger(__name__)
60
59
61
60
62 def is_http_error(response):
61 def is_http_error(response):
63 # error which should have traceback
62 # error which should have traceback
64 return response.status_code > 499
63 return response.status_code > 499
65
64
66
65
67 def should_load_all():
66 def should_load_all():
68 """
67 """
69 Returns if all application components should be loaded. In some cases it's
68 Returns if all application components should be loaded. In some cases it's
70 desired to skip apps loading for faster shell script execution
69 desired to skip apps loading for faster shell script execution
71 """
70 """
72 ssh_cmd = os.environ.get('RC_CMD_SSH_WRAPPER')
71 ssh_cmd = os.environ.get('RC_CMD_SSH_WRAPPER')
73 if ssh_cmd:
72 if ssh_cmd:
74 return False
73 return False
75
74
76 return True
75 return True
77
76
78
77
79 def make_pyramid_app(global_config, **settings):
78 def make_pyramid_app(global_config, **settings):
80 """
79 """
81 Constructs the WSGI application based on Pyramid.
80 Constructs the WSGI application based on Pyramid.
82
81
83 Specials:
82 Specials:
84
83
85 * The application can also be integrated like a plugin via the call to
84 * The application can also be integrated like a plugin via the call to
86 `includeme`. This is accompanied with the other utility functions which
85 `includeme`. This is accompanied with the other utility functions which
87 are called. Changing this should be done with great care to not break
86 are called. Changing this should be done with great care to not break
88 cases when these fragments are assembled from another place.
87 cases when these fragments are assembled from another place.
89
88
90 """
89 """
91 start_time = time.time()
90 start_time = time.time()
92 log.info('Pyramid app config starting')
91 log.info('Pyramid app config starting')
93
92
94 sanitize_settings_and_apply_defaults(global_config, settings)
93 sanitize_settings_and_apply_defaults(global_config, settings)
95
94
96 # init and bootstrap StatsdClient
95 # init and bootstrap StatsdClient
97 StatsdClient.setup(settings)
96 StatsdClient.setup(settings)
98
97
99 config = Configurator(settings=settings)
98 config = Configurator(settings=settings)
100 # Init our statsd at very start
99 # Init our statsd at very start
101 config.registry.statsd = StatsdClient.statsd
100 config.registry.statsd = StatsdClient.statsd
102
101
103 # Apply compatibility patches
102 # Apply compatibility patches
104 patches.inspect_getargspec()
103 patches.inspect_getargspec()
105
104
106 load_pyramid_environment(global_config, settings)
105 load_pyramid_environment(global_config, settings)
107
106
108 # Static file view comes first
107 # Static file view comes first
109 includeme_first(config)
108 includeme_first(config)
110
109
111 includeme(config)
110 includeme(config)
112
111
113 pyramid_app = config.make_wsgi_app()
112 pyramid_app = config.make_wsgi_app()
114 pyramid_app = wrap_app_in_wsgi_middlewares(pyramid_app, config)
113 pyramid_app = wrap_app_in_wsgi_middlewares(pyramid_app, config)
115 pyramid_app.config = config
114 pyramid_app.config = config
116
115
117 celery_settings = get_celery_config(settings)
116 celery_settings = get_celery_config(settings)
118 config.configure_celery(celery_settings)
117 config.configure_celery(celery_settings)
119
118
120 # creating the app uses a connection - return it after we are done
119 # creating the app uses a connection - return it after we are done
121 meta.Session.remove()
120 meta.Session.remove()
122
121
123 total_time = time.time() - start_time
122 total_time = time.time() - start_time
124 log.info('Pyramid app `%s` created and configured in %.2fs',
123 log.info('Pyramid app `%s` created and configured in %.2fs',
125 getattr(pyramid_app, 'func_name', 'pyramid_app'), total_time)
124 getattr(pyramid_app, 'func_name', 'pyramid_app'), total_time)
126 return pyramid_app
125 return pyramid_app
127
126
128
127
129 def get_celery_config(settings):
128 def get_celery_config(settings):
130 """
129 """
131 Converts basic ini configuration into celery 4.X options
130 Converts basic ini configuration into celery 4.X options
132 """
131 """
133
132
134 def key_converter(key_name):
133 def key_converter(key_name):
135 pref = 'celery.'
134 pref = 'celery.'
136 if key_name.startswith(pref):
135 if key_name.startswith(pref):
137 return key_name[len(pref):].replace('.', '_').lower()
136 return key_name[len(pref):].replace('.', '_').lower()
138
137
139 def type_converter(parsed_key, value):
138 def type_converter(parsed_key, value):
140 # cast to int
139 # cast to int
141 if value.isdigit():
140 if value.isdigit():
142 return int(value)
141 return int(value)
143
142
144 # cast to bool
143 # cast to bool
145 if value.lower() in ['true', 'false', 'True', 'False']:
144 if value.lower() in ['true', 'false', 'True', 'False']:
146 return value.lower() == 'true'
145 return value.lower() == 'true'
147 return value
146 return value
148
147
149 celery_config = {}
148 celery_config = {}
150 for k, v in settings.items():
149 for k, v in settings.items():
151 pref = 'celery.'
150 pref = 'celery.'
152 if k.startswith(pref):
151 if k.startswith(pref):
153 celery_config[key_converter(k)] = type_converter(key_converter(k), v)
152 celery_config[key_converter(k)] = type_converter(key_converter(k), v)
154
153
155 # TODO:rethink if we want to support celerybeat based file config, probably NOT
154 # TODO:rethink if we want to support celerybeat based file config, probably NOT
156 # beat_config = {}
155 # beat_config = {}
157 # for section in parser.sections():
156 # for section in parser.sections():
158 # if section.startswith('celerybeat:'):
157 # if section.startswith('celerybeat:'):
159 # name = section.split(':', 1)[1]
158 # name = section.split(':', 1)[1]
160 # beat_config[name] = get_beat_config(parser, section)
159 # beat_config[name] = get_beat_config(parser, section)
161
160
162 # final compose of settings
161 # final compose of settings
163 celery_settings = {}
162 celery_settings = {}
164
163
165 if celery_config:
164 if celery_config:
166 celery_settings.update(celery_config)
165 celery_settings.update(celery_config)
167 # if beat_config:
166 # if beat_config:
168 # celery_settings.update({'beat_schedule': beat_config})
167 # celery_settings.update({'beat_schedule': beat_config})
169
168
170 return celery_settings
169 return celery_settings
171
170
172
171
173 def not_found_view(request):
172 def not_found_view(request):
174 """
173 """
175 This creates the view which should be registered as not-found-view to
174 This creates the view which should be registered as not-found-view to
176 pyramid.
175 pyramid.
177 """
176 """
178
177
179 if not getattr(request, 'vcs_call', None):
178 if not getattr(request, 'vcs_call', None):
180 # handle like regular case with our error_handler
179 # handle like regular case with our error_handler
181 return error_handler(HTTPNotFound(), request)
180 return error_handler(HTTPNotFound(), request)
182
181
183 # handle not found view as a vcs call
182 # handle not found view as a vcs call
184 settings = request.registry.settings
183 settings = request.registry.settings
185 ae_client = getattr(request, 'ae_client', None)
184 ae_client = getattr(request, 'ae_client', None)
186 vcs_app = VCSMiddleware(
185 vcs_app = VCSMiddleware(
187 HTTPNotFound(), request.registry, settings,
186 HTTPNotFound(), request.registry, settings,
188 appenlight_client=ae_client)
187 appenlight_client=ae_client)
189
188
190 return wsgiapp(vcs_app)(None, request)
189 return wsgiapp(vcs_app)(None, request)
191
190
192
191
193 def error_handler(exception, request):
192 def error_handler(exception, request):
194 import rhodecode
193 import rhodecode
195 from rhodecode.lib import helpers
194 from rhodecode.lib import helpers
196 from rhodecode.lib.utils2 import str2bool
195 from rhodecode.lib.utils2 import str2bool
197
196
198 rhodecode_title = rhodecode.CONFIG.get('rhodecode_title') or 'RhodeCode'
197 rhodecode_title = rhodecode.CONFIG.get('rhodecode_title') or 'RhodeCode'
199
198
200 base_response = HTTPInternalServerError()
199 base_response = HTTPInternalServerError()
201 # prefer original exception for the response since it may have headers set
200 # prefer original exception for the response since it may have headers set
202 if isinstance(exception, HTTPException):
201 if isinstance(exception, HTTPException):
203 base_response = exception
202 base_response = exception
204 elif isinstance(exception, VCSCommunicationError):
203 elif isinstance(exception, VCSCommunicationError):
205 base_response = VCSServerUnavailable()
204 base_response = VCSServerUnavailable()
206
205
207 if is_http_error(base_response):
206 if is_http_error(base_response):
208 log.exception(
207 log.exception(
209 'error occurred handling this request for path: %s', request.path)
208 'error occurred handling this request for path: %s', request.path)
210
209
211 error_explanation = base_response.explanation or str(base_response)
210 error_explanation = base_response.explanation or str(base_response)
212 if base_response.status_code == 404:
211 if base_response.status_code == 404:
213 error_explanation += " Optionally you don't have permission to access this page."
212 error_explanation += " Optionally you don't have permission to access this page."
214 c = AttributeDict()
213 c = AttributeDict()
215 c.error_message = base_response.status
214 c.error_message = base_response.status
216 c.error_explanation = error_explanation
215 c.error_explanation = error_explanation
217 c.visual = AttributeDict()
216 c.visual = AttributeDict()
218
217
219 c.visual.rhodecode_support_url = (
218 c.visual.rhodecode_support_url = (
220 request.registry.settings.get('rhodecode_support_url') or
219 request.registry.settings.get('rhodecode_support_url') or
221 request.route_url('rhodecode_support')
220 request.route_url('rhodecode_support')
222 )
221 )
223 c.redirect_time = 0
222 c.redirect_time = 0
224 c.rhodecode_name = rhodecode_title
223 c.rhodecode_name = rhodecode_title
225 if not c.rhodecode_name:
224 if not c.rhodecode_name:
226 c.rhodecode_name = 'Rhodecode'
225 c.rhodecode_name = 'Rhodecode'
227
226
228 c.causes = []
227 c.causes = []
229 if is_http_error(base_response):
228 if is_http_error(base_response):
230 c.causes.append('Server is overloaded.')
229 c.causes.append('Server is overloaded.')
231 c.causes.append('Server database connection is lost.')
230 c.causes.append('Server database connection is lost.')
232 c.causes.append('Server expected unhandled error.')
231 c.causes.append('Server expected unhandled error.')
233
232
234 if hasattr(base_response, 'causes'):
233 if hasattr(base_response, 'causes'):
235 c.causes = base_response.causes
234 c.causes = base_response.causes
236
235
237 c.messages = helpers.flash.pop_messages(request=request)
236 c.messages = helpers.flash.pop_messages(request=request)
238 exc_info = sys.exc_info()
237 exc_info = sys.exc_info()
239 c.exception_id = id(exc_info)
238 c.exception_id = id(exc_info)
240 c.show_exception_id = isinstance(base_response, VCSServerUnavailable) \
239 c.show_exception_id = isinstance(base_response, VCSServerUnavailable) \
241 or base_response.status_code > 499
240 or base_response.status_code > 499
242 c.exception_id_url = request.route_url(
241 c.exception_id_url = request.route_url(
243 'admin_settings_exception_tracker_show', exception_id=c.exception_id)
242 'admin_settings_exception_tracker_show', exception_id=c.exception_id)
244
243
245 if c.show_exception_id:
244 if c.show_exception_id:
246 store_exception(c.exception_id, exc_info)
245 store_exception(c.exception_id, exc_info)
247 c.exception_debug = str2bool(rhodecode.CONFIG.get('debug'))
246 c.exception_debug = str2bool(rhodecode.CONFIG.get('debug'))
248 c.exception_config_ini = rhodecode.CONFIG.get('__file__')
247 c.exception_config_ini = rhodecode.CONFIG.get('__file__')
249
248
250 response = render_to_response(
249 response = render_to_response(
251 '/errors/error_document.mako', {'c': c, 'h': helpers}, request=request,
250 '/errors/error_document.mako', {'c': c, 'h': helpers}, request=request,
252 response=base_response)
251 response=base_response)
253
252
254 statsd = request.registry.statsd
253 statsd = request.registry.statsd
255 if statsd and base_response.status_code > 499:
254 if statsd and base_response.status_code > 499:
256 exc_type = "{}.{}".format(exception.__class__.__module__, exception.__class__.__name__)
255 exc_type = "{}.{}".format(exception.__class__.__module__, exception.__class__.__name__)
257 statsd.incr('rhodecode_exception_total',
256 statsd.incr('rhodecode_exception_total',
258 tags=["exc_source:web",
257 tags=["exc_source:web",
259 "http_code:{}".format(base_response.status_code),
258 "http_code:{}".format(base_response.status_code),
260 "type:{}".format(exc_type)])
259 "type:{}".format(exc_type)])
261
260
262 return response
261 return response
263
262
264
263
265 def includeme_first(config):
264 def includeme_first(config):
266 # redirect automatic browser favicon.ico requests to correct place
265 # redirect automatic browser favicon.ico requests to correct place
267 def favicon_redirect(context, request):
266 def favicon_redirect(context, request):
268 return HTTPFound(
267 return HTTPFound(
269 request.static_path('rhodecode:public/images/favicon.ico'))
268 request.static_path('rhodecode:public/images/favicon.ico'))
270
269
271 config.add_view(favicon_redirect, route_name='favicon')
270 config.add_view(favicon_redirect, route_name='favicon')
272 config.add_route('favicon', '/favicon.ico')
271 config.add_route('favicon', '/favicon.ico')
273
272
274 def robots_redirect(context, request):
273 def robots_redirect(context, request):
275 return HTTPFound(
274 return HTTPFound(
276 request.static_path('rhodecode:public/robots.txt'))
275 request.static_path('rhodecode:public/robots.txt'))
277
276
278 config.add_view(robots_redirect, route_name='robots')
277 config.add_view(robots_redirect, route_name='robots')
279 config.add_route('robots', '/robots.txt')
278 config.add_route('robots', '/robots.txt')
280
279
281 config.add_static_view(
280 config.add_static_view(
282 '_static/deform', 'deform:static')
281 '_static/deform', 'deform:static')
283 config.add_static_view(
282 config.add_static_view(
284 '_static/rhodecode', path='rhodecode:public', cache_max_age=3600 * 24)
283 '_static/rhodecode', path='rhodecode:public', cache_max_age=3600 * 24)
285
284
286
285
287 def includeme(config, auth_resources=None):
286 def includeme(config, auth_resources=None):
288 from rhodecode.lib.celerylib.loader import configure_celery
287 from rhodecode.lib.celerylib.loader import configure_celery
289 log.debug('Initializing main includeme from %s', os.path.basename(__file__))
288 log.debug('Initializing main includeme from %s', os.path.basename(__file__))
290 settings = config.registry.settings
289 settings = config.registry.settings
291 config.set_request_factory(Request)
290 config.set_request_factory(Request)
292
291
293 # plugin information
292 # plugin information
294 config.registry.rhodecode_plugins = collections.OrderedDict()
293 config.registry.rhodecode_plugins = collections.OrderedDict()
295
294
296 config.add_directive(
295 config.add_directive(
297 'register_rhodecode_plugin', register_rhodecode_plugin)
296 'register_rhodecode_plugin', register_rhodecode_plugin)
298
297
299 config.add_directive('configure_celery', configure_celery)
298 config.add_directive('configure_celery', configure_celery)
300
299
301 if settings.get('appenlight', False):
300 if settings.get('appenlight', False):
302 config.include('appenlight_client.ext.pyramid_tween')
301 config.include('appenlight_client.ext.pyramid_tween')
303
302
304 load_all = should_load_all()
303 load_all = should_load_all()
305
304
306 # Includes which are required. The application would fail without them.
305 # Includes which are required. The application would fail without them.
307 config.include('pyramid_mako')
306 config.include('pyramid_mako')
308 config.include('rhodecode.lib.rc_beaker')
307 config.include('rhodecode.lib.rc_beaker')
309 config.include('rhodecode.lib.rc_cache')
308 config.include('rhodecode.lib.rc_cache')
310 config.include('rhodecode.apps._base.navigation')
309 config.include('rhodecode.apps._base.navigation')
311 config.include('rhodecode.apps._base.subscribers')
310 config.include('rhodecode.apps._base.subscribers')
312 config.include('rhodecode.tweens')
311 config.include('rhodecode.tweens')
313 config.include('rhodecode.authentication')
312 config.include('rhodecode.authentication')
314
313
315 if load_all:
314 if load_all:
316 ce_auth_resources = [
315 ce_auth_resources = [
317 'rhodecode.authentication.plugins.auth_crowd',
316 'rhodecode.authentication.plugins.auth_crowd',
318 'rhodecode.authentication.plugins.auth_headers',
317 'rhodecode.authentication.plugins.auth_headers',
319 'rhodecode.authentication.plugins.auth_jasig_cas',
318 'rhodecode.authentication.plugins.auth_jasig_cas',
320 'rhodecode.authentication.plugins.auth_ldap',
319 'rhodecode.authentication.plugins.auth_ldap',
321 'rhodecode.authentication.plugins.auth_pam',
320 'rhodecode.authentication.plugins.auth_pam',
322 'rhodecode.authentication.plugins.auth_rhodecode',
321 'rhodecode.authentication.plugins.auth_rhodecode',
323 'rhodecode.authentication.plugins.auth_token',
322 'rhodecode.authentication.plugins.auth_token',
324 ]
323 ]
325
324
326 # load CE authentication plugins
325 # load CE authentication plugins
327
326
328 if auth_resources:
327 if auth_resources:
329 ce_auth_resources.extend(auth_resources)
328 ce_auth_resources.extend(auth_resources)
330
329
331 for resource in ce_auth_resources:
330 for resource in ce_auth_resources:
332 config.include(resource)
331 config.include(resource)
333
332
334 # Auto discover authentication plugins and include their configuration.
333 # Auto discover authentication plugins and include their configuration.
335 if asbool(settings.get('auth_plugin.import_legacy_plugins', 'true')):
334 if asbool(settings.get('auth_plugin.import_legacy_plugins', 'true')):
336 from rhodecode.authentication import discover_legacy_plugins
335 from rhodecode.authentication import discover_legacy_plugins
337 discover_legacy_plugins(config)
336 discover_legacy_plugins(config)
338
337
339 # apps
338 # apps
340 if load_all:
339 if load_all:
341 log.debug('Starting config.include() calls')
340 log.debug('Starting config.include() calls')
342 config.include('rhodecode.api.includeme')
341 config.include('rhodecode.api.includeme')
343 config.include('rhodecode.apps._base.includeme')
342 config.include('rhodecode.apps._base.includeme')
344 config.include('rhodecode.apps._base.navigation.includeme')
343 config.include('rhodecode.apps._base.navigation.includeme')
345 config.include('rhodecode.apps._base.subscribers.includeme')
344 config.include('rhodecode.apps._base.subscribers.includeme')
346 config.include('rhodecode.apps.hovercards.includeme')
345 config.include('rhodecode.apps.hovercards.includeme')
347 config.include('rhodecode.apps.ops.includeme')
346 config.include('rhodecode.apps.ops.includeme')
348 config.include('rhodecode.apps.channelstream.includeme')
347 config.include('rhodecode.apps.channelstream.includeme')
349 config.include('rhodecode.apps.file_store.includeme')
348 config.include('rhodecode.apps.file_store.includeme')
350 config.include('rhodecode.apps.admin.includeme')
349 config.include('rhodecode.apps.admin.includeme')
351 config.include('rhodecode.apps.login.includeme')
350 config.include('rhodecode.apps.login.includeme')
352 config.include('rhodecode.apps.home.includeme')
351 config.include('rhodecode.apps.home.includeme')
353 config.include('rhodecode.apps.journal.includeme')
352 config.include('rhodecode.apps.journal.includeme')
354
353
355 config.include('rhodecode.apps.repository.includeme')
354 config.include('rhodecode.apps.repository.includeme')
356 config.include('rhodecode.apps.repo_group.includeme')
355 config.include('rhodecode.apps.repo_group.includeme')
357 config.include('rhodecode.apps.user_group.includeme')
356 config.include('rhodecode.apps.user_group.includeme')
358 config.include('rhodecode.apps.search.includeme')
357 config.include('rhodecode.apps.search.includeme')
359 config.include('rhodecode.apps.user_profile.includeme')
358 config.include('rhodecode.apps.user_profile.includeme')
360 config.include('rhodecode.apps.user_group_profile.includeme')
359 config.include('rhodecode.apps.user_group_profile.includeme')
361 config.include('rhodecode.apps.my_account.includeme')
360 config.include('rhodecode.apps.my_account.includeme')
362 config.include('rhodecode.apps.gist.includeme')
361 config.include('rhodecode.apps.gist.includeme')
363
362
364 config.include('rhodecode.apps.svn_support.includeme')
363 config.include('rhodecode.apps.svn_support.includeme')
365 config.include('rhodecode.apps.ssh_support.includeme')
364 config.include('rhodecode.apps.ssh_support.includeme')
366 config.include('rhodecode.apps.debug_style')
365 config.include('rhodecode.apps.debug_style')
367
366
368 if load_all:
367 if load_all:
369 config.include('rhodecode.integrations.includeme')
368 config.include('rhodecode.integrations.includeme')
370 config.include('rhodecode.integrations.routes.includeme')
369 config.include('rhodecode.integrations.routes.includeme')
371
370
372 config.add_route('rhodecode_support', 'https://rhodecode.com/help/', static=True)
371 config.add_route('rhodecode_support', 'https://rhodecode.com/help/', static=True)
373 settings['default_locale_name'] = settings.get('lang', 'en')
372 settings['default_locale_name'] = settings.get('lang', 'en')
374 config.add_translation_dirs('rhodecode:i18n/')
373 config.add_translation_dirs('rhodecode:i18n/')
375
374
376 # Add subscribers.
375 # Add subscribers.
377 if load_all:
376 if load_all:
378 log.debug('Adding subscribers....')
377 log.debug('Adding subscribers....')
379 config.add_subscriber(scan_repositories_if_enabled,
378 config.add_subscriber(scan_repositories_if_enabled,
380 pyramid.events.ApplicationCreated)
379 pyramid.events.ApplicationCreated)
381 config.add_subscriber(write_metadata_if_needed,
380 config.add_subscriber(write_metadata_if_needed,
382 pyramid.events.ApplicationCreated)
381 pyramid.events.ApplicationCreated)
383 config.add_subscriber(write_usage_data,
382 config.add_subscriber(write_usage_data,
384 pyramid.events.ApplicationCreated)
383 pyramid.events.ApplicationCreated)
385 config.add_subscriber(write_js_routes_if_enabled,
384 config.add_subscriber(write_js_routes_if_enabled,
386 pyramid.events.ApplicationCreated)
385 pyramid.events.ApplicationCreated)
387
386
388 # Set the authorization policy.
387 # Set the authorization policy.
389 authz_policy = ACLAuthorizationPolicy()
388 authz_policy = ACLAuthorizationPolicy()
390 config.set_authorization_policy(authz_policy)
389 config.set_authorization_policy(authz_policy)
391
390
392 # Set the default renderer for HTML templates to mako.
391 # Set the default renderer for HTML templates to mako.
393 config.add_mako_renderer('.html')
392 config.add_mako_renderer('.html')
394
393
395 config.add_renderer(
394 config.add_renderer(
396 name='json_ext',
395 name='json_ext',
397 factory='rhodecode.lib.ext_json_renderer.pyramid_ext_json')
396 factory='rhodecode.lib.ext_json_renderer.pyramid_ext_json')
398
397
399 config.add_renderer(
398 config.add_renderer(
400 name='string_html',
399 name='string_html',
401 factory='rhodecode.lib.string_renderer.html')
400 factory='rhodecode.lib.string_renderer.html')
402
401
403 # include RhodeCode plugins
402 # include RhodeCode plugins
404 includes = aslist(settings.get('rhodecode.includes', []))
403 includes = aslist(settings.get('rhodecode.includes', []))
405 log.debug('processing rhodecode.includes data...')
404 log.debug('processing rhodecode.includes data...')
406 for inc in includes:
405 for inc in includes:
407 config.include(inc)
406 config.include(inc)
408
407
409 # custom not found view, if our pyramid app doesn't know how to handle
408 # custom not found view, if our pyramid app doesn't know how to handle
410 # the request pass it to potential VCS handling ap
409 # the request pass it to potential VCS handling ap
411 config.add_notfound_view(not_found_view)
410 config.add_notfound_view(not_found_view)
412 if not settings.get('debugtoolbar.enabled', False):
411 if not settings.get('debugtoolbar.enabled', False):
413 # disabled debugtoolbar handle all exceptions via the error_handlers
412 # disabled debugtoolbar handle all exceptions via the error_handlers
414 config.add_view(error_handler, context=Exception)
413 config.add_view(error_handler, context=Exception)
415
414
416 # all errors including 403/404/50X
415 # all errors including 403/404/50X
417 config.add_view(error_handler, context=HTTPError)
416 config.add_view(error_handler, context=HTTPError)
418
417
419
418
420 def wrap_app_in_wsgi_middlewares(pyramid_app, config):
419 def wrap_app_in_wsgi_middlewares(pyramid_app, config):
421 """
420 """
422 Apply outer WSGI middlewares around the application.
421 Apply outer WSGI middlewares around the application.
423 """
422 """
424 registry = config.registry
423 registry = config.registry
425 settings = registry.settings
424 settings = registry.settings
426
425
427 # enable https redirects based on HTTP_X_URL_SCHEME set by proxy
426 # enable https redirects based on HTTP_X_URL_SCHEME set by proxy
428 pyramid_app = HttpsFixup(pyramid_app, settings)
427 pyramid_app = HttpsFixup(pyramid_app, settings)
429
428
430 pyramid_app, _ae_client = wrap_in_appenlight_if_enabled(
429 pyramid_app, _ae_client = wrap_in_appenlight_if_enabled(
431 pyramid_app, settings)
430 pyramid_app, settings)
432 registry.ae_client = _ae_client
431 registry.ae_client = _ae_client
433
432
434 if settings['gzip_responses']:
433 if settings['gzip_responses']:
435 pyramid_app = make_gzip_middleware(
434 pyramid_app = make_gzip_middleware(
436 pyramid_app, settings, compress_level=1)
435 pyramid_app, settings, compress_level=1)
437
436
438 # this should be the outer most middleware in the wsgi stack since
437 # this should be the outer most middleware in the wsgi stack since
439 # middleware like Routes make database calls
438 # middleware like Routes make database calls
440 def pyramid_app_with_cleanup(environ, start_response):
439 def pyramid_app_with_cleanup(environ, start_response):
441 start = time.time()
440 start = time.time()
442 try:
441 try:
443 return pyramid_app(environ, start_response)
442 return pyramid_app(environ, start_response)
444 finally:
443 finally:
445 # Dispose current database session and rollback uncommitted
444 # Dispose current database session and rollback uncommitted
446 # transactions.
445 # transactions.
447 meta.Session.remove()
446 meta.Session.remove()
448
447
449 # In a single threaded mode server, on non sqlite db we should have
448 # In a single threaded mode server, on non sqlite db we should have
450 # '0 Current Checked out connections' at the end of a request,
449 # '0 Current Checked out connections' at the end of a request,
451 # if not, then something, somewhere is leaving a connection open
450 # if not, then something, somewhere is leaving a connection open
452 pool = meta.Base.metadata.bind.engine.pool
451 pool = meta.Base.metadata.bind.engine.pool
453 log.debug('sa pool status: %s', pool.status())
452 log.debug('sa pool status: %s', pool.status())
454 total = time.time() - start
453 total = time.time() - start
455 log.debug('Request processing finalized: %.4fs', total)
454 log.debug('Request processing finalized: %.4fs', total)
456
455
457 return pyramid_app_with_cleanup
456 return pyramid_app_with_cleanup
458
457
459
458
460 def sanitize_settings_and_apply_defaults(global_config, settings):
459 def sanitize_settings_and_apply_defaults(global_config, settings):
461 """
460 """
462 Applies settings defaults and does all type conversion.
461 Applies settings defaults and does all type conversion.
463
462
464 We would move all settings parsing and preparation into this place, so that
463 We would move all settings parsing and preparation into this place, so that
465 we have only one place left which deals with this part. The remaining parts
464 we have only one place left which deals with this part. The remaining parts
466 of the application would start to rely fully on well prepared settings.
465 of the application would start to rely fully on well prepared settings.
467
466
468 This piece would later be split up per topic to avoid a big fat monster
467 This piece would later be split up per topic to avoid a big fat monster
469 function.
468 function.
470 """
469 """
471
470
472 global_settings_maker = SettingsMaker(global_config)
471 global_settings_maker = SettingsMaker(global_config)
473 global_settings_maker.make_setting('debug', default=False, parser='bool')
472 global_settings_maker.make_setting('debug', default=False, parser='bool')
474 debug_enabled = asbool(global_config.get('debug'))
473 debug_enabled = asbool(global_config.get('debug'))
475
474
476 settings_maker = SettingsMaker(settings)
475 settings_maker = SettingsMaker(settings)
477
476
478 settings_maker.make_setting(
477 settings_maker.make_setting(
479 'logging.autoconfigure',
478 'logging.autoconfigure',
480 default=False,
479 default=False,
481 parser='bool')
480 parser='bool')
482
481
483 logging_conf = os.path.join(os.path.dirname(global_config.get('__file__')), 'logging.ini')
482 logging_conf = os.path.join(os.path.dirname(global_config.get('__file__')), 'logging.ini')
484 settings_maker.enable_logging(logging_conf, level='INFO' if debug_enabled else 'DEBUG')
483 settings_maker.enable_logging(logging_conf, level='INFO' if debug_enabled else 'DEBUG')
485
484
486 # Default includes, possible to change as a user
485 # Default includes, possible to change as a user
487 pyramid_includes = settings_maker.make_setting('pyramid.includes', [], parser='list:newline')
486 pyramid_includes = settings_maker.make_setting('pyramid.includes', [], parser='list:newline')
488 log.debug(
487 log.debug(
489 "Using the following pyramid.includes: %s",
488 "Using the following pyramid.includes: %s",
490 pyramid_includes)
489 pyramid_includes)
491
490
492 settings_maker.make_setting('rhodecode.edition', 'Community Edition')
491 settings_maker.make_setting('rhodecode.edition', 'Community Edition')
493 settings_maker.make_setting('rhodecode.edition_id', 'CE')
492 settings_maker.make_setting('rhodecode.edition_id', 'CE')
494
493
495 if 'mako.default_filters' not in settings:
494 if 'mako.default_filters' not in settings:
496 # set custom default filters if we don't have it defined
495 # set custom default filters if we don't have it defined
497 settings['mako.imports'] = 'from rhodecode.lib.base import h_filter'
496 settings['mako.imports'] = 'from rhodecode.lib.base import h_filter'
498 settings['mako.default_filters'] = 'h_filter'
497 settings['mako.default_filters'] = 'h_filter'
499
498
500 if 'mako.directories' not in settings:
499 if 'mako.directories' not in settings:
501 mako_directories = settings.setdefault('mako.directories', [
500 mako_directories = settings.setdefault('mako.directories', [
502 # Base templates of the original application
501 # Base templates of the original application
503 'rhodecode:templates',
502 'rhodecode:templates',
504 ])
503 ])
505 log.debug(
504 log.debug(
506 "Using the following Mako template directories: %s",
505 "Using the following Mako template directories: %s",
507 mako_directories)
506 mako_directories)
508
507
509 # NOTE(marcink): fix redis requirement for schema of connection since 3.X
508 # NOTE(marcink): fix redis requirement for schema of connection since 3.X
510 if 'beaker.session.type' in settings and settings['beaker.session.type'] == 'ext:redis':
509 if 'beaker.session.type' in settings and settings['beaker.session.type'] == 'ext:redis':
511 raw_url = settings['beaker.session.url']
510 raw_url = settings['beaker.session.url']
512 if not raw_url.startswith(('redis://', 'rediss://', 'unix://')):
511 if not raw_url.startswith(('redis://', 'rediss://', 'unix://')):
513 settings['beaker.session.url'] = 'redis://' + raw_url
512 settings['beaker.session.url'] = 'redis://' + raw_url
514
513
515 settings_maker.make_setting('__file__', global_config.get('__file__'))
514 settings_maker.make_setting('__file__', global_config.get('__file__'))
516
515
517 # TODO: johbo: Re-think this, usually the call to config.include
516 # TODO: johbo: Re-think this, usually the call to config.include
518 # should allow to pass in a prefix.
517 # should allow to pass in a prefix.
519 settings_maker.make_setting('rhodecode.api.url', '/_admin/api')
518 settings_maker.make_setting('rhodecode.api.url', '/_admin/api')
520
519
521 # Sanitize generic settings.
520 # Sanitize generic settings.
522 settings_maker.make_setting('default_encoding', 'UTF-8', parser='list')
521 settings_maker.make_setting('default_encoding', 'UTF-8', parser='list')
523 settings_maker.make_setting('is_test', False, parser='bool')
522 settings_maker.make_setting('is_test', False, parser='bool')
524 settings_maker.make_setting('gzip_responses', False, parser='bool')
523 settings_maker.make_setting('gzip_responses', False, parser='bool')
525
524
526 # statsd
525 # statsd
527 settings_maker.make_setting('statsd.enabled', False, parser='bool')
526 settings_maker.make_setting('statsd.enabled', False, parser='bool')
528 settings_maker.make_setting('statsd.statsd_host', 'statsd-exporter', parser='string')
527 settings_maker.make_setting('statsd.statsd_host', 'statsd-exporter', parser='string')
529 settings_maker.make_setting('statsd.statsd_port', 9125, parser='int')
528 settings_maker.make_setting('statsd.statsd_port', 9125, parser='int')
530 settings_maker.make_setting('statsd.statsd_prefix', '')
529 settings_maker.make_setting('statsd.statsd_prefix', '')
531 settings_maker.make_setting('statsd.statsd_ipv6', False, parser='bool')
530 settings_maker.make_setting('statsd.statsd_ipv6', False, parser='bool')
532
531
533 settings_maker.make_setting('vcs.svn.compatible_version', '')
532 settings_maker.make_setting('vcs.svn.compatible_version', '')
534 settings_maker.make_setting('vcs.hooks.protocol', 'http')
533 settings_maker.make_setting('vcs.hooks.protocol', 'http')
535 settings_maker.make_setting('vcs.hooks.host', '127.0.0.1')
534 settings_maker.make_setting('vcs.hooks.host', '127.0.0.1')
536 settings_maker.make_setting('vcs.scm_app_implementation', 'http')
535 settings_maker.make_setting('vcs.scm_app_implementation', 'http')
537 settings_maker.make_setting('vcs.server', '')
536 settings_maker.make_setting('vcs.server', '')
538 settings_maker.make_setting('vcs.server.protocol', 'http')
537 settings_maker.make_setting('vcs.server.protocol', 'http')
539 settings_maker.make_setting('vcs.server.enable', 'true', parser='bool')
538 settings_maker.make_setting('vcs.server.enable', 'true', parser='bool')
540 settings_maker.make_setting('startup.import_repos', 'false', parser='bool')
539 settings_maker.make_setting('startup.import_repos', 'false', parser='bool')
541 settings_maker.make_setting('vcs.hooks.direct_calls', 'false', parser='bool')
540 settings_maker.make_setting('vcs.hooks.direct_calls', 'false', parser='bool')
542 settings_maker.make_setting('vcs.start_server', 'false', parser='bool')
541 settings_maker.make_setting('vcs.start_server', 'false', parser='bool')
543 settings_maker.make_setting('vcs.backends', 'hg, git, svn', parser='list')
542 settings_maker.make_setting('vcs.backends', 'hg, git, svn', parser='list')
544 settings_maker.make_setting('vcs.connection_timeout', 3600, parser='int')
543 settings_maker.make_setting('vcs.connection_timeout', 3600, parser='int')
545
544
546 settings_maker.make_setting('vcs.methods.cache', True, parser='bool')
545 settings_maker.make_setting('vcs.methods.cache', True, parser='bool')
547
546
548 # Support legacy values of vcs.scm_app_implementation. Legacy
547 # Support legacy values of vcs.scm_app_implementation. Legacy
549 # configurations may use 'rhodecode.lib.middleware.utils.scm_app_http', or
548 # configurations may use 'rhodecode.lib.middleware.utils.scm_app_http', or
550 # disabled since 4.13 'vcsserver.scm_app' which is now mapped to 'http'.
549 # disabled since 4.13 'vcsserver.scm_app' which is now mapped to 'http'.
551 scm_app_impl = settings['vcs.scm_app_implementation']
550 scm_app_impl = settings['vcs.scm_app_implementation']
552 if scm_app_impl in ['rhodecode.lib.middleware.utils.scm_app_http', 'vcsserver.scm_app']:
551 if scm_app_impl in ['rhodecode.lib.middleware.utils.scm_app_http', 'vcsserver.scm_app']:
553 settings['vcs.scm_app_implementation'] = 'http'
552 settings['vcs.scm_app_implementation'] = 'http'
554
553
555 settings_maker.make_setting('appenlight', False, parser='bool')
554 settings_maker.make_setting('appenlight', False, parser='bool')
556
555
557 temp_store = tempfile.gettempdir()
556 temp_store = tempfile.gettempdir()
558 tmp_cache_dir = os.path.join(temp_store, 'rc_cache')
557 tmp_cache_dir = os.path.join(temp_store, 'rc_cache')
559
558
560 # save default, cache dir, and use it for all backends later.
559 # save default, cache dir, and use it for all backends later.
561 default_cache_dir = settings_maker.make_setting(
560 default_cache_dir = settings_maker.make_setting(
562 'cache_dir',
561 'cache_dir',
563 default=tmp_cache_dir, default_when_empty=True,
562 default=tmp_cache_dir, default_when_empty=True,
564 parser='dir:ensured')
563 parser='dir:ensured')
565
564
566 # exception store cache
565 # exception store cache
567 settings_maker.make_setting(
566 settings_maker.make_setting(
568 'exception_tracker.store_path',
567 'exception_tracker.store_path',
569 default=os.path.join(default_cache_dir, 'exc_store'), default_when_empty=True,
568 default=os.path.join(default_cache_dir, 'exc_store'), default_when_empty=True,
570 parser='dir:ensured'
569 parser='dir:ensured'
571 )
570 )
572
571
573 settings_maker.make_setting(
572 settings_maker.make_setting(
574 'celerybeat-schedule.path',
573 'celerybeat-schedule.path',
575 default=os.path.join(default_cache_dir, 'celerybeat_schedule', 'celerybeat-schedule.db'), default_when_empty=True,
574 default=os.path.join(default_cache_dir, 'celerybeat_schedule', 'celerybeat-schedule.db'), default_when_empty=True,
576 parser='file:ensured'
575 parser='file:ensured'
577 )
576 )
578
577
579 settings_maker.make_setting('exception_tracker.send_email', False, parser='bool')
578 settings_maker.make_setting('exception_tracker.send_email', False, parser='bool')
580 settings_maker.make_setting('exception_tracker.email_prefix', '[RHODECODE ERROR]', default_when_empty=True)
579 settings_maker.make_setting('exception_tracker.email_prefix', '[RHODECODE ERROR]', default_when_empty=True)
581
580
582 # cache_general
581 # cache_general
583 settings_maker.make_setting('rc_cache.cache_general.backend', 'dogpile.cache.rc.file_namespace')
582 settings_maker.make_setting('rc_cache.cache_general.backend', 'dogpile.cache.rc.file_namespace')
584 settings_maker.make_setting('rc_cache.cache_general.expiration_time', 60 * 60 * 12, parser='int')
583 settings_maker.make_setting('rc_cache.cache_general.expiration_time', 60 * 60 * 12, parser='int')
585 settings_maker.make_setting('rc_cache.cache_general.arguments.filename', os.path.join(default_cache_dir, 'rhodecode_cache_general.db'))
584 settings_maker.make_setting('rc_cache.cache_general.arguments.filename', os.path.join(default_cache_dir, 'rhodecode_cache_general.db'))
586
585
587 # cache_perms
586 # cache_perms
588 settings_maker.make_setting('rc_cache.cache_perms.backend', 'dogpile.cache.rc.file_namespace')
587 settings_maker.make_setting('rc_cache.cache_perms.backend', 'dogpile.cache.rc.file_namespace')
589 settings_maker.make_setting('rc_cache.cache_perms.expiration_time', 60 * 60, parser='int')
588 settings_maker.make_setting('rc_cache.cache_perms.expiration_time', 60 * 60, parser='int')
590 settings_maker.make_setting('rc_cache.cache_perms.arguments.filename', os.path.join(default_cache_dir, 'rhodecode_cache_perms.db'))
589 settings_maker.make_setting('rc_cache.cache_perms.arguments.filename', os.path.join(default_cache_dir, 'rhodecode_cache_perms.db'))
591
590
592 # cache_repo
591 # cache_repo
593 settings_maker.make_setting('rc_cache.cache_repo.backend', 'dogpile.cache.rc.file_namespace')
592 settings_maker.make_setting('rc_cache.cache_repo.backend', 'dogpile.cache.rc.file_namespace')
594 settings_maker.make_setting('rc_cache.cache_repo.expiration_time', 60 * 60 * 24 * 30, parser='int')
593 settings_maker.make_setting('rc_cache.cache_repo.expiration_time', 60 * 60 * 24 * 30, parser='int')
595 settings_maker.make_setting('rc_cache.cache_repo.arguments.filename', os.path.join(default_cache_dir, 'rhodecode_cache_repo.db'))
594 settings_maker.make_setting('rc_cache.cache_repo.arguments.filename', os.path.join(default_cache_dir, 'rhodecode_cache_repo.db'))
596
595
597 # cache_license
596 # cache_license
598 settings_maker.make_setting('rc_cache.cache_license.backend', 'dogpile.cache.rc.file_namespace')
597 settings_maker.make_setting('rc_cache.cache_license.backend', 'dogpile.cache.rc.file_namespace')
599 settings_maker.make_setting('rc_cache.cache_license.expiration_time', 60 * 5, parser='int')
598 settings_maker.make_setting('rc_cache.cache_license.expiration_time', 60 * 5, parser='int')
600 settings_maker.make_setting('rc_cache.cache_license.arguments.filename', os.path.join(default_cache_dir, 'rhodecode_cache_license.db'))
599 settings_maker.make_setting('rc_cache.cache_license.arguments.filename', os.path.join(default_cache_dir, 'rhodecode_cache_license.db'))
601
600
602 # cache_repo_longterm memory, 96H
601 # cache_repo_longterm memory, 96H
603 settings_maker.make_setting('rc_cache.cache_repo_longterm.backend', 'dogpile.cache.rc.memory_lru')
602 settings_maker.make_setting('rc_cache.cache_repo_longterm.backend', 'dogpile.cache.rc.memory_lru')
604 settings_maker.make_setting('rc_cache.cache_repo_longterm.expiration_time', 345600, parser='int')
603 settings_maker.make_setting('rc_cache.cache_repo_longterm.expiration_time', 345600, parser='int')
605 settings_maker.make_setting('rc_cache.cache_repo_longterm.max_size', 10000, parser='int')
604 settings_maker.make_setting('rc_cache.cache_repo_longterm.max_size', 10000, parser='int')
606
605
607 # sql_cache_short
606 # sql_cache_short
608 settings_maker.make_setting('rc_cache.sql_cache_short.backend', 'dogpile.cache.rc.memory_lru')
607 settings_maker.make_setting('rc_cache.sql_cache_short.backend', 'dogpile.cache.rc.memory_lru')
609 settings_maker.make_setting('rc_cache.sql_cache_short.expiration_time', 30, parser='int')
608 settings_maker.make_setting('rc_cache.sql_cache_short.expiration_time', 30, parser='int')
610 settings_maker.make_setting('rc_cache.sql_cache_short.max_size', 10000, parser='int')
609 settings_maker.make_setting('rc_cache.sql_cache_short.max_size', 10000, parser='int')
611
610
612 settings_maker.env_expand()
611 settings_maker.env_expand()
613
612
614 # configure instance id
613 # configure instance id
615 config_utils.set_instance_id(settings)
614 config_utils.set_instance_id(settings)
616
615
617 return settings
616 return settings
@@ -1,99 +1,99 b''
1 # -*- coding: utf-8 -*-
1
2
2
3 # Copyright (C) 2016-2020 RhodeCode GmbH
3 # Copyright (C) 2016-2020 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
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
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
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/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 """
21 """
22 Compatibility patches.
22 Compatibility patches.
23
23
24 Please keep the following principles in mind:
24 Please keep the following principles in mind:
25
25
26 * Keep imports local, so that importing this module does not cause too many
26 * Keep imports local, so that importing this module does not cause too many
27 side effects by itself.
27 side effects by itself.
28
28
29 * Try to make patches idempotent, calling them multiple times should not do
29 * Try to make patches idempotent, calling them multiple times should not do
30 harm. If that is not possible, ensure that the second call explodes.
30 harm. If that is not possible, ensure that the second call explodes.
31
31
32 """
32 """
33
33
34
34
35 def inspect_getargspec():
35 def inspect_getargspec():
36 """
36 """
37 Pyramid rely on inspect.getargspec to lookup the signature of
37 Pyramid rely on inspect.getargspec to lookup the signature of
38 view functions. This is not compatible with cython, therefore we replace
38 view functions. This is not compatible with cython, therefore we replace
39 getargspec with a custom version.
39 getargspec with a custom version.
40 Code is inspired by the inspect module from Python-3.4
40 Code is inspired by the inspect module from Python-3.4
41 """
41 """
42 import inspect
42 import inspect
43
43
44 def _isCython(func):
44 def _isCython(func):
45 """
45 """
46 Private helper that checks if a function is a cython function.
46 Private helper that checks if a function is a cython function.
47 """
47 """
48 return func.__class__.__name__ == 'cython_function_or_method'
48 return func.__class__.__name__ == 'cython_function_or_method'
49
49
50 def unwrap(func):
50 def unwrap(func):
51 """
51 """
52 Get the object wrapped by *func*.
52 Get the object wrapped by *func*.
53
53
54 Follows the chain of :attr:`__wrapped__` attributes returning the last
54 Follows the chain of :attr:`__wrapped__` attributes returning the last
55 object in the chain.
55 object in the chain.
56
56
57 *stop* is an optional callback accepting an object in the wrapper chain
57 *stop* is an optional callback accepting an object in the wrapper chain
58 as its sole argument that allows the unwrapping to be terminated early
58 as its sole argument that allows the unwrapping to be terminated early
59 if the callback returns a true value. If the callback never returns a
59 if the callback returns a true value. If the callback never returns a
60 true value, the last object in the chain is returned as usual. For
60 true value, the last object in the chain is returned as usual. For
61 example, :func:`signature` uses this to stop unwrapping if any object
61 example, :func:`signature` uses this to stop unwrapping if any object
62 in the chain has a ``__signature__`` attribute defined.
62 in the chain has a ``__signature__`` attribute defined.
63
63
64 :exc:`ValueError` is raised if a cycle is encountered.
64 :exc:`ValueError` is raised if a cycle is encountered.
65 """
65 """
66 f = func # remember the original func for error reporting
66 f = func # remember the original func for error reporting
67 memo = {id(f)} # Memoise by id to tolerate non-hashable objects
67 memo = {id(f)} # Memoise by id to tolerate non-hashable objects
68 while hasattr(func, '__wrapped__'):
68 while hasattr(func, '__wrapped__'):
69 func = func.__wrapped__
69 func = func.__wrapped__
70 id_func = id(func)
70 id_func = id(func)
71 if id_func in memo:
71 if id_func in memo:
72 raise ValueError('wrapper loop when unwrapping {!r}'.format(f))
72 raise ValueError('wrapper loop when unwrapping {!r}'.format(f))
73 memo.add(id_func)
73 memo.add(id_func)
74 return func
74 return func
75
75
76 def custom_getargspec(func):
76 def custom_getargspec(func):
77 """
77 """
78 Get the names and default values of a function's arguments.
78 Get the names and default values of a function's arguments.
79
79
80 A tuple of four things is returned: (args, varargs, varkw, defaults).
80 A tuple of four things is returned: (args, varargs, varkw, defaults).
81 'args' is a list of the argument names (it may contain nested lists).
81 'args' is a list of the argument names (it may contain nested lists).
82 'varargs' and 'varkw' are the names of the * and ** arguments or None.
82 'varargs' and 'varkw' are the names of the * and ** arguments or None.
83 'defaults' is an n-tuple of the default values of the last n arguments.
83 'defaults' is an n-tuple of the default values of the last n arguments.
84 """
84 """
85
85
86 func = unwrap(func)
86 func = unwrap(func)
87
87
88 if inspect.ismethod(func):
88 if inspect.ismethod(func):
89 func = func.im_func
89 func = func.im_func
90 if not inspect.isfunction(func):
90 if not inspect.isfunction(func):
91 if not _isCython(func):
91 if not _isCython(func):
92 raise TypeError('{!r} is not a Python or Cython function'
92 raise TypeError('{!r} is not a Python or Cython function'
93 .format(func))
93 .format(func))
94 args, varargs, varkw = inspect.getargs(func.func_code)
94 args, varargs, varkw = inspect.getargs(func.func_code)
95 return inspect.ArgSpec(args, varargs, varkw, func.func_defaults)
95 return inspect.ArgSpec(args, varargs, varkw, func.func_defaults)
96
96
97 inspect.getargspec = custom_getargspec
97 inspect.getargspec = custom_getargspec
98
98
99 return inspect
99 return inspect
@@ -1,88 +1,88 b''
1 # -*- coding: utf-8 -*-
1
2 # Copyright (C) 2016-2020 RhodeCode GmbH
2 # Copyright (C) 2016-2020 RhodeCode GmbH
3 #
3 #
4 # This program is free software: you can redistribute it and/or modify
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License, version 3
5 # it under the terms of the GNU Affero General Public License, version 3
6 # (only), as published by the Free Software Foundation.
6 # (only), as published by the Free Software Foundation.
7 #
7 #
8 # This program is distributed in the hope that it will be useful,
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
11 # GNU General Public License for more details.
12 #
12 #
13 # You should have received a copy of the GNU Affero General Public License
13 # You should have received a copy of the GNU Affero General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 #
15 #
16 # This program is dual-licensed. If you wish to learn more about the
16 # This program is dual-licensed. If you wish to learn more about the
17 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
19
19
20 """
20 """
21 example usage in hooks::
21 example usage in hooks::
22
22
23 from .helpers import extra_fields
23 from .helpers import extra_fields
24 # returns list of dicts with key-val fetched from extra fields
24 # returns list of dicts with key-val fetched from extra fields
25 repo_extra_fields = extra_fields.run(**kwargs)
25 repo_extra_fields = extra_fields.run(**kwargs)
26 repo_extra_fields.get('endpoint_url')
26 repo_extra_fields.get('endpoint_url')
27
27
28 # the field stored the following example values
28 # the field stored the following example values
29 {u'created_on': datetime.datetime(),
29 {u'created_on': datetime.datetime(),
30 u'field_key': u'endpoint_url',
30 u'field_key': u'endpoint_url',
31 u'field_label': u'Endpoint URL',
31 u'field_label': u'Endpoint URL',
32 u'field_desc': u'Full HTTP endpoint to call if given',
32 u'field_desc': u'Full HTTP endpoint to call if given',
33 u'field_type': u'str',
33 u'field_type': u'str',
34 u'field_value': u'http://server.com/post',
34 u'field_value': u'http://server.com/post',
35 u'repo_field_id': 1,
35 u'repo_field_id': 1,
36 u'repository_id': 1}
36 u'repository_id': 1}
37 # for example to obtain the value:
37 # for example to obtain the value:
38 endpoint_field = repo_extra_fields.get('endpoint_url')
38 endpoint_field = repo_extra_fields.get('endpoint_url')
39 if endpoint_field:
39 if endpoint_field:
40 url = endpoint_field['field_value']
40 url = endpoint_field['field_value']
41
41
42 """
42 """
43
43
44
44
45 def run(*args, **kwargs):
45 def run(*args, **kwargs):
46 from rhodecode.model.db import Repository
46 from rhodecode.model.db import Repository
47 # use temp name then the main one propagated
47 # use temp name then the main one propagated
48 repo_name = kwargs.pop('REPOSITORY', None) or kwargs['repository']
48 repo_name = kwargs.pop('REPOSITORY', None) or kwargs['repository']
49 repo = Repository.get_by_repo_name(repo_name)
49 repo = Repository.get_by_repo_name(repo_name)
50
50
51 fields = {}
51 fields = {}
52 for field in repo.extra_fields:
52 for field in repo.extra_fields:
53 fields[field.field_key] = field.get_dict()
53 fields[field.field_key] = field.get_dict()
54
54
55 return fields
55 return fields
56
56
57
57
58 class _Undefined(object):
58 class _Undefined(object):
59 pass
59 pass
60
60
61
61
62 def get_field(extra_fields_data, key, default=_Undefined(), convert_type=True):
62 def get_field(extra_fields_data, key, default=_Undefined(), convert_type=True):
63 """
63 """
64 field_value = get_field(extra_fields, key='ci_endpoint_url', default='')
64 field_value = get_field(extra_fields, key='ci_endpoint_url', default='')
65 """
65 """
66 from ..utils import str2bool, aslist
66 from ..utils import str2bool, aslist
67
67
68 if key not in extra_fields_data:
68 if key not in extra_fields_data:
69 if isinstance(default, _Undefined):
69 if isinstance(default, _Undefined):
70 raise ValueError('key {} not present in extra_fields'.format(key))
70 raise ValueError('key {} not present in extra_fields'.format(key))
71 return default
71 return default
72
72
73 # NOTE(dan): from metadata we get field_label, field_value, field_desc, field_type
73 # NOTE(dan): from metadata we get field_label, field_value, field_desc, field_type
74 field_metadata = extra_fields_data[key]
74 field_metadata = extra_fields_data[key]
75
75
76 field_value = field_metadata['field_value']
76 field_value = field_metadata['field_value']
77
77
78 # NOTE(dan): empty value, use default
78 # NOTE(dan): empty value, use default
79 if not field_value and not isinstance(default, _Undefined):
79 if not field_value and not isinstance(default, _Undefined):
80 return default
80 return default
81
81
82 if convert_type:
82 if convert_type:
83 # 'str', 'unicode', 'list', 'tuple'
83 # 'str', 'unicode', 'list', 'tuple'
84 _type = field_metadata['field_type']
84 _type = field_metadata['field_type']
85 if _type in ['list', 'tuple']:
85 if _type in ['list', 'tuple']:
86 field_value = aslist(field_value)
86 field_value = aslist(field_value)
87
87
88 return field_value
88 return field_value
@@ -1,61 +1,61 b''
1 # -*- coding: utf-8 -*-
1
2 # Copyright (C) 2016-2020 RhodeCode GmbH
2 # Copyright (C) 2016-2020 RhodeCode GmbH
3 #
3 #
4 # This program is free software: you can redistribute it and/or modify
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License, version 3
5 # it under the terms of the GNU Affero General Public License, version 3
6 # (only), as published by the Free Software Foundation.
6 # (only), as published by the Free Software Foundation.
7 #
7 #
8 # This program is distributed in the hope that it will be useful,
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
11 # GNU General Public License for more details.
12 #
12 #
13 # You should have received a copy of the GNU Affero General Public License
13 # You should have received a copy of the GNU Affero General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 #
15 #
16 # This program is dual-licensed. If you wish to learn more about the
16 # This program is dual-licensed. If you wish to learn more about the
17 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
19
19
20 """
20 """
21 Extract and serialize commits taken from a list of commit_ids. This should
21 Extract and serialize commits taken from a list of commit_ids. This should
22 be used in post_push hook
22 be used in post_push hook
23
23
24 us in hooks::
24 us in hooks::
25
25
26 from .helpers import extract_post_commits
26 from .helpers import extract_post_commits
27 # returns list of dicts with key-val fetched from extra fields
27 # returns list of dicts with key-val fetched from extra fields
28 commit_list = extract_post_commits.run(**kwargs)
28 commit_list = extract_post_commits.run(**kwargs)
29 """
29 """
30 import traceback
30 import traceback
31
31
32
32
33 def run(*args, **kwargs):
33 def run(*args, **kwargs):
34 from rhodecode.lib.utils2 import extract_mentioned_users
34 from rhodecode.lib.utils2 import extract_mentioned_users
35 from rhodecode.model.db import Repository
35 from rhodecode.model.db import Repository
36
36
37 commit_ids = kwargs.get('commit_ids')
37 commit_ids = kwargs.get('commit_ids')
38 if not commit_ids:
38 if not commit_ids:
39 return 0
39 return 0
40
40
41 # use temp name then the main one propagated
41 # use temp name then the main one propagated
42 repo_name = kwargs.pop('REPOSITORY', None) or kwargs['repository']
42 repo_name = kwargs.pop('REPOSITORY', None) or kwargs['repository']
43
43
44 repo = Repository.get_by_repo_name(repo_name)
44 repo = Repository.get_by_repo_name(repo_name)
45 commits = []
45 commits = []
46
46
47 vcs_repo = repo.scm_instance(cache=False)
47 vcs_repo = repo.scm_instance(cache=False)
48 try:
48 try:
49 for commit_id in commit_ids:
49 for commit_id in commit_ids:
50 cs = vcs_repo.get_changeset(commit_id)
50 cs = vcs_repo.get_changeset(commit_id)
51 cs_data = cs.__json__()
51 cs_data = cs.__json__()
52 cs_data['mentions'] = extract_mentioned_users(cs_data['message'])
52 cs_data['mentions'] = extract_mentioned_users(cs_data['message'])
53 # optionally add more logic to parse the commits, like reading extra
53 # optionally add more logic to parse the commits, like reading extra
54 # fields of repository to read managers of reviewers ?
54 # fields of repository to read managers of reviewers ?
55 commits.append(cs_data)
55 commits.append(cs_data)
56 except Exception:
56 except Exception:
57 print(traceback.format_exc())
57 print(traceback.format_exc())
58 # we don't send any commits when crash happens, only full list matters
58 # we don't send any commits when crash happens, only full list matters
59 # we short circuit then.
59 # we short circuit then.
60 return []
60 return []
61 return commits
61 return commits
@@ -1,91 +1,91 b''
1 # -*- coding: utf-8 -*-
1
2 # Copyright (C) 2016-2020 RhodeCode GmbH
2 # Copyright (C) 2016-2020 RhodeCode GmbH
3 #
3 #
4 # This program is free software: you can redistribute it and/or modify
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License, version 3
5 # it under the terms of the GNU Affero General Public License, version 3
6 # (only), as published by the Free Software Foundation.
6 # (only), as published by the Free Software Foundation.
7 #
7 #
8 # This program is distributed in the hope that it will be useful,
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
11 # GNU General Public License for more details.
12 #
12 #
13 # You should have received a copy of the GNU Affero General Public License
13 # You should have received a copy of the GNU Affero General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 #
15 #
16 # This program is dual-licensed. If you wish to learn more about the
16 # This program is dual-licensed. If you wish to learn more about the
17 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
19
19
20 """
20 """
21 us in hooks::
21 us in hooks::
22
22
23 from .helpers import extract_pre_commits
23 from .helpers import extract_pre_commits
24 # returns list of dicts with key-val fetched from extra fields
24 # returns list of dicts with key-val fetched from extra fields
25 commit_list = extract_pre_commits.run(**kwargs)
25 commit_list = extract_pre_commits.run(**kwargs)
26
26
27 """
27 """
28 import re
28 import re
29 import collections
29 import collections
30 import json
30 import json
31
31
32
32
33 def get_hg_commits(repo, refs):
33 def get_hg_commits(repo, refs):
34 commits = []
34 commits = []
35 return commits
35 return commits
36
36
37
37
38 def get_git_commits(repo, refs):
38 def get_git_commits(repo, refs):
39 commits = []
39 commits = []
40
40
41 for data in refs:
41 for data in refs:
42 # we should now extract commit data
42 # we should now extract commit data
43 old_rev = data['old_rev']
43 old_rev = data['old_rev']
44 new_rev = data['new_rev']
44 new_rev = data['new_rev']
45
45
46 if '00000000' in old_rev:
46 if '00000000' in old_rev:
47 # new branch, we don't need to extract nothing
47 # new branch, we don't need to extract nothing
48 return commits
48 return commits
49
49
50 git_env = dict(data['git_env'])
50 git_env = dict(data['git_env'])
51 # https://github.com/git/git/blob/master/Documentation/pretty-formats.txt
51 # https://github.com/git/git/blob/master/Documentation/pretty-formats.txt
52 cmd = [
52 cmd = [
53 'log',
53 'log',
54 '--pretty=format:{"commit_id": "%H", "author": "%aN <%aE>", "date": "%ad", "message": "%s"}',
54 '--pretty=format:{"commit_id": "%H", "author": "%aN <%aE>", "date": "%ad", "message": "%s"}',
55 '{}...{}'.format(old_rev, new_rev)
55 '{}...{}'.format(old_rev, new_rev)
56 ]
56 ]
57
57
58 stdout, stderr = repo.run_git_command(cmd, extra_env=git_env)
58 stdout, stderr = repo.run_git_command(cmd, extra_env=git_env)
59 for line in stdout.splitlines():
59 for line in stdout.splitlines():
60 try:
60 try:
61 data = json.loads(line)
61 data = json.loads(line)
62 commits.append(data)
62 commits.append(data)
63 except Exception:
63 except Exception:
64 print('Failed to load data from GIT line')
64 print('Failed to load data from GIT line')
65
65
66 return commits
66 return commits
67
67
68
68
69 def run(*args, **kwargs):
69 def run(*args, **kwargs):
70 from rhodecode.model.db import Repository
70 from rhodecode.model.db import Repository
71
71
72 vcs_type = kwargs['scm']
72 vcs_type = kwargs['scm']
73 # use temp name then the main one propagated
73 # use temp name then the main one propagated
74 repo_name = kwargs.pop('REPOSITORY', None) or kwargs['repository']
74 repo_name = kwargs.pop('REPOSITORY', None) or kwargs['repository']
75
75
76 repo = Repository.get_by_repo_name(repo_name)
76 repo = Repository.get_by_repo_name(repo_name)
77 vcs_repo = repo.scm_instance(cache=False)
77 vcs_repo = repo.scm_instance(cache=False)
78
78
79 commits = []
79 commits = []
80
80
81 if vcs_type == 'git':
81 if vcs_type == 'git':
82 for rev_data in kwargs['commit_ids']:
82 for rev_data in kwargs['commit_ids']:
83 new_environ = dict((k, v) for k, v in rev_data['git_env'])
83 new_environ = dict((k, v) for k, v in rev_data['git_env'])
84 commits = get_git_commits(vcs_repo, kwargs['commit_ids'])
84 commits = get_git_commits(vcs_repo, kwargs['commit_ids'])
85
85
86 if vcs_type == 'hg':
86 if vcs_type == 'hg':
87 for rev_data in kwargs['commit_ids']:
87 for rev_data in kwargs['commit_ids']:
88 new_environ = dict((k, v) for k, v in rev_data['hg_env'])
88 new_environ = dict((k, v) for k, v in rev_data['hg_env'])
89 commits = get_hg_commits(vcs_repo, kwargs['commit_ids'])
89 commits = get_hg_commits(vcs_repo, kwargs['commit_ids'])
90
90
91 return commits
91 return commits
@@ -1,147 +1,147 b''
1 # -*- coding: utf-8 -*-
1
2 # Copyright (C) 2016-2020 RhodeCode GmbH
2 # Copyright (C) 2016-2020 RhodeCode GmbH
3 #
3 #
4 # This program is free software: you can redistribute it and/or modify
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License, version 3
5 # it under the terms of the GNU Affero General Public License, version 3
6 # (only), as published by the Free Software Foundation.
6 # (only), as published by the Free Software Foundation.
7 #
7 #
8 # This program is distributed in the hope that it will be useful,
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
11 # GNU General Public License for more details.
12 #
12 #
13 # You should have received a copy of the GNU Affero General Public License
13 # You should have received a copy of the GNU Affero General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 #
15 #
16 # This program is dual-licensed. If you wish to learn more about the
16 # This program is dual-licensed. If you wish to learn more about the
17 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
19
19
20 """
20 """
21 us in hooks::
21 us in hooks::
22
22
23 from .helpers import extract_pre_files
23 from .helpers import extract_pre_files
24 # returns list of dicts with key-val fetched from extra fields
24 # returns list of dicts with key-val fetched from extra fields
25 file_list = extract_pre_files.run(**kwargs)
25 file_list = extract_pre_files.run(**kwargs)
26
26
27 """
27 """
28 import re
28 import re
29 import collections
29 import collections
30 import json
30 import json
31
31
32 from rhodecode.lib import diffs
32 from rhodecode.lib import diffs
33 from rhodecode.lib.vcs.backends.hg.diff import MercurialDiff
33 from rhodecode.lib.vcs.backends.hg.diff import MercurialDiff
34 from rhodecode.lib.vcs.backends.git.diff import GitDiff
34 from rhodecode.lib.vcs.backends.git.diff import GitDiff
35 from vcsserver.utils import safe_int
35 from vcsserver.utils import safe_int
36
36
37
37
38 def get_svn_files(repo, vcs_repo, refs):
38 def get_svn_files(repo, vcs_repo, refs):
39 txn_id = refs[0]
39 txn_id = refs[0]
40 files = []
40 files = []
41
41
42 stdout, stderr = vcs_repo.run_svn_command(
42 stdout, stderr = vcs_repo.run_svn_command(
43 ['svnlook', 'changed', repo.repo_full_path, '--transaction', txn_id])
43 ['svnlook', 'changed', repo.repo_full_path, '--transaction', txn_id])
44
44
45 svn_op_to_rc_op = {
45 svn_op_to_rc_op = {
46 'A': 'A',
46 'A': 'A',
47 'U': 'M',
47 'U': 'M',
48 'D': 'D',
48 'D': 'D',
49 }
49 }
50
50
51 for entry in stdout.splitlines():
51 for entry in stdout.splitlines():
52 parsed_entry = {
52 parsed_entry = {
53 'raw_diff': '',
53 'raw_diff': '',
54 'filename': '',
54 'filename': '',
55 'chunks': [],
55 'chunks': [],
56 'ops': {},
56 'ops': {},
57 'file_size': 0
57 'file_size': 0
58 }
58 }
59
59
60 op = entry[0]
60 op = entry[0]
61 path = entry[1:].strip()
61 path = entry[1:].strip()
62
62
63 rc_op = svn_op_to_rc_op.get(op) or '?'
63 rc_op = svn_op_to_rc_op.get(op) or '?'
64 parsed_entry['filename'] = path
64 parsed_entry['filename'] = path
65 parsed_entry['operation'] = rc_op
65 parsed_entry['operation'] = rc_op
66
66
67 if rc_op in ['A', 'M']:
67 if rc_op in ['A', 'M']:
68
68
69 stdout, stderr = vcs_repo.run_svn_command(
69 stdout, stderr = vcs_repo.run_svn_command(
70 ['svnlook', 'filesize', repo.repo_full_path, path, '--transaction', txn_id],
70 ['svnlook', 'filesize', repo.repo_full_path, path, '--transaction', txn_id],
71 _safe=True
71 _safe=True
72 )
72 )
73
73
74 if "Path '{}' is not a file".format(path.rstrip('/')) in stderr:
74 if "Path '{}' is not a file".format(path.rstrip('/')) in stderr:
75 # skip dirs
75 # skip dirs
76 continue
76 continue
77
77
78 parsed_entry['file_size'] = safe_int(stdout.strip()) or 0
78 parsed_entry['file_size'] = safe_int(stdout.strip()) or 0
79
79
80 files.append(parsed_entry)
80 files.append(parsed_entry)
81
81
82 return files
82 return files
83
83
84
84
85 def get_hg_files(repo, vcs_repo, refs):
85 def get_hg_files(repo, vcs_repo, refs):
86 files = []
86 files = []
87 return files
87 return files
88
88
89
89
90 def get_git_files(repo, vcs_repo, refs):
90 def get_git_files(repo, vcs_repo, refs):
91 files = []
91 files = []
92
92
93 for data in refs:
93 for data in refs:
94 # we should now extract commit data
94 # we should now extract commit data
95 old_rev = data['old_rev']
95 old_rev = data['old_rev']
96 new_rev = data['new_rev']
96 new_rev = data['new_rev']
97
97
98 if '00000000' in old_rev:
98 if '00000000' in old_rev:
99 # new branch, we don't need to extract nothing
99 # new branch, we don't need to extract nothing
100 return files
100 return files
101
101
102 git_env = dict(data['git_env'])
102 git_env = dict(data['git_env'])
103
103
104 cmd = [
104 cmd = [
105 'diff', old_rev, new_rev
105 'diff', old_rev, new_rev
106 ]
106 ]
107
107
108 stdout, stderr = vcs_repo.run_git_command(cmd, extra_env=git_env)
108 stdout, stderr = vcs_repo.run_git_command(cmd, extra_env=git_env)
109 vcs_diff = GitDiff(stdout)
109 vcs_diff = GitDiff(stdout)
110
110
111 diff_processor = diffs.DiffProcessor(vcs_diff, format='newdiff')
111 diff_processor = diffs.DiffProcessor(vcs_diff, format='newdiff')
112 # this is list of dicts with diff information
112 # this is list of dicts with diff information
113 # _parsed[0].keys()
113 # _parsed[0].keys()
114 # ['raw_diff', 'old_revision', 'stats', 'original_filename',
114 # ['raw_diff', 'old_revision', 'stats', 'original_filename',
115 # 'is_limited_diff', 'chunks', 'new_revision', 'operation',
115 # 'is_limited_diff', 'chunks', 'new_revision', 'operation',
116 # 'exceeds_limit', 'filename']
116 # 'exceeds_limit', 'filename']
117 files = _parsed = diff_processor.prepare()
117 files = _parsed = diff_processor.prepare()
118
118
119 return files
119 return files
120
120
121
121
122 def run(*args, **kwargs):
122 def run(*args, **kwargs):
123 from rhodecode.model.db import Repository
123 from rhodecode.model.db import Repository
124
124
125 vcs_type = kwargs['scm']
125 vcs_type = kwargs['scm']
126 # use temp name then the main one propagated
126 # use temp name then the main one propagated
127 repo_name = kwargs.pop('REPOSITORY', None) or kwargs['repository']
127 repo_name = kwargs.pop('REPOSITORY', None) or kwargs['repository']
128
128
129 repo = Repository.get_by_repo_name(repo_name)
129 repo = Repository.get_by_repo_name(repo_name)
130 vcs_repo = repo.scm_instance(cache=False)
130 vcs_repo = repo.scm_instance(cache=False)
131
131
132 files = []
132 files = []
133
133
134 if vcs_type == 'git':
134 if vcs_type == 'git':
135 for rev_data in kwargs['commit_ids']:
135 for rev_data in kwargs['commit_ids']:
136 new_environ = dict((k, v) for k, v in rev_data['git_env'])
136 new_environ = dict((k, v) for k, v in rev_data['git_env'])
137 files = get_git_files(repo, vcs_repo, kwargs['commit_ids'])
137 files = get_git_files(repo, vcs_repo, kwargs['commit_ids'])
138
138
139 if vcs_type == 'hg':
139 if vcs_type == 'hg':
140 for rev_data in kwargs['commit_ids']:
140 for rev_data in kwargs['commit_ids']:
141 new_environ = dict((k, v) for k, v in rev_data['hg_env'])
141 new_environ = dict((k, v) for k, v in rev_data['hg_env'])
142 files = get_hg_files(repo, vcs_repo, kwargs['commit_ids'])
142 files = get_hg_files(repo, vcs_repo, kwargs['commit_ids'])
143
143
144 if vcs_type == 'svn':
144 if vcs_type == 'svn':
145 files = get_svn_files(repo, vcs_repo, kwargs['commit_ids'])
145 files = get_svn_files(repo, vcs_repo, kwargs['commit_ids'])
146
146
147 return files
147 return files
@@ -1,49 +1,49 b''
1 # -*- coding: utf-8 -*-
1
2 # Copyright (C) 2016-2020 RhodeCode GmbH
2 # Copyright (C) 2016-2020 RhodeCode GmbH
3 #
3 #
4 # This program is free software: you can redistribute it and/or modify
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License, version 3
5 # it under the terms of the GNU Affero General Public License, version 3
6 # (only), as published by the Free Software Foundation.
6 # (only), as published by the Free Software Foundation.
7 #
7 #
8 # This program is distributed in the hope that it will be useful,
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
11 # GNU General Public License for more details.
12 #
12 #
13 # You should have received a copy of the GNU Affero General Public License
13 # You should have received a copy of the GNU Affero General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 #
15 #
16 # This program is dual-licensed. If you wish to learn more about the
16 # This program is dual-licensed. If you wish to learn more about the
17 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
19
19
20 """
20 """
21 us in hooks::
21 us in hooks::
22
22
23 from .helpers import http_call
23 from .helpers import http_call
24 # returns response after making a POST call
24 # returns response after making a POST call
25 response = http_call.run(url=url, json_data={"key": "val"})
25 response = http_call.run(url=url, json_data={"key": "val"})
26
26
27 # returns response after making a GET call
27 # returns response after making a GET call
28 response = http_call.run(url=url, params={"key": "val"}, method='get')
28 response = http_call.run(url=url, params={"key": "val"}, method='get')
29
29
30 """
30 """
31
31
32 from rhodecode.integrations.types.base import requests_retry_call
32 from rhodecode.integrations.types.base import requests_retry_call
33
33
34
34
35 def run(url, json_data=None, params=None, method='post'):
35 def run(url, json_data=None, params=None, method='post'):
36 requests_session = requests_retry_call()
36 requests_session = requests_retry_call()
37 requests_session.verify = True # Verify SSL
37 requests_session.verify = True # Verify SSL
38 method_caller = getattr(requests_session, method, 'post')
38 method_caller = getattr(requests_session, method, 'post')
39
39
40 timeout = 60
40 timeout = 60
41 if json_data:
41 if json_data:
42 resp = method_caller(url, json=json_data, timeout=timeout)
42 resp = method_caller(url, json=json_data, timeout=timeout)
43 elif params:
43 elif params:
44 resp = method_caller(url, params=params, timeout=timeout)
44 resp = method_caller(url, params=params, timeout=timeout)
45 else:
45 else:
46 raise AttributeError('Provide json_data= or params= in function call')
46 raise AttributeError('Provide json_data= or params= in function call')
47 resp.raise_for_status() # raise exception on a failed request
47 resp.raise_for_status() # raise exception on a failed request
48 return resp
48 return resp
49
49
@@ -1,106 +1,105 b''
1 # -*- coding: utf-8 -*-
2
1
3 # Copyright (C) 2010-2020 RhodeCode GmbH
2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 #
3 #
5 # This program is free software: you can redistribute it and/or modify
4 # 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
5 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
6 # (only), as published by the Free Software Foundation.
8 #
7 #
9 # This program is distributed in the hope that it will be useful,
8 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
11 # GNU General Public License for more details.
13 #
12 #
14 # You should have received a copy of the GNU Affero General Public License
13 # 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/>.
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
15 #
17 # This program is dual-licensed. If you wish to learn more about the
16 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
19
21 """
20 """
22 Single source for redirection links.
21 Single source for redirection links.
23
22
24 Goal of this module is to provide a single source of truth regarding external
23 Goal of this module is to provide a single source of truth regarding external
25 links. The data inside this module is used to configure the routing
24 links. The data inside this module is used to configure the routing
26 system of Enterprise and it is used also as a base to check if this data
25 system of Enterprise and it is used also as a base to check if this data
27 and our server configuration are in sync.
26 and our server configuration are in sync.
28
27
29 .. py:data:: link_config
28 .. py:data:: link_config
30
29
31 Contains the configuration for external links. Each item is supposed to be
30 Contains the configuration for external links. Each item is supposed to be
32 a `dict` like this example::
31 a `dict` like this example::
33
32
34 {"name": "url_name",
33 {"name": "url_name",
35 "target": "https://rhodecode.com/r1/enterprise/keyword/",
34 "target": "https://rhodecode.com/r1/enterprise/keyword/",
36 "external_target": "https://example.com/some-page.html",
35 "external_target": "https://example.com/some-page.html",
37 }
36 }
38
37
39 then you can retrieve the url by simply calling the URL function:
38 then you can retrieve the url by simply calling the URL function:
40
39
41 `h.route_path('url_name')`
40 `h.route_path('url_name')`
42
41
43 The redirection must be first implemented in our servers before
42 The redirection must be first implemented in our servers before
44 you can see it working.
43 you can see it working.
45 """
44 """
46 # pragma: no cover
45 # pragma: no cover
47
46
48
47
49 link_config = [
48 link_config = [
50 {
49 {
51 "name": "enterprise_docs",
50 "name": "enterprise_docs",
52 "target": "https://rhodecode.com/r1/enterprise/docs/",
51 "target": "https://rhodecode.com/r1/enterprise/docs/",
53 "external_target": "https://docs.rhodecode.com/RhodeCode-Enterprise/",
52 "external_target": "https://docs.rhodecode.com/RhodeCode-Enterprise/",
54 },
53 },
55 {
54 {
56 "name": "enterprise_log_file_locations",
55 "name": "enterprise_log_file_locations",
57 "target": "https://rhodecode.com/r1/enterprise/docs/admin-system-overview/",
56 "target": "https://rhodecode.com/r1/enterprise/docs/admin-system-overview/",
58 "external_target": "https://docs.rhodecode.com/RhodeCode-Enterprise/admin/system-overview.html#log-files",
57 "external_target": "https://docs.rhodecode.com/RhodeCode-Enterprise/admin/system-overview.html#log-files",
59 },
58 },
60 {
59 {
61 "name": "enterprise_issue_tracker_settings",
60 "name": "enterprise_issue_tracker_settings",
62 "target": "https://rhodecode.com/r1/enterprise/docs/issue-trackers-overview/",
61 "target": "https://rhodecode.com/r1/enterprise/docs/issue-trackers-overview/",
63 "external_target": "https://docs.rhodecode.com/RhodeCode-Enterprise/issue-trackers/issue-trackers.html",
62 "external_target": "https://docs.rhodecode.com/RhodeCode-Enterprise/issue-trackers/issue-trackers.html",
64 },
63 },
65 {
64 {
66 "name": "enterprise_svn_setup",
65 "name": "enterprise_svn_setup",
67 "target": "https://rhodecode.com/r1/enterprise/docs/svn-setup/",
66 "target": "https://rhodecode.com/r1/enterprise/docs/svn-setup/",
68 "external_target": "https://docs.rhodecode.com/RhodeCode-Enterprise/admin/svn-http.html",
67 "external_target": "https://docs.rhodecode.com/RhodeCode-Enterprise/admin/svn-http.html",
69 },
68 },
70 {
69 {
71 "name": "enterprise_license_convert_from_old",
70 "name": "enterprise_license_convert_from_old",
72 "target": "https://rhodecode.com/r1/enterprise/convert-license/",
71 "target": "https://rhodecode.com/r1/enterprise/convert-license/",
73 "external_target": "https://rhodecode.com/u/license-upgrade",
72 "external_target": "https://rhodecode.com/u/license-upgrade",
74 },
73 },
75 {
74 {
76 "name": "rst_help",
75 "name": "rst_help",
77 "target": "http://docutils.sourceforge.io/docs/user/rst/quickref.html",
76 "target": "http://docutils.sourceforge.io/docs/user/rst/quickref.html",
78 "external_target": "https://docutils.sourceforge.io/docs/user/rst/quickref.html",
77 "external_target": "https://docutils.sourceforge.io/docs/user/rst/quickref.html",
79 },
78 },
80 {
79 {
81 "name": "markdown_help",
80 "name": "markdown_help",
82 "target": "https://daringfireball.net/projects/markdown/syntax",
81 "target": "https://daringfireball.net/projects/markdown/syntax",
83 "external_target": "https://daringfireball.net/projects/markdown/syntax",
82 "external_target": "https://daringfireball.net/projects/markdown/syntax",
84 },
83 },
85 {
84 {
86 "name": "rhodecode_official",
85 "name": "rhodecode_official",
87 "target": "https://rhodecode.com",
86 "target": "https://rhodecode.com",
88 "external_target": "https://rhodecode.com/",
87 "external_target": "https://rhodecode.com/",
89 },
88 },
90 {
89 {
91 "name": "rhodecode_support",
90 "name": "rhodecode_support",
92 "target": "https://rhodecode.com/help/",
91 "target": "https://rhodecode.com/help/",
93 "external_target": "https://rhodecode.com/support",
92 "external_target": "https://rhodecode.com/support",
94 },
93 },
95 {
94 {
96 "name": "rhodecode_translations",
95 "name": "rhodecode_translations",
97 "target": "https://rhodecode.com/translate/enterprise",
96 "target": "https://rhodecode.com/translate/enterprise",
98 "external_target": "https://explore.transifex.com/rhodecode/RhodeCode/",
97 "external_target": "https://explore.transifex.com/rhodecode/RhodeCode/",
99 },
98 },
100
99
101 ]
100 ]
102
101
103
102
104 def connect_redirection_links(config):
103 def connect_redirection_links(config):
105 for link in link_config:
104 for link in link_config:
106 config.add_route(link['name'], link['target'], static=True)
105 config.add_route(link['name'], link['target'], static=True)
@@ -1,205 +1,204 b''
1 # -*- coding: utf-8 -*-
2
1
3 # Copyright (C) 2010-2020 RhodeCode GmbH
2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 #
3 #
5 # This program is free software: you can redistribute it and/or modify
4 # 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
5 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
6 # (only), as published by the Free Software Foundation.
8 #
7 #
9 # This program is distributed in the hope that it will be useful,
8 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
11 # GNU General Public License for more details.
13 #
12 #
14 # You should have received a copy of the GNU Affero General Public License
13 # 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/>.
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
15 #
17 # This program is dual-licensed. If you wish to learn more about the
16 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
19
21 import os
20 import os
22 import textwrap
21 import textwrap
23 import string
22 import string
24 import functools
23 import functools
25 import logging
24 import logging
26 import tempfile
25 import tempfile
27 import logging.config
26 import logging.config
28 log = logging.getLogger(__name__)
27 log = logging.getLogger(__name__)
29
28
30 # skip keys, that are set here, so we don't double process those
29 # skip keys, that are set here, so we don't double process those
31 set_keys = {
30 set_keys = {
32 '__file__': ''
31 '__file__': ''
33 }
32 }
34
33
35
34
36 def str2bool(_str):
35 def str2bool(_str):
37 """
36 """
38 returns True/False value from given string, it tries to translate the
37 returns True/False value from given string, it tries to translate the
39 string into boolean
38 string into boolean
40
39
41 :param _str: string value to translate into boolean
40 :param _str: string value to translate into boolean
42 :rtype: boolean
41 :rtype: boolean
43 :returns: boolean from given string
42 :returns: boolean from given string
44 """
43 """
45 if _str is None:
44 if _str is None:
46 return False
45 return False
47 if _str in (True, False):
46 if _str in (True, False):
48 return _str
47 return _str
49 _str = str(_str).strip().lower()
48 _str = str(_str).strip().lower()
50 return _str in ('t', 'true', 'y', 'yes', 'on', '1')
49 return _str in ('t', 'true', 'y', 'yes', 'on', '1')
51
50
52
51
53 def aslist(obj, sep=None, strip=True):
52 def aslist(obj, sep=None, strip=True):
54 """
53 """
55 Returns given string separated by sep as list
54 Returns given string separated by sep as list
56
55
57 :param obj:
56 :param obj:
58 :param sep:
57 :param sep:
59 :param strip:
58 :param strip:
60 """
59 """
61 if isinstance(obj, str):
60 if isinstance(obj, str):
62 if obj in ['', ""]:
61 if obj in ['', ""]:
63 return []
62 return []
64
63
65 lst = obj.split(sep)
64 lst = obj.split(sep)
66 if strip:
65 if strip:
67 lst = [v.strip() for v in lst]
66 lst = [v.strip() for v in lst]
68 return lst
67 return lst
69 elif isinstance(obj, (list, tuple)):
68 elif isinstance(obj, (list, tuple)):
70 return obj
69 return obj
71 elif obj is None:
70 elif obj is None:
72 return []
71 return []
73 else:
72 else:
74 return [obj]
73 return [obj]
75
74
76
75
77 class SettingsMaker(object):
76 class SettingsMaker(object):
78
77
79 def __init__(self, app_settings):
78 def __init__(self, app_settings):
80 self.settings = app_settings
79 self.settings = app_settings
81
80
82 @classmethod
81 @classmethod
83 def _bool_func(cls, input_val):
82 def _bool_func(cls, input_val):
84 return str2bool(input_val)
83 return str2bool(input_val)
85
84
86 @classmethod
85 @classmethod
87 def _int_func(cls, input_val):
86 def _int_func(cls, input_val):
88 return int(input_val)
87 return int(input_val)
89
88
90 @classmethod
89 @classmethod
91 def _list_func(cls, input_val, sep=','):
90 def _list_func(cls, input_val, sep=','):
92 return aslist(input_val, sep=sep)
91 return aslist(input_val, sep=sep)
93
92
94 @classmethod
93 @classmethod
95 def _string_func(cls, input_val, lower=True):
94 def _string_func(cls, input_val, lower=True):
96 if lower:
95 if lower:
97 input_val = input_val.lower()
96 input_val = input_val.lower()
98 return input_val
97 return input_val
99
98
100 @classmethod
99 @classmethod
101 def _float_func(cls, input_val):
100 def _float_func(cls, input_val):
102 return float(input_val)
101 return float(input_val)
103
102
104 @classmethod
103 @classmethod
105 def _dir_func(cls, input_val, ensure_dir=False, mode=0o755):
104 def _dir_func(cls, input_val, ensure_dir=False, mode=0o755):
106
105
107 # ensure we have our dir created
106 # ensure we have our dir created
108 if not os.path.isdir(input_val) and ensure_dir:
107 if not os.path.isdir(input_val) and ensure_dir:
109 os.makedirs(input_val, mode=mode)
108 os.makedirs(input_val, mode=mode)
110
109
111 if not os.path.isdir(input_val):
110 if not os.path.isdir(input_val):
112 raise Exception('Dir at {} does not exist'.format(input_val))
111 raise Exception('Dir at {} does not exist'.format(input_val))
113 return input_val
112 return input_val
114
113
115 @classmethod
114 @classmethod
116 def _file_path_func(cls, input_val, ensure_dir=False, mode=0o755):
115 def _file_path_func(cls, input_val, ensure_dir=False, mode=0o755):
117 dirname = os.path.dirname(input_val)
116 dirname = os.path.dirname(input_val)
118 cls._dir_func(dirname, ensure_dir=ensure_dir)
117 cls._dir_func(dirname, ensure_dir=ensure_dir)
119 return input_val
118 return input_val
120
119
121 @classmethod
120 @classmethod
122 def _key_transformator(cls, key):
121 def _key_transformator(cls, key):
123 return "{}_{}".format('RC'.upper(), key.upper().replace('.', '_').replace('-', '_'))
122 return "{}_{}".format('RC'.upper(), key.upper().replace('.', '_').replace('-', '_'))
124
123
125 def maybe_env_key(self, key):
124 def maybe_env_key(self, key):
126 # now maybe we have this KEY in env, search and use the value with higher priority.
125 # now maybe we have this KEY in env, search and use the value with higher priority.
127 transformed_key = self._key_transformator(key)
126 transformed_key = self._key_transformator(key)
128 envvar_value = os.environ.get(transformed_key)
127 envvar_value = os.environ.get(transformed_key)
129 if envvar_value:
128 if envvar_value:
130 log.debug('using `%s` key instead of `%s` key for config', transformed_key, key)
129 log.debug('using `%s` key instead of `%s` key for config', transformed_key, key)
131
130
132 return envvar_value
131 return envvar_value
133
132
134 def env_expand(self):
133 def env_expand(self):
135 replaced = {}
134 replaced = {}
136 for k, v in self.settings.items():
135 for k, v in self.settings.items():
137 if k not in set_keys:
136 if k not in set_keys:
138 envvar_value = self.maybe_env_key(k)
137 envvar_value = self.maybe_env_key(k)
139 if envvar_value:
138 if envvar_value:
140 replaced[k] = envvar_value
139 replaced[k] = envvar_value
141 set_keys[k] = envvar_value
140 set_keys[k] = envvar_value
142
141
143 # replace ALL keys updated
142 # replace ALL keys updated
144 self.settings.update(replaced)
143 self.settings.update(replaced)
145
144
146 def enable_logging(self, logging_conf=None, level='INFO', formatter='generic'):
145 def enable_logging(self, logging_conf=None, level='INFO', formatter='generic'):
147 """
146 """
148 Helper to enable debug on running instance
147 Helper to enable debug on running instance
149 :return:
148 :return:
150 """
149 """
151
150
152 if not str2bool(self.settings.get('logging.autoconfigure')):
151 if not str2bool(self.settings.get('logging.autoconfigure')):
153 log.info('logging configuration based on main .ini file')
152 log.info('logging configuration based on main .ini file')
154 return
153 return
155
154
156 if logging_conf is None:
155 if logging_conf is None:
157 logging_conf = self.settings.get('logging.logging_conf_file') or ''
156 logging_conf = self.settings.get('logging.logging_conf_file') or ''
158
157
159 if not os.path.isfile(logging_conf):
158 if not os.path.isfile(logging_conf):
160 log.error('Unable to setup logging based on %s, '
159 log.error('Unable to setup logging based on %s, '
161 'file does not exist.... specify path using logging.logging_conf_file= config setting. ', logging_conf)
160 'file does not exist.... specify path using logging.logging_conf_file= config setting. ', logging_conf)
162 return
161 return
163
162
164 with open(logging_conf, 'rb') as f:
163 with open(logging_conf, 'rb') as f:
165 ini_template = textwrap.dedent(f.read())
164 ini_template = textwrap.dedent(f.read())
166 ini_template = string.Template(ini_template).safe_substitute(
165 ini_template = string.Template(ini_template).safe_substitute(
167 RC_LOGGING_LEVEL=os.environ.get('RC_LOGGING_LEVEL', '') or level,
166 RC_LOGGING_LEVEL=os.environ.get('RC_LOGGING_LEVEL', '') or level,
168 RC_LOGGING_FORMATTER=os.environ.get('RC_LOGGING_FORMATTER', '') or formatter
167 RC_LOGGING_FORMATTER=os.environ.get('RC_LOGGING_FORMATTER', '') or formatter
169 )
168 )
170
169
171 with tempfile.NamedTemporaryFile(prefix='rc_logging_', suffix='.ini', delete=False) as f:
170 with tempfile.NamedTemporaryFile(prefix='rc_logging_', suffix='.ini', delete=False) as f:
172 log.info('Saved Temporary LOGGING config at %s', f.name)
171 log.info('Saved Temporary LOGGING config at %s', f.name)
173 f.write(ini_template)
172 f.write(ini_template)
174
173
175 logging.config.fileConfig(f.name)
174 logging.config.fileConfig(f.name)
176 os.remove(f.name)
175 os.remove(f.name)
177
176
178 def make_setting(self, key, default, lower=False, default_when_empty=False, parser=None):
177 def make_setting(self, key, default, lower=False, default_when_empty=False, parser=None):
179 input_val = self.settings.get(key, default)
178 input_val = self.settings.get(key, default)
180
179
181 if default_when_empty and not input_val:
180 if default_when_empty and not input_val:
182 # use default value when value is set in the config but it is empty
181 # use default value when value is set in the config but it is empty
183 input_val = default
182 input_val = default
184
183
185 parser_func = {
184 parser_func = {
186 'bool': self._bool_func,
185 'bool': self._bool_func,
187 'int': self._int_func,
186 'int': self._int_func,
188 'list': self._list_func,
187 'list': self._list_func,
189 'list:newline': functools.partial(self._list_func, sep='/n'),
188 'list:newline': functools.partial(self._list_func, sep='/n'),
190 'list:spacesep': functools.partial(self._list_func, sep=' '),
189 'list:spacesep': functools.partial(self._list_func, sep=' '),
191 'string': functools.partial(self._string_func, lower=lower),
190 'string': functools.partial(self._string_func, lower=lower),
192 'dir': self._dir_func,
191 'dir': self._dir_func,
193 'dir:ensured': functools.partial(self._dir_func, ensure_dir=True),
192 'dir:ensured': functools.partial(self._dir_func, ensure_dir=True),
194 'file': self._file_path_func,
193 'file': self._file_path_func,
195 'file:ensured': functools.partial(self._file_path_func, ensure_dir=True),
194 'file:ensured': functools.partial(self._file_path_func, ensure_dir=True),
196 None: lambda i: i
195 None: lambda i: i
197 }[parser]
196 }[parser]
198
197
199 envvar_value = self.maybe_env_key(key)
198 envvar_value = self.maybe_env_key(key)
200 if envvar_value:
199 if envvar_value:
201 input_val = envvar_value
200 input_val = envvar_value
202 set_keys[key] = input_val
201 set_keys[key] = input_val
203
202
204 self.settings[key] = parser_func(input_val)
203 self.settings[key] = parser_func(input_val)
205 return self.settings[key]
204 return self.settings[key]
@@ -1,104 +1,103 b''
1 # -*- coding: utf-8 -*-
2
1
3 # Copyright (C) 2010-2020 RhodeCode GmbH
2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 #
3 #
5 # This program is free software: you can redistribute it and/or modify
4 # 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
5 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
6 # (only), as published by the Free Software Foundation.
8 #
7 #
9 # This program is distributed in the hope that it will be useful,
8 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
11 # GNU General Public License for more details.
13 #
12 #
14 # You should have received a copy of the GNU Affero General Public License
13 # 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/>.
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
15 #
17 # This program is dual-licensed. If you wish to learn more about the
16 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
19
21 import os
20 import os
22 import platform
21 import platform
23
22
24 from rhodecode.model import init_model
23 from rhodecode.model import init_model
25
24
26
25
27 def configure_vcs(config):
26 def configure_vcs(config):
28 """
27 """
29 Patch VCS config with some RhodeCode specific stuff
28 Patch VCS config with some RhodeCode specific stuff
30 """
29 """
31 from rhodecode.lib.vcs import conf
30 from rhodecode.lib.vcs import conf
32 import rhodecode.lib.vcs.conf.settings
31 import rhodecode.lib.vcs.conf.settings
33
32
34 conf.settings.BACKENDS = {
33 conf.settings.BACKENDS = {
35 'hg': 'rhodecode.lib.vcs.backends.hg.MercurialRepository',
34 'hg': 'rhodecode.lib.vcs.backends.hg.MercurialRepository',
36 'git': 'rhodecode.lib.vcs.backends.git.GitRepository',
35 'git': 'rhodecode.lib.vcs.backends.git.GitRepository',
37 'svn': 'rhodecode.lib.vcs.backends.svn.SubversionRepository',
36 'svn': 'rhodecode.lib.vcs.backends.svn.SubversionRepository',
38 }
37 }
39
38
40 conf.settings.HOOKS_PROTOCOL = config['vcs.hooks.protocol']
39 conf.settings.HOOKS_PROTOCOL = config['vcs.hooks.protocol']
41 conf.settings.HOOKS_HOST = config['vcs.hooks.host']
40 conf.settings.HOOKS_HOST = config['vcs.hooks.host']
42 conf.settings.HOOKS_DIRECT_CALLS = config['vcs.hooks.direct_calls']
41 conf.settings.HOOKS_DIRECT_CALLS = config['vcs.hooks.direct_calls']
43 conf.settings.DEFAULT_ENCODINGS = config['default_encoding']
42 conf.settings.DEFAULT_ENCODINGS = config['default_encoding']
44 conf.settings.ALIASES[:] = config['vcs.backends']
43 conf.settings.ALIASES[:] = config['vcs.backends']
45 conf.settings.SVN_COMPATIBLE_VERSION = config['vcs.svn.compatible_version']
44 conf.settings.SVN_COMPATIBLE_VERSION = config['vcs.svn.compatible_version']
46
45
47
46
48 def initialize_database(config):
47 def initialize_database(config):
49 from rhodecode.lib.utils2 import engine_from_config, get_encryption_key
48 from rhodecode.lib.utils2 import engine_from_config, get_encryption_key
50 engine = engine_from_config(config, 'sqlalchemy.db1.')
49 engine = engine_from_config(config, 'sqlalchemy.db1.')
51 init_model(engine, encryption_key=get_encryption_key(config))
50 init_model(engine, encryption_key=get_encryption_key(config))
52
51
53
52
54 def initialize_test_environment(settings, test_env=None):
53 def initialize_test_environment(settings, test_env=None):
55 if test_env is None:
54 if test_env is None:
56 test_env = not int(os.environ.get('RC_NO_TMP_PATH', 0))
55 test_env = not int(os.environ.get('RC_NO_TMP_PATH', 0))
57
56
58 from rhodecode.lib.utils import (
57 from rhodecode.lib.utils import (
59 create_test_directory, create_test_database, create_test_repositories,
58 create_test_directory, create_test_database, create_test_repositories,
60 create_test_index)
59 create_test_index)
61 from rhodecode.tests import TESTS_TMP_PATH
60 from rhodecode.tests import TESTS_TMP_PATH
62 from rhodecode.lib.vcs.backends.hg import largefiles_store
61 from rhodecode.lib.vcs.backends.hg import largefiles_store
63 from rhodecode.lib.vcs.backends.git import lfs_store
62 from rhodecode.lib.vcs.backends.git import lfs_store
64
63
65 # test repos
64 # test repos
66 if test_env:
65 if test_env:
67 create_test_directory(TESTS_TMP_PATH)
66 create_test_directory(TESTS_TMP_PATH)
68 # large object stores
67 # large object stores
69 create_test_directory(largefiles_store(TESTS_TMP_PATH))
68 create_test_directory(largefiles_store(TESTS_TMP_PATH))
70 create_test_directory(lfs_store(TESTS_TMP_PATH))
69 create_test_directory(lfs_store(TESTS_TMP_PATH))
71
70
72 create_test_database(TESTS_TMP_PATH, settings)
71 create_test_database(TESTS_TMP_PATH, settings)
73 create_test_repositories(TESTS_TMP_PATH, settings)
72 create_test_repositories(TESTS_TMP_PATH, settings)
74 create_test_index(TESTS_TMP_PATH, settings)
73 create_test_index(TESTS_TMP_PATH, settings)
75
74
76
75
77 def get_vcs_server_protocol(config):
76 def get_vcs_server_protocol(config):
78 return config['vcs.server.protocol']
77 return config['vcs.server.protocol']
79
78
80
79
81 def set_instance_id(config):
80 def set_instance_id(config):
82 """
81 """
83 Sets a dynamic generated config['instance_id'] if missing or '*'
82 Sets a dynamic generated config['instance_id'] if missing or '*'
84 E.g instance_id = *cluster-1 or instance_id = *
83 E.g instance_id = *cluster-1 or instance_id = *
85 """
84 """
86
85
87 config['instance_id'] = config.get('instance_id') or ''
86 config['instance_id'] = config.get('instance_id') or ''
88 instance_id = config['instance_id']
87 instance_id = config['instance_id']
89 if instance_id.startswith('*') or not instance_id:
88 if instance_id.startswith('*') or not instance_id:
90 prefix = instance_id.lstrip('*')
89 prefix = instance_id.lstrip('*')
91 _platform_id = platform.uname()[1] or 'instance'
90 _platform_id = platform.uname()[1] or 'instance'
92 config['instance_id'] = '{prefix}uname:{platform}-pid:{pid}'.format(
91 config['instance_id'] = '{prefix}uname:{platform}-pid:{pid}'.format(
93 prefix=prefix,
92 prefix=prefix,
94 platform=_platform_id,
93 platform=_platform_id,
95 pid=os.getpid())
94 pid=os.getpid())
96
95
97
96
98 def get_default_user_id():
97 def get_default_user_id():
99 from rhodecode.model.db import User, Session
98 from rhodecode.model.db import User, Session
100 user_id = Session()\
99 user_id = Session()\
101 .query(User.user_id)\
100 .query(User.user_id)\
102 .filter(User.username == User.DEFAULT_USER)\
101 .filter(User.username == User.DEFAULT_USER)\
103 .scalar()
102 .scalar()
104 return user_id
103 return user_id
General Comments 0
You need to be logged in to leave comments. Login now