##// END OF EJS Templates
system-info: fetch vcs settings from vcsserver. Fixes #4276...
marcink -
r1111:5dd5a063 default
parent child Browse files
Show More
This diff has been collapsed as it changes many lines, (582 lines changed) Show them Hide them
@@ -0,0 +1,582 b''
1 import os
2 import sys
3 import time
4 import platform
5 import pkg_resources
6 import logging
7
8
9 log = logging.getLogger(__name__)
10
11
12 psutil = None
13
14 try:
15 # cygwin cannot have yet psutil support.
16 import psutil as psutil
17 except ImportError:
18 pass
19
20
21 _NA = 'NOT AVAILABLE'
22
23 STATE_OK = 'ok'
24 STATE_ERR = 'error'
25 STATE_WARN = 'warning'
26
27 STATE_OK_DEFAULT = {'message': '', 'type': STATE_OK}
28
29
30 # HELPERS
31 def percentage(part, whole):
32 whole = float(whole)
33 if whole > 0:
34 return 100 * float(part) / whole
35 return 0
36
37
38 def get_storage_size(storage_path):
39 sizes = []
40 for file_ in os.listdir(storage_path):
41 storage_file = os.path.join(storage_path, file_)
42 if os.path.isfile(storage_file):
43 try:
44 sizes.append(os.path.getsize(storage_file))
45 except OSError:
46 log.exception('Failed to get size of storage file %s',
47 storage_file)
48 pass
49
50 return sum(sizes)
51
52
53 class SysInfoRes(object):
54 def __init__(self, value, state=STATE_OK_DEFAULT, human_value=None):
55 self.value = value
56 self.state = state
57 self.human_value = human_value or value
58
59 def __json__(self):
60 return {
61 'value': self.value,
62 'state': self.state,
63 'human_value': self.human_value,
64 }
65
66 def __str__(self):
67 return '<SysInfoRes({})>'.format(self.__json__())
68
69
70 class SysInfo(object):
71
72 def __init__(self, func_name, **kwargs):
73 self.func_name = func_name
74 self.value = _NA
75 self.state = None
76 self.kwargs = kwargs or {}
77
78 def __call__(self):
79 computed = self.compute(**self.kwargs)
80 if not isinstance(computed, SysInfoRes):
81 raise ValueError(
82 'computed value for {} is not instance of '
83 '{}, got {} instead'.format(
84 self.func_name, SysInfoRes, type(computed)))
85 return computed.__json__()
86
87 def __str__(self):
88 return '<SysInfo({})>'.format(self.func_name)
89
90 def compute(self, **kwargs):
91 return self.func_name(**kwargs)
92
93
94 # SysInfo functions
95 def python_info():
96 value = {
97 'version': ' '.join(platform._sys_version()),
98 'executable': sys.executable
99 }
100 return SysInfoRes(value=value)
101
102
103 def py_modules():
104 mods = dict([(p.project_name, p.version)
105 for p in pkg_resources.working_set])
106 value = sorted(mods.items(), key=lambda k: k[0].lower())
107 return SysInfoRes(value=value)
108
109
110 def platform_type():
111 from rhodecode.lib.utils import safe_unicode
112 value = safe_unicode(platform.platform())
113 return SysInfoRes(value=value)
114
115
116 def uptime():
117 from rhodecode.lib.helpers import age, time_to_datetime
118 from rhodecode.translation import _
119
120 _uptime = _uptime_human = {'boot_time': 0, 'uptime': 0}
121 state = STATE_OK_DEFAULT
122 if not psutil:
123 return SysInfoRes(value=_uptime, state=state)
124
125 boot_time = psutil.boot_time()
126 _uptime['boot_time'] = boot_time
127 _uptime['uptime'] = time.time() - boot_time
128
129 _uptime_human['boot_time'] = time_to_datetime(boot_time)
130 _uptime_human['uptime'] = _('Server started {}').format(
131 age(time_to_datetime(boot_time)))
132
133 return SysInfoRes(value=_uptime, human_value=_uptime_human)
134
135
136 def memory():
137 from rhodecode.lib.helpers import format_byte_size_binary
138 _memory = {'available': 0, 'used': 0, 'cached': 0, 'percent': 0,
139 'percent_used': 0, 'free': 0, 'inactive': 0, 'active': 0,
140 'shared': 0, 'total': 0, 'buffers': 0}
141 state = STATE_OK_DEFAULT
142 if not psutil:
143 return SysInfoRes(value=_memory, state=state)
144
145 # memory
146 _memory = dict(psutil.virtual_memory()._asdict())
147 _memory['percent_used'] = psutil._common.usage_percent(
148 (_memory['total'] - _memory['free']), _memory['total'], 1)
149
150 try:
151 human_value = '%s/%s, %s%% used' % (
152 format_byte_size_binary(_memory['used']),
153 format_byte_size_binary(_memory['total']),
154 _memory['percent_used'],)
155 except TypeError:
156 human_value = 'NOT AVAILABLE'
157
158 if state['type'] == STATE_OK and _memory['percent_used'] > 90:
159 msg = 'Critical: your available RAM memory is very low.'
160 state = {'message': msg, 'type': STATE_ERR}
161
162 elif state['type'] == STATE_OK and _memory['percent_used'] > 70:
163 msg = 'Warning: your available RAM memory is running low.'
164 state = {'message': msg, 'type': STATE_WARN}
165
166 return SysInfoRes(value=_memory, state=state, human_value=human_value)
167
168
169 def machine_load():
170 _load = {'1_min': _NA, '5_min': _NA, '15_min': _NA}
171
172 state = STATE_OK_DEFAULT
173 if not psutil:
174 return SysInfoRes(value=_load, state=state)
175
176 # load averages
177 if hasattr(psutil.os, 'getloadavg'):
178 _load = dict(zip(['1_min', '5_min', '15_min'], psutil.os.getloadavg()))
179
180 human_value = '1min: %s, 5min: %s, 15min: %s' % (
181 _load['1_min'], _load['5_min'], _load['15_min'])
182
183 # TODO: warn about too-much load 15 min
184 return SysInfoRes(value=_load, state=state, human_value=human_value)
185
186
187 def cpu():
188 state = STATE_OK_DEFAULT
189 cpu_value = 0
190 if not psutil:
191 return SysInfoRes(value=cpu_value, state=state)
192
193 cpu_value = psutil.cpu_percent(0.5)
194 human_value = '{} %'.format(cpu_value)
195 return SysInfoRes(value=cpu_value, state=state, human_value=human_value)
196
197
198 def storage():
199 from rhodecode.lib.helpers import format_byte_size_binary
200 from rhodecode.model.settings import VcsSettingsModel
201 path = VcsSettingsModel().get_repos_location()
202
203 # disk storage
204 disk = {'percent': 0, 'used': 0, 'total': 0, 'path': path, 'text': ''}
205 state = STATE_OK_DEFAULT
206 if not psutil:
207 return SysInfoRes(value=disk, state=state)
208
209 try:
210 disk.update(dict(psutil.disk_usage(path)._asdict()))
211 except Exception as e:
212 log.exception('Failed to fetch disk info')
213 state = {'message': str(e), 'type': STATE_ERR}
214
215 human_value = disk
216 human_value['text'] = "{}/{}, {}% used".format(
217 format_byte_size_binary(disk['used']),
218 format_byte_size_binary(disk['total']),
219 (disk['percent']))
220
221 if state['type'] == STATE_OK and disk['percent'] > 90:
222 msg = 'Critical: your disk space is very low.'
223 state = {'message': msg, 'type': STATE_ERR}
224
225 elif state['type'] == STATE_OK and disk['percent'] > 70:
226 msg = 'Warning: your disk space is running low.'
227 state = {'message': msg, 'type': STATE_WARN}
228
229 return SysInfoRes(value=disk, state=state, human_value=human_value)
230
231
232 def storage_inodes():
233 from rhodecode.model.settings import VcsSettingsModel
234 path = VcsSettingsModel().get_repos_location()
235
236 _disk_inodes = dict(percent=0, free=0, used=0, total=0, path=path, text='')
237 state = STATE_OK_DEFAULT
238 if not psutil:
239 return SysInfoRes(value=_disk_inodes, state=state)
240
241 try:
242 i_stat = os.statvfs(path)
243
244 _disk_inodes['used'] = i_stat.f_ffree
245 _disk_inodes['free'] = i_stat.f_favail
246 _disk_inodes['total'] = i_stat.f_files
247 _disk_inodes['percent'] = percentage(
248 _disk_inodes['used'], _disk_inodes['total'])
249 except Exception as e:
250 log.exception('Failed to fetch disk inodes info')
251 state = {'message': str(e), 'type': STATE_ERR}
252
253 human_value = _disk_inodes
254 human_value['text'] = "{}/{}, {}% used".format(
255 _disk_inodes['used'], _disk_inodes['total'], _disk_inodes['percent'])
256
257 if state['type'] == STATE_OK and _disk_inodes['percent'] > 90:
258 msg = 'Critical: your disk free inodes are very low.'
259 state = {'message': msg, 'type': STATE_ERR}
260
261 elif state['type'] == STATE_OK and _disk_inodes['percent'] > 70:
262 msg = 'Warning: your disk free inodes are running low.'
263 state = {'message': msg, 'type': STATE_WARN}
264
265 return SysInfoRes(value=_disk_inodes, state=state)
266
267
268 def storage_archives():
269 import rhodecode
270 from rhodecode.lib.utils import safe_str
271 from rhodecode.lib.helpers import format_byte_size_binary
272
273 msg = 'Enable this by setting ' \
274 'archive_cache_dir=/path/to/cache option in the .ini file'
275 path = safe_str(rhodecode.CONFIG.get('archive_cache_dir', msg))
276
277 disk_archive = dict(percent=0, used=0, total=0, items=0, path=path, text='')
278 state = STATE_OK_DEFAULT
279 try:
280 items_count = 0
281 used = 0
282 for root, dirs, files in os.walk(path):
283 if root == path:
284 items_count = len(dirs)
285
286 for f in files:
287 try:
288 used += os.path.getsize(os.path.join(root, f))
289 except OSError:
290 pass
291 disk_archive.update({
292 'percent': 100,
293 'used': used,
294 'total': used,
295 'items': items_count
296 })
297
298 except Exception as e:
299 log.exception('failed to fetch archive cache storage')
300 state = {'message': str(e), 'type': STATE_ERR}
301
302 human_value = disk_archive
303 human_value['text'] = "{} ({} items)".format(format_byte_size_binary(
304 disk_archive['used']), disk_archive['total'])
305
306 return SysInfoRes(value=disk_archive, state=state, human_value=human_value)
307
308
309 def storage_gist():
310 from rhodecode.model.gist import GIST_STORE_LOC
311 from rhodecode.model.settings import VcsSettingsModel
312 from rhodecode.lib.utils import safe_str
313 from rhodecode.lib.helpers import format_byte_size_binary
314 path = safe_str(os.path.join(
315 VcsSettingsModel().get_repos_location(), GIST_STORE_LOC))
316
317 # gist storage
318 _disk_gist = dict(percent=0, used=0, total=0, items=0, path=path, text='')
319 state = STATE_OK_DEFAULT
320
321 try:
322 items_count = 0
323 used = 0
324 for root, dirs, files in os.walk(path):
325 if root == path:
326 items_count = len(dirs)
327
328 for f in files:
329 try:
330 used += os.path.getsize(os.path.join(root, f))
331 except OSError:
332 pass
333 _disk_gist.update({
334 'percent': 100,
335 'used': used,
336 'total': used,
337 'items': items_count
338 })
339 except Exception as e:
340 log.exception('failed to fetch gist storage items')
341 state = {'message': str(e), 'type': STATE_ERR}
342
343 human_value = _disk_gist
344 human_value['text'] = "{} ({} items)".format(format_byte_size_binary(
345 _disk_gist['used']), _disk_gist['items'])
346 return SysInfoRes(value=_disk_gist, state=state, human_value=human_value)
347
348
349 def storage_search():
350 import rhodecode
351 path = rhodecode.CONFIG.get('search.location', '')
352
353 # search index storage
354 _disk_index = dict(percent=0, used=0, total=0, path=path, text='')
355 state = STATE_OK_DEFAULT
356 try:
357 search_index_storage_path_exists = os.path.isdir(path)
358 if search_index_storage_path_exists:
359 used = get_storage_size(path)
360 _disk_index.update({
361 'percent': 100,
362 'used': used,
363 'total': used,
364 })
365 except Exception as e:
366 log.exception('failed to fetch search index storage')
367 state = {'message': str(e), 'type': STATE_ERR}
368
369 human_value = _disk_index
370 human_value['text'] = "{}/{}, {}% used".format(
371 _disk_index['used'], _disk_index['total'], _disk_index['percent'])
372
373 return SysInfoRes(value=_disk_index, state=state, human_value=human_value)
374
375
376 def git_info():
377 from rhodecode.lib.vcs.backends import git
378 state = STATE_OK_DEFAULT
379 value = human_value = ''
380 try:
381 value = git.discover_git_version(raise_on_exc=True)
382 human_value = 'version reported from VCSServer: {}'.format(value)
383 except Exception as e:
384 state = {'message': str(e), 'type': STATE_ERR}
385
386 return SysInfoRes(value=value, state=state, human_value=human_value)
387
388
389 def hg_info():
390 from rhodecode.lib.vcs.backends import hg
391 state = STATE_OK_DEFAULT
392 value = human_value = ''
393 try:
394 value = hg.discover_hg_version(raise_on_exc=True)
395 human_value = 'version reported from VCSServer: {}'.format(value)
396 except Exception as e:
397 state = {'message': str(e), 'type': STATE_ERR}
398 return SysInfoRes(value=value, state=state, human_value=human_value)
399
400
401 def svn_info():
402 from rhodecode.lib.vcs.backends import svn
403 state = STATE_OK_DEFAULT
404 value = human_value = ''
405 try:
406 value = svn.discover_svn_version(raise_on_exc=True)
407 human_value = 'version reported from VCSServer: {}'.format(value)
408 except Exception as e:
409 state = {'message': str(e), 'type': STATE_ERR}
410 return SysInfoRes(value=value, state=state, human_value=human_value)
411
412
413 def vcs_backends():
414 import rhodecode
415 value = rhodecode.CONFIG.get('vcs.backends', '').split(',')
416 human_value = 'Enabled backends in order: {}'.format(','.join(value))
417 return SysInfoRes(value=value, human_value=human_value)
418
419
420 def vcs_server():
421 import rhodecode
422 from rhodecode.lib.vcs.backends import get_vcsserver_version
423
424 server_url = rhodecode.CONFIG.get('vcs.server')
425 enabled = rhodecode.CONFIG.get('vcs.server.enable')
426 protocol = rhodecode.CONFIG.get('vcs.server.protocol')
427 state = STATE_OK_DEFAULT
428 version = None
429
430 try:
431 version = get_vcsserver_version()
432 connection = 'connected'
433 except Exception as e:
434 connection = 'failed'
435 state = {'message': str(e), 'type': STATE_ERR}
436
437 value = dict(
438 url=server_url,
439 enabled=enabled,
440 protocol=protocol,
441 connection=connection,
442 version=version,
443 text='',
444 )
445
446 human_value = value
447 human_value['text'] = \
448 '{url}@ver:{ver} via {mode} mode, connection:{conn}'.format(
449 url=server_url, ver=version, mode=protocol, conn=connection)
450
451 return SysInfoRes(value='', state=state, human_value=human_value)
452
453
454 def rhodecode_app_info():
455 import rhodecode
456 return SysInfoRes(value={'rhodecode_version': rhodecode.__version__})
457
458
459 def rhodecode_config():
460 import rhodecode
461 path = rhodecode.CONFIG.get('__file__')
462 rhodecode_ini_safe = rhodecode.CONFIG.copy()
463
464 blacklist = [
465 'rhodecode_license_key',
466 'routes.map',
467 'pylons.h',
468 'pylons.app_globals',
469 'pylons.environ_config',
470 'sqlalchemy.db1.url',
471 'channelstream.secret',
472 'beaker.session.secret',
473 'rhodecode.encrypted_values.secret',
474 'rhodecode_auth_github_consumer_key',
475 'rhodecode_auth_github_consumer_secret',
476 'rhodecode_auth_google_consumer_key',
477 'rhodecode_auth_google_consumer_secret',
478 'rhodecode_auth_bitbucket_consumer_secret',
479 'rhodecode_auth_bitbucket_consumer_key',
480 'rhodecode_auth_twitter_consumer_secret',
481 'rhodecode_auth_twitter_consumer_key',
482
483 'rhodecode_auth_twitter_secret',
484 'rhodecode_auth_github_secret',
485 'rhodecode_auth_google_secret',
486 'rhodecode_auth_bitbucket_secret',
487
488 'appenlight.api_key',
489 ('app_conf', 'sqlalchemy.db1.url')
490 ]
491 for k in blacklist:
492 if isinstance(k, tuple):
493 section, key = k
494 if section in rhodecode_ini_safe:
495 rhodecode_ini_safe[section] = '**OBFUSCATED**'
496 else:
497 rhodecode_ini_safe.pop(k, None)
498
499 # TODO: maybe put some CONFIG checks here ?
500 return SysInfoRes(value={'config': rhodecode_ini_safe, 'path': path})
501
502
503 def database_info():
504 import rhodecode
505 from sqlalchemy.engine import url as engine_url
506 from rhodecode.model.meta import Base as sql_base, Session
507 from rhodecode.model.db import DbMigrateVersion
508
509 state = STATE_OK_DEFAULT
510
511 db_migrate = DbMigrateVersion.query().filter(
512 DbMigrateVersion.repository_id == 'rhodecode_db_migrations').one()
513
514 db_url_obj = engine_url.make_url(rhodecode.CONFIG['sqlalchemy.db1.url'])
515
516 try:
517 engine = sql_base.metadata.bind
518 db_server_info = engine.dialect._get_server_version_info(
519 Session.connection(bind=engine))
520 db_version = '.'.join(map(str, db_server_info))
521 except Exception:
522 log.exception('failed to fetch db version')
523 db_version = 'UNKNOWN'
524
525 db_info = dict(
526 migrate_version=db_migrate.version,
527 type=db_url_obj.get_backend_name(),
528 version=db_version,
529 url=repr(db_url_obj)
530 )
531
532 human_value = db_info
533 human_value['url'] = "{} @ migration version: {}".format(
534 db_info['url'], db_info['migrate_version'])
535 human_value['version'] = "{} {}".format(db_info['type'], db_info['version'])
536 return SysInfoRes(value=db_info, state=state, human_value=human_value)
537
538
539 def server_info(environ):
540 import rhodecode
541 from rhodecode.lib.base import get_server_ip_addr, get_server_port
542
543 value = {
544 'server_ip': '%s:%s' % (
545 get_server_ip_addr(environ, log_errors=False),
546 get_server_port(environ)
547 ),
548 'server_id': rhodecode.CONFIG.get('instance_id'),
549 }
550 return SysInfoRes(value=value)
551
552
553 def get_system_info(environ):
554 environ = environ or {}
555 return {
556 'rhodecode_app': SysInfo(rhodecode_app_info)(),
557 'rhodecode_config': SysInfo(rhodecode_config)(),
558 'python': SysInfo(python_info)(),
559 'py_modules': SysInfo(py_modules)(),
560
561 'platform': SysInfo(platform_type)(),
562 'server': SysInfo(server_info, environ=environ)(),
563 'database': SysInfo(database_info)(),
564
565 'storage': SysInfo(storage)(),
566 'storage_inodes': SysInfo(storage_inodes)(),
567 'storage_archive': SysInfo(storage_archives)(),
568 'storage_search': SysInfo(storage_search)(),
569 'storage_gist': SysInfo(storage_gist)(),
570
571 'uptime': SysInfo(uptime)(),
572 'load': SysInfo(machine_load)(),
573 'cpu': SysInfo(cpu)(),
574 'memory': SysInfo(memory)(),
575
576 'vcs_backends': SysInfo(vcs_backends)(),
577 'vcs_server': SysInfo(vcs_server)(),
578
579 'git': SysInfo(git_info)(),
580 'hg': SysInfo(hg_info)(),
581 'svn': SysInfo(svn_info)(),
582 }
@@ -0,0 +1,15 b''
1 import py.test
2
3 from rhodecode.lib.system_info import get_system_info
4
5
6 def test_system_info(app):
7 info = get_system_info({})
8 assert info['load']['value']['15_min'] != 'NOT AVAILABLE'
9
10
11 def test_system_info_without_psutil(monkeypatch, app):
12 import rhodecode.lib.system_info
13 monkeypatch.setattr(rhodecode.lib.system_info, 'psutil', None)
14 info = get_system_info({})
15 assert info['load']['value']['15_min'] == 'NOT AVAILABLE'
@@ -45,9 +45,9 b' class TestGetServerInfo(object):'
45 expected['uptime'] = resp['result']['uptime']
45 expected['uptime'] = resp['result']['uptime']
46 expected['load'] = resp['result']['load']
46 expected['load'] = resp['result']['load']
47 expected['cpu'] = resp['result']['cpu']
47 expected['cpu'] = resp['result']['cpu']
48 expected['disk'] = resp['result']['disk']
48 expected['storage'] = resp['result']['storage']
49 expected['disk_inodes'] = resp['result']['disk_inodes']
49 expected['storage_inodes'] = resp['result']['storage_inodes']
50 expected['server_ip'] = '127.0.0.1:80'
50 expected['server'] = resp['result']['server']
51
51
52 assert_ok(id_, expected, given=response.body)
52 assert_ok(id_, expected, given=response.body)
53
53
@@ -60,8 +60,8 b' class TestGetServerInfo(object):'
60 expected['uptime'] = resp['result']['uptime']
60 expected['uptime'] = resp['result']['uptime']
61 expected['load'] = resp['result']['load']
61 expected['load'] = resp['result']['load']
62 expected['cpu'] = resp['result']['cpu']
62 expected['cpu'] = resp['result']['cpu']
63 expected['disk'] = resp['result']['disk']
63 expected['storage'] = resp['result']['storage']
64 expected['disk_inodes'] = resp['result']['disk_inodes']
64 expected['storage_inodes'] = resp['result']['storage_inodes']
65 expected['server_ip'] = '127.0.0.1:80'
65 expected['server'] = resp['result']['server']
66
66
67 assert_ok(id_, expected, given=response.body)
67 assert_ok(id_, expected, given=response.body)
@@ -548,62 +548,85 b' class SettingsController(BaseController)'
548 """GET /admin/settings/system: All items in the collection"""
548 """GET /admin/settings/system: All items in the collection"""
549 # url('admin_settings_system')
549 # url('admin_settings_system')
550 snapshot = str2bool(request.GET.get('snapshot'))
550 snapshot = str2bool(request.GET.get('snapshot'))
551 c.active = 'system'
551 defaults = self._form_defaults()
552
552
553 defaults = self._form_defaults()
553 c.active = 'system'
554 c.rhodecode_ini = rhodecode.CONFIG
555 c.rhodecode_update_url = defaults.get('rhodecode_update_url')
554 c.rhodecode_update_url = defaults.get('rhodecode_update_url')
556 server_info = ScmModel().get_server_info(request.environ)
555 server_info = ScmModel().get_server_info(request.environ)
556
557 for key, val in server_info.iteritems():
557 for key, val in server_info.iteritems():
558 setattr(c, key, val)
558 setattr(c, key, val)
559
559
560 if c.disk['percent'] > 90:
560 def val(name, subkey='human_value'):
561 h.flash(h.literal(_(
561 return server_info[name][subkey]
562 'Critical: your disk space is very low <b>%s%%</b> used' %
562
563 c.disk['percent'])), 'error')
563 def state(name):
564 elif c.disk['percent'] > 70:
564 return server_info[name]['state']
565 h.flash(h.literal(_(
565
566 'Warning: your disk space is running low <b>%s%%</b> used' %
566 def val2(name):
567 c.disk['percent'])), 'warning')
567 val = server_info[name]['human_value']
568 state = server_info[name]['state']
569 return val, state
568
570
569 try:
571 c.data_items = [
570 c.uptime_age = h._age(
572 # update info
571 h.time_to_datetime(c.boot_time), False, show_suffix=False)
573 (_('Update info'), h.literal(
572 except TypeError:
574 '<span class="link" id="check_for_update" >%s.</span>' % (
573 c.uptime_age = c.boot_time
575 _('Check for updates')) +
576 '<br/> <span >%s.</span>' % (_('Note: please make sure this server can access `%s` for the update link to work') % c.rhodecode_update_url)
577 ), ''),
578
579 # RhodeCode specific
580 (_('RhodeCode Version'), c.rhodecode_version, ''),
581 (_('RhodeCode Server IP'), val('server')['server_ip'], state('server')),
582 (_('RhodeCode Server ID'), val('server')['server_id'], state('server')),
583 (_('RhodeCode Configuration'), val('rhodecode_config')['path'], state('rhodecode_config')),
584 ('', '', ''), # spacer
585
586 # Database
587 (_('Database'), val('database')['url'], state('database')),
588 (_('Database version'), val('database')['version'], state('database')),
589 ('', '', ''), # spacer
574
590
575 try:
591 # Platform/Python
576 c.system_memory = '%s/%s, %s%% (%s%%) used%s' % (
592 (_('Platform'), val('platform'), state('platform')),
577 h.format_byte_size_binary(c.memory['used']),
593 (_('Python version'), val('python')['version'], state('python')),
578 h.format_byte_size_binary(c.memory['total']),
594 (_('Python path'), val('python')['executable'], state('python')),
579 c.memory['percent2'],
595 ('', '', ''), # spacer
580 c.memory['percent'],
596
581 ' %s' % c.memory['error'] if 'error' in c.memory else '')
597 # Systems stats
582 except TypeError:
598 (_('CPU'), val('cpu'), state('cpu')),
583 c.system_memory = 'NOT AVAILABLE'
599 (_('Load'), val('load'), state('load')),
600 (_('Memory'), val('memory'), state('memory')),
601 (_('Uptime'), val('uptime')['uptime'], state('uptime')),
602 ('', '', ''), # spacer
603
604 # Repo storage
605 (_('Storage location'), val('storage')['path'], state('storage')),
606 (_('Storage info'), val('storage')['text'], state('storage')),
607 (_('Storage inodes'), val('storage_inodes')['text'], state('storage_inodes')),
584
608
585 rhodecode_ini_safe = rhodecode.CONFIG.copy()
609 (_('Gist storage location'), val('storage_gist')['path'], state('storage_gist')),
586 blacklist = [
610 (_('Gist storage info'), val('storage_gist')['text'], state('storage_gist')),
587 'rhodecode_license_key',
611
588 'routes.map',
612 (_('Archive cache storage location'), val('storage_archive')['path'], state('storage_archive')),
589 'pylons.h',
613 (_('Archive cache info'), val('storage_archive')['text'], state('storage_archive')),
590 'pylons.app_globals',
614
591 'pylons.environ_config',
615 (_('Search storage'), val('storage_search')['path'], state('storage_search')),
592 'sqlalchemy.db1.url',
616 (_('Search info'), val('storage_search')['text'], state('storage_search')),
593 ('app_conf', 'sqlalchemy.db1.url')
617 ('', '', ''), # spacer
618
619 # VCS specific
620 (_('VCS Backends'), val('vcs_backends'), state('vcs_backends')),
621 (_('VCS Server'), val('vcs_server')['text'], state('vcs_server')),
622 (_('GIT'), val('git'), state('git')),
623 (_('HG'), val('hg'), state('hg')),
624 (_('SVN'), val('svn'), state('svn')),
625
594 ]
626 ]
595 for k in blacklist:
596 if isinstance(k, tuple):
597 section, key = k
598 if section in rhodecode_ini_safe:
599 rhodecode_ini_safe[section].pop(key, None)
600 else:
601 rhodecode_ini_safe.pop(k, None)
602
603 c.rhodecode_ini_safe = rhodecode_ini_safe
604
627
605 # TODO: marcink, figure out how to allow only selected users to do this
628 # TODO: marcink, figure out how to allow only selected users to do this
606 c.allowed_to_snapshot = False
629 c.allowed_to_snapshot = c.rhodecode_user.admin
607
630
608 if snapshot:
631 if snapshot:
609 if c.allowed_to_snapshot:
632 if c.allowed_to_snapshot:
@@ -99,6 +99,7 b' def connect_pyro4(server_and_port):'
99 connection.Git = None
99 connection.Git = None
100 connection.Hg = None
100 connection.Hg = None
101 connection.Svn = None
101 connection.Svn = None
102 connection.Service = None
102
103
103
104
104 def connect_http(server_and_port):
105 def connect_http(server_and_port):
@@ -113,6 +114,8 b' def connect_http(server_and_port):'
113 server_and_port, '/hg', session_factory)
114 server_and_port, '/hg', session_factory)
114 connection.Svn = client_http.RepoMaker(
115 connection.Svn = client_http.RepoMaker(
115 server_and_port, '/svn', session_factory)
116 server_and_port, '/svn', session_factory)
117 connection.Service = client_http.ServiceConnection(
118 server_and_port, '/_service', session_factory)
116
119
117 scm_app.HG_REMOTE_WSGI = client_http.VcsHttpProxy(
120 scm_app.HG_REMOTE_WSGI = client_http.VcsHttpProxy(
118 server_and_port, '/proxy/hg')
121 server_and_port, '/proxy/hg')
@@ -124,6 +127,7 b' def connect_http(server_and_port):'
124 connection.Git = None
127 connection.Git = None
125 connection.Hg = None
128 connection.Hg = None
126 connection.Svn = None
129 connection.Svn = None
130 connection.Service = None
127
131
128
132
129 def connect_vcs(server_and_port, protocol):
133 def connect_vcs(server_and_port, protocol):
@@ -76,3 +76,12 b' def get_supported_backends():'
76 Returns list of aliases of supported backends.
76 Returns list of aliases of supported backends.
77 """
77 """
78 return settings.BACKENDS.keys()
78 return settings.BACKENDS.keys()
79
80
81 def get_vcsserver_version():
82 from rhodecode.lib.vcs import connection
83 data = connection.Service.get_vcsserver_service_data()
84 if data and 'version' in data:
85 return data['version']
86
87 return None
@@ -33,7 +33,7 b' from rhodecode.lib.vcs.backends.git.inme'
33 log = logging.getLogger(__name__)
33 log = logging.getLogger(__name__)
34
34
35
35
36 def discover_git_version():
36 def discover_git_version(raise_on_exc=False):
37 """
37 """
38 Returns the string as it was returned by running 'git --version'
38 Returns the string as it was returned by running 'git --version'
39
39
@@ -44,4 +44,6 b' def discover_git_version():'
44 return connection.Git.discover_git_version()
44 return connection.Git.discover_git_version()
45 except Exception:
45 except Exception:
46 log.warning("Failed to discover the Git version", exc_info=True)
46 log.warning("Failed to discover the Git version", exc_info=True)
47 if raise_on_exc:
48 raise
47 return ''
49 return ''
@@ -21,7 +21,28 b''
21 """
21 """
22 HG module
22 HG module
23 """
23 """
24 import logging
24
25
26 from rhodecode.lib.vcs import connection
25 from rhodecode.lib.vcs.backends.hg.commit import MercurialCommit
27 from rhodecode.lib.vcs.backends.hg.commit import MercurialCommit
26 from rhodecode.lib.vcs.backends.hg.inmemory import MercurialInMemoryCommit
28 from rhodecode.lib.vcs.backends.hg.inmemory import MercurialInMemoryCommit
27 from rhodecode.lib.vcs.backends.hg.repository import MercurialRepository
29 from rhodecode.lib.vcs.backends.hg.repository import MercurialRepository
30
31
32 log = logging.getLogger(__name__)
33
34
35 def discover_hg_version(raise_on_exc=False):
36 """
37 Returns the string as it was returned by running 'git --version'
38
39 It will return an empty string in case the connection is not initialized
40 or no vcsserver is available.
41 """
42 try:
43 return connection.Hg.discover_hg_version()
44 except Exception:
45 log.warning("Failed to discover the HG version", exc_info=True)
46 if raise_on_exc:
47 raise
48 return ''
@@ -21,6 +21,27 b''
21 """
21 """
22 SVN module
22 SVN module
23 """
23 """
24 import logging
24
25
26 from rhodecode.lib.vcs import connection
25 from rhodecode.lib.vcs.backends.svn.commit import SubversionCommit
27 from rhodecode.lib.vcs.backends.svn.commit import SubversionCommit
26 from rhodecode.lib.vcs.backends.svn.repository import SubversionRepository
28 from rhodecode.lib.vcs.backends.svn.repository import SubversionRepository
29
30
31 log = logging.getLogger(__name__)
32
33
34 def discover_svn_version(raise_on_exc=False):
35 """
36 Returns the string as it was returned by running 'git --version'
37
38 It will return an empty string in case the connection is not initialized
39 or no vcsserver is available.
40 """
41 try:
42 return connection.Svn.discover_svn_version()
43 except Exception:
44 log.warning("Failed to discover the SVN version", exc_info=True)
45 if raise_on_exc:
46 raise
47 return ''
@@ -30,6 +30,8 b' def _not_initialized(*args, **kwargs):'
30 "Make sure `vcs.server` is enabled in your configuration.")
30 "Make sure `vcs.server` is enabled in your configuration.")
31
31
32 # TODO: figure out a nice default value for these things
32 # TODO: figure out a nice default value for these things
33 Service = _not_initialized
34
33 Git = _not_initialized
35 Git = _not_initialized
34 Hg = _not_initialized
36 Hg = _not_initialized
35 Svn = _not_initialized
37 Svn = _not_initialized
@@ -25,13 +25,11 b' Scm model for RhodeCode'
25 import os.path
25 import os.path
26 import re
26 import re
27 import sys
27 import sys
28 import time
29 import traceback
28 import traceback
30 import logging
29 import logging
31 import cStringIO
30 import cStringIO
32 import pkg_resources
31 import pkg_resources
33
32
34 import pylons
35 from pylons.i18n.translation import _
33 from pylons.i18n.translation import _
36 from sqlalchemy import func
34 from sqlalchemy import func
37 from zope.cachedescriptors.property import Lazy as LazyProperty
35 from zope.cachedescriptors.property import Lazy as LazyProperty
@@ -50,12 +48,12 b' from rhodecode.lib.exceptions import Non'
50 from rhodecode.lib import hooks_utils, caches
48 from rhodecode.lib import hooks_utils, caches
51 from rhodecode.lib.utils import (
49 from rhodecode.lib.utils import (
52 get_filesystem_repos, action_logger, make_db_config)
50 get_filesystem_repos, action_logger, make_db_config)
53 from rhodecode.lib.utils2 import (
51 from rhodecode.lib.utils2 import (safe_str, safe_unicode)
54 safe_str, safe_unicode, get_server_url, md5)
52 from rhodecode.lib.system_info import get_system_info
55 from rhodecode.model import BaseModel
53 from rhodecode.model import BaseModel
56 from rhodecode.model.db import (
54 from rhodecode.model.db import (
57 Repository, CacheKey, UserFollowing, UserLog, User, RepoGroup,
55 Repository, CacheKey, UserFollowing, UserLog, User, RepoGroup,
58 PullRequest, DbMigrateVersion)
56 PullRequest)
59 from rhodecode.model.settings import VcsSettingsModel
57 from rhodecode.model.settings import VcsSettingsModel
60
58
61 log = logging.getLogger(__name__)
59 log = logging.getLogger(__name__)
@@ -882,218 +880,8 b' class ScmModel(BaseModel):'
882 self.install_svn_hooks(repo)
880 self.install_svn_hooks(repo)
883
881
884 def get_server_info(self, environ=None):
882 def get_server_info(self, environ=None):
885 import platform
883 server_info = get_system_info(environ)
886 import rhodecode
884 return server_info
887 import pkg_resources
888 from rhodecode.model.meta import Base as sql_base, Session
889 from sqlalchemy.engine import url
890 from rhodecode.lib.base import get_server_ip_addr, get_server_port
891 from rhodecode.lib.vcs.backends.git import discover_git_version
892 from rhodecode.model.gist import GIST_STORE_LOC
893
894 def percentage(part, whole):
895 whole = float(whole)
896 if whole > 0:
897 return 100 * float(part) / whole
898 return 0
899
900 try:
901 # cygwin cannot have yet psutil support.
902 import psutil
903 except ImportError:
904 psutil = None
905
906 environ = environ or {}
907 _NA = 'NOT AVAILABLE'
908 _memory = _NA
909 _uptime = _NA
910 _boot_time = _NA
911 _cpu = _NA
912 _disk = dict(percent=0, used=0, total=0, error='')
913 _disk_inodes = dict(percent=0, free=0, used=0, total=0, error='')
914 _load = {'1_min': _NA, '5_min': _NA, '15_min': _NA}
915
916 model = VcsSettingsModel()
917 storage_path = model.get_repos_location()
918 gist_storage_path = os.path.join(storage_path, GIST_STORE_LOC)
919 archive_storage_path = rhodecode.CONFIG.get('archive_cache_dir', '')
920 search_index_storage_path = rhodecode.CONFIG.get('search.location', '')
921
922 if psutil:
923 # disk storage
924 try:
925 _disk = dict(psutil.disk_usage(storage_path)._asdict())
926 except Exception as e:
927 log.exception('Failed to fetch disk info')
928 _disk = {'percent': 0, 'used': 0, 'total': 0, 'error': str(e)}
929
930 # disk inodes usage
931 try:
932 i_stat = os.statvfs(storage_path)
933
934 _disk_inodes['used'] = i_stat.f_ffree
935 _disk_inodes['free'] = i_stat.f_favail
936 _disk_inodes['total'] = i_stat.f_files
937 _disk_inodes['percent'] = percentage(
938 _disk_inodes['used'], _disk_inodes['total'])
939 except Exception as e:
940 log.exception('Failed to fetch disk inodes info')
941 _disk_inodes['error'] = str(e)
942
943 # memory
944 _memory = dict(psutil.virtual_memory()._asdict())
945 _memory['percent2'] = psutil._common.usage_percent(
946 (_memory['total'] - _memory['free']),
947 _memory['total'], 1)
948
949 # load averages
950 if hasattr(psutil.os, 'getloadavg'):
951 _load = dict(zip(
952 ['1_min', '5_min', '15_min'], psutil.os.getloadavg()))
953 _uptime = time.time() - psutil.boot_time()
954 _boot_time = psutil.boot_time()
955 _cpu = psutil.cpu_percent(0.5)
956
957 mods = dict([(p.project_name, p.version)
958 for p in pkg_resources.working_set])
959
960 def get_storage_size(storage_path):
961 sizes = []
962 for file_ in os.listdir(storage_path):
963 storage_file = os.path.join(storage_path, file_)
964 if os.path.isfile(storage_file):
965 try:
966 sizes.append(os.path.getsize(storage_file))
967 except OSError:
968 log.exception('Failed to get size of storage file %s',
969 storage_file)
970 pass
971
972 return sum(sizes)
973
974 # archive cache storage
975 _disk_archive = {'percent': 0, 'used': 0, 'total': 0}
976 try:
977 archive_storage_path_exists = os.path.isdir(
978 archive_storage_path)
979 if archive_storage_path and archive_storage_path_exists:
980 used = get_storage_size(archive_storage_path)
981 _disk_archive.update({
982 'used': used,
983 'total': used,
984 })
985 except Exception as e:
986 log.exception('failed to fetch archive cache storage')
987 _disk_archive['error'] = str(e)
988
989 # search index storage
990 _disk_index = {'percent': 0, 'used': 0, 'total': 0}
991 try:
992 search_index_storage_path_exists = os.path.isdir(
993 search_index_storage_path)
994 if search_index_storage_path_exists:
995 used = get_storage_size(search_index_storage_path)
996 _disk_index.update({
997 'percent': 100,
998 'used': used,
999 'total': used,
1000 })
1001 except Exception as e:
1002 log.exception('failed to fetch search index storage')
1003 _disk_index['error'] = str(e)
1004
1005 # gist storage
1006 _disk_gist = {'percent': 0, 'used': 0, 'total': 0, 'items': 0}
1007 try:
1008 items_count = 0
1009 used = 0
1010 for root, dirs, files in os.walk(safe_str(gist_storage_path)):
1011 if root == gist_storage_path:
1012 items_count = len(dirs)
1013
1014 for f in files:
1015 try:
1016 used += os.path.getsize(os.path.join(root, f))
1017 except OSError:
1018 pass
1019 _disk_gist.update({
1020 'percent': 100,
1021 'used': used,
1022 'total': used,
1023 'items': items_count
1024 })
1025 except Exception as e:
1026 log.exception('failed to fetch gist storage items')
1027 _disk_gist['error'] = str(e)
1028
1029 # GIT info
1030 git_ver = discover_git_version()
1031
1032 # SVN info
1033 # TODO: johbo: Add discover_svn_version to replace this code.
1034 try:
1035 import svn.core
1036 svn_ver = svn.core.SVN_VERSION
1037 except ImportError:
1038 svn_ver = None
1039
1040 # DB stuff
1041 db_info = url.make_url(rhodecode.CONFIG['sqlalchemy.db1.url'])
1042 db_type = db_info.__to_string__()
1043 try:
1044 engine = sql_base.metadata.bind
1045 db_server_info = engine.dialect._get_server_version_info(
1046 Session.connection(bind=engine))
1047 db_version = '%s %s' % (db_info.drivername,
1048 '.'.join(map(str, db_server_info)))
1049 except Exception:
1050 log.exception('failed to fetch db version')
1051 db_version = '%s %s' % (db_info.drivername, '?')
1052
1053 db_migrate = DbMigrateVersion.query().filter(
1054 DbMigrateVersion.repository_id == 'rhodecode_db_migrations').one()
1055 db_migrate_version = db_migrate.version
1056
1057 info = {
1058 'py_version': ' '.join(platform._sys_version()),
1059 'py_path': sys.executable,
1060 'py_modules': sorted(mods.items(), key=lambda k: k[0].lower()),
1061
1062 'platform': safe_unicode(platform.platform()),
1063 'storage': storage_path,
1064 'archive_storage': archive_storage_path,
1065 'index_storage': search_index_storage_path,
1066 'gist_storage': gist_storage_path,
1067
1068
1069 'db_type': db_type,
1070 'db_version': db_version,
1071 'db_migrate_version': db_migrate_version,
1072
1073 'rhodecode_version': rhodecode.__version__,
1074 'rhodecode_config_ini': rhodecode.CONFIG.get('__file__'),
1075 'server_ip': '%s:%s' % (
1076 get_server_ip_addr(environ, log_errors=False),
1077 get_server_port(environ)
1078 ),
1079 'server_id': rhodecode.CONFIG.get('instance_id'),
1080
1081 'git_version': safe_unicode(git_ver),
1082 'hg_version': mods.get('mercurial'),
1083 'svn_version': svn_ver,
1084
1085 'uptime': _uptime,
1086 'boot_time': _boot_time,
1087 'load': _load,
1088 'cpu': _cpu,
1089 'memory': _memory,
1090 'disk': _disk,
1091 'disk_inodes': _disk_inodes,
1092 'disk_archive': _disk_archive,
1093 'disk_gist': _disk_gist,
1094 'disk_index': _disk_index,
1095 }
1096 return info
1097
885
1098
886
1099 def _check_rhodecode_hook(hook_path):
887 def _check_rhodecode_hook(hook_path):
@@ -1,42 +1,3 b''
1 <%
2 elems = [
3 ## general
4 (_('RhodeCode Enterprise version'), h.literal('%s <div class="link" id="check_for_update" >%s</div>' % (c.rhodecode_version, _('check for updates'))), ''),
5 (_('Upgrade info endpoint'), h.literal('%s <br/><span >%s.</span>' % (c.rhodecode_update_url, _('Note: please make sure this server can access this url'))), ''),
6 (_('Configuration INI file'), c.rhodecode_config_ini, ''),
7 ## systems stats
8 (_('RhodeCode Enterprise Server IP'), c.server_ip, ''),
9 (_('RhodeCode Enterprise Server ID'), c.server_id, ''),
10 (_('Platform'), c.platform, ''),
11 (_('Uptime'), c.uptime_age, ''),
12 (_('Storage location'), c.storage, ''),
13 (_('Storage disk space'), "%s/%s, %s%% used%s" % (h.format_byte_size_binary(c.disk['used']), h.format_byte_size_binary(c.disk['total']),(c.disk['percent']), ' %s' % c.disk['error'] if 'error' in c.disk else ''), ''),
14 (_('Storage file limit (inodes)'), "%s/%s, %.1f%% used%s" % (c.disk_inodes['used'], c.disk_inodes['total'],(c.disk_inodes['percent']), ' %s' % c.disk_inodes['error'] if 'error' in c.disk_inodes else ''), ''),
15
16 (_('Search index storage'), c.index_storage, ''),
17 (_('Search index size'), "%s %s" % (h.format_byte_size_binary(c.disk_index['used']), ' %s' % c.disk_index['error'] if 'error' in c.disk_index else ''), ''),
18
19 (_('Gist storage'), c.gist_storage, ''),
20 (_('Gist storage size'), "%s (%s items)%s" % (h.format_byte_size_binary(c.disk_gist['used']),c.disk_gist['items'], ' %s' % c.disk_gist['error'] if 'error' in c.disk_gist else ''), ''),
21
22 (_('Archive cache'), h.literal('%s <br/><span >%s.</span>' % (c.archive_storage, _('Enable this by setting archive_cache_dir=/path/to/cache option in the .ini file'))), ''),
23 (_('Archive cache size'), "%s%s" % (h.format_byte_size_binary(c.disk_archive['used']), ' %s' % c.disk_archive['error'] if 'error' in c.disk_archive else ''), ''),
24
25 (_('System memory'), c.system_memory, ''),
26 (_('CPU'), '%s %%' %(c.cpu), ''),
27 (_('Load'), '1min: %s, 5min: %s, 15min: %s' %(c.load['1_min'],c.load['5_min'],c.load['15_min']), ''),
28
29 ## rhodecode stuff
30 (_('Python version'), c.py_version, ''),
31 (_('Python path'), c.py_path, ''),
32 (_('GIT version'), c.git_version, ''),
33 (_('HG version'), c.hg_version, ''),
34 (_('SVN version'), c.svn_version, ''),
35 (_('Database'), "%s @ version: %s" % (c.db_type, c.db_migrate_version), ''),
36 (_('Database version'), c.db_version, ''),
37
38 ]
39 %>
40
1
41 <div id="update_notice" style="display: none; margin: -40px 0px 20px 0px">
2 <div id="update_notice" style="display: none; margin: -40px 0px 20px 0px">
42 <div>${_('Checking for updates...')}</div>
3 <div>${_('Checking for updates...')}</div>
@@ -47,15 +8,21 b''
47 <div class="panel-heading">
8 <div class="panel-heading">
48 <h3 class="panel-title">${_('System Info')}</h3>
9 <h3 class="panel-title">${_('System Info')}</h3>
49 % if c.allowed_to_snapshot:
10 % if c.allowed_to_snapshot:
50 <a href="${url('admin_settings_system', snapshot=1)}" class="panel-edit">${_('create snapshot')}</a>
11 <a href="${url('admin_settings_system', snapshot=1)}" class="panel-edit">${_('create summary snapshot')}</a>
51 % endif
12 % endif
52 </div>
13 </div>
53 <div class="panel-body">
14 <div class="panel-body">
54 <dl class="dl-horizontal settings">
15 <dl class="dl-horizontal settings">
55 %for dt, dd, tt in elems:
16 % for dt, dd, warn in c.data_items:
56 <dt>${dt}:</dt>
17 <dt>${dt}${':' if dt else '---'}</dt>
57 <dd title="${tt}">${dd}</dd>
18 <dd>${dd}${'' if dt else '---'}
58 %endfor
19 % if warn and warn['message']:
20 <div class="alert-${warn['type']}">
21 <strong>${warn['message']}</strong>
22 </div>
23 % endif
24 </dd>
25 % endfor
59 </dl>
26 </dl>
60 </div>
27 </div>
61 </div>
28 </div>
@@ -71,12 +38,12 b''
71 <col class='content'>
38 <col class='content'>
72 </colgroup>
39 </colgroup>
73 <tbody>
40 <tbody>
74 %for key, value in c.py_modules:
41 % for key, value in c.py_modules['human_value']:
75 <tr>
42 <tr>
76 <td>${key}</td>
43 <td>${key}</td>
77 <td>${value}</td>
44 <td>${value}</td>
78 </tr>
45 </tr>
79 %endfor
46 % endfor
80 </tbody>
47 </tbody>
81 </table>
48 </table>
82 </div>
49 </div>
@@ -1,61 +1,27 b''
1 <%
2 elems = [
3 ## general
4 (_('RhodeCode Enterprise version'), c.rhodecode_version, ''),
5 (_('Upgrade info endpoint'), c.rhodecode_update_url, ''),
6 (_('Configuration INI file'), c.rhodecode_config_ini, ''),
7 ## systems stats
8 (_('RhodeCode Enterprise Server IP'), c.server_ip, ''),
9 (_('RhodeCode Enterprise Server ID'), c.server_id, ''),
10 (_('Platform'), c.platform, ''),
11 (_('Uptime'), c.uptime_age, ''),
12 (_('Storage location'), c.storage, ''),
13 (_('Storage disk space'), "%s/%s, %s%% used%s" % (h.format_byte_size_binary(c.disk['used']), h.format_byte_size_binary(c.disk['total']),(c.disk['percent']), ' %s' % c.disk['error'] if 'error' in c.disk else ''), ''),
14
15 (_('Search index storage'), c.index_storage, ''),
16 (_('Search index size'), "%s %s" % (h.format_byte_size_binary(c.disk_index['used']), ' %s' % c.disk_index['error'] if 'error' in c.disk_index else ''), ''),
17
18 (_('Gist storage'), c.gist_storage, ''),
19 (_('Gist storage size'), "%s (%s items)%s" % (h.format_byte_size_binary(c.disk_gist['used']),c.disk_gist['items'], ' %s' % c.disk_gist['error'] if 'error' in c.disk_gist else ''), ''),
20
21 (_('Archive cache'), c.archive_storage, ''),
22 (_('Archive cache size'), "%s%s" % (h.format_byte_size_binary(c.disk_archive['used']), ' %s' % c.disk_archive['error'] if 'error' in c.disk_archive else ''), ''),
23
24 (_('System memory'), c.system_memory, ''),
25 (_('CPU'), '%s %%' %(c.cpu), ''),
26 (_('Load'), '1min: %s, 5min: %s, 15min: %s' %(c.load['1_min'],c.load['5_min'],c.load['15_min']), ''),
27
28 ## rhodecode stuff
29 (_('Python version'), c.py_version, ''),
30 (_('Python path'), c.py_path, ''),
31 (_('GIT version'), c.git_version, ''),
32 (_('HG version'), c.hg_version, ''),
33 (_('SVN version'), c.svn_version, ''),
34 (_('Database'), "%s @ version: %s" % (c.db_type, c.db_migrate_version), ''),
35 (_('Database version'), c.db_version, ''),
36
37 ]
38 %>
39
1
40 <pre>
2 <pre>
41 SYSTEM INFO
3 SYSTEM INFO
42 -----------
4 -----------
43
5
44 % for dt, dd, tt in elems:
6 % for dt, dd, warn in c.data_items:
45 ${dt}: ${dd}
7 ${dt}${':' if dt else '---'}
8 ${dd}
9 % if warn and warn['message']:
10 ALERT_${warn['type'].upper()} ${warn['message']}
11 % endif
46 % endfor
12 % endfor
47
13
48 PYTHON PACKAGES
14 PYTHON PACKAGES
49 ---------------
15 ---------------
50
16
51 % for key, value in c.py_modules:
17 % for key, value in c.py_modules['human_value']:
52 ${key}: ${value}
18 ${key}: ${value}
53 % endfor
19 % endfor
54
20
55 SYSTEM SETTINGS
21 SYSTEM SETTINGS
56 ---------------
22 ---------------
57
23
58 % for key, value in sorted(c.rhodecode_ini_safe.items()):
24 % for key, value in sorted(c.rhodecode_config['human_value'].items()):
59 % if isinstance(value, dict):
25 % if isinstance(value, dict):
60
26
61 % for key2, value2 in value.items():
27 % for key2, value2 in value.items():
General Comments 0
You need to be logged in to leave comments. Login now