##// END OF EJS Templates
system-info: expose workers of vcsserver in system info data.
marcink -
r1465:c65ff93e default
parent child Browse files
Show More
@@ -1,684 +1,693 b''
1 1 import os
2 2 import sys
3 3 import time
4 4 import platform
5 5 import pkg_resources
6 6 import logging
7 7 import string
8 8
9 9
10 10 log = logging.getLogger(__name__)
11 11
12 12
13 13 psutil = None
14 14
15 15 try:
16 16 # cygwin cannot have yet psutil support.
17 17 import psutil as psutil
18 18 except ImportError:
19 19 pass
20 20
21 21
22 22 _NA = 'NOT AVAILABLE'
23 23
24 24 STATE_OK = 'ok'
25 25 STATE_ERR = 'error'
26 26 STATE_WARN = 'warning'
27 27
28 28 STATE_OK_DEFAULT = {'message': '', 'type': STATE_OK}
29 29
30 30
31 31 # HELPERS
32 32 def percentage(part, whole):
33 33 whole = float(whole)
34 34 if whole > 0:
35 35 return round(100 * float(part) / whole, 1)
36 36 return 0.0
37 37
38 38
39 39 def get_storage_size(storage_path):
40 40 sizes = []
41 41 for file_ in os.listdir(storage_path):
42 42 storage_file = os.path.join(storage_path, file_)
43 43 if os.path.isfile(storage_file):
44 44 try:
45 45 sizes.append(os.path.getsize(storage_file))
46 46 except OSError:
47 47 log.exception('Failed to get size of storage file %s',
48 48 storage_file)
49 49 pass
50 50
51 51 return sum(sizes)
52 52
53 53
54 54 class SysInfoRes(object):
55 55 def __init__(self, value, state=STATE_OK_DEFAULT, human_value=None):
56 56 self.value = value
57 57 self.state = state
58 58 self.human_value = human_value or value
59 59
60 60 def __json__(self):
61 61 return {
62 62 'value': self.value,
63 63 'state': self.state,
64 64 'human_value': self.human_value,
65 65 }
66 66
67 67 def get_value(self):
68 68 return self.__json__()
69 69
70 70 def __str__(self):
71 71 return '<SysInfoRes({})>'.format(self.__json__())
72 72
73 73
74 74 class SysInfo(object):
75 75
76 76 def __init__(self, func_name, **kwargs):
77 77 self.func_name = func_name
78 78 self.value = _NA
79 79 self.state = None
80 80 self.kwargs = kwargs or {}
81 81
82 82 def __call__(self):
83 83 computed = self.compute(**self.kwargs)
84 84 if not isinstance(computed, SysInfoRes):
85 85 raise ValueError(
86 86 'computed value for {} is not instance of '
87 87 '{}, got {} instead'.format(
88 88 self.func_name, SysInfoRes, type(computed)))
89 89 return computed.__json__()
90 90
91 91 def __str__(self):
92 92 return '<SysInfo({})>'.format(self.func_name)
93 93
94 94 def compute(self, **kwargs):
95 95 return self.func_name(**kwargs)
96 96
97 97
98 98 # SysInfo functions
99 99 def python_info():
100 100 value = dict(version=' '.join(platform._sys_version()),
101 101 executable=sys.executable)
102 102 return SysInfoRes(value=value)
103 103
104 104
105 105 def py_modules():
106 106 mods = dict([(p.project_name, p.version)
107 107 for p in pkg_resources.working_set])
108 108 value = sorted(mods.items(), key=lambda k: k[0].lower())
109 109 return SysInfoRes(value=value)
110 110
111 111
112 112 def platform_type():
113 113 from rhodecode.lib.utils import safe_unicode, generate_platform_uuid
114 114
115 115 value = dict(
116 116 name=safe_unicode(platform.platform()),
117 117 uuid=generate_platform_uuid()
118 118 )
119 119 return SysInfoRes(value=value)
120 120
121 121
122 122 def uptime():
123 123 from rhodecode.lib.helpers import age, time_to_datetime
124 124 from rhodecode.translation import TranslationString
125 125
126 126 value = dict(boot_time=0, uptime=0, text='')
127 127 state = STATE_OK_DEFAULT
128 128 if not psutil:
129 129 return SysInfoRes(value=value, state=state)
130 130
131 131 boot_time = psutil.boot_time()
132 132 value['boot_time'] = boot_time
133 133 value['uptime'] = time.time() - boot_time
134 134
135 135 date_or_age = age(time_to_datetime(boot_time))
136 136 if isinstance(date_or_age, TranslationString):
137 137 date_or_age = date_or_age.interpolate()
138 138
139 139 human_value = value.copy()
140 140 human_value['boot_time'] = time_to_datetime(boot_time)
141 141 human_value['uptime'] = age(time_to_datetime(boot_time), show_suffix=False)
142 142
143 143 human_value['text'] = u'Server started {}'.format(date_or_age)
144 144 return SysInfoRes(value=value, human_value=human_value)
145 145
146 146
147 147 def memory():
148 148 from rhodecode.lib.helpers import format_byte_size_binary
149 149 value = dict(available=0, used=0, used_real=0, cached=0, percent=0,
150 150 percent_used=0, free=0, inactive=0, active=0, shared=0,
151 151 total=0, buffers=0, text='')
152 152
153 153 state = STATE_OK_DEFAULT
154 154 if not psutil:
155 155 return SysInfoRes(value=value, state=state)
156 156
157 157 value.update(dict(psutil.virtual_memory()._asdict()))
158 158 value['used_real'] = value['total'] - value['available']
159 159 value['percent_used'] = psutil._common.usage_percent(
160 160 value['used_real'], value['total'], 1)
161 161
162 162 human_value = value.copy()
163 163 human_value['text'] = '%s/%s, %s%% used' % (
164 164 format_byte_size_binary(value['used_real']),
165 165 format_byte_size_binary(value['total']),
166 166 value['percent_used'],)
167 167
168 168 keys = value.keys()[::]
169 169 keys.pop(keys.index('percent'))
170 170 keys.pop(keys.index('percent_used'))
171 171 keys.pop(keys.index('text'))
172 172 for k in keys:
173 173 human_value[k] = format_byte_size_binary(value[k])
174 174
175 175 if state['type'] == STATE_OK and value['percent_used'] > 90:
176 176 msg = 'Critical: your available RAM memory is very low.'
177 177 state = {'message': msg, 'type': STATE_ERR}
178 178
179 179 elif state['type'] == STATE_OK and value['percent_used'] > 70:
180 180 msg = 'Warning: your available RAM memory is running low.'
181 181 state = {'message': msg, 'type': STATE_WARN}
182 182
183 183 return SysInfoRes(value=value, state=state, human_value=human_value)
184 184
185 185
186 186 def machine_load():
187 187 value = {'1_min': _NA, '5_min': _NA, '15_min': _NA, 'text': ''}
188 188 state = STATE_OK_DEFAULT
189 189 if not psutil:
190 190 return SysInfoRes(value=value, state=state)
191 191
192 192 # load averages
193 193 if hasattr(psutil.os, 'getloadavg'):
194 194 value.update(dict(
195 195 zip(['1_min', '5_min', '15_min'], psutil.os.getloadavg())))
196 196
197 197 human_value = value.copy()
198 198 human_value['text'] = '1min: {}, 5min: {}, 15min: {}'.format(
199 199 value['1_min'], value['5_min'], value['15_min'])
200 200
201 201 if state['type'] == STATE_OK and value['15_min'] > 5:
202 202 msg = 'Warning: your machine load is very high.'
203 203 state = {'message': msg, 'type': STATE_WARN}
204 204
205 205 return SysInfoRes(value=value, state=state, human_value=human_value)
206 206
207 207
208 208 def cpu():
209 209 value = {'cpu': 0, 'cpu_count': 0, 'cpu_usage': []}
210 210 state = STATE_OK_DEFAULT
211 211
212 212 if not psutil:
213 213 return SysInfoRes(value=value, state=state)
214 214
215 215 value['cpu'] = psutil.cpu_percent(0.5)
216 216 value['cpu_usage'] = psutil.cpu_percent(0.5, percpu=True)
217 217 value['cpu_count'] = psutil.cpu_count()
218 218
219 219 human_value = value.copy()
220 220 human_value['text'] = '{} cores at {} %'.format(
221 221 value['cpu_count'], value['cpu'])
222 222
223 223 return SysInfoRes(value=value, state=state, human_value=human_value)
224 224
225 225
226 226 def storage():
227 227 from rhodecode.lib.helpers import format_byte_size_binary
228 228 from rhodecode.model.settings import VcsSettingsModel
229 229 path = VcsSettingsModel().get_repos_location()
230 230
231 231 value = dict(percent=0, used=0, total=0, path=path, text='')
232 232 state = STATE_OK_DEFAULT
233 233 if not psutil:
234 234 return SysInfoRes(value=value, state=state)
235 235
236 236 try:
237 237 value.update(dict(psutil.disk_usage(path)._asdict()))
238 238 except Exception as e:
239 239 log.exception('Failed to fetch disk info')
240 240 state = {'message': str(e), 'type': STATE_ERR}
241 241
242 242 human_value = value.copy()
243 243 human_value['used'] = format_byte_size_binary(value['used'])
244 244 human_value['total'] = format_byte_size_binary(value['total'])
245 245 human_value['text'] = "{}/{}, {}% used".format(
246 246 format_byte_size_binary(value['used']),
247 247 format_byte_size_binary(value['total']),
248 248 value['percent'])
249 249
250 250 if state['type'] == STATE_OK and value['percent'] > 90:
251 251 msg = 'Critical: your disk space is very low.'
252 252 state = {'message': msg, 'type': STATE_ERR}
253 253
254 254 elif state['type'] == STATE_OK and value['percent'] > 70:
255 255 msg = 'Warning: your disk space is running low.'
256 256 state = {'message': msg, 'type': STATE_WARN}
257 257
258 258 return SysInfoRes(value=value, state=state, human_value=human_value)
259 259
260 260
261 261 def storage_inodes():
262 262 from rhodecode.model.settings import VcsSettingsModel
263 263 path = VcsSettingsModel().get_repos_location()
264 264
265 265 value = dict(percent=0, free=0, used=0, total=0, path=path, text='')
266 266 state = STATE_OK_DEFAULT
267 267 if not psutil:
268 268 return SysInfoRes(value=value, state=state)
269 269
270 270 try:
271 271 i_stat = os.statvfs(path)
272 272 value['free'] = i_stat.f_ffree
273 273 value['used'] = i_stat.f_files-i_stat.f_favail
274 274 value['total'] = i_stat.f_files
275 275 value['percent'] = percentage(value['used'], value['total'])
276 276 except Exception as e:
277 277 log.exception('Failed to fetch disk inodes info')
278 278 state = {'message': str(e), 'type': STATE_ERR}
279 279
280 280 human_value = value.copy()
281 281 human_value['text'] = "{}/{}, {}% used".format(
282 282 value['used'], value['total'], value['percent'])
283 283
284 284 if state['type'] == STATE_OK and value['percent'] > 90:
285 285 msg = 'Critical: your disk free inodes are very low.'
286 286 state = {'message': msg, 'type': STATE_ERR}
287 287
288 288 elif state['type'] == STATE_OK and value['percent'] > 70:
289 289 msg = 'Warning: your disk free inodes are running low.'
290 290 state = {'message': msg, 'type': STATE_WARN}
291 291
292 292 return SysInfoRes(value=value, state=state, human_value=human_value)
293 293
294 294
295 295 def storage_archives():
296 296 import rhodecode
297 297 from rhodecode.lib.utils import safe_str
298 298 from rhodecode.lib.helpers import format_byte_size_binary
299 299
300 300 msg = 'Enable this by setting ' \
301 301 'archive_cache_dir=/path/to/cache option in the .ini file'
302 302 path = safe_str(rhodecode.CONFIG.get('archive_cache_dir', msg))
303 303
304 304 value = dict(percent=0, used=0, total=0, items=0, path=path, text='')
305 305 state = STATE_OK_DEFAULT
306 306 try:
307 307 items_count = 0
308 308 used = 0
309 309 for root, dirs, files in os.walk(path):
310 310 if root == path:
311 311 items_count = len(files)
312 312
313 313 for f in files:
314 314 try:
315 315 used += os.path.getsize(os.path.join(root, f))
316 316 except OSError:
317 317 pass
318 318 value.update({
319 319 'percent': 100,
320 320 'used': used,
321 321 'total': used,
322 322 'items': items_count
323 323 })
324 324
325 325 except Exception as e:
326 326 log.exception('failed to fetch archive cache storage')
327 327 state = {'message': str(e), 'type': STATE_ERR}
328 328
329 329 human_value = value.copy()
330 330 human_value['used'] = format_byte_size_binary(value['used'])
331 331 human_value['total'] = format_byte_size_binary(value['total'])
332 332 human_value['text'] = "{} ({} items)".format(
333 333 human_value['used'], value['items'])
334 334
335 335 return SysInfoRes(value=value, state=state, human_value=human_value)
336 336
337 337
338 338 def storage_gist():
339 339 from rhodecode.model.gist import GIST_STORE_LOC
340 340 from rhodecode.model.settings import VcsSettingsModel
341 341 from rhodecode.lib.utils import safe_str
342 342 from rhodecode.lib.helpers import format_byte_size_binary
343 343 path = safe_str(os.path.join(
344 344 VcsSettingsModel().get_repos_location(), GIST_STORE_LOC))
345 345
346 346 # gist storage
347 347 value = dict(percent=0, used=0, total=0, items=0, path=path, text='')
348 348 state = STATE_OK_DEFAULT
349 349
350 350 try:
351 351 items_count = 0
352 352 used = 0
353 353 for root, dirs, files in os.walk(path):
354 354 if root == path:
355 355 items_count = len(dirs)
356 356
357 357 for f in files:
358 358 try:
359 359 used += os.path.getsize(os.path.join(root, f))
360 360 except OSError:
361 361 pass
362 362 value.update({
363 363 'percent': 100,
364 364 'used': used,
365 365 'total': used,
366 366 'items': items_count
367 367 })
368 368 except Exception as e:
369 369 log.exception('failed to fetch gist storage items')
370 370 state = {'message': str(e), 'type': STATE_ERR}
371 371
372 372 human_value = value.copy()
373 373 human_value['used'] = format_byte_size_binary(value['used'])
374 374 human_value['total'] = format_byte_size_binary(value['total'])
375 375 human_value['text'] = "{} ({} items)".format(
376 376 human_value['used'], value['items'])
377 377
378 378 return SysInfoRes(value=value, state=state, human_value=human_value)
379 379
380 380
381 381 def storage_temp():
382 382 import tempfile
383 383 from rhodecode.lib.helpers import format_byte_size_binary
384 384
385 385 path = tempfile.gettempdir()
386 386 value = dict(percent=0, used=0, total=0, items=0, path=path, text='')
387 387 state = STATE_OK_DEFAULT
388 388
389 389 if not psutil:
390 390 return SysInfoRes(value=value, state=state)
391 391
392 392 try:
393 393 value.update(dict(psutil.disk_usage(path)._asdict()))
394 394 except Exception as e:
395 395 log.exception('Failed to fetch temp dir info')
396 396 state = {'message': str(e), 'type': STATE_ERR}
397 397
398 398 human_value = value.copy()
399 399 human_value['used'] = format_byte_size_binary(value['used'])
400 400 human_value['total'] = format_byte_size_binary(value['total'])
401 401 human_value['text'] = "{}/{}, {}% used".format(
402 402 format_byte_size_binary(value['used']),
403 403 format_byte_size_binary(value['total']),
404 404 value['percent'])
405 405
406 406 return SysInfoRes(value=value, state=state, human_value=human_value)
407 407
408 408
409 409 def search_info():
410 410 import rhodecode
411 411 from rhodecode.lib.index import searcher_from_config
412 412
413 413 backend = rhodecode.CONFIG.get('search.module', '')
414 414 location = rhodecode.CONFIG.get('search.location', '')
415 415
416 416 try:
417 417 searcher = searcher_from_config(rhodecode.CONFIG)
418 418 searcher = searcher.__class__.__name__
419 419 except Exception:
420 420 searcher = None
421 421
422 422 value = dict(
423 423 backend=backend, searcher=searcher, location=location, text='')
424 424 state = STATE_OK_DEFAULT
425 425
426 426 human_value = value.copy()
427 427 human_value['text'] = "backend:`{}`".format(human_value['backend'])
428 428
429 429 return SysInfoRes(value=value, state=state, human_value=human_value)
430 430
431 431
432 432 def git_info():
433 433 from rhodecode.lib.vcs.backends import git
434 434 state = STATE_OK_DEFAULT
435 435 value = human_value = ''
436 436 try:
437 437 value = git.discover_git_version(raise_on_exc=True)
438 438 human_value = 'version reported from VCSServer: {}'.format(value)
439 439 except Exception as e:
440 440 state = {'message': str(e), 'type': STATE_ERR}
441 441
442 442 return SysInfoRes(value=value, state=state, human_value=human_value)
443 443
444 444
445 445 def hg_info():
446 446 from rhodecode.lib.vcs.backends import hg
447 447 state = STATE_OK_DEFAULT
448 448 value = human_value = ''
449 449 try:
450 450 value = hg.discover_hg_version(raise_on_exc=True)
451 451 human_value = 'version reported from VCSServer: {}'.format(value)
452 452 except Exception as e:
453 453 state = {'message': str(e), 'type': STATE_ERR}
454 454 return SysInfoRes(value=value, state=state, human_value=human_value)
455 455
456 456
457 457 def svn_info():
458 458 from rhodecode.lib.vcs.backends import svn
459 459 state = STATE_OK_DEFAULT
460 460 value = human_value = ''
461 461 try:
462 462 value = svn.discover_svn_version(raise_on_exc=True)
463 463 human_value = 'version reported from VCSServer: {}'.format(value)
464 464 except Exception as e:
465 465 state = {'message': str(e), 'type': STATE_ERR}
466 466 return SysInfoRes(value=value, state=state, human_value=human_value)
467 467
468 468
469 469 def vcs_backends():
470 470 import rhodecode
471 471 value = map(
472 472 string.strip, rhodecode.CONFIG.get('vcs.backends', '').split(','))
473 473 human_value = 'Enabled backends in order: {}'.format(','.join(value))
474 474 return SysInfoRes(value=value, human_value=human_value)
475 475
476 476
477 477 def vcs_server():
478 478 import rhodecode
479 from rhodecode.lib.vcs.backends import get_vcsserver_version
479 from rhodecode.lib.vcs.backends import get_vcsserver_service_data
480 480
481 481 server_url = rhodecode.CONFIG.get('vcs.server')
482 482 enabled = rhodecode.CONFIG.get('vcs.server.enable')
483 483 protocol = rhodecode.CONFIG.get('vcs.server.protocol') or 'http'
484 484 state = STATE_OK_DEFAULT
485 485 version = None
486 workers = 0
486 487
487 488 try:
488 version = get_vcsserver_version()
489 data = get_vcsserver_service_data()
490 if data and 'version' in data:
491 version = data['version']
492
493 if data and 'config' in data:
494 conf = data['config']
495 workers = conf.get('workers', '?')
496
489 497 connection = 'connected'
490 498 except Exception as e:
491 499 connection = 'failed'
492 500 state = {'message': str(e), 'type': STATE_ERR}
493 501
494 502 value = dict(
495 503 url=server_url,
496 504 enabled=enabled,
497 505 protocol=protocol,
498 506 connection=connection,
499 507 version=version,
500 508 text='',
501 509 )
502 510
503 511 human_value = value.copy()
504 512 human_value['text'] = \
505 '{url}@ver:{ver} via {mode} mode, connection:{conn}'.format(
506 url=server_url, ver=version, mode=protocol, conn=connection)
513 '{url}@ver:{ver} via {mode} mode[workers:{workers}], connection:{conn}'.format(
514 url=server_url, ver=version, workers=workers, mode=protocol,
515 conn=connection)
507 516
508 517 return SysInfoRes(value=value, state=state, human_value=human_value)
509 518
510 519
511 520 def rhodecode_app_info():
512 521 import rhodecode
513 522 edition = rhodecode.CONFIG.get('rhodecode.edition')
514 523
515 524 value = dict(
516 525 rhodecode_version=rhodecode.__version__,
517 526 rhodecode_lib_path=os.path.abspath(rhodecode.__file__),
518 527 text=''
519 528 )
520 529 human_value = value.copy()
521 530 human_value['text'] = 'RhodeCode {edition}, version {ver}'.format(
522 531 edition=edition, ver=value['rhodecode_version']
523 532 )
524 533 return SysInfoRes(value=value, human_value=human_value)
525 534
526 535
527 536 def rhodecode_config():
528 537 import rhodecode
529 import ConfigParser
538 import ConfigParser as configparser
530 539 path = rhodecode.CONFIG.get('__file__')
531 540 rhodecode_ini_safe = rhodecode.CONFIG.copy()
532 541
533 542 try:
534 config = ConfigParser.ConfigParser()
543 config = configparser.ConfigParser()
535 544 config.read(path)
536 545 parsed_ini = config
537 546 if parsed_ini.has_section('server:main'):
538 547 parsed_ini = dict(parsed_ini.items('server:main'))
539 548 except Exception:
540 549 log.exception('Failed to read .ini file for display')
541 550 parsed_ini = {}
542 551
543 552 rhodecode_ini_safe['server:main'] = parsed_ini
544 553
545 554 blacklist = [
546 555 'rhodecode_license_key',
547 556 'routes.map',
548 557 'pylons.h',
549 558 'pylons.app_globals',
550 559 'pylons.environ_config',
551 560 'sqlalchemy.db1.url',
552 561 'channelstream.secret',
553 562 'beaker.session.secret',
554 563 'rhodecode.encrypted_values.secret',
555 564 'rhodecode_auth_github_consumer_key',
556 565 'rhodecode_auth_github_consumer_secret',
557 566 'rhodecode_auth_google_consumer_key',
558 567 'rhodecode_auth_google_consumer_secret',
559 568 'rhodecode_auth_bitbucket_consumer_secret',
560 569 'rhodecode_auth_bitbucket_consumer_key',
561 570 'rhodecode_auth_twitter_consumer_secret',
562 571 'rhodecode_auth_twitter_consumer_key',
563 572
564 573 'rhodecode_auth_twitter_secret',
565 574 'rhodecode_auth_github_secret',
566 575 'rhodecode_auth_google_secret',
567 576 'rhodecode_auth_bitbucket_secret',
568 577
569 578 'appenlight.api_key',
570 579 ('app_conf', 'sqlalchemy.db1.url')
571 580 ]
572 581 for k in blacklist:
573 582 if isinstance(k, tuple):
574 583 section, key = k
575 584 if section in rhodecode_ini_safe:
576 585 rhodecode_ini_safe[section] = '**OBFUSCATED**'
577 586 else:
578 587 rhodecode_ini_safe.pop(k, None)
579 588
580 589 # TODO: maybe put some CONFIG checks here ?
581 590 return SysInfoRes(value={'config': rhodecode_ini_safe, 'path': path})
582 591
583 592
584 593 def database_info():
585 594 import rhodecode
586 595 from sqlalchemy.engine import url as engine_url
587 596 from rhodecode.model.meta import Base as sql_base, Session
588 597 from rhodecode.model.db import DbMigrateVersion
589 598
590 599 state = STATE_OK_DEFAULT
591 600
592 601 db_migrate = DbMigrateVersion.query().filter(
593 602 DbMigrateVersion.repository_id == 'rhodecode_db_migrations').one()
594 603
595 604 db_url_obj = engine_url.make_url(rhodecode.CONFIG['sqlalchemy.db1.url'])
596 605
597 606 try:
598 607 engine = sql_base.metadata.bind
599 608 db_server_info = engine.dialect._get_server_version_info(
600 609 Session.connection(bind=engine))
601 610 db_version = '.'.join(map(str, db_server_info))
602 611 except Exception:
603 612 log.exception('failed to fetch db version')
604 613 db_version = 'UNKNOWN'
605 614
606 615 db_info = dict(
607 616 migrate_version=db_migrate.version,
608 617 type=db_url_obj.get_backend_name(),
609 618 version=db_version,
610 619 url=repr(db_url_obj)
611 620 )
612 621
613 622 human_value = db_info.copy()
614 623 human_value['url'] = "{} @ migration version: {}".format(
615 624 db_info['url'], db_info['migrate_version'])
616 625 human_value['version'] = "{} {}".format(db_info['type'], db_info['version'])
617 626 return SysInfoRes(value=db_info, state=state, human_value=human_value)
618 627
619 628
620 629 def server_info(environ):
621 630 import rhodecode
622 631 from rhodecode.lib.base import get_server_ip_addr, get_server_port
623 632
624 633 value = {
625 634 'server_ip': '%s:%s' % (
626 635 get_server_ip_addr(environ, log_errors=False),
627 636 get_server_port(environ)
628 637 ),
629 638 'server_id': rhodecode.CONFIG.get('instance_id'),
630 639 }
631 640 return SysInfoRes(value=value)
632 641
633 642
634 643 def usage_info():
635 644 from rhodecode.model.db import User, Repository
636 645 value = {
637 646 'users': User.query().count(),
638 647 'users_active': User.query().filter(User.active == True).count(),
639 648 'repositories': Repository.query().count(),
640 649 'repository_types': {
641 650 'hg': Repository.query().filter(
642 651 Repository.repo_type == 'hg').count(),
643 652 'git': Repository.query().filter(
644 653 Repository.repo_type == 'git').count(),
645 654 'svn': Repository.query().filter(
646 655 Repository.repo_type == 'svn').count(),
647 656 },
648 657 }
649 658 return SysInfoRes(value=value)
650 659
651 660
652 661 def get_system_info(environ):
653 662 environ = environ or {}
654 663 return {
655 664 'rhodecode_app': SysInfo(rhodecode_app_info)(),
656 665 'rhodecode_config': SysInfo(rhodecode_config)(),
657 666 'rhodecode_usage': SysInfo(usage_info)(),
658 667 'python': SysInfo(python_info)(),
659 668 'py_modules': SysInfo(py_modules)(),
660 669
661 670 'platform': SysInfo(platform_type)(),
662 671 'server': SysInfo(server_info, environ=environ)(),
663 672 'database': SysInfo(database_info)(),
664 673
665 674 'storage': SysInfo(storage)(),
666 675 'storage_inodes': SysInfo(storage_inodes)(),
667 676 'storage_archive': SysInfo(storage_archives)(),
668 677 'storage_gist': SysInfo(storage_gist)(),
669 678 'storage_temp': SysInfo(storage_temp)(),
670 679
671 680 'search': SysInfo(search_info)(),
672 681
673 682 'uptime': SysInfo(uptime)(),
674 683 'load': SysInfo(machine_load)(),
675 684 'cpu': SysInfo(cpu)(),
676 685 'memory': SysInfo(memory)(),
677 686
678 687 'vcs_backends': SysInfo(vcs_backends)(),
679 688 'vcs_server': SysInfo(vcs_server)(),
680 689
681 690 'git': SysInfo(git_info)(),
682 691 'hg': SysInfo(hg_info)(),
683 692 'svn': SysInfo(svn_info)(),
684 693 }
@@ -1,98 +1,95 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2014-2017 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21 """
22 22 VCS Backends module
23 23 """
24 24
25 25 import os
26 26 import logging
27 27
28 28 from pprint import pformat
29 29
30 30 from rhodecode.lib.vcs.conf import settings
31 31 from rhodecode.lib.vcs.exceptions import VCSError
32 32 from rhodecode.lib.vcs.utils.helpers import get_scm
33 33 from rhodecode.lib.vcs.utils.imports import import_class
34 34
35 35
36 36 log = logging.getLogger(__name__)
37 37
38 38
39 39 def get_vcs_instance(repo_path, *args, **kwargs):
40 40 """
41 41 Given a path to a repository an instance of the corresponding vcs backend
42 42 repository class is created and returned. If no repository can be found
43 43 for the path it returns None. Arguments and keyword arguments are passed
44 44 to the vcs backend repository class.
45 45 """
46 46 from rhodecode.lib.utils2 import safe_str
47 47
48 48 explicit_vcs_alias = kwargs.pop('_vcs_alias', None)
49 49 try:
50 50 vcs_alias = safe_str(explicit_vcs_alias or get_scm(repo_path)[0])
51 51 log.debug(
52 52 'Creating instance of %s repository from %s', vcs_alias,
53 53 safe_str(repo_path))
54 54 backend = get_backend(vcs_alias)
55 55
56 56 if explicit_vcs_alias:
57 57 # do final verification of existance of the path, this does the
58 58 # same as get_scm() call which we skip in explicit_vcs_alias
59 59 if not os.path.isdir(repo_path):
60 60 raise VCSError("Given path %s is not a directory" % repo_path)
61 61 except VCSError:
62 62 log.exception(
63 63 'Perhaps this repository is in db and not in '
64 64 'filesystem run rescan repositories with '
65 65 '"destroy old data" option from admin panel')
66 66 return None
67 67
68 68 return backend(repo_path=repo_path, *args, **kwargs)
69 69
70 70
71 71 def get_backend(alias):
72 72 """
73 73 Returns ``Repository`` class identified by the given alias or raises
74 74 VCSError if alias is not recognized or backend class cannot be imported.
75 75 """
76 76 if alias not in settings.BACKENDS:
77 77 raise VCSError(
78 78 "Given alias '%s' is not recognized! Allowed aliases:\n%s" %
79 79 (alias, pformat(settings.BACKENDS.keys())))
80 80 backend_path = settings.BACKENDS[alias]
81 81 klass = import_class(backend_path)
82 82 return klass
83 83
84 84
85 85 def get_supported_backends():
86 86 """
87 87 Returns list of aliases of supported backends.
88 88 """
89 89 return settings.BACKENDS.keys()
90 90
91 91
92 def get_vcsserver_version():
92 def get_vcsserver_service_data():
93 93 from rhodecode.lib.vcs import connection
94 data = connection.Service.get_vcsserver_service_data()
95 if data and 'version' in data:
96 return data['version']
94 return connection.Service.get_vcsserver_service_data()
97 95
98 return None
General Comments 0
You need to be logged in to leave comments. Login now