##// END OF EJS Templates
exc_store: allow to specify a custom path for exception store.
marcink -
r539:de749a38 default
parent child Browse files
Show More
@@ -26,6 +26,14 b' locale = en_US.UTF-8'
26 ## at installation time, e.g /home/user/vcsserver-1/profile/bin
26 ## at installation time, e.g /home/user/vcsserver-1/profile/bin
27 core.binary_dir = ""
27 core.binary_dir = ""
28
28
29 ## custom exception store path, defaults to TMPDIR
30 exception_store_path =
31
32 ## Default cache dir for caches. Putting this into a ramdisk
33 ## can boost performance, eg. /tmpfs/data_ramdisk, however this directory might require
34 ## large ammount of space
35 cache_dir = %(here)s/rcdev/data
36
29 ## cache region for storing repo_objects cache
37 ## cache region for storing repo_objects cache
30 rc_cache.repo_object.backend = dogpile.cache.rc.memory_lru
38 rc_cache.repo_object.backend = dogpile.cache.rc.memory_lru
31 ## cache auto-expires after N seconds
39 ## cache auto-expires after N seconds
@@ -47,6 +47,14 b' locale = en_US.UTF-8'
47 ## at installation time, e.g /home/user/vcsserver-1/profile/bin
47 ## at installation time, e.g /home/user/vcsserver-1/profile/bin
48 core.binary_dir = ""
48 core.binary_dir = ""
49
49
50 ## custom exception store path, defaults to TMPDIR
51 exception_store_path =
52
53 ## Default cache dir for caches. Putting this into a ramdisk
54 ## can boost performance, eg. /tmpfs/data_ramdisk, however this directory might require
55 ## large ammount of space
56 cache_dir = %(here)s/rcdev/data
57
50 ## cache region for storing repo_objects cache
58 ## cache region for storing repo_objects cache
51 rc_cache.repo_object.backend = dogpile.cache.rc.memory_lru
59 rc_cache.repo_object.backend = dogpile.cache.rc.memory_lru
52 ## cache auto-expires after N seconds
60 ## cache auto-expires after N seconds
@@ -19,3 +19,10 b' import pkgutil'
19
19
20
20
21 __version__ = pkgutil.get_data('vcsserver', 'VERSION').strip()
21 __version__ = pkgutil.get_data('vcsserver', 'VERSION').strip()
22
23 # link to config for pyramid
24 CONFIG = {}
25
26 # Populated with the settings dictionary from application init in
27 #
28 PYRAMID_SETTINGS = {}
@@ -23,6 +23,7 b' import logging'
23 import uuid
23 import uuid
24 import wsgiref.util
24 import wsgiref.util
25 import traceback
25 import traceback
26 import tempfile
26 from itertools import chain
27 from itertools import chain
27
28
28 import simplejson as json
29 import simplejson as json
@@ -45,7 +46,7 b' except locale.Error as e:'
45 'LOCALE ERROR: failed to set LC_ALL, fallback to LC_ALL=C, org error: %s', e)
46 'LOCALE ERROR: failed to set LC_ALL, fallback to LC_ALL=C, org error: %s', e)
46 os.environ['LC_ALL'] = 'C'
47 os.environ['LC_ALL'] = 'C'
47
48
48
49 import vcsserver
49 from vcsserver import remote_wsgi, scm_app, settings, hgpatches
50 from vcsserver import remote_wsgi, scm_app, settings, hgpatches
50 from vcsserver.git_lfs.app import GIT_LFS_CONTENT_TYPE, GIT_LFS_PROTO_PAT
51 from vcsserver.git_lfs.app import GIT_LFS_CONTENT_TYPE, GIT_LFS_PROTO_PAT
51 from vcsserver.echo_stub import remote_wsgi as remote_wsgi_stub
52 from vcsserver.echo_stub import remote_wsgi as remote_wsgi_stub
@@ -73,8 +74,6 b' except ImportError:'
73 SvnRemote = None
74 SvnRemote = None
74
75
75
76
76
77
78 def _is_request_chunked(environ):
77 def _is_request_chunked(environ):
79 stream = environ.get('HTTP_TRANSFER_ENCODING', '') == 'chunked'
78 stream = environ.get('HTTP_TRANSFER_ENCODING', '') == 'chunked'
80 return stream
79 return stream
@@ -82,6 +81,7 b' def _is_request_chunked(environ):'
82
81
83 def _int_setting(settings, name, default):
82 def _int_setting(settings, name, default):
84 settings[name] = int(settings.get(name, default))
83 settings[name] = int(settings.get(name, default))
84 return settings[name]
85
85
86
86
87 def _bool_setting(settings, name, default):
87 def _bool_setting(settings, name, default):
@@ -89,6 +89,7 b' def _bool_setting(settings, name, defaul'
89 if isinstance(input_val, unicode):
89 if isinstance(input_val, unicode):
90 input_val = input_val.encode('utf8')
90 input_val = input_val.encode('utf8')
91 settings[name] = asbool(input_val)
91 settings[name] = asbool(input_val)
92 return settings[name]
92
93
93
94
94 def _list_setting(settings, name, default):
95 def _list_setting(settings, name, default):
@@ -96,13 +97,20 b' def _list_setting(settings, name, defaul'
96
97
97 # Otherwise we assume it uses pyramids space/newline separation.
98 # Otherwise we assume it uses pyramids space/newline separation.
98 settings[name] = aslist(raw_value)
99 settings[name] = aslist(raw_value)
100 return settings[name]
99
101
100
102
101 def _string_setting(settings, name, default, lower=True):
103 def _string_setting(settings, name, default, lower=True, default_when_empty=False):
102 value = settings.get(name, default)
104 value = settings.get(name, default)
105
106 if default_when_empty and not value:
107 # use default value when value is empty
108 value = default
109
103 if lower:
110 if lower:
104 value = value.lower()
111 value = value.lower()
105 settings[name] = value
112 settings[name] = value
113 return settings[name]
106
114
107
115
108 class VCS(object):
116 class VCS(object):
@@ -214,13 +222,17 b' class HTTPApplication(object):'
214 self._use_echo_app = True
222 self._use_echo_app = True
215 log.warning("Using EchoApp for VCS operations.")
223 log.warning("Using EchoApp for VCS operations.")
216 self.remote_wsgi = remote_wsgi_stub
224 self.remote_wsgi = remote_wsgi_stub
217 self._configure_settings(settings)
225
226 self._configure_settings(global_config, settings)
218 self._configure()
227 self._configure()
219
228
220 def _configure_settings(self, app_settings):
229 def _configure_settings(self, global_config, app_settings):
221 """
230 """
222 Configure the settings module.
231 Configure the settings module.
223 """
232 """
233 settings_merged = global_config.copy()
234 settings_merged.update(app_settings)
235
224 git_path = app_settings.get('git_path', None)
236 git_path = app_settings.get('git_path', None)
225 if git_path:
237 if git_path:
226 settings.GIT_EXECUTABLE = git_path
238 settings.GIT_EXECUTABLE = git_path
@@ -228,7 +240,30 b' class HTTPApplication(object):'
228 if binary_dir:
240 if binary_dir:
229 settings.BINARY_DIR = binary_dir
241 settings.BINARY_DIR = binary_dir
230
242
243 # Store the settings to make them available to other modules.
244 vcsserver.PYRAMID_SETTINGS = settings_merged
245 vcsserver.CONFIG = settings_merged
246
231 def _sanitize_settings_and_apply_defaults(self, settings):
247 def _sanitize_settings_and_apply_defaults(self, settings):
248
249 default_cache_dir = os.path.join(tempfile.gettempdir(), 'rc_cache')
250
251 # save default, cache dir, and use it for all backends later.
252 default_cache_dir = _string_setting(
253 settings,
254 'cache_dir',
255 default_cache_dir, lower=False, default_when_empty=True)
256
257 # ensure we have our dir created
258 if not os.path.isdir(default_cache_dir):
259 os.makedirs(default_cache_dir, mode=0755)
260
261 # exception store cache
262 _string_setting(
263 settings,
264 'exception_store_path',
265 default_cache_dir, lower=False)
266
232 # repo_object cache
267 # repo_object cache
233 _string_setting(
268 _string_setting(
234 settings,
269 settings,
@@ -31,6 +31,7 b' log = logging.getLogger(__name__)'
31
31
32 # NOTE: Any changes should be synced with exc_tracking at rhodecode.lib.exc_tracking
32 # NOTE: Any changes should be synced with exc_tracking at rhodecode.lib.exc_tracking
33 global_prefix = 'vcsserver'
33 global_prefix = 'vcsserver'
34 exc_store_dir_name = 'rc_exception_store_v1'
34
35
35
36
36 def exc_serialize(exc_id, tb, exc_type):
37 def exc_serialize(exc_id, tb, exc_type):
@@ -54,13 +55,10 b' def get_exc_store():'
54 """
55 """
55 Get and create exception store if it's not existing
56 Get and create exception store if it's not existing
56 """
57 """
57 exc_store_dir = 'rc_exception_store_v1'
58 import vcsserver as app
58 # fallback
59 _exc_store_path = os.path.join(tempfile.gettempdir(), exc_store_dir)
60
59
61 exc_store_dir = '' # TODO: need a persistent cross instance store here
60 exc_store_dir = app.CONFIG.get('exception_store_path', '') or tempfile.gettempdir()
62 if exc_store_dir:
61 _exc_store_path = os.path.join(exc_store_dir, exc_store_dir_name)
63 _exc_store_path = os.path.join(exc_store_dir, exc_store_dir)
64
62
65 _exc_store_path = os.path.abspath(_exc_store_path)
63 _exc_store_path = os.path.abspath(_exc_store_path)
66 if not os.path.isdir(_exc_store_path):
64 if not os.path.isdir(_exc_store_path):
@@ -87,6 +85,13 b' def _store_exception(exc_id, exc_info, p'
87
85
88
86
89 def store_exception(exc_id, exc_info, prefix=global_prefix):
87 def store_exception(exc_id, exc_info, prefix=global_prefix):
88 """
89 Example usage::
90
91 exc_info = sys.exc_info()
92 store_exception(id(exc_info), exc_info)
93 """
94
90 try:
95 try:
91 _store_exception(exc_id=exc_id, exc_info=exc_info, prefix=prefix)
96 _store_exception(exc_id=exc_id, exc_info=exc_info, prefix=prefix)
92 except Exception:
97 except Exception:
@@ -25,7 +25,7 b' from vcsserver.base import obfuscate_qs'
25 @mock.patch('vcsserver.http_main.VCS', mock.Mock())
25 @mock.patch('vcsserver.http_main.VCS', mock.Mock())
26 @mock.patch('vcsserver.hgpatches.patch_largefiles_capabilities')
26 @mock.patch('vcsserver.hgpatches.patch_largefiles_capabilities')
27 def test_applies_largefiles_patch(patch_largefiles_capabilities):
27 def test_applies_largefiles_patch(patch_largefiles_capabilities):
28 http_main.main([])
28 http_main.main({})
29 patch_largefiles_capabilities.assert_called_once_with()
29 patch_largefiles_capabilities.assert_called_once_with()
30
30
31
31
@@ -35,7 +35,7 b' def test_applies_largefiles_patch(patch_'
35 'vcsserver.hgpatches.patch_largefiles_capabilities',
35 'vcsserver.hgpatches.patch_largefiles_capabilities',
36 mock.Mock(side_effect=Exception("Must not be called")))
36 mock.Mock(side_effect=Exception("Must not be called")))
37 def test_applies_largefiles_patch_only_if_mercurial_is_available():
37 def test_applies_largefiles_patch_only_if_mercurial_is_available():
38 http_main.main([])
38 http_main.main({})
39
39
40
40
41 @pytest.mark.parametrize('given, expected', [
41 @pytest.mark.parametrize('given, expected', [
General Comments 0
You need to be logged in to leave comments. Login now