##// END OF EJS Templates
merged with stable
super-admin -
r4738:610dc89a merge default
parent child
Show More
@@ -78,3 +78,4 6eaf953da06e468a4c4e5239d3d0e700bda6b163
78 f8161cbc2d94a935d3c395a0e758d9a094287169 v4.25.0
78 f8161cbc2d94a935d3c395a0e758d9a094287169 v4.25.0
79 77fe47b5b39338e71b2c040de2c0359b529b6251 v4.25.1
79 77fe47b5b39338e71b2c040de2c0359b529b6251 v4.25.1
80 27475bd8a718b9a00a37a8563c4927120865ad85 v4.25.2
80 27475bd8a718b9a00a37a8563c4927120865ad85 v4.25.2
81 b4ba10dcb4ab67d02b8c5cff32a3827f6c4fdedb v4.26.0
@@ -19,11 +19,12 done = true
19 [task:generate_api_docs]
19 [task:generate_api_docs]
20 done = true
20 done = true
21
21
22 [task:updated_translation]
23 done = true
24
22 [release]
25 [release]
23 state = prepared
26 state = prepared
24 version = 4.25.2
27 version = 4.26.0
25
26 [task:updated_translation]
27
28
28 [task:generate_js_routes]
29 [task:generate_js_routes]
29
30
@@ -101,4 +101,18 2b) Add user called 'admin' into all rep
101 In [3]: permission_name = 'group.write'
101 In [3]: permission_name = 'group.write'
102 In [4]: for repo_group in RepoGroup.get_all():
102 In [4]: for repo_group in RepoGroup.get_all():
103 ...: RepoGroupModel().grant_user_permission(repo_group, user, permission_name)
103 ...: RepoGroupModel().grant_user_permission(repo_group, user, permission_name)
104 ...: Session().commit() No newline at end of file
104 ...: Session().commit()
105
106
107 Delete a problematic pull request
108 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
109
110 .. code-block:: python
111 :dedent: 1
112
113 In [1]: from rhodecode.model.pull_request import PullRequestModel
114 In [2]: pullrequest_id = 123
115 In [3]: pr = PullRequest.get(pullrequest_id)
116 In [4]: super_admin = User.get_first_super_admin()
117 In [5]: PullRequestModel().delete(pr, super_admin)
118 In [6]: Session().commit()
@@ -51,6 +51,14 def admin_routes(config):
51 route_name='ops_redirect_test', request_method='GET',
51 route_name='ops_redirect_test', request_method='GET',
52 renderer='json_ext')
52 renderer='json_ext')
53
53
54 config.add_route(
55 name='ops_healthcheck',
56 pattern='/status')
57 config.add_view(
58 OpsView,
59 attr='ops_healthcheck',
60 route_name='ops_healthcheck', request_method='GET',
61 renderer='json_ext')
54
62
55 def includeme(config):
63 def includeme(config):
56 config.include(admin_routes, route_prefix=ADMIN_PREFIX + '/ops')
64 config.include(admin_routes, route_prefix=ADMIN_PREFIX + '/ops')
@@ -26,6 +26,8 from pyramid.httpexceptions import HTTPF
26
26
27 from rhodecode.apps._base import BaseAppView
27 from rhodecode.apps._base import BaseAppView
28 from rhodecode.lib import helpers as h
28 from rhodecode.lib import helpers as h
29 from rhodecode.lib.auth import LoginRequired
30 from rhodecode.model.db import UserApiKeys
29
31
30 log = logging.getLogger(__name__)
32 log = logging.getLogger(__name__)
31
33
@@ -72,3 +74,24 class OpsView(BaseAppView):
72 """
74 """
73 redirect_to = self.request.GET.get('to') or h.route_path('home')
75 redirect_to = self.request.GET.get('to') or h.route_path('home')
74 raise HTTPFound(redirect_to)
76 raise HTTPFound(redirect_to)
77
78 @LoginRequired(auth_token_access=[UserApiKeys.ROLE_HTTP])
79 def ops_healthcheck(self):
80 from rhodecode.lib.system_info import load_system_info
81
82 vcsserver_info = load_system_info('vcs_server')
83 if vcsserver_info:
84 vcsserver_info = vcsserver_info['human_value']
85
86 db_info = load_system_info('database_info')
87 if db_info:
88 db_info = db_info['human_value']
89
90 health_spec = {
91 'caller_ip': self.request.user.ip_addr,
92 'vcsserver': vcsserver_info,
93 'db': db_info,
94 }
95
96 return {'healthcheck': health_spec}
97
@@ -43,6 +43,9 class ResultWrapper(object):
43
43
44 def run_task(task, *args, **kwargs):
44 def run_task(task, *args, **kwargs):
45 log.debug('Got task `%s` for execution', task)
45 log.debug('Got task `%s` for execution', task)
46 if task is None:
47 raise ValueError('Got non-existing task for execution')
48
46 if rhodecode.CELERY_ENABLED:
49 if rhodecode.CELERY_ENABLED:
47 celery_is_up = False
50 celery_is_up = False
48 try:
51 try:
@@ -386,9 +386,7 def beat_check(*args, **kwargs):
386 return time.time()
386 return time.time()
387
387
388
388
389 @async_task(ignore_result=True)
389 def sync_last_update_for_objects(*args, **kwargs):
390 def sync_last_update(*args, **kwargs):
391
392 skip_repos = kwargs.get('skip_repos')
390 skip_repos = kwargs.get('skip_repos')
393 if not skip_repos:
391 if not skip_repos:
394 repos = Repository.query() \
392 repos = Repository.query() \
@@ -405,3 +403,8 def sync_last_update(*args, **kwargs):
405 for root_gr in repo_groups:
403 for root_gr in repo_groups:
406 for repo_gr in reversed(root_gr.recursive_groups()):
404 for repo_gr in reversed(root_gr.recursive_groups()):
407 repo_gr.update_commit_cache()
405 repo_gr.update_commit_cache()
406
407
408 @async_task(ignore_result=True)
409 def sync_last_update(*args, **kwargs):
410 sync_last_update_for_objects(*args, **kwargs)
@@ -166,8 +166,9 def detect_vcs_request(environ, backends
166 # static files no detection
166 # static files no detection
167 '_static',
167 '_static',
168
168
169 # skip ops ping
169 # skip ops ping, status
170 '_admin/ops/ping',
170 '_admin/ops/ping',
171 '_admin/ops/status',
171
172
172 # full channelstream connect should be VCS skipped
173 # full channelstream connect should be VCS skipped
173 '_admin/channelstream/connect',
174 '_admin/channelstream/connect',
@@ -300,7 +300,6 class BaseRedisBackend(redis_backend.Red
300 def get_mutex(self, key):
300 def get_mutex(self, key):
301 if self.distributed_lock:
301 if self.distributed_lock:
302 lock_key = redis_backend.u('_lock_{0}').format(key)
302 lock_key = redis_backend.u('_lock_{0}').format(key)
303 log.debug('Trying to acquire Redis lock for key %s', lock_key)
304 return get_mutex_lock(self.client, lock_key, self._lock_timeout,
303 return get_mutex_lock(self.client, lock_key, self._lock_timeout,
305 auto_renewal=self._lock_auto_renewal)
304 auto_renewal=self._lock_auto_renewal)
306 else:
305 else:
@@ -333,12 +332,22 def get_mutex_lock(client, lock_key, loc
333 strict=True,
332 strict=True,
334 )
333 )
335
334
335 def __repr__(self):
336 return "{}:{}".format(self.__class__.__name__, lock_key)
337
338 def __str__(self):
339 return "{}:{}".format(self.__class__.__name__, lock_key)
340
336 def __init__(self):
341 def __init__(self):
337 self.lock = self.get_lock()
342 self.lock = self.get_lock()
343 self.lock_key = lock_key
338
344
339 def acquire(self, wait=True):
345 def acquire(self, wait=True):
346 log.debug('Trying to acquire Redis lock for key %s', self.lock_key)
340 try:
347 try:
341 return self.lock.acquire(wait)
348 acquired = self.lock.acquire(wait)
349 log.debug('Got lock for key %s, %s', self.lock_key, acquired)
350 return acquired
342 except redis_lock.AlreadyAcquired:
351 except redis_lock.AlreadyAcquired:
343 return False
352 return False
344 except redis_lock.AlreadyStarted:
353 except redis_lock.AlreadyStarted:
@@ -122,7 +122,11 class RhodeCodeCacheRegion(CacheRegion):
122
122
123 if not condition:
123 if not condition:
124 log.debug('Calling un-cached func:%s', user_func.func_name)
124 log.debug('Calling un-cached func:%s', user_func.func_name)
125 return user_func(*arg, **kw)
125 start = time.time()
126 result = user_func(*arg, **kw)
127 total = time.time() - start
128 log.debug('un-cached func:%s took %.4fs', user_func.func_name, total)
129 return result
126
130
127 key = key_generator(*arg, **kw)
131 key = key_generator(*arg, **kw)
128
132
@@ -24,6 +24,8 import sys
24 import time
24 import time
25 import platform
25 import platform
26 import collections
26 import collections
27 from functools import wraps
28
27 import pkg_resources
29 import pkg_resources
28 import logging
30 import logging
29 import resource
31 import resource
@@ -51,6 +53,26 STATE_WARN = 'warning'
51 STATE_OK_DEFAULT = {'message': '', 'type': STATE_OK}
53 STATE_OK_DEFAULT = {'message': '', 'type': STATE_OK}
52
54
53
55
56 registered_helpers = {}
57
58
59 def register_sysinfo(func):
60 """
61 @register_helper
62 def db_check():
63 pass
64
65 db_check == registered_helpers['db_check']
66 """
67 global registered_helpers
68 registered_helpers[func.__name__] = func
69
70 @wraps(func)
71 def _wrapper(*args, **kwargs):
72 return func(*args, **kwargs)
73 return _wrapper
74
75
54 # HELPERS
76 # HELPERS
55 def percentage(part, whole):
77 def percentage(part, whole):
56 whole = float(whole)
78 whole = float(whole)
@@ -136,12 +158,14 class SysInfo(object):
136
158
137
159
138 # SysInfo functions
160 # SysInfo functions
161 @register_sysinfo
139 def python_info():
162 def python_info():
140 value = dict(version=' '.join(platform._sys_version()),
163 value = dict(version=' '.join(platform._sys_version()),
141 executable=sys.executable)
164 executable=sys.executable)
142 return SysInfoRes(value=value)
165 return SysInfoRes(value=value)
143
166
144
167
168 @register_sysinfo
145 def py_modules():
169 def py_modules():
146 mods = dict([(p.project_name, {'version': p.version, 'location': p.location})
170 mods = dict([(p.project_name, {'version': p.version, 'location': p.location})
147 for p in pkg_resources.working_set])
171 for p in pkg_resources.working_set])
@@ -150,6 +174,7 def py_modules():
150 return SysInfoRes(value=value)
174 return SysInfoRes(value=value)
151
175
152
176
177 @register_sysinfo
153 def platform_type():
178 def platform_type():
154 from rhodecode.lib.utils import safe_unicode, generate_platform_uuid
179 from rhodecode.lib.utils import safe_unicode, generate_platform_uuid
155
180
@@ -160,6 +185,7 def platform_type():
160 return SysInfoRes(value=value)
185 return SysInfoRes(value=value)
161
186
162
187
188 @register_sysinfo
163 def locale_info():
189 def locale_info():
164 import locale
190 import locale
165
191
@@ -175,6 +201,7 def locale_info():
175 return SysInfoRes(value=value, human_value=human_value)
201 return SysInfoRes(value=value, human_value=human_value)
176
202
177
203
204 @register_sysinfo
178 def ulimit_info():
205 def ulimit_info():
179 data = collections.OrderedDict([
206 data = collections.OrderedDict([
180 ('cpu time (seconds)', get_resource(resource.RLIMIT_CPU)),
207 ('cpu time (seconds)', get_resource(resource.RLIMIT_CPU)),
@@ -198,6 +225,7 def ulimit_info():
198 return SysInfoRes(value=value)
225 return SysInfoRes(value=value)
199
226
200
227
228 @register_sysinfo
201 def uptime():
229 def uptime():
202 from rhodecode.lib.helpers import age, time_to_datetime
230 from rhodecode.lib.helpers import age, time_to_datetime
203 from rhodecode.translation import TranslationString
231 from rhodecode.translation import TranslationString
@@ -223,6 +251,7 def uptime():
223 return SysInfoRes(value=value, human_value=human_value)
251 return SysInfoRes(value=value, human_value=human_value)
224
252
225
253
254 @register_sysinfo
226 def memory():
255 def memory():
227 from rhodecode.lib.helpers import format_byte_size_binary
256 from rhodecode.lib.helpers import format_byte_size_binary
228 value = dict(available=0, used=0, used_real=0, cached=0, percent=0,
257 value = dict(available=0, used=0, used_real=0, cached=0, percent=0,
@@ -262,6 +291,7 def memory():
262 return SysInfoRes(value=value, state=state, human_value=human_value)
291 return SysInfoRes(value=value, state=state, human_value=human_value)
263
292
264
293
294 @register_sysinfo
265 def machine_load():
295 def machine_load():
266 value = {'1_min': _NA, '5_min': _NA, '15_min': _NA, 'text': ''}
296 value = {'1_min': _NA, '5_min': _NA, '15_min': _NA, 'text': ''}
267 state = STATE_OK_DEFAULT
297 state = STATE_OK_DEFAULT
@@ -284,6 +314,7 def machine_load():
284 return SysInfoRes(value=value, state=state, human_value=human_value)
314 return SysInfoRes(value=value, state=state, human_value=human_value)
285
315
286
316
317 @register_sysinfo
287 def cpu():
318 def cpu():
288 value = {'cpu': 0, 'cpu_count': 0, 'cpu_usage': []}
319 value = {'cpu': 0, 'cpu_count': 0, 'cpu_usage': []}
289 state = STATE_OK_DEFAULT
320 state = STATE_OK_DEFAULT
@@ -302,6 +333,7 def cpu():
302 return SysInfoRes(value=value, state=state, human_value=human_value)
333 return SysInfoRes(value=value, state=state, human_value=human_value)
303
334
304
335
336 @register_sysinfo
305 def storage():
337 def storage():
306 from rhodecode.lib.helpers import format_byte_size_binary
338 from rhodecode.lib.helpers import format_byte_size_binary
307 from rhodecode.model.settings import VcsSettingsModel
339 from rhodecode.model.settings import VcsSettingsModel
@@ -337,6 +369,7 def storage():
337 return SysInfoRes(value=value, state=state, human_value=human_value)
369 return SysInfoRes(value=value, state=state, human_value=human_value)
338
370
339
371
372 @register_sysinfo
340 def storage_inodes():
373 def storage_inodes():
341 from rhodecode.model.settings import VcsSettingsModel
374 from rhodecode.model.settings import VcsSettingsModel
342 path = VcsSettingsModel().get_repos_location()
375 path = VcsSettingsModel().get_repos_location()
@@ -371,6 +404,7 def storage_inodes():
371 return SysInfoRes(value=value, state=state, human_value=human_value)
404 return SysInfoRes(value=value, state=state, human_value=human_value)
372
405
373
406
407 @register_sysinfo
374 def storage_archives():
408 def storage_archives():
375 import rhodecode
409 import rhodecode
376 from rhodecode.lib.utils import safe_str
410 from rhodecode.lib.utils import safe_str
@@ -414,6 +448,7 def storage_archives():
414 return SysInfoRes(value=value, state=state, human_value=human_value)
448 return SysInfoRes(value=value, state=state, human_value=human_value)
415
449
416
450
451 @register_sysinfo
417 def storage_gist():
452 def storage_gist():
418 from rhodecode.model.gist import GIST_STORE_LOC
453 from rhodecode.model.gist import GIST_STORE_LOC
419 from rhodecode.model.settings import VcsSettingsModel
454 from rhodecode.model.settings import VcsSettingsModel
@@ -457,6 +492,7 def storage_gist():
457 return SysInfoRes(value=value, state=state, human_value=human_value)
492 return SysInfoRes(value=value, state=state, human_value=human_value)
458
493
459
494
495 @register_sysinfo
460 def storage_temp():
496 def storage_temp():
461 import tempfile
497 import tempfile
462 from rhodecode.lib.helpers import format_byte_size_binary
498 from rhodecode.lib.helpers import format_byte_size_binary
@@ -485,6 +521,7 def storage_temp():
485 return SysInfoRes(value=value, state=state, human_value=human_value)
521 return SysInfoRes(value=value, state=state, human_value=human_value)
486
522
487
523
524 @register_sysinfo
488 def search_info():
525 def search_info():
489 import rhodecode
526 import rhodecode
490 from rhodecode.lib.index import searcher_from_config
527 from rhodecode.lib.index import searcher_from_config
@@ -508,6 +545,7 def search_info():
508 return SysInfoRes(value=value, state=state, human_value=human_value)
545 return SysInfoRes(value=value, state=state, human_value=human_value)
509
546
510
547
548 @register_sysinfo
511 def git_info():
549 def git_info():
512 from rhodecode.lib.vcs.backends import git
550 from rhodecode.lib.vcs.backends import git
513 state = STATE_OK_DEFAULT
551 state = STATE_OK_DEFAULT
@@ -521,6 +559,7 def git_info():
521 return SysInfoRes(value=value, state=state, human_value=human_value)
559 return SysInfoRes(value=value, state=state, human_value=human_value)
522
560
523
561
562 @register_sysinfo
524 def hg_info():
563 def hg_info():
525 from rhodecode.lib.vcs.backends import hg
564 from rhodecode.lib.vcs.backends import hg
526 state = STATE_OK_DEFAULT
565 state = STATE_OK_DEFAULT
@@ -533,6 +572,7 def hg_info():
533 return SysInfoRes(value=value, state=state, human_value=human_value)
572 return SysInfoRes(value=value, state=state, human_value=human_value)
534
573
535
574
575 @register_sysinfo
536 def svn_info():
576 def svn_info():
537 from rhodecode.lib.vcs.backends import svn
577 from rhodecode.lib.vcs.backends import svn
538 state = STATE_OK_DEFAULT
578 state = STATE_OK_DEFAULT
@@ -545,6 +585,7 def svn_info():
545 return SysInfoRes(value=value, state=state, human_value=human_value)
585 return SysInfoRes(value=value, state=state, human_value=human_value)
546
586
547
587
588 @register_sysinfo
548 def vcs_backends():
589 def vcs_backends():
549 import rhodecode
590 import rhodecode
550 value = rhodecode.CONFIG.get('vcs.backends')
591 value = rhodecode.CONFIG.get('vcs.backends')
@@ -552,6 +593,7 def vcs_backends():
552 return SysInfoRes(value=value, human_value=human_value)
593 return SysInfoRes(value=value, human_value=human_value)
553
594
554
595
596 @register_sysinfo
555 def vcs_server():
597 def vcs_server():
556 import rhodecode
598 import rhodecode
557 from rhodecode.lib.vcs.backends import get_vcsserver_service_data
599 from rhodecode.lib.vcs.backends import get_vcsserver_service_data
@@ -595,6 +637,7 def vcs_server():
595 return SysInfoRes(value=value, state=state, human_value=human_value)
637 return SysInfoRes(value=value, state=state, human_value=human_value)
596
638
597
639
640 @register_sysinfo
598 def vcs_server_config():
641 def vcs_server_config():
599 from rhodecode.lib.vcs.backends import get_vcsserver_service_data
642 from rhodecode.lib.vcs.backends import get_vcsserver_service_data
600 state = STATE_OK_DEFAULT
643 state = STATE_OK_DEFAULT
@@ -612,6 +655,7 def vcs_server_config():
612 return SysInfoRes(value=value, state=state, human_value=human_value)
655 return SysInfoRes(value=value, state=state, human_value=human_value)
613
656
614
657
658 @register_sysinfo
615 def rhodecode_app_info():
659 def rhodecode_app_info():
616 import rhodecode
660 import rhodecode
617 edition = rhodecode.CONFIG.get('rhodecode.edition')
661 edition = rhodecode.CONFIG.get('rhodecode.edition')
@@ -628,6 +672,7 def rhodecode_app_info():
628 return SysInfoRes(value=value, human_value=human_value)
672 return SysInfoRes(value=value, human_value=human_value)
629
673
630
674
675 @register_sysinfo
631 def rhodecode_config():
676 def rhodecode_config():
632 import rhodecode
677 import rhodecode
633 path = rhodecode.CONFIG.get('__file__')
678 path = rhodecode.CONFIG.get('__file__')
@@ -683,6 +728,7 def rhodecode_config():
683 'path': path, 'cert_path': cert_path})
728 'path': path, 'cert_path': cert_path})
684
729
685
730
731 @register_sysinfo
686 def database_info():
732 def database_info():
687 import rhodecode
733 import rhodecode
688 from sqlalchemy.engine import url as engine_url
734 from sqlalchemy.engine import url as engine_url
@@ -727,6 +773,7 def database_info():
727 return SysInfoRes(value=db_info, state=state, human_value=human_value)
773 return SysInfoRes(value=db_info, state=state, human_value=human_value)
728
774
729
775
776 @register_sysinfo
730 def server_info(environ):
777 def server_info(environ):
731 import rhodecode
778 import rhodecode
732 from rhodecode.lib.base import get_server_ip_addr, get_server_port
779 from rhodecode.lib.base import get_server_ip_addr, get_server_port
@@ -741,6 +788,7 def server_info(environ):
741 return SysInfoRes(value=value)
788 return SysInfoRes(value=value)
742
789
743
790
791 @register_sysinfo
744 def usage_info():
792 def usage_info():
745 from rhodecode.model.db import User, Repository
793 from rhodecode.model.db import User, Repository
746 value = {
794 value = {
@@ -795,3 +843,11 def get_system_info(environ):
795 'hg': SysInfo(hg_info)(),
843 'hg': SysInfo(hg_info)(),
796 'svn': SysInfo(svn_info)(),
844 'svn': SysInfo(svn_info)(),
797 }
845 }
846
847
848 def load_system_info(key):
849 """
850 get_sys_info('vcs_server')
851 get_sys_info('database')
852 """
853 return SysInfo(registered_helpers[key])()
General Comments 0
You need to be logged in to leave comments. Login now