system_info.py
234 lines
| 9.3 KiB
| text/x-python
|
PythonLexer
r1503 | # -*- coding: utf-8 -*- | |||
r4306 | # Copyright (C) 2016-2020 RhodeCode GmbH | |||
r1503 | # | |||
# This program is free software: you can redistribute it and/or modify | ||||
# it under the terms of the GNU Affero General Public License, version 3 | ||||
# (only), as published by the Free Software Foundation. | ||||
# | ||||
# This program is distributed in the hope that it will be useful, | ||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
# GNU General Public License for more details. | ||||
# | ||||
# You should have received a copy of the GNU Affero General Public License | ||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
# | ||||
# This program is dual-licensed. If you wish to learn more about the | ||||
# RhodeCode Enterprise Edition, including its added features, Support services, | ||||
# and proprietary license terms, please see https://rhodecode.com/licenses/ | ||||
import logging | ||||
r4914 | import urllib.request, urllib.error, urllib.parse | |||
r4743 | import os | |||
r1503 | ||||
import rhodecode | ||||
r1511 | from rhodecode.apps._base import BaseAppView | |||
r3238 | from rhodecode.apps._base.navigation import navigation_list | |||
r1503 | from rhodecode.lib import helpers as h | |||
from rhodecode.lib.auth import (LoginRequired, HasPermissionAllDecorator) | ||||
from rhodecode.lib.utils2 import str2bool | ||||
from rhodecode.lib import system_info | ||||
r2431 | from rhodecode.model.update import UpdateModel | |||
r1503 | ||||
log = logging.getLogger(__name__) | ||||
r1511 | class AdminSystemInfoSettingsView(BaseAppView): | |||
r1782 | def load_default_context(self): | |||
c = self._get_local_tmpl_context() | ||||
return c | ||||
r1503 | ||||
r4743 | def get_env_data(self): | |||
black_list = [ | ||||
'NIX_LDFLAGS', | ||||
'NIX_CFLAGS_COMPILE', | ||||
'propagatedBuildInputs', | ||||
'propagatedNativeBuildInputs', | ||||
'postInstall', | ||||
'buildInputs', | ||||
'buildPhase', | ||||
'preShellHook', | ||||
'preShellHook', | ||||
'preCheck', | ||||
'preBuild', | ||||
'postShellHook', | ||||
'postFixup', | ||||
'postCheck', | ||||
'nativeBuildInputs', | ||||
'installPhase', | ||||
'installCheckPhase', | ||||
'checkPhase', | ||||
'configurePhase', | ||||
'shellHook' | ||||
] | ||||
secret_list = [ | ||||
'RHODECODE_USER_PASS' | ||||
] | ||||
for k, v in sorted(os.environ.items()): | ||||
if k in black_list: | ||||
continue | ||||
if k in secret_list: | ||||
v = '*****' | ||||
yield k, v | ||||
r1503 | @LoginRequired() | |||
@HasPermissionAllDecorator('hg.admin') | ||||
def settings_system_info(self): | ||||
_ = self.request.translate | ||||
r1782 | c = self.load_default_context() | |||
r1503 | ||||
c.active = 'system' | ||||
c.navlist = navigation_list(self.request) | ||||
# TODO(marcink), figure out how to allow only selected users to do this | ||||
c.allowed_to_snapshot = self._rhodecode_user.admin | ||||
snapshot = str2bool(self.request.params.get('snapshot')) | ||||
r2431 | c.rhodecode_update_url = UpdateModel().get_update_url() | |||
r4743 | c.env_data = self.get_env_data() | |||
r1503 | server_info = system_info.get_system_info(self.request.environ) | |||
for key, val in server_info.items(): | ||||
setattr(c, key, val) | ||||
def val(name, subkey='human_value'): | ||||
return server_info[name][subkey] | ||||
def state(name): | ||||
return server_info[name]['state'] | ||||
def val2(name): | ||||
val = server_info[name]['human_value'] | ||||
state = server_info[name]['state'] | ||||
return val, state | ||||
update_info_msg = _('Note: please make sure this server can ' | ||||
'access `${url}` for the update link to work', | ||||
mapping=dict(url=c.rhodecode_update_url)) | ||||
r2431 | version = UpdateModel().get_stored_version() | |||
is_outdated = UpdateModel().is_outdated( | ||||
rhodecode.__version__, version) | ||||
update_state = { | ||||
'type': 'warning', | ||||
'message': 'New version available: {}'.format(version) | ||||
} \ | ||||
if is_outdated else {} | ||||
r1503 | c.data_items = [ | |||
# update info | ||||
(_('Update info'), h.literal( | ||||
'<span class="link" id="check_for_update" >%s.</span>' % ( | ||||
_('Check for updates')) + | ||||
'<br/> <span >%s.</span>' % (update_info_msg) | ||||
), ''), | ||||
# RhodeCode specific | ||||
(_('RhodeCode Version'), val('rhodecode_app')['text'], state('rhodecode_app')), | ||||
r2431 | (_('Latest version'), version, update_state), | |||
r3292 | (_('RhodeCode Base URL'), val('rhodecode_config')['config'].get('app.base_url'), state('rhodecode_config')), | |||
r1503 | (_('RhodeCode Server IP'), val('server')['server_ip'], state('server')), | |||
(_('RhodeCode Server ID'), val('server')['server_id'], state('server')), | ||||
(_('RhodeCode Configuration'), val('rhodecode_config')['path'], state('rhodecode_config')), | ||||
r1729 | (_('RhodeCode Certificate'), val('rhodecode_config')['cert_path'], state('rhodecode_config')), | |||
r1503 | (_('Workers'), val('rhodecode_config')['config']['server:main'].get('workers', '?'), state('rhodecode_config')), | |||
(_('Worker Type'), val('rhodecode_config')['config']['server:main'].get('worker_class', 'sync'), state('rhodecode_config')), | ||||
('', '', ''), # spacer | ||||
# Database | ||||
(_('Database'), val('database')['url'], state('database')), | ||||
(_('Database version'), val('database')['version'], state('database')), | ||||
('', '', ''), # spacer | ||||
# Platform/Python | ||||
(_('Platform'), val('platform')['name'], state('platform')), | ||||
(_('Platform UUID'), val('platform')['uuid'], state('platform')), | ||||
r2914 | (_('Lang'), val('locale'), state('locale')), | |||
r1503 | (_('Python version'), val('python')['version'], state('python')), | |||
(_('Python path'), val('python')['executable'], state('python')), | ||||
('', '', ''), # spacer | ||||
# Systems stats | ||||
(_('CPU'), val('cpu')['text'], state('cpu')), | ||||
(_('Load'), val('load')['text'], state('load')), | ||||
(_('Memory'), val('memory')['text'], state('memory')), | ||||
(_('Uptime'), val('uptime')['text'], state('uptime')), | ||||
('', '', ''), # spacer | ||||
r2673 | # ulimit | |||
(_('Ulimit'), val('ulimit')['text'], state('ulimit')), | ||||
r1503 | # Repo storage | |||
(_('Storage location'), val('storage')['path'], state('storage')), | ||||
(_('Storage info'), val('storage')['text'], state('storage')), | ||||
(_('Storage inodes'), val('storage_inodes')['text'], state('storage_inodes')), | ||||
(_('Gist storage location'), val('storage_gist')['path'], state('storage_gist')), | ||||
(_('Gist storage info'), val('storage_gist')['text'], state('storage_gist')), | ||||
(_('Archive cache storage location'), val('storage_archive')['path'], state('storage_archive')), | ||||
(_('Archive cache info'), val('storage_archive')['text'], state('storage_archive')), | ||||
(_('Temp storage location'), val('storage_temp')['path'], state('storage_temp')), | ||||
(_('Temp storage info'), val('storage_temp')['text'], state('storage_temp')), | ||||
(_('Search info'), val('search')['text'], state('search')), | ||||
(_('Search location'), val('search')['location'], state('search')), | ||||
('', '', ''), # spacer | ||||
# VCS specific | ||||
(_('VCS Backends'), val('vcs_backends'), state('vcs_backends')), | ||||
(_('VCS Server'), val('vcs_server')['text'], state('vcs_server')), | ||||
(_('GIT'), val('git'), state('git')), | ||||
(_('HG'), val('hg'), state('hg')), | ||||
(_('SVN'), val('svn'), state('svn')), | ||||
] | ||||
r3943 | c.vcsserver_data_items = [ | |||
(k, v) for k,v in (val('vcs_server_config') or {}).items() | ||||
] | ||||
r1503 | if snapshot: | |||
if c.allowed_to_snapshot: | ||||
c.data_items.pop(0) # remove server info | ||||
self.request.override_renderer = 'admin/settings/settings_system_snapshot.mako' | ||||
else: | ||||
r2366 | h.flash('You are not allowed to do this', category='warning') | |||
r1782 | return self._get_template_context(c) | |||
r1503 | ||||
@LoginRequired() | ||||
@HasPermissionAllDecorator('hg.admin') | ||||
def settings_system_info_check_update(self): | ||||
_ = self.request.translate | ||||
r1782 | c = self.load_default_context() | |||
r1503 | ||||
r2431 | update_url = UpdateModel().get_update_url() | |||
r1503 | ||||
_err = lambda s: '<div style="color:#ff8888; padding:4px 0px">{}</div>'.format(s) | ||||
try: | ||||
r2431 | data = UpdateModel().get_update_data(update_url) | |||
r4914 | except urllib.error.URLError as e: | |||
r1503 | log.exception("Exception contacting upgrade server") | |||
self.request.override_renderer = 'string' | ||||
return _err('Failed to contact upgrade server: %r' % e) | ||||
except ValueError as e: | ||||
log.exception("Bad data sent from update server") | ||||
self.request.override_renderer = 'string' | ||||
return _err('Bad data sent from update server') | ||||
latest = data['versions'][0] | ||||
c.update_url = update_url | ||||
c.latest_data = latest | ||||
c.latest_ver = latest['version'] | ||||
c.cur_ver = rhodecode.__version__ | ||||
c.should_upgrade = False | ||||
r2431 | is_oudated = UpdateModel().is_outdated(c.cur_ver, c.latest_ver) | |||
if is_oudated: | ||||
r1503 | c.should_upgrade = True | |||
c.important_notices = latest['general'] | ||||
r2431 | UpdateModel().store_version(latest['version']) | |||
r1782 | return self._get_template_context(c) | |||