##// END OF EJS Templates
tests: avoid collision with dev servers - use port 4999 for testing
Mads Kiilerich -
r5388:5f932134 default
parent child Browse files
Show More
@@ -1,536 +1,536 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 # This program is free software: you can redistribute it and/or modify
2 # This program is free software: you can redistribute it and/or modify
3 # it under the terms of the GNU General Public License as published by
3 # it under the terms of the GNU General Public License as published by
4 # the Free Software Foundation, either version 3 of the License, or
4 # the Free Software Foundation, either version 3 of the License, or
5 # (at your option) any later version.
5 # (at your option) any later version.
6 #
6 #
7 # This program is distributed in the hope that it will be useful,
7 # This program is distributed in the hope that it will be useful,
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # GNU General Public License for more details.
10 # GNU General Public License for more details.
11 #
11 #
12 # You should have received a copy of the GNU General Public License
12 # You should have received a copy of the GNU General Public License
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 """
14 """
15 kallithea.tests.other.manual_test_vcs_operations
15 kallithea.tests.other.manual_test_vcs_operations
16 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
16 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17
17
18 Test suite for making push/pull operations.
18 Test suite for making push/pull operations.
19
19
20 Run it in two terminals::
20 Run it in two terminals::
21 paster serve test.ini
21 paster serve test.ini
22 KALLITHEA_WHOOSH_TEST_DISABLE=1 KALLITHEA_NO_TMP_PATH=1 nosetests kallithea/tests/other/manual_test_vcs_operations.py
22 KALLITHEA_WHOOSH_TEST_DISABLE=1 KALLITHEA_NO_TMP_PATH=1 nosetests kallithea/tests/other/manual_test_vcs_operations.py
23
23
24 You must have git > 1.8.1 for tests to work fine
24 You must have git > 1.8.1 for tests to work fine
25
25
26 This file was forked by the Kallithea project in July 2014.
26 This file was forked by the Kallithea project in July 2014.
27 Original author and date, and relevant copyright and licensing information is below:
27 Original author and date, and relevant copyright and licensing information is below:
28 :created_on: Dec 30, 2010
28 :created_on: Dec 30, 2010
29 :author: marcink
29 :author: marcink
30 :copyright: (c) 2013 RhodeCode GmbH, and others.
30 :copyright: (c) 2013 RhodeCode GmbH, and others.
31 :license: GPLv3, see LICENSE.md for more details.
31 :license: GPLv3, see LICENSE.md for more details.
32
32
33 """
33 """
34
34
35 import tempfile
35 import tempfile
36 import time
36 import time
37 from os.path import join as jn
37 from os.path import join as jn
38
38
39 from tempfile import _RandomNameSequence
39 from tempfile import _RandomNameSequence
40 from subprocess import Popen, PIPE
40 from subprocess import Popen, PIPE
41
41
42 from kallithea.tests import *
42 from kallithea.tests import *
43 from kallithea.model.db import User, Repository, UserIpMap, CacheInvalidation
43 from kallithea.model.db import User, Repository, UserIpMap, CacheInvalidation
44 from kallithea.model.meta import Session
44 from kallithea.model.meta import Session
45 from kallithea.model.repo import RepoModel
45 from kallithea.model.repo import RepoModel
46 from kallithea.model.user import UserModel
46 from kallithea.model.user import UserModel
47
47
48 DEBUG = True
48 DEBUG = True
49 HOST = '127.0.0.1:5000' # test host
49 HOST = '127.0.0.1:4999' # test host
50
50
51
51
52 class Command(object):
52 class Command(object):
53
53
54 def __init__(self, cwd):
54 def __init__(self, cwd):
55 self.cwd = cwd
55 self.cwd = cwd
56
56
57 def execute(self, cmd, *args):
57 def execute(self, cmd, *args):
58 """
58 """
59 Runs command on the system with given ``args``.
59 Runs command on the system with given ``args``.
60 """
60 """
61
61
62 command = cmd + ' ' + ' '.join(args)
62 command = cmd + ' ' + ' '.join(args)
63 if DEBUG:
63 if DEBUG:
64 print '*** CMD %s ***' % command
64 print '*** CMD %s ***' % command
65 p = Popen(command, shell=True, stdout=PIPE, stderr=PIPE, cwd=self.cwd)
65 p = Popen(command, shell=True, stdout=PIPE, stderr=PIPE, cwd=self.cwd)
66 stdout, stderr = p.communicate()
66 stdout, stderr = p.communicate()
67 if DEBUG:
67 if DEBUG:
68 print 'stdout:', repr(stdout)
68 print 'stdout:', repr(stdout)
69 print 'stderr:', repr(stderr)
69 print 'stderr:', repr(stderr)
70 return stdout, stderr
70 return stdout, stderr
71
71
72
72
73 def _get_tmp_dir():
73 def _get_tmp_dir():
74 return tempfile.mkdtemp(prefix='rc_integration_test')
74 return tempfile.mkdtemp(prefix='rc_integration_test')
75
75
76
76
77 def _construct_url(repo, dest=None, **kwargs):
77 def _construct_url(repo, dest=None, **kwargs):
78 if dest is None:
78 if dest is None:
79 #make temp clone
79 #make temp clone
80 dest = _get_tmp_dir()
80 dest = _get_tmp_dir()
81 params = {
81 params = {
82 'user': TEST_USER_ADMIN_LOGIN,
82 'user': TEST_USER_ADMIN_LOGIN,
83 'passwd': TEST_USER_ADMIN_PASS,
83 'passwd': TEST_USER_ADMIN_PASS,
84 'host': HOST,
84 'host': HOST,
85 'cloned_repo': repo,
85 'cloned_repo': repo,
86 'dest': dest
86 'dest': dest
87 }
87 }
88 params.update(**kwargs)
88 params.update(**kwargs)
89 if params['user'] and params['passwd']:
89 if params['user'] and params['passwd']:
90 _url = 'http://%(user)s:%(passwd)s@%(host)s/%(cloned_repo)s %(dest)s' % params
90 _url = 'http://%(user)s:%(passwd)s@%(host)s/%(cloned_repo)s %(dest)s' % params
91 else:
91 else:
92 _url = 'http://(host)s/%(cloned_repo)s %(dest)s' % params
92 _url = 'http://(host)s/%(cloned_repo)s %(dest)s' % params
93 return _url
93 return _url
94
94
95
95
96 def _add_files_and_push(vcs, DEST, **kwargs):
96 def _add_files_and_push(vcs, DEST, **kwargs):
97 """
97 """
98 Generate some files, add it to DEST repo and push back
98 Generate some files, add it to DEST repo and push back
99 vcs is git or hg and defines what VCS we want to make those files for
99 vcs is git or hg and defines what VCS we want to make those files for
100
100
101 :param vcs:
101 :param vcs:
102 :param DEST:
102 :param DEST:
103 """
103 """
104 # commit some stuff into this repo
104 # commit some stuff into this repo
105 cwd = path = jn(DEST)
105 cwd = path = jn(DEST)
106 #added_file = jn(path, '%ssetupΔ…ΕΌΕΊΔ‡.py' % _RandomNameSequence().next())
106 #added_file = jn(path, '%ssetupΔ…ΕΌΕΊΔ‡.py' % _RandomNameSequence().next())
107 added_file = jn(path, '%ssetup.py' % _RandomNameSequence().next())
107 added_file = jn(path, '%ssetup.py' % _RandomNameSequence().next())
108 Command(cwd).execute('touch %s' % added_file)
108 Command(cwd).execute('touch %s' % added_file)
109 Command(cwd).execute('%s add %s' % (vcs, added_file))
109 Command(cwd).execute('%s add %s' % (vcs, added_file))
110
110
111 for i in xrange(kwargs.get('files_no', 3)):
111 for i in xrange(kwargs.get('files_no', 3)):
112 cmd = """echo 'added_line%s' >> %s""" % (i, added_file)
112 cmd = """echo 'added_line%s' >> %s""" % (i, added_file)
113 Command(cwd).execute(cmd)
113 Command(cwd).execute(cmd)
114 author_str = 'User ǝɯɐᴎ <me@email.com>'
114 author_str = 'User ǝɯɐᴎ <me@email.com>'
115 if vcs == 'hg':
115 if vcs == 'hg':
116 cmd = """hg commit -m 'commited new %s' -u '%s' %s """ % (
116 cmd = """hg commit -m 'commited new %s' -u '%s' %s """ % (
117 i, author_str, added_file
117 i, author_str, added_file
118 )
118 )
119 elif vcs == 'git':
119 elif vcs == 'git':
120 cmd = """EMAIL="me@email.com" git commit -m 'commited new %s' --author '%s' %s """ % (
120 cmd = """EMAIL="me@email.com" git commit -m 'commited new %s' --author '%s' %s """ % (
121 i, author_str, added_file
121 i, author_str, added_file
122 )
122 )
123 Command(cwd).execute(cmd)
123 Command(cwd).execute(cmd)
124
124
125 # PUSH it back
125 # PUSH it back
126 _REPO = None
126 _REPO = None
127 if vcs == 'hg':
127 if vcs == 'hg':
128 _REPO = HG_REPO
128 _REPO = HG_REPO
129 elif vcs == 'git':
129 elif vcs == 'git':
130 _REPO = GIT_REPO
130 _REPO = GIT_REPO
131
131
132 kwargs['dest'] = ''
132 kwargs['dest'] = ''
133 clone_url = _construct_url(_REPO, **kwargs)
133 clone_url = _construct_url(_REPO, **kwargs)
134 if 'clone_url' in kwargs:
134 if 'clone_url' in kwargs:
135 clone_url = kwargs['clone_url']
135 clone_url = kwargs['clone_url']
136 stdout = stderr = None
136 stdout = stderr = None
137 if vcs == 'hg':
137 if vcs == 'hg':
138 stdout, stderr = Command(cwd).execute('hg push --verbose', clone_url)
138 stdout, stderr = Command(cwd).execute('hg push --verbose', clone_url)
139 elif vcs == 'git':
139 elif vcs == 'git':
140 stdout, stderr = Command(cwd).execute('git push --verbose', clone_url + " master")
140 stdout, stderr = Command(cwd).execute('git push --verbose', clone_url + " master")
141
141
142 return stdout, stderr
142 return stdout, stderr
143
143
144
144
145 def set_anonymous_access(enable=True):
145 def set_anonymous_access(enable=True):
146 user = User.get_by_username(User.DEFAULT_USER)
146 user = User.get_by_username(User.DEFAULT_USER)
147 user.active = enable
147 user.active = enable
148 Session().add(user)
148 Session().add(user)
149 Session().commit()
149 Session().commit()
150 print '\tanonymous access is now:', enable
150 print '\tanonymous access is now:', enable
151 if enable != User.get_by_username(User.DEFAULT_USER).active:
151 if enable != User.get_by_username(User.DEFAULT_USER).active:
152 raise Exception('Cannot set anonymous access')
152 raise Exception('Cannot set anonymous access')
153
153
154
154
155 #==============================================================================
155 #==============================================================================
156 # TESTS
156 # TESTS
157 #==============================================================================
157 #==============================================================================
158
158
159
159
160 def _check_proper_git_push(stdout, stderr):
160 def _check_proper_git_push(stdout, stderr):
161 #WTF Git stderr is output ?!
161 #WTF Git stderr is output ?!
162 assert 'fatal' not in stderr
162 assert 'fatal' not in stderr
163 assert 'rejected' not in stderr
163 assert 'rejected' not in stderr
164 assert 'Pushing to' in stderr
164 assert 'Pushing to' in stderr
165 assert 'master -> master' in stderr
165 assert 'master -> master' in stderr
166
166
167
167
168 class TestVCSOperations(BaseTestCase):
168 class TestVCSOperations(BaseTestCase):
169
169
170 @classmethod
170 @classmethod
171 def setup_class(cls):
171 def setup_class(cls):
172 #DISABLE ANONYMOUS ACCESS
172 #DISABLE ANONYMOUS ACCESS
173 set_anonymous_access(False)
173 set_anonymous_access(False)
174
174
175 def setUp(self):
175 def setUp(self):
176 r = Repository.get_by_repo_name(GIT_REPO)
176 r = Repository.get_by_repo_name(GIT_REPO)
177 Repository.unlock(r)
177 Repository.unlock(r)
178 r.enable_locking = False
178 r.enable_locking = False
179 Session().add(r)
179 Session().add(r)
180 Session().commit()
180 Session().commit()
181
181
182 r = Repository.get_by_repo_name(HG_REPO)
182 r = Repository.get_by_repo_name(HG_REPO)
183 Repository.unlock(r)
183 Repository.unlock(r)
184 r.enable_locking = False
184 r.enable_locking = False
185 Session().add(r)
185 Session().add(r)
186 Session().commit()
186 Session().commit()
187
187
188 def test_clone_hg_repo_by_admin(self):
188 def test_clone_hg_repo_by_admin(self):
189 clone_url = _construct_url(HG_REPO)
189 clone_url = _construct_url(HG_REPO)
190 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
190 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
191
191
192 assert 'requesting all changes' in stdout
192 assert 'requesting all changes' in stdout
193 assert 'adding changesets' in stdout
193 assert 'adding changesets' in stdout
194 assert 'adding manifests' in stdout
194 assert 'adding manifests' in stdout
195 assert 'adding file changes' in stdout
195 assert 'adding file changes' in stdout
196
196
197 assert stderr == ''
197 assert stderr == ''
198
198
199 def test_clone_git_repo_by_admin(self):
199 def test_clone_git_repo_by_admin(self):
200 clone_url = _construct_url(GIT_REPO)
200 clone_url = _construct_url(GIT_REPO)
201 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
201 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
202
202
203 assert 'Cloning into' in stdout + stderr
203 assert 'Cloning into' in stdout + stderr
204 assert stderr == '' or stdout == ''
204 assert stderr == '' or stdout == ''
205
205
206 def test_clone_wrong_credentials_hg(self):
206 def test_clone_wrong_credentials_hg(self):
207 clone_url = _construct_url(HG_REPO, passwd='bad!')
207 clone_url = _construct_url(HG_REPO, passwd='bad!')
208 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
208 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
209 assert 'abort: authorization failed' in stderr
209 assert 'abort: authorization failed' in stderr
210
210
211 def test_clone_wrong_credentials_git(self):
211 def test_clone_wrong_credentials_git(self):
212 clone_url = _construct_url(GIT_REPO, passwd='bad!')
212 clone_url = _construct_url(GIT_REPO, passwd='bad!')
213 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
213 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
214 assert 'fatal: Authentication failed' in stderr
214 assert 'fatal: Authentication failed' in stderr
215
215
216 def test_clone_git_dir_as_hg(self):
216 def test_clone_git_dir_as_hg(self):
217 clone_url = _construct_url(GIT_REPO)
217 clone_url = _construct_url(GIT_REPO)
218 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
218 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
219 assert 'HTTP Error 404: Not Found' in stderr
219 assert 'HTTP Error 404: Not Found' in stderr
220
220
221 def test_clone_hg_repo_as_git(self):
221 def test_clone_hg_repo_as_git(self):
222 clone_url = _construct_url(HG_REPO)
222 clone_url = _construct_url(HG_REPO)
223 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
223 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
224 assert 'not found' in stderr
224 assert 'not found' in stderr
225
225
226 def test_clone_non_existing_path_hg(self):
226 def test_clone_non_existing_path_hg(self):
227 clone_url = _construct_url('trololo')
227 clone_url = _construct_url('trololo')
228 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
228 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
229 assert 'HTTP Error 404: Not Found' in stderr
229 assert 'HTTP Error 404: Not Found' in stderr
230
230
231 def test_clone_non_existing_path_git(self):
231 def test_clone_non_existing_path_git(self):
232 clone_url = _construct_url('trololo')
232 clone_url = _construct_url('trololo')
233 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
233 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
234 assert 'not found' in stderr
234 assert 'not found' in stderr
235
235
236 def test_push_new_file_hg(self):
236 def test_push_new_file_hg(self):
237 DEST = _get_tmp_dir()
237 DEST = _get_tmp_dir()
238 clone_url = _construct_url(HG_REPO, dest=DEST)
238 clone_url = _construct_url(HG_REPO, dest=DEST)
239 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
239 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
240
240
241 stdout, stderr = _add_files_and_push('hg', DEST)
241 stdout, stderr = _add_files_and_push('hg', DEST)
242
242
243 assert 'pushing to' in stdout
243 assert 'pushing to' in stdout
244 assert 'Repository size' in stdout
244 assert 'Repository size' in stdout
245 assert 'Last revision is now' in stdout
245 assert 'Last revision is now' in stdout
246
246
247 def test_push_new_file_git(self):
247 def test_push_new_file_git(self):
248 DEST = _get_tmp_dir()
248 DEST = _get_tmp_dir()
249 clone_url = _construct_url(GIT_REPO, dest=DEST)
249 clone_url = _construct_url(GIT_REPO, dest=DEST)
250 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
250 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
251
251
252 # commit some stuff into this repo
252 # commit some stuff into this repo
253 stdout, stderr = _add_files_and_push('git', DEST)
253 stdout, stderr = _add_files_and_push('git', DEST)
254
254
255 print [(x.repo_full_path,x.repo_path) for x in Repository.get_all()]
255 print [(x.repo_full_path,x.repo_path) for x in Repository.get_all()]
256 _check_proper_git_push(stdout, stderr)
256 _check_proper_git_push(stdout, stderr)
257
257
258 def test_push_invalidates_cache_hg(self):
258 def test_push_invalidates_cache_hg(self):
259 key = CacheInvalidation.query().filter(CacheInvalidation.cache_key
259 key = CacheInvalidation.query().filter(CacheInvalidation.cache_key
260 ==HG_REPO).scalar()
260 ==HG_REPO).scalar()
261 if not key:
261 if not key:
262 key = CacheInvalidation(HG_REPO, HG_REPO)
262 key = CacheInvalidation(HG_REPO, HG_REPO)
263
263
264 key.cache_active = True
264 key.cache_active = True
265 Session().add(key)
265 Session().add(key)
266 Session().commit()
266 Session().commit()
267
267
268 DEST = _get_tmp_dir()
268 DEST = _get_tmp_dir()
269 clone_url = _construct_url(HG_REPO, dest=DEST)
269 clone_url = _construct_url(HG_REPO, dest=DEST)
270 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
270 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
271
271
272 stdout, stderr = _add_files_and_push('hg', DEST, files_no=1)
272 stdout, stderr = _add_files_and_push('hg', DEST, files_no=1)
273
273
274 key = CacheInvalidation.query().filter(CacheInvalidation.cache_key
274 key = CacheInvalidation.query().filter(CacheInvalidation.cache_key
275 ==HG_REPO).one()
275 ==HG_REPO).one()
276 self.assertEqual(key.cache_active, False)
276 self.assertEqual(key.cache_active, False)
277
277
278 def test_push_invalidates_cache_git(self):
278 def test_push_invalidates_cache_git(self):
279 key = CacheInvalidation.query().filter(CacheInvalidation.cache_key
279 key = CacheInvalidation.query().filter(CacheInvalidation.cache_key
280 ==GIT_REPO).scalar()
280 ==GIT_REPO).scalar()
281 if not key:
281 if not key:
282 key = CacheInvalidation(GIT_REPO, GIT_REPO)
282 key = CacheInvalidation(GIT_REPO, GIT_REPO)
283
283
284 key.cache_active = True
284 key.cache_active = True
285 Session().add(key)
285 Session().add(key)
286 Session().commit()
286 Session().commit()
287
287
288 DEST = _get_tmp_dir()
288 DEST = _get_tmp_dir()
289 clone_url = _construct_url(GIT_REPO, dest=DEST)
289 clone_url = _construct_url(GIT_REPO, dest=DEST)
290 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
290 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
291
291
292 # commit some stuff into this repo
292 # commit some stuff into this repo
293 stdout, stderr = _add_files_and_push('git', DEST, files_no=1)
293 stdout, stderr = _add_files_and_push('git', DEST, files_no=1)
294 _check_proper_git_push(stdout, stderr)
294 _check_proper_git_push(stdout, stderr)
295
295
296 key = CacheInvalidation.query().filter(CacheInvalidation.cache_key
296 key = CacheInvalidation.query().filter(CacheInvalidation.cache_key
297 ==GIT_REPO).one()
297 ==GIT_REPO).one()
298 print CacheInvalidation.get_all()
298 print CacheInvalidation.get_all()
299 self.assertEqual(key.cache_active, False)
299 self.assertEqual(key.cache_active, False)
300
300
301 def test_push_wrong_credentials_hg(self):
301 def test_push_wrong_credentials_hg(self):
302 DEST = _get_tmp_dir()
302 DEST = _get_tmp_dir()
303 clone_url = _construct_url(HG_REPO, dest=DEST)
303 clone_url = _construct_url(HG_REPO, dest=DEST)
304 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
304 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
305
305
306 stdout, stderr = _add_files_and_push('hg', DEST, user='bad',
306 stdout, stderr = _add_files_and_push('hg', DEST, user='bad',
307 passwd='name')
307 passwd='name')
308
308
309 assert 'abort: authorization failed' in stderr
309 assert 'abort: authorization failed' in stderr
310
310
311 def test_push_wrong_credentials_git(self):
311 def test_push_wrong_credentials_git(self):
312 DEST = _get_tmp_dir()
312 DEST = _get_tmp_dir()
313 clone_url = _construct_url(GIT_REPO, dest=DEST)
313 clone_url = _construct_url(GIT_REPO, dest=DEST)
314 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
314 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
315
315
316 stdout, stderr = _add_files_and_push('git', DEST, user='bad',
316 stdout, stderr = _add_files_and_push('git', DEST, user='bad',
317 passwd='name')
317 passwd='name')
318
318
319 assert 'fatal: Authentication failed' in stderr
319 assert 'fatal: Authentication failed' in stderr
320
320
321 def test_push_back_to_wrong_url_hg(self):
321 def test_push_back_to_wrong_url_hg(self):
322 DEST = _get_tmp_dir()
322 DEST = _get_tmp_dir()
323 clone_url = _construct_url(HG_REPO, dest=DEST)
323 clone_url = _construct_url(HG_REPO, dest=DEST)
324 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
324 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
325
325
326 stdout, stderr = _add_files_and_push('hg', DEST,
326 stdout, stderr = _add_files_and_push('hg', DEST,
327 clone_url='http://127.0.0.1:5000/tmp',)
327 clone_url='http://%s/tmp' % HOST)
328
328
329 assert 'HTTP Error 404: Not Found' in stderr
329 assert 'HTTP Error 404: Not Found' in stderr
330
330
331 def test_push_back_to_wrong_url_git(self):
331 def test_push_back_to_wrong_url_git(self):
332 DEST = _get_tmp_dir()
332 DEST = _get_tmp_dir()
333 clone_url = _construct_url(GIT_REPO, dest=DEST)
333 clone_url = _construct_url(GIT_REPO, dest=DEST)
334 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
334 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
335
335
336 stdout, stderr = _add_files_and_push('git', DEST,
336 stdout, stderr = _add_files_and_push('git', DEST,
337 clone_url='http://127.0.0.1:5000/tmp',)
337 clone_url='http://%s/tmp' % HOST)
338
338
339 assert 'not found' in stderr
339 assert 'not found' in stderr
340
340
341 def test_clone_and_create_lock_hg(self):
341 def test_clone_and_create_lock_hg(self):
342 # enable locking
342 # enable locking
343 r = Repository.get_by_repo_name(HG_REPO)
343 r = Repository.get_by_repo_name(HG_REPO)
344 r.enable_locking = True
344 r.enable_locking = True
345 Session().add(r)
345 Session().add(r)
346 Session().commit()
346 Session().commit()
347 # clone
347 # clone
348 clone_url = _construct_url(HG_REPO)
348 clone_url = _construct_url(HG_REPO)
349 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
349 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
350
350
351 #check if lock was made
351 #check if lock was made
352 r = Repository.get_by_repo_name(HG_REPO)
352 r = Repository.get_by_repo_name(HG_REPO)
353 assert r.locked[0] == User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id
353 assert r.locked[0] == User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id
354
354
355 def test_clone_and_create_lock_git(self):
355 def test_clone_and_create_lock_git(self):
356 # enable locking
356 # enable locking
357 r = Repository.get_by_repo_name(GIT_REPO)
357 r = Repository.get_by_repo_name(GIT_REPO)
358 r.enable_locking = True
358 r.enable_locking = True
359 Session().add(r)
359 Session().add(r)
360 Session().commit()
360 Session().commit()
361 # clone
361 # clone
362 clone_url = _construct_url(GIT_REPO)
362 clone_url = _construct_url(GIT_REPO)
363 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
363 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
364
364
365 #check if lock was made
365 #check if lock was made
366 r = Repository.get_by_repo_name(GIT_REPO)
366 r = Repository.get_by_repo_name(GIT_REPO)
367 assert r.locked[0] == User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id
367 assert r.locked[0] == User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id
368
368
369 def test_clone_after_repo_was_locked_hg(self):
369 def test_clone_after_repo_was_locked_hg(self):
370 #lock repo
370 #lock repo
371 r = Repository.get_by_repo_name(HG_REPO)
371 r = Repository.get_by_repo_name(HG_REPO)
372 Repository.lock(r, User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id)
372 Repository.lock(r, User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id)
373 #pull fails since repo is locked
373 #pull fails since repo is locked
374 clone_url = _construct_url(HG_REPO)
374 clone_url = _construct_url(HG_REPO)
375 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
375 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
376 msg = ("""abort: HTTP Error 423: Repository `%s` locked by user `%s`"""
376 msg = ("""abort: HTTP Error 423: Repository `%s` locked by user `%s`"""
377 % (HG_REPO, TEST_USER_ADMIN_LOGIN))
377 % (HG_REPO, TEST_USER_ADMIN_LOGIN))
378 assert msg in stderr
378 assert msg in stderr
379
379
380 def test_clone_after_repo_was_locked_git(self):
380 def test_clone_after_repo_was_locked_git(self):
381 #lock repo
381 #lock repo
382 r = Repository.get_by_repo_name(GIT_REPO)
382 r = Repository.get_by_repo_name(GIT_REPO)
383 Repository.lock(r, User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id)
383 Repository.lock(r, User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id)
384 #pull fails since repo is locked
384 #pull fails since repo is locked
385 clone_url = _construct_url(GIT_REPO)
385 clone_url = _construct_url(GIT_REPO)
386 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
386 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
387 msg = ("""The requested URL returned error: 423""")
387 msg = ("""The requested URL returned error: 423""")
388 assert msg in stderr
388 assert msg in stderr
389
389
390 def test_push_on_locked_repo_by_other_user_hg(self):
390 def test_push_on_locked_repo_by_other_user_hg(self):
391 #clone some temp
391 #clone some temp
392 DEST = _get_tmp_dir()
392 DEST = _get_tmp_dir()
393 clone_url = _construct_url(HG_REPO, dest=DEST)
393 clone_url = _construct_url(HG_REPO, dest=DEST)
394 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
394 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
395
395
396 #lock repo
396 #lock repo
397 r = Repository.get_by_repo_name(HG_REPO)
397 r = Repository.get_by_repo_name(HG_REPO)
398 # let this user actually push !
398 # let this user actually push !
399 RepoModel().grant_user_permission(repo=r, user=TEST_USER_REGULAR_LOGIN,
399 RepoModel().grant_user_permission(repo=r, user=TEST_USER_REGULAR_LOGIN,
400 perm='repository.write')
400 perm='repository.write')
401 Session().commit()
401 Session().commit()
402 Repository.lock(r, User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id)
402 Repository.lock(r, User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id)
403
403
404 #push fails repo is locked by other user !
404 #push fails repo is locked by other user !
405 stdout, stderr = _add_files_and_push('hg', DEST,
405 stdout, stderr = _add_files_and_push('hg', DEST,
406 user=TEST_USER_REGULAR_LOGIN,
406 user=TEST_USER_REGULAR_LOGIN,
407 passwd=TEST_USER_REGULAR_PASS)
407 passwd=TEST_USER_REGULAR_PASS)
408 msg = ("""abort: HTTP Error 423: Repository `%s` locked by user `%s`"""
408 msg = ("""abort: HTTP Error 423: Repository `%s` locked by user `%s`"""
409 % (HG_REPO, TEST_USER_ADMIN_LOGIN))
409 % (HG_REPO, TEST_USER_ADMIN_LOGIN))
410 assert msg in stderr
410 assert msg in stderr
411
411
412 def test_push_on_locked_repo_by_other_user_git(self):
412 def test_push_on_locked_repo_by_other_user_git(self):
413 #clone some temp
413 #clone some temp
414 DEST = _get_tmp_dir()
414 DEST = _get_tmp_dir()
415 clone_url = _construct_url(GIT_REPO, dest=DEST)
415 clone_url = _construct_url(GIT_REPO, dest=DEST)
416 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
416 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
417
417
418 #lock repo
418 #lock repo
419 r = Repository.get_by_repo_name(GIT_REPO)
419 r = Repository.get_by_repo_name(GIT_REPO)
420 # let this user actually push !
420 # let this user actually push !
421 RepoModel().grant_user_permission(repo=r, user=TEST_USER_REGULAR_LOGIN,
421 RepoModel().grant_user_permission(repo=r, user=TEST_USER_REGULAR_LOGIN,
422 perm='repository.write')
422 perm='repository.write')
423 Session().commit()
423 Session().commit()
424 Repository.lock(r, User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id)
424 Repository.lock(r, User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id)
425
425
426 #push fails repo is locked by other user !
426 #push fails repo is locked by other user !
427 stdout, stderr = _add_files_and_push('git', DEST,
427 stdout, stderr = _add_files_and_push('git', DEST,
428 user=TEST_USER_REGULAR_LOGIN,
428 user=TEST_USER_REGULAR_LOGIN,
429 passwd=TEST_USER_REGULAR_PASS)
429 passwd=TEST_USER_REGULAR_PASS)
430 err = 'Repository `%s` locked by user `%s`' % (GIT_REPO, TEST_USER_ADMIN_LOGIN)
430 err = 'Repository `%s` locked by user `%s`' % (GIT_REPO, TEST_USER_ADMIN_LOGIN)
431 assert err in stderr
431 assert err in stderr
432
432
433 #TODO: fix this somehow later on Git, Git is stupid and even if we throw
433 #TODO: fix this somehow later on Git, Git is stupid and even if we throw
434 #back 423 to it, it makes ANOTHER request and we fail there with 405 :/
434 #back 423 to it, it makes ANOTHER request and we fail there with 405 :/
435
435
436 msg = ("""abort: HTTP Error 423: Repository `%s` locked by user `%s`"""
436 msg = ("""abort: HTTP Error 423: Repository `%s` locked by user `%s`"""
437 % (GIT_REPO, TEST_USER_ADMIN_LOGIN))
437 % (GIT_REPO, TEST_USER_ADMIN_LOGIN))
438 #msg = "405 Method Not Allowed"
438 #msg = "405 Method Not Allowed"
439 #assert msg in stderr
439 #assert msg in stderr
440
440
441 def test_push_unlocks_repository_hg(self):
441 def test_push_unlocks_repository_hg(self):
442 # enable locking
442 # enable locking
443 r = Repository.get_by_repo_name(HG_REPO)
443 r = Repository.get_by_repo_name(HG_REPO)
444 r.enable_locking = True
444 r.enable_locking = True
445 Session().add(r)
445 Session().add(r)
446 Session().commit()
446 Session().commit()
447 #clone some temp
447 #clone some temp
448 DEST = _get_tmp_dir()
448 DEST = _get_tmp_dir()
449 clone_url = _construct_url(HG_REPO, dest=DEST)
449 clone_url = _construct_url(HG_REPO, dest=DEST)
450 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
450 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
451
451
452 #check for lock repo after clone
452 #check for lock repo after clone
453 r = Repository.get_by_repo_name(HG_REPO)
453 r = Repository.get_by_repo_name(HG_REPO)
454 uid = User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id
454 uid = User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id
455 assert r.locked[0] == uid
455 assert r.locked[0] == uid
456
456
457 #push is ok and repo is now unlocked
457 #push is ok and repo is now unlocked
458 stdout, stderr = _add_files_and_push('hg', DEST)
458 stdout, stderr = _add_files_and_push('hg', DEST)
459 assert ('remote: Released lock on repo `%s`' % HG_REPO) in stdout
459 assert ('remote: Released lock on repo `%s`' % HG_REPO) in stdout
460 #we need to cleanup the Session Here !
460 #we need to cleanup the Session Here !
461 Session.remove()
461 Session.remove()
462 r = Repository.get_by_repo_name(HG_REPO)
462 r = Repository.get_by_repo_name(HG_REPO)
463 assert r.locked == [None, None]
463 assert r.locked == [None, None]
464
464
465 #TODO: fix me ! somehow during tests hooks don't get called on Git
465 #TODO: fix me ! somehow during tests hooks don't get called on Git
466 def test_push_unlocks_repository_git(self):
466 def test_push_unlocks_repository_git(self):
467 # enable locking
467 # enable locking
468 r = Repository.get_by_repo_name(GIT_REPO)
468 r = Repository.get_by_repo_name(GIT_REPO)
469 r.enable_locking = True
469 r.enable_locking = True
470 Session().add(r)
470 Session().add(r)
471 Session().commit()
471 Session().commit()
472 #clone some temp
472 #clone some temp
473 DEST = _get_tmp_dir()
473 DEST = _get_tmp_dir()
474 clone_url = _construct_url(GIT_REPO, dest=DEST)
474 clone_url = _construct_url(GIT_REPO, dest=DEST)
475 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
475 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
476
476
477 #check for lock repo after clone
477 #check for lock repo after clone
478 r = Repository.get_by_repo_name(GIT_REPO)
478 r = Repository.get_by_repo_name(GIT_REPO)
479 assert r.locked[0] == User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id
479 assert r.locked[0] == User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id
480
480
481 #push is ok and repo is now unlocked
481 #push is ok and repo is now unlocked
482 stdout, stderr = _add_files_and_push('git', DEST)
482 stdout, stderr = _add_files_and_push('git', DEST)
483 _check_proper_git_push(stdout, stderr)
483 _check_proper_git_push(stdout, stderr)
484
484
485 #assert ('remote: Released lock on repo `%s`' % GIT_REPO) in stdout
485 #assert ('remote: Released lock on repo `%s`' % GIT_REPO) in stdout
486 #we need to cleanup the Session Here !
486 #we need to cleanup the Session Here !
487 Session.remove()
487 Session.remove()
488 r = Repository.get_by_repo_name(GIT_REPO)
488 r = Repository.get_by_repo_name(GIT_REPO)
489 assert r.locked == [None, None]
489 assert r.locked == [None, None]
490
490
491 def test_ip_restriction_hg(self):
491 def test_ip_restriction_hg(self):
492 user_model = UserModel()
492 user_model = UserModel()
493 try:
493 try:
494 user_model.add_extra_ip(TEST_USER_ADMIN_LOGIN, '10.10.10.10/32')
494 user_model.add_extra_ip(TEST_USER_ADMIN_LOGIN, '10.10.10.10/32')
495 Session().commit()
495 Session().commit()
496 clone_url = _construct_url(HG_REPO)
496 clone_url = _construct_url(HG_REPO)
497 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
497 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
498 assert 'abort: HTTP Error 403: Forbidden' in stderr
498 assert 'abort: HTTP Error 403: Forbidden' in stderr
499 finally:
499 finally:
500 #release IP restrictions
500 #release IP restrictions
501 for ip in UserIpMap.getAll():
501 for ip in UserIpMap.getAll():
502 UserIpMap.delete(ip.ip_id)
502 UserIpMap.delete(ip.ip_id)
503 Session().commit()
503 Session().commit()
504
504
505 time.sleep(2)
505 time.sleep(2)
506 clone_url = _construct_url(HG_REPO)
506 clone_url = _construct_url(HG_REPO)
507 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
507 stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
508
508
509 assert 'requesting all changes' in stdout
509 assert 'requesting all changes' in stdout
510 assert 'adding changesets' in stdout
510 assert 'adding changesets' in stdout
511 assert 'adding manifests' in stdout
511 assert 'adding manifests' in stdout
512 assert 'adding file changes' in stdout
512 assert 'adding file changes' in stdout
513
513
514 assert stderr == ''
514 assert stderr == ''
515
515
516 def test_ip_restriction_git(self):
516 def test_ip_restriction_git(self):
517 user_model = UserModel()
517 user_model = UserModel()
518 try:
518 try:
519 user_model.add_extra_ip(TEST_USER_ADMIN_LOGIN, '10.10.10.10/32')
519 user_model.add_extra_ip(TEST_USER_ADMIN_LOGIN, '10.10.10.10/32')
520 Session().commit()
520 Session().commit()
521 clone_url = _construct_url(GIT_REPO)
521 clone_url = _construct_url(GIT_REPO)
522 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
522 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
523 msg = ("""The requested URL returned error: 403""")
523 msg = ("""The requested URL returned error: 403""")
524 assert msg in stderr
524 assert msg in stderr
525 finally:
525 finally:
526 #release IP restrictions
526 #release IP restrictions
527 for ip in UserIpMap.getAll():
527 for ip in UserIpMap.getAll():
528 UserIpMap.delete(ip.ip_id)
528 UserIpMap.delete(ip.ip_id)
529 Session().commit()
529 Session().commit()
530
530
531 time.sleep(2)
531 time.sleep(2)
532 clone_url = _construct_url(GIT_REPO)
532 clone_url = _construct_url(GIT_REPO)
533 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
533 stdout, stderr = Command('/tmp').execute('git clone', clone_url)
534
534
535 assert 'Cloning into' in stdout + stderr
535 assert 'Cloning into' in stdout + stderr
536 assert stderr == '' or stdout == ''
536 assert stderr == '' or stdout == ''
@@ -1,614 +1,614 b''
1 ################################################################################
1 ################################################################################
2 ################################################################################
2 ################################################################################
3 # Kallithea - config for tests: #
3 # Kallithea - config for tests: #
4 # initial_repo_scan = true #
4 # initial_repo_scan = true #
5 # vcs_full_cache = false #
5 # vcs_full_cache = false #
6 # sqlalchemy and kallithea_test.sqlite #
6 # sqlalchemy and kallithea_test.sqlite #
7 # custom logging #
7 # custom logging #
8 # #
8 # #
9 # The %(here)s variable will be replaced with the parent directory of this file#
9 # The %(here)s variable will be replaced with the parent directory of this file#
10 ################################################################################
10 ################################################################################
11 ################################################################################
11 ################################################################################
12
12
13 [DEFAULT]
13 [DEFAULT]
14 debug = true
14 debug = true
15 pdebug = false
15 pdebug = false
16
16
17 ################################################################################
17 ################################################################################
18 ## E-mail settings ##
18 ## E-mail settings ##
19 ## ##
19 ## ##
20 ## Refer to the documentation ("E-mail settings") for more details. ##
20 ## Refer to the documentation ("E-mail settings") for more details. ##
21 ## ##
21 ## ##
22 ## It is recommended to use a valid sender address that passes access ##
22 ## It is recommended to use a valid sender address that passes access ##
23 ## validation and spam filtering in mail servers. ##
23 ## validation and spam filtering in mail servers. ##
24 ################################################################################
24 ################################################################################
25
25
26 ## 'From' header for application e-mails. You can optionally add a name.
26 ## 'From' header for application e-mails. You can optionally add a name.
27 ## Default:
27 ## Default:
28 #app_email_from = Kallithea
28 #app_email_from = Kallithea
29 ## Examples:
29 ## Examples:
30 #app_email_from = Kallithea <kallithea-noreply@example.com>
30 #app_email_from = Kallithea <kallithea-noreply@example.com>
31 #app_email_from = kallithea-noreply@example.com
31 #app_email_from = kallithea-noreply@example.com
32
32
33 ## Subject prefix for application e-mails.
33 ## Subject prefix for application e-mails.
34 ## A space between this prefix and the real subject is automatically added.
34 ## A space between this prefix and the real subject is automatically added.
35 ## Default:
35 ## Default:
36 #email_prefix =
36 #email_prefix =
37 ## Example:
37 ## Example:
38 #email_prefix = [Kallithea]
38 #email_prefix = [Kallithea]
39
39
40 ## Recipients for error e-mails and fallback recipients of application mails.
40 ## Recipients for error e-mails and fallback recipients of application mails.
41 ## Multiple addresses can be specified, space-separated.
41 ## Multiple addresses can be specified, space-separated.
42 ## Only addresses are allowed, do not add any name part.
42 ## Only addresses are allowed, do not add any name part.
43 ## Default:
43 ## Default:
44 #email_to =
44 #email_to =
45 ## Examples:
45 ## Examples:
46 #email_to = admin@example.com
46 #email_to = admin@example.com
47 #email_to = admin@example.com another_admin@example.com
47 #email_to = admin@example.com another_admin@example.com
48
48
49 ## 'From' header for error e-mails. You can optionally add a name.
49 ## 'From' header for error e-mails. You can optionally add a name.
50 ## Default:
50 ## Default:
51 #error_email_from = pylons@yourapp.com
51 #error_email_from = pylons@yourapp.com
52 ## Examples:
52 ## Examples:
53 #error_email_from = Kallithea Errors <kallithea-noreply@example.com>
53 #error_email_from = Kallithea Errors <kallithea-noreply@example.com>
54 #error_email_from = paste_error@example.com
54 #error_email_from = paste_error@example.com
55
55
56 ## SMTP server settings
56 ## SMTP server settings
57 ## Only smtp_server is mandatory. All other settings take the specified default
57 ## Only smtp_server is mandatory. All other settings take the specified default
58 ## values.
58 ## values.
59 #smtp_server = mail.server.com
59 #smtp_server = mail.server.com
60 #smtp_username =
60 #smtp_username =
61 #smtp_password =
61 #smtp_password =
62 #smtp_port = 25
62 #smtp_port = 25
63 #smtp_use_tls = false
63 #smtp_use_tls = false
64 #smtp_use_ssl = false
64 #smtp_use_ssl = false
65 ## SMTP authentication parameters to use (e.g. LOGIN PLAIN CRAM-MD5, etc.).
65 ## SMTP authentication parameters to use (e.g. LOGIN PLAIN CRAM-MD5, etc.).
66 ## If empty, use any of the authentication parameters supported by the server.
66 ## If empty, use any of the authentication parameters supported by the server.
67 #smtp_auth =
67 #smtp_auth =
68
68
69 [server:main]
69 [server:main]
70 ## PASTE ##
70 ## PASTE ##
71 #use = egg:Paste#http
71 #use = egg:Paste#http
72 ## nr of worker threads to spawn
72 ## nr of worker threads to spawn
73 #threadpool_workers = 5
73 #threadpool_workers = 5
74 ## max request before thread respawn
74 ## max request before thread respawn
75 #threadpool_max_requests = 10
75 #threadpool_max_requests = 10
76 ## option to use threads of process
76 ## option to use threads of process
77 #use_threadpool = true
77 #use_threadpool = true
78
78
79 ## WAITRESS ##
79 ## WAITRESS ##
80 use = egg:waitress#main
80 use = egg:waitress#main
81 ## number of worker threads
81 ## number of worker threads
82 threads = 5
82 threads = 5
83 ## MAX BODY SIZE 100GB
83 ## MAX BODY SIZE 100GB
84 max_request_body_size = 107374182400
84 max_request_body_size = 107374182400
85 ## use poll instead of select, fixes fd limits, may not work on old
85 ## use poll instead of select, fixes fd limits, may not work on old
86 ## windows systems.
86 ## windows systems.
87 #asyncore_use_poll = True
87 #asyncore_use_poll = True
88
88
89 ## GUNICORN ##
89 ## GUNICORN ##
90 #use = egg:gunicorn#main
90 #use = egg:gunicorn#main
91 ## number of process workers. You must set `instance_id = *` when this option
91 ## number of process workers. You must set `instance_id = *` when this option
92 ## is set to more than one worker
92 ## is set to more than one worker
93 #workers = 1
93 #workers = 1
94 ## process name
94 ## process name
95 #proc_name = kallithea
95 #proc_name = kallithea
96 ## type of worker class, one of sync, eventlet, gevent, tornado
96 ## type of worker class, one of sync, eventlet, gevent, tornado
97 ## recommended for bigger setup is using of of other than sync one
97 ## recommended for bigger setup is using of of other than sync one
98 #worker_class = sync
98 #worker_class = sync
99 #max_requests = 1000
99 #max_requests = 1000
100 ## ammount of time a worker can handle request before it gets killed and
100 ## ammount of time a worker can handle request before it gets killed and
101 ## restarted
101 ## restarted
102 #timeout = 3600
102 #timeout = 3600
103
103
104 ## UWSGI ##
104 ## UWSGI ##
105 ## run with uwsgi --ini-paste-logged <inifile.ini>
105 ## run with uwsgi --ini-paste-logged <inifile.ini>
106 #[uwsgi]
106 #[uwsgi]
107 #socket = /tmp/uwsgi.sock
107 #socket = /tmp/uwsgi.sock
108 #master = true
108 #master = true
109 #http = 127.0.0.1:5000
109 #http = 127.0.0.1:5000
110
110
111 ## set as deamon and redirect all output to file
111 ## set as deamon and redirect all output to file
112 #daemonize = ./uwsgi_kallithea.log
112 #daemonize = ./uwsgi_kallithea.log
113
113
114 ## master process PID
114 ## master process PID
115 #pidfile = ./uwsgi_kallithea.pid
115 #pidfile = ./uwsgi_kallithea.pid
116
116
117 ## stats server with workers statistics, use uwsgitop
117 ## stats server with workers statistics, use uwsgitop
118 ## for monitoring, `uwsgitop 127.0.0.1:1717`
118 ## for monitoring, `uwsgitop 127.0.0.1:1717`
119 #stats = 127.0.0.1:1717
119 #stats = 127.0.0.1:1717
120 #memory-report = true
120 #memory-report = true
121
121
122 ## log 5XX errors
122 ## log 5XX errors
123 #log-5xx = true
123 #log-5xx = true
124
124
125 ## Set the socket listen queue size.
125 ## Set the socket listen queue size.
126 #listen = 256
126 #listen = 256
127
127
128 ## Gracefully Reload workers after the specified amount of managed requests
128 ## Gracefully Reload workers after the specified amount of managed requests
129 ## (avoid memory leaks).
129 ## (avoid memory leaks).
130 #max-requests = 1000
130 #max-requests = 1000
131
131
132 ## enable large buffers
132 ## enable large buffers
133 #buffer-size = 65535
133 #buffer-size = 65535
134
134
135 ## socket and http timeouts ##
135 ## socket and http timeouts ##
136 #http-timeout = 3600
136 #http-timeout = 3600
137 #socket-timeout = 3600
137 #socket-timeout = 3600
138
138
139 ## Log requests slower than the specified number of milliseconds.
139 ## Log requests slower than the specified number of milliseconds.
140 #log-slow = 10
140 #log-slow = 10
141
141
142 ## Exit if no app can be loaded.
142 ## Exit if no app can be loaded.
143 #need-app = true
143 #need-app = true
144
144
145 ## Set lazy mode (load apps in workers instead of master).
145 ## Set lazy mode (load apps in workers instead of master).
146 #lazy = true
146 #lazy = true
147
147
148 ## scaling ##
148 ## scaling ##
149 ## set cheaper algorithm to use, if not set default will be used
149 ## set cheaper algorithm to use, if not set default will be used
150 #cheaper-algo = spare
150 #cheaper-algo = spare
151
151
152 ## minimum number of workers to keep at all times
152 ## minimum number of workers to keep at all times
153 #cheaper = 1
153 #cheaper = 1
154
154
155 ## number of workers to spawn at startup
155 ## number of workers to spawn at startup
156 #cheaper-initial = 1
156 #cheaper-initial = 1
157
157
158 ## maximum number of workers that can be spawned
158 ## maximum number of workers that can be spawned
159 #workers = 4
159 #workers = 4
160
160
161 ## how many workers should be spawned at a time
161 ## how many workers should be spawned at a time
162 #cheaper-step = 1
162 #cheaper-step = 1
163
163
164 ## COMMON ##
164 ## COMMON ##
165 host = 127.0.0.1
165 host = 127.0.0.1
166 port = 5000
166 port = 4999
167
167
168 ## middleware for hosting the WSGI application under a URL prefix
168 ## middleware for hosting the WSGI application under a URL prefix
169 #[filter:proxy-prefix]
169 #[filter:proxy-prefix]
170 #use = egg:PasteDeploy#prefix
170 #use = egg:PasteDeploy#prefix
171 #prefix = /<your-prefix>
171 #prefix = /<your-prefix>
172
172
173 [app:main]
173 [app:main]
174 use = egg:kallithea
174 use = egg:kallithea
175 ## enable proxy prefix middleware
175 ## enable proxy prefix middleware
176 #filter-with = proxy-prefix
176 #filter-with = proxy-prefix
177
177
178 full_stack = true
178 full_stack = true
179 static_files = true
179 static_files = true
180 ## Available Languages:
180 ## Available Languages:
181 ## cs de fr hu ja nl_BE pl pt_BR ru sk zh_CN zh_TW
181 ## cs de fr hu ja nl_BE pl pt_BR ru sk zh_CN zh_TW
182 lang =
182 lang =
183 cache_dir = %(here)s/data
183 cache_dir = %(here)s/data
184 index_dir = %(here)s/data/index
184 index_dir = %(here)s/data/index
185
185
186 ## perform a full repository scan on each server start, this should be
186 ## perform a full repository scan on each server start, this should be
187 ## set to false after first startup, to allow faster server restarts.
187 ## set to false after first startup, to allow faster server restarts.
188 #initial_repo_scan = false
188 #initial_repo_scan = false
189 initial_repo_scan = true
189 initial_repo_scan = true
190
190
191 ## uncomment and set this path to use archive download cache
191 ## uncomment and set this path to use archive download cache
192 archive_cache_dir = %(here)s/tarballcache
192 archive_cache_dir = %(here)s/tarballcache
193
193
194 ## change this to unique ID for security
194 ## change this to unique ID for security
195 app_instance_uuid = test
195 app_instance_uuid = test
196
196
197 ## cut off limit for large diffs (size in bytes)
197 ## cut off limit for large diffs (size in bytes)
198 cut_off_limit = 256000
198 cut_off_limit = 256000
199
199
200 ## use cache version of scm repo everywhere
200 ## use cache version of scm repo everywhere
201 #vcs_full_cache = true
201 #vcs_full_cache = true
202 vcs_full_cache = false
202 vcs_full_cache = false
203
203
204 ## force https in Kallithea, fixes https redirects, assumes it's always https
204 ## force https in Kallithea, fixes https redirects, assumes it's always https
205 force_https = false
205 force_https = false
206
206
207 ## use Strict-Transport-Security headers
207 ## use Strict-Transport-Security headers
208 use_htsts = false
208 use_htsts = false
209
209
210 ## number of commits stats will parse on each iteration
210 ## number of commits stats will parse on each iteration
211 commit_parse_limit = 25
211 commit_parse_limit = 25
212
212
213 ## path to git executable
213 ## path to git executable
214 git_path = git
214 git_path = git
215
215
216 ## git rev filter option, --all is the default filter, if you need to
216 ## git rev filter option, --all is the default filter, if you need to
217 ## hide all refs in changelog switch this to --branches --tags
217 ## hide all refs in changelog switch this to --branches --tags
218 #git_rev_filter = --branches --tags
218 #git_rev_filter = --branches --tags
219
219
220 ## RSS feed options
220 ## RSS feed options
221 rss_cut_off_limit = 256000
221 rss_cut_off_limit = 256000
222 rss_items_per_page = 10
222 rss_items_per_page = 10
223 rss_include_diff = false
223 rss_include_diff = false
224
224
225 ## options for showing and identifying changesets
225 ## options for showing and identifying changesets
226 show_sha_length = 12
226 show_sha_length = 12
227 show_revision_number = true
227 show_revision_number = true
228
228
229 ## gist URL alias, used to create nicer urls for gist. This should be an
229 ## gist URL alias, used to create nicer urls for gist. This should be an
230 ## url that does rewrites to _admin/gists/<gistid>.
230 ## url that does rewrites to _admin/gists/<gistid>.
231 ## example: http://gist.kallithea.server/{gistid}. Empty means use the internal
231 ## example: http://gist.kallithea.server/{gistid}. Empty means use the internal
232 ## Kallithea url, ie. http[s]://your.kallithea.server/_admin/gists/<gistid>
232 ## Kallithea url, ie. http[s]://your.kallithea.server/_admin/gists/<gistid>
233 gist_alias_url =
233 gist_alias_url =
234
234
235 ## white list of API enabled controllers. This allows to add list of
235 ## white list of API enabled controllers. This allows to add list of
236 ## controllers to which access will be enabled by api_key. eg: to enable
236 ## controllers to which access will be enabled by api_key. eg: to enable
237 ## api access to raw_files put `FilesController:raw`, to enable access to patches
237 ## api access to raw_files put `FilesController:raw`, to enable access to patches
238 ## add `ChangesetController:changeset_patch`. This list should be "," separated
238 ## add `ChangesetController:changeset_patch`. This list should be "," separated
239 ## Syntax is <ControllerClass>:<function>. Check debug logs for generated names
239 ## Syntax is <ControllerClass>:<function>. Check debug logs for generated names
240 ## Recommended settings below are commented out:
240 ## Recommended settings below are commented out:
241 api_access_controllers_whitelist =
241 api_access_controllers_whitelist =
242 # ChangesetController:changeset_patch,
242 # ChangesetController:changeset_patch,
243 # ChangesetController:changeset_raw,
243 # ChangesetController:changeset_raw,
244 # FilesController:raw,
244 # FilesController:raw,
245 # FilesController:archivefile
245 # FilesController:archivefile
246
246
247 ## default encoding used to convert from and to unicode
247 ## default encoding used to convert from and to unicode
248 ## can be also a comma seperated list of encoding in case of mixed encodings
248 ## can be also a comma seperated list of encoding in case of mixed encodings
249 default_encoding = utf8
249 default_encoding = utf8
250
250
251 ## issue tracker for Kallithea (leave blank to disable, absent for default)
251 ## issue tracker for Kallithea (leave blank to disable, absent for default)
252 #bugtracker = https://bitbucket.org/conservancy/kallithea/issues
252 #bugtracker = https://bitbucket.org/conservancy/kallithea/issues
253
253
254 ## issue tracking mapping for commits messages
254 ## issue tracking mapping for commits messages
255 ## comment out issue_pat, issue_server, issue_prefix to enable
255 ## comment out issue_pat, issue_server, issue_prefix to enable
256
256
257 ## pattern to get the issues from commit messages
257 ## pattern to get the issues from commit messages
258 ## default one used here is #<numbers> with a regex passive group for `#`
258 ## default one used here is #<numbers> with a regex passive group for `#`
259 ## {id} will be all groups matched from this pattern
259 ## {id} will be all groups matched from this pattern
260
260
261 issue_pat = (?:\s*#)(\d+)
261 issue_pat = (?:\s*#)(\d+)
262
262
263 ## server url to the issue, each {id} will be replaced with match
263 ## server url to the issue, each {id} will be replaced with match
264 ## fetched from the regex and {repo} is replaced with full repository name
264 ## fetched from the regex and {repo} is replaced with full repository name
265 ## including groups {repo_name} is replaced with just name of repo
265 ## including groups {repo_name} is replaced with just name of repo
266
266
267 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
267 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
268
268
269 ## prefix to add to link to indicate it's an url
269 ## prefix to add to link to indicate it's an url
270 ## #314 will be replaced by <issue_prefix><id>
270 ## #314 will be replaced by <issue_prefix><id>
271
271
272 issue_prefix = #
272 issue_prefix = #
273
273
274 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
274 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
275 ## multiple patterns, to other issues server, wiki or others
275 ## multiple patterns, to other issues server, wiki or others
276 ## below an example how to create a wiki pattern
276 ## below an example how to create a wiki pattern
277 # wiki-some-id -> https://mywiki.com/some-id
277 # wiki-some-id -> https://mywiki.com/some-id
278
278
279 #issue_pat_wiki = (?:wiki-)(.+)
279 #issue_pat_wiki = (?:wiki-)(.+)
280 #issue_server_link_wiki = https://mywiki.com/{id}
280 #issue_server_link_wiki = https://mywiki.com/{id}
281 #issue_prefix_wiki = WIKI-
281 #issue_prefix_wiki = WIKI-
282
282
283 ## instance-id prefix
283 ## instance-id prefix
284 ## a prefix key for this instance used for cache invalidation when running
284 ## a prefix key for this instance used for cache invalidation when running
285 ## multiple instances of kallithea, make sure it's globally unique for
285 ## multiple instances of kallithea, make sure it's globally unique for
286 ## all running kallithea instances. Leave empty if you don't use it
286 ## all running kallithea instances. Leave empty if you don't use it
287 instance_id =
287 instance_id =
288
288
289 ## alternative return HTTP header for failed authentication. Default HTTP
289 ## alternative return HTTP header for failed authentication. Default HTTP
290 ## response is 401 HTTPUnauthorized. Currently Mercurial clients have trouble with
290 ## response is 401 HTTPUnauthorized. Currently Mercurial clients have trouble with
291 ## handling that. Set this variable to 403 to return HTTPForbidden
291 ## handling that. Set this variable to 403 to return HTTPForbidden
292 auth_ret_code =
292 auth_ret_code =
293
293
294 ## locking return code. When repository is locked return this HTTP code. 2XX
294 ## locking return code. When repository is locked return this HTTP code. 2XX
295 ## codes don't break the transactions while 4XX codes do
295 ## codes don't break the transactions while 4XX codes do
296 lock_ret_code = 423
296 lock_ret_code = 423
297
297
298 ## allows to change the repository location in settings page
298 ## allows to change the repository location in settings page
299 allow_repo_location_change = True
299 allow_repo_location_change = True
300
300
301 ## allows to setup custom hooks in settings page
301 ## allows to setup custom hooks in settings page
302 allow_custom_hooks_settings = True
302 allow_custom_hooks_settings = True
303
303
304 ####################################
304 ####################################
305 ### CELERY CONFIG ####
305 ### CELERY CONFIG ####
306 ####################################
306 ####################################
307
307
308 use_celery = false
308 use_celery = false
309 broker.host = localhost
309 broker.host = localhost
310 broker.vhost = rabbitmqhost
310 broker.vhost = rabbitmqhost
311 broker.port = 5672
311 broker.port = 5672
312 broker.user = rabbitmq
312 broker.user = rabbitmq
313 broker.password = qweqwe
313 broker.password = qweqwe
314
314
315 celery.imports = kallithea.lib.celerylib.tasks
315 celery.imports = kallithea.lib.celerylib.tasks
316
316
317 celery.result.backend = amqp
317 celery.result.backend = amqp
318 celery.result.dburi = amqp://
318 celery.result.dburi = amqp://
319 celery.result.serialier = json
319 celery.result.serialier = json
320
320
321 #celery.send.task.error.emails = true
321 #celery.send.task.error.emails = true
322 #celery.amqp.task.result.expires = 18000
322 #celery.amqp.task.result.expires = 18000
323
323
324 celeryd.concurrency = 2
324 celeryd.concurrency = 2
325 #celeryd.log.file = celeryd.log
325 #celeryd.log.file = celeryd.log
326 celeryd.log.level = DEBUG
326 celeryd.log.level = DEBUG
327 celeryd.max.tasks.per.child = 1
327 celeryd.max.tasks.per.child = 1
328
328
329 ## tasks will never be sent to the queue, but executed locally instead.
329 ## tasks will never be sent to the queue, but executed locally instead.
330 celery.always.eager = false
330 celery.always.eager = false
331
331
332 ####################################
332 ####################################
333 ### BEAKER CACHE ####
333 ### BEAKER CACHE ####
334 ####################################
334 ####################################
335
335
336 beaker.cache.data_dir = %(here)s/data/cache/data
336 beaker.cache.data_dir = %(here)s/data/cache/data
337 beaker.cache.lock_dir = %(here)s/data/cache/lock
337 beaker.cache.lock_dir = %(here)s/data/cache/lock
338
338
339 beaker.cache.regions = super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
339 beaker.cache.regions = super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
340
340
341 beaker.cache.super_short_term.type = memory
341 beaker.cache.super_short_term.type = memory
342 beaker.cache.super_short_term.expire = 10
342 beaker.cache.super_short_term.expire = 10
343 beaker.cache.super_short_term.key_length = 256
343 beaker.cache.super_short_term.key_length = 256
344
344
345 beaker.cache.short_term.type = memory
345 beaker.cache.short_term.type = memory
346 beaker.cache.short_term.expire = 60
346 beaker.cache.short_term.expire = 60
347 beaker.cache.short_term.key_length = 256
347 beaker.cache.short_term.key_length = 256
348
348
349 beaker.cache.long_term.type = memory
349 beaker.cache.long_term.type = memory
350 beaker.cache.long_term.expire = 36000
350 beaker.cache.long_term.expire = 36000
351 beaker.cache.long_term.key_length = 256
351 beaker.cache.long_term.key_length = 256
352
352
353 beaker.cache.sql_cache_short.type = memory
353 beaker.cache.sql_cache_short.type = memory
354 beaker.cache.sql_cache_short.expire = 1
354 beaker.cache.sql_cache_short.expire = 1
355 beaker.cache.sql_cache_short.key_length = 256
355 beaker.cache.sql_cache_short.key_length = 256
356
356
357 beaker.cache.sql_cache_med.type = memory
357 beaker.cache.sql_cache_med.type = memory
358 beaker.cache.sql_cache_med.expire = 360
358 beaker.cache.sql_cache_med.expire = 360
359 beaker.cache.sql_cache_med.key_length = 256
359 beaker.cache.sql_cache_med.key_length = 256
360
360
361 beaker.cache.sql_cache_long.type = file
361 beaker.cache.sql_cache_long.type = file
362 beaker.cache.sql_cache_long.expire = 3600
362 beaker.cache.sql_cache_long.expire = 3600
363 beaker.cache.sql_cache_long.key_length = 256
363 beaker.cache.sql_cache_long.key_length = 256
364
364
365 ####################################
365 ####################################
366 ### BEAKER SESSION ####
366 ### BEAKER SESSION ####
367 ####################################
367 ####################################
368 ## Type of storage used for the session, current types are
368 ## Type of storage used for the session, current types are
369 ## dbm, file, memcached, database, and memory.
369 ## dbm, file, memcached, database, and memory.
370 ## The storage uses the Container API
370 ## The storage uses the Container API
371 ## that is also used by the cache system.
371 ## that is also used by the cache system.
372
372
373 ## db session ##
373 ## db session ##
374 #beaker.session.type = ext:database
374 #beaker.session.type = ext:database
375 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/kallithea
375 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/kallithea
376 #beaker.session.table_name = db_session
376 #beaker.session.table_name = db_session
377
377
378 ## encrypted cookie client side session, good for many instances ##
378 ## encrypted cookie client side session, good for many instances ##
379 #beaker.session.type = cookie
379 #beaker.session.type = cookie
380
380
381 ## file based cookies (default) ##
381 ## file based cookies (default) ##
382 #beaker.session.type = file
382 #beaker.session.type = file
383
383
384 ## beaker.session.key should be unique for a given host, even when running
384 ## beaker.session.key should be unique for a given host, even when running
385 ## on different ports. Otherwise, cookie sessions will be shared and messed up.
385 ## on different ports. Otherwise, cookie sessions will be shared and messed up.
386 beaker.session.key = kallithea
386 beaker.session.key = kallithea
387 beaker.session.secret = {74e0cd75-b339-478b-b129-07dd221def1f}
387 beaker.session.secret = {74e0cd75-b339-478b-b129-07dd221def1f}
388
388
389 ## Secure encrypted cookie. Requires AES and AES python libraries
389 ## Secure encrypted cookie. Requires AES and AES python libraries
390 ## you must disable beaker.session.secret to use this
390 ## you must disable beaker.session.secret to use this
391 #beaker.session.encrypt_key = <key_for_encryption>
391 #beaker.session.encrypt_key = <key_for_encryption>
392 #beaker.session.validate_key = <validation_key>
392 #beaker.session.validate_key = <validation_key>
393
393
394 ## sets session as invalid if it haven't been accessed for given amount of time
394 ## sets session as invalid if it haven't been accessed for given amount of time
395 beaker.session.timeout = 2592000
395 beaker.session.timeout = 2592000
396 beaker.session.httponly = true
396 beaker.session.httponly = true
397 #beaker.session.cookie_path = /<your-prefix>
397 #beaker.session.cookie_path = /<your-prefix>
398
398
399 ## uncomment for https secure cookie
399 ## uncomment for https secure cookie
400 beaker.session.secure = false
400 beaker.session.secure = false
401
401
402 ## auto save the session to not to use .save()
402 ## auto save the session to not to use .save()
403 beaker.session.auto = False
403 beaker.session.auto = False
404
404
405 ## default cookie expiration time in seconds `true` expire at browser close ##
405 ## default cookie expiration time in seconds `true` expire at browser close ##
406 #beaker.session.cookie_expires = 3600
406 #beaker.session.cookie_expires = 3600
407
407
408 ############################
408 ############################
409 ## ERROR HANDLING SYSTEMS ##
409 ## ERROR HANDLING SYSTEMS ##
410 ############################
410 ############################
411
411
412 ####################
412 ####################
413 ### [errormator] ###
413 ### [errormator] ###
414 ####################
414 ####################
415
415
416 ## Errormator is tailored to work with Kallithea, see
416 ## Errormator is tailored to work with Kallithea, see
417 ## http://errormator.com for details how to obtain an account
417 ## http://errormator.com for details how to obtain an account
418 ## you must install python package `errormator_client` to make it work
418 ## you must install python package `errormator_client` to make it work
419
419
420 ## errormator enabled
420 ## errormator enabled
421 errormator = false
421 errormator = false
422
422
423 errormator.server_url = https://api.errormator.com
423 errormator.server_url = https://api.errormator.com
424 errormator.api_key = YOUR_API_KEY
424 errormator.api_key = YOUR_API_KEY
425
425
426 ## TWEAK AMOUNT OF INFO SENT HERE
426 ## TWEAK AMOUNT OF INFO SENT HERE
427
427
428 ## enables 404 error logging (default False)
428 ## enables 404 error logging (default False)
429 errormator.report_404 = false
429 errormator.report_404 = false
430
430
431 ## time in seconds after request is considered being slow (default 1)
431 ## time in seconds after request is considered being slow (default 1)
432 errormator.slow_request_time = 1
432 errormator.slow_request_time = 1
433
433
434 ## record slow requests in application
434 ## record slow requests in application
435 ## (needs to be enabled for slow datastore recording and time tracking)
435 ## (needs to be enabled for slow datastore recording and time tracking)
436 errormator.slow_requests = true
436 errormator.slow_requests = true
437
437
438 ## enable hooking to application loggers
438 ## enable hooking to application loggers
439 #errormator.logging = true
439 #errormator.logging = true
440
440
441 ## minimum log level for log capture
441 ## minimum log level for log capture
442 #errormator.logging.level = WARNING
442 #errormator.logging.level = WARNING
443
443
444 ## send logs only from erroneous/slow requests
444 ## send logs only from erroneous/slow requests
445 ## (saves API quota for intensive logging)
445 ## (saves API quota for intensive logging)
446 errormator.logging_on_error = false
446 errormator.logging_on_error = false
447
447
448 ## list of additonal keywords that should be grabbed from environ object
448 ## list of additonal keywords that should be grabbed from environ object
449 ## can be string with comma separated list of words in lowercase
449 ## can be string with comma separated list of words in lowercase
450 ## (by default client will always send following info:
450 ## (by default client will always send following info:
451 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
451 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
452 ## start with HTTP* this list be extended with additional keywords here
452 ## start with HTTP* this list be extended with additional keywords here
453 errormator.environ_keys_whitelist =
453 errormator.environ_keys_whitelist =
454
454
455 ## list of keywords that should be blanked from request object
455 ## list of keywords that should be blanked from request object
456 ## can be string with comma separated list of words in lowercase
456 ## can be string with comma separated list of words in lowercase
457 ## (by default client will always blank keys that contain following words
457 ## (by default client will always blank keys that contain following words
458 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
458 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
459 ## this list be extended with additional keywords set here
459 ## this list be extended with additional keywords set here
460 errormator.request_keys_blacklist =
460 errormator.request_keys_blacklist =
461
461
462 ## list of namespaces that should be ignores when gathering log entries
462 ## list of namespaces that should be ignores when gathering log entries
463 ## can be string with comma separated list of namespaces
463 ## can be string with comma separated list of namespaces
464 ## (by default the client ignores own entries: errormator_client.client)
464 ## (by default the client ignores own entries: errormator_client.client)
465 errormator.log_namespace_blacklist =
465 errormator.log_namespace_blacklist =
466
466
467 ################
467 ################
468 ### [sentry] ###
468 ### [sentry] ###
469 ################
469 ################
470
470
471 ## sentry is a alternative open source error aggregator
471 ## sentry is a alternative open source error aggregator
472 ## you must install python packages `sentry` and `raven` to enable
472 ## you must install python packages `sentry` and `raven` to enable
473
473
474 sentry.dsn = YOUR_DNS
474 sentry.dsn = YOUR_DNS
475 sentry.servers =
475 sentry.servers =
476 sentry.name =
476 sentry.name =
477 sentry.key =
477 sentry.key =
478 sentry.public_key =
478 sentry.public_key =
479 sentry.secret_key =
479 sentry.secret_key =
480 sentry.project =
480 sentry.project =
481 sentry.site =
481 sentry.site =
482 sentry.include_paths =
482 sentry.include_paths =
483 sentry.exclude_paths =
483 sentry.exclude_paths =
484
484
485 ################################################################################
485 ################################################################################
486 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
486 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
487 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
487 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
488 ## execute malicious code after an exception is raised. ##
488 ## execute malicious code after an exception is raised. ##
489 ################################################################################
489 ################################################################################
490 set debug = false
490 set debug = false
491
491
492 ##################################
492 ##################################
493 ### LOGVIEW CONFIG ###
493 ### LOGVIEW CONFIG ###
494 ##################################
494 ##################################
495
495
496 logview.sqlalchemy = #faa
496 logview.sqlalchemy = #faa
497 logview.pylons.templating = #bfb
497 logview.pylons.templating = #bfb
498 logview.pylons.util = #eee
498 logview.pylons.util = #eee
499
499
500 #########################################################
500 #########################################################
501 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
501 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
502 #########################################################
502 #########################################################
503
503
504 # SQLITE [default]
504 # SQLITE [default]
505 #sqlalchemy.db1.url = sqlite:///%(here)s/kallithea.db?timeout=60
505 #sqlalchemy.db1.url = sqlite:///%(here)s/kallithea.db?timeout=60
506 sqlalchemy.db1.url = sqlite:///%(here)s/kallithea_test.sqlite
506 sqlalchemy.db1.url = sqlite:///%(here)s/kallithea_test.sqlite
507
507
508 # POSTGRESQL
508 # POSTGRESQL
509 #sqlalchemy.db1.url = postgresql://user:pass@localhost/kallithea
509 #sqlalchemy.db1.url = postgresql://user:pass@localhost/kallithea
510
510
511 # MySQL
511 # MySQL
512 #sqlalchemy.db1.url = mysql://user:pass@localhost/kallithea
512 #sqlalchemy.db1.url = mysql://user:pass@localhost/kallithea
513
513
514 # see sqlalchemy docs for others
514 # see sqlalchemy docs for others
515
515
516 sqlalchemy.db1.echo = false
516 sqlalchemy.db1.echo = false
517 sqlalchemy.db1.pool_recycle = 3600
517 sqlalchemy.db1.pool_recycle = 3600
518 sqlalchemy.db1.convert_unicode = true
518 sqlalchemy.db1.convert_unicode = true
519
519
520 ################################
520 ################################
521 ### LOGGING CONFIGURATION ####
521 ### LOGGING CONFIGURATION ####
522 ################################
522 ################################
523
523
524 [loggers]
524 [loggers]
525 keys = root, routes, kallithea, sqlalchemy, beaker, templates, whoosh_indexer
525 keys = root, routes, kallithea, sqlalchemy, beaker, templates, whoosh_indexer
526
526
527 [handlers]
527 [handlers]
528 keys = console, console_sql
528 keys = console, console_sql
529
529
530 [formatters]
530 [formatters]
531 keys = generic, color_formatter, color_formatter_sql
531 keys = generic, color_formatter, color_formatter_sql
532
532
533 #############
533 #############
534 ## LOGGERS ##
534 ## LOGGERS ##
535 #############
535 #############
536
536
537 [logger_root]
537 [logger_root]
538 #level = NOTSET
538 #level = NOTSET
539 level = DEBUG
539 level = DEBUG
540 handlers = console
540 handlers = console
541
541
542 [logger_routes]
542 [logger_routes]
543 level = DEBUG
543 level = DEBUG
544 handlers =
544 handlers =
545 qualname = routes.middleware
545 qualname = routes.middleware
546 ## "level = DEBUG" logs the route matched and routing variables.
546 ## "level = DEBUG" logs the route matched and routing variables.
547 propagate = 1
547 propagate = 1
548
548
549 [logger_beaker]
549 [logger_beaker]
550 level = DEBUG
550 level = DEBUG
551 handlers =
551 handlers =
552 qualname = beaker.container
552 qualname = beaker.container
553 propagate = 1
553 propagate = 1
554
554
555 [logger_templates]
555 [logger_templates]
556 level = INFO
556 level = INFO
557 handlers =
557 handlers =
558 qualname = pylons.templating
558 qualname = pylons.templating
559 propagate = 1
559 propagate = 1
560
560
561 [logger_kallithea]
561 [logger_kallithea]
562 level = DEBUG
562 level = DEBUG
563 handlers =
563 handlers =
564 qualname = kallithea
564 qualname = kallithea
565 propagate = 1
565 propagate = 1
566
566
567 [logger_sqlalchemy]
567 [logger_sqlalchemy]
568 #level = INFO
568 #level = INFO
569 #handlers = console_sql
569 #handlers = console_sql
570 level = ERROR
570 level = ERROR
571 handlers = console
571 handlers = console
572 qualname = sqlalchemy.engine
572 qualname = sqlalchemy.engine
573 propagate = 0
573 propagate = 0
574
574
575 [logger_whoosh_indexer]
575 [logger_whoosh_indexer]
576 level = DEBUG
576 level = DEBUG
577 handlers =
577 handlers =
578 qualname = whoosh_indexer
578 qualname = whoosh_indexer
579 propagate = 1
579 propagate = 1
580
580
581 ##############
581 ##############
582 ## HANDLERS ##
582 ## HANDLERS ##
583 ##############
583 ##############
584
584
585 [handler_console]
585 [handler_console]
586 class = StreamHandler
586 class = StreamHandler
587 args = (sys.stderr,)
587 args = (sys.stderr,)
588 #level = INFO
588 #level = INFO
589 level = NOTSET
589 level = NOTSET
590 formatter = generic
590 formatter = generic
591
591
592 [handler_console_sql]
592 [handler_console_sql]
593 class = StreamHandler
593 class = StreamHandler
594 args = (sys.stderr,)
594 args = (sys.stderr,)
595 level = WARN
595 level = WARN
596 formatter = generic
596 formatter = generic
597
597
598 ################
598 ################
599 ## FORMATTERS ##
599 ## FORMATTERS ##
600 ################
600 ################
601
601
602 [formatter_generic]
602 [formatter_generic]
603 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
603 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
604 datefmt = %Y-%m-%d %H:%M:%S
604 datefmt = %Y-%m-%d %H:%M:%S
605
605
606 [formatter_color_formatter]
606 [formatter_color_formatter]
607 class = kallithea.lib.colored_formatter.ColorFormatter
607 class = kallithea.lib.colored_formatter.ColorFormatter
608 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
608 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
609 datefmt = %Y-%m-%d %H:%M:%S
609 datefmt = %Y-%m-%d %H:%M:%S
610
610
611 [formatter_color_formatter_sql]
611 [formatter_color_formatter_sql]
612 class = kallithea.lib.colored_formatter.ColorFormatterSql
612 class = kallithea.lib.colored_formatter.ColorFormatterSql
613 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
613 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
614 datefmt = %Y-%m-%d %H:%M:%S
614 datefmt = %Y-%m-%d %H:%M:%S
General Comments 0
You need to be logged in to leave comments. Login now