##// END OF EJS Templates
system-info: expose env variables
super-admin -
r4743:9f402145 default
parent child Browse files
Show More
@@ -1,200 +1,234 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2020 RhodeCode GmbH
3 # Copyright (C) 2016-2020 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import logging
21 import logging
22 import urllib2
22 import urllib2
23
23 import os
24
25
24
26 import rhodecode
25 import rhodecode
27 from rhodecode.apps._base import BaseAppView
26 from rhodecode.apps._base import BaseAppView
28 from rhodecode.apps._base.navigation import navigation_list
27 from rhodecode.apps._base.navigation import navigation_list
29 from rhodecode.lib import helpers as h
28 from rhodecode.lib import helpers as h
30 from rhodecode.lib.auth import (LoginRequired, HasPermissionAllDecorator)
29 from rhodecode.lib.auth import (LoginRequired, HasPermissionAllDecorator)
31 from rhodecode.lib.utils2 import str2bool
30 from rhodecode.lib.utils2 import str2bool
32 from rhodecode.lib import system_info
31 from rhodecode.lib import system_info
33 from rhodecode.model.update import UpdateModel
32 from rhodecode.model.update import UpdateModel
34
33
35 log = logging.getLogger(__name__)
34 log = logging.getLogger(__name__)
36
35
37
36
38 class AdminSystemInfoSettingsView(BaseAppView):
37 class AdminSystemInfoSettingsView(BaseAppView):
39 def load_default_context(self):
38 def load_default_context(self):
40 c = self._get_local_tmpl_context()
39 c = self._get_local_tmpl_context()
41 return c
40 return c
42
41
42 def get_env_data(self):
43 black_list = [
44 'NIX_LDFLAGS',
45 'NIX_CFLAGS_COMPILE',
46 'propagatedBuildInputs',
47 'propagatedNativeBuildInputs',
48 'postInstall',
49 'buildInputs',
50 'buildPhase',
51 'preShellHook',
52 'preShellHook',
53 'preCheck',
54 'preBuild',
55 'postShellHook',
56 'postFixup',
57 'postCheck',
58 'nativeBuildInputs',
59 'installPhase',
60 'installCheckPhase',
61 'checkPhase',
62 'configurePhase',
63 'shellHook'
64 ]
65 secret_list = [
66 'RHODECODE_USER_PASS'
67 ]
68
69 for k, v in sorted(os.environ.items()):
70 if k in black_list:
71 continue
72 if k in secret_list:
73 v = '*****'
74 yield k, v
75
43 @LoginRequired()
76 @LoginRequired()
44 @HasPermissionAllDecorator('hg.admin')
77 @HasPermissionAllDecorator('hg.admin')
45 def settings_system_info(self):
78 def settings_system_info(self):
46 _ = self.request.translate
79 _ = self.request.translate
47 c = self.load_default_context()
80 c = self.load_default_context()
48
81
49 c.active = 'system'
82 c.active = 'system'
50 c.navlist = navigation_list(self.request)
83 c.navlist = navigation_list(self.request)
51
84
52 # TODO(marcink), figure out how to allow only selected users to do this
85 # TODO(marcink), figure out how to allow only selected users to do this
53 c.allowed_to_snapshot = self._rhodecode_user.admin
86 c.allowed_to_snapshot = self._rhodecode_user.admin
54
87
55 snapshot = str2bool(self.request.params.get('snapshot'))
88 snapshot = str2bool(self.request.params.get('snapshot'))
56
89
57 c.rhodecode_update_url = UpdateModel().get_update_url()
90 c.rhodecode_update_url = UpdateModel().get_update_url()
91 c.env_data = self.get_env_data()
58 server_info = system_info.get_system_info(self.request.environ)
92 server_info = system_info.get_system_info(self.request.environ)
59
93
60 for key, val in server_info.items():
94 for key, val in server_info.items():
61 setattr(c, key, val)
95 setattr(c, key, val)
62
96
63 def val(name, subkey='human_value'):
97 def val(name, subkey='human_value'):
64 return server_info[name][subkey]
98 return server_info[name][subkey]
65
99
66 def state(name):
100 def state(name):
67 return server_info[name]['state']
101 return server_info[name]['state']
68
102
69 def val2(name):
103 def val2(name):
70 val = server_info[name]['human_value']
104 val = server_info[name]['human_value']
71 state = server_info[name]['state']
105 state = server_info[name]['state']
72 return val, state
106 return val, state
73
107
74 update_info_msg = _('Note: please make sure this server can '
108 update_info_msg = _('Note: please make sure this server can '
75 'access `${url}` for the update link to work',
109 'access `${url}` for the update link to work',
76 mapping=dict(url=c.rhodecode_update_url))
110 mapping=dict(url=c.rhodecode_update_url))
77 version = UpdateModel().get_stored_version()
111 version = UpdateModel().get_stored_version()
78 is_outdated = UpdateModel().is_outdated(
112 is_outdated = UpdateModel().is_outdated(
79 rhodecode.__version__, version)
113 rhodecode.__version__, version)
80 update_state = {
114 update_state = {
81 'type': 'warning',
115 'type': 'warning',
82 'message': 'New version available: {}'.format(version)
116 'message': 'New version available: {}'.format(version)
83 } \
117 } \
84 if is_outdated else {}
118 if is_outdated else {}
85 c.data_items = [
119 c.data_items = [
86 # update info
120 # update info
87 (_('Update info'), h.literal(
121 (_('Update info'), h.literal(
88 '<span class="link" id="check_for_update" >%s.</span>' % (
122 '<span class="link" id="check_for_update" >%s.</span>' % (
89 _('Check for updates')) +
123 _('Check for updates')) +
90 '<br/> <span >%s.</span>' % (update_info_msg)
124 '<br/> <span >%s.</span>' % (update_info_msg)
91 ), ''),
125 ), ''),
92
126
93 # RhodeCode specific
127 # RhodeCode specific
94 (_('RhodeCode Version'), val('rhodecode_app')['text'], state('rhodecode_app')),
128 (_('RhodeCode Version'), val('rhodecode_app')['text'], state('rhodecode_app')),
95 (_('Latest version'), version, update_state),
129 (_('Latest version'), version, update_state),
96 (_('RhodeCode Base URL'), val('rhodecode_config')['config'].get('app.base_url'), state('rhodecode_config')),
130 (_('RhodeCode Base URL'), val('rhodecode_config')['config'].get('app.base_url'), state('rhodecode_config')),
97 (_('RhodeCode Server IP'), val('server')['server_ip'], state('server')),
131 (_('RhodeCode Server IP'), val('server')['server_ip'], state('server')),
98 (_('RhodeCode Server ID'), val('server')['server_id'], state('server')),
132 (_('RhodeCode Server ID'), val('server')['server_id'], state('server')),
99 (_('RhodeCode Configuration'), val('rhodecode_config')['path'], state('rhodecode_config')),
133 (_('RhodeCode Configuration'), val('rhodecode_config')['path'], state('rhodecode_config')),
100 (_('RhodeCode Certificate'), val('rhodecode_config')['cert_path'], state('rhodecode_config')),
134 (_('RhodeCode Certificate'), val('rhodecode_config')['cert_path'], state('rhodecode_config')),
101 (_('Workers'), val('rhodecode_config')['config']['server:main'].get('workers', '?'), state('rhodecode_config')),
135 (_('Workers'), val('rhodecode_config')['config']['server:main'].get('workers', '?'), state('rhodecode_config')),
102 (_('Worker Type'), val('rhodecode_config')['config']['server:main'].get('worker_class', 'sync'), state('rhodecode_config')),
136 (_('Worker Type'), val('rhodecode_config')['config']['server:main'].get('worker_class', 'sync'), state('rhodecode_config')),
103 ('', '', ''), # spacer
137 ('', '', ''), # spacer
104
138
105 # Database
139 # Database
106 (_('Database'), val('database')['url'], state('database')),
140 (_('Database'), val('database')['url'], state('database')),
107 (_('Database version'), val('database')['version'], state('database')),
141 (_('Database version'), val('database')['version'], state('database')),
108 ('', '', ''), # spacer
142 ('', '', ''), # spacer
109
143
110 # Platform/Python
144 # Platform/Python
111 (_('Platform'), val('platform')['name'], state('platform')),
145 (_('Platform'), val('platform')['name'], state('platform')),
112 (_('Platform UUID'), val('platform')['uuid'], state('platform')),
146 (_('Platform UUID'), val('platform')['uuid'], state('platform')),
113 (_('Lang'), val('locale'), state('locale')),
147 (_('Lang'), val('locale'), state('locale')),
114 (_('Python version'), val('python')['version'], state('python')),
148 (_('Python version'), val('python')['version'], state('python')),
115 (_('Python path'), val('python')['executable'], state('python')),
149 (_('Python path'), val('python')['executable'], state('python')),
116 ('', '', ''), # spacer
150 ('', '', ''), # spacer
117
151
118 # Systems stats
152 # Systems stats
119 (_('CPU'), val('cpu')['text'], state('cpu')),
153 (_('CPU'), val('cpu')['text'], state('cpu')),
120 (_('Load'), val('load')['text'], state('load')),
154 (_('Load'), val('load')['text'], state('load')),
121 (_('Memory'), val('memory')['text'], state('memory')),
155 (_('Memory'), val('memory')['text'], state('memory')),
122 (_('Uptime'), val('uptime')['text'], state('uptime')),
156 (_('Uptime'), val('uptime')['text'], state('uptime')),
123 ('', '', ''), # spacer
157 ('', '', ''), # spacer
124
158
125 # ulimit
159 # ulimit
126 (_('Ulimit'), val('ulimit')['text'], state('ulimit')),
160 (_('Ulimit'), val('ulimit')['text'], state('ulimit')),
127
161
128 # Repo storage
162 # Repo storage
129 (_('Storage location'), val('storage')['path'], state('storage')),
163 (_('Storage location'), val('storage')['path'], state('storage')),
130 (_('Storage info'), val('storage')['text'], state('storage')),
164 (_('Storage info'), val('storage')['text'], state('storage')),
131 (_('Storage inodes'), val('storage_inodes')['text'], state('storage_inodes')),
165 (_('Storage inodes'), val('storage_inodes')['text'], state('storage_inodes')),
132
166
133 (_('Gist storage location'), val('storage_gist')['path'], state('storage_gist')),
167 (_('Gist storage location'), val('storage_gist')['path'], state('storage_gist')),
134 (_('Gist storage info'), val('storage_gist')['text'], state('storage_gist')),
168 (_('Gist storage info'), val('storage_gist')['text'], state('storage_gist')),
135
169
136 (_('Archive cache storage location'), val('storage_archive')['path'], state('storage_archive')),
170 (_('Archive cache storage location'), val('storage_archive')['path'], state('storage_archive')),
137 (_('Archive cache info'), val('storage_archive')['text'], state('storage_archive')),
171 (_('Archive cache info'), val('storage_archive')['text'], state('storage_archive')),
138
172
139 (_('Temp storage location'), val('storage_temp')['path'], state('storage_temp')),
173 (_('Temp storage location'), val('storage_temp')['path'], state('storage_temp')),
140 (_('Temp storage info'), val('storage_temp')['text'], state('storage_temp')),
174 (_('Temp storage info'), val('storage_temp')['text'], state('storage_temp')),
141
175
142 (_('Search info'), val('search')['text'], state('search')),
176 (_('Search info'), val('search')['text'], state('search')),
143 (_('Search location'), val('search')['location'], state('search')),
177 (_('Search location'), val('search')['location'], state('search')),
144 ('', '', ''), # spacer
178 ('', '', ''), # spacer
145
179
146 # VCS specific
180 # VCS specific
147 (_('VCS Backends'), val('vcs_backends'), state('vcs_backends')),
181 (_('VCS Backends'), val('vcs_backends'), state('vcs_backends')),
148 (_('VCS Server'), val('vcs_server')['text'], state('vcs_server')),
182 (_('VCS Server'), val('vcs_server')['text'], state('vcs_server')),
149 (_('GIT'), val('git'), state('git')),
183 (_('GIT'), val('git'), state('git')),
150 (_('HG'), val('hg'), state('hg')),
184 (_('HG'), val('hg'), state('hg')),
151 (_('SVN'), val('svn'), state('svn')),
185 (_('SVN'), val('svn'), state('svn')),
152
186
153 ]
187 ]
154
188
155 c.vcsserver_data_items = [
189 c.vcsserver_data_items = [
156 (k, v) for k,v in (val('vcs_server_config') or {}).items()
190 (k, v) for k,v in (val('vcs_server_config') or {}).items()
157 ]
191 ]
158
192
159 if snapshot:
193 if snapshot:
160 if c.allowed_to_snapshot:
194 if c.allowed_to_snapshot:
161 c.data_items.pop(0) # remove server info
195 c.data_items.pop(0) # remove server info
162 self.request.override_renderer = 'admin/settings/settings_system_snapshot.mako'
196 self.request.override_renderer = 'admin/settings/settings_system_snapshot.mako'
163 else:
197 else:
164 h.flash('You are not allowed to do this', category='warning')
198 h.flash('You are not allowed to do this', category='warning')
165 return self._get_template_context(c)
199 return self._get_template_context(c)
166
200
167 @LoginRequired()
201 @LoginRequired()
168 @HasPermissionAllDecorator('hg.admin')
202 @HasPermissionAllDecorator('hg.admin')
169 def settings_system_info_check_update(self):
203 def settings_system_info_check_update(self):
170 _ = self.request.translate
204 _ = self.request.translate
171 c = self.load_default_context()
205 c = self.load_default_context()
172
206
173 update_url = UpdateModel().get_update_url()
207 update_url = UpdateModel().get_update_url()
174
208
175 _err = lambda s: '<div style="color:#ff8888; padding:4px 0px">{}</div>'.format(s)
209 _err = lambda s: '<div style="color:#ff8888; padding:4px 0px">{}</div>'.format(s)
176 try:
210 try:
177 data = UpdateModel().get_update_data(update_url)
211 data = UpdateModel().get_update_data(update_url)
178 except urllib2.URLError as e:
212 except urllib2.URLError as e:
179 log.exception("Exception contacting upgrade server")
213 log.exception("Exception contacting upgrade server")
180 self.request.override_renderer = 'string'
214 self.request.override_renderer = 'string'
181 return _err('Failed to contact upgrade server: %r' % e)
215 return _err('Failed to contact upgrade server: %r' % e)
182 except ValueError as e:
216 except ValueError as e:
183 log.exception("Bad data sent from update server")
217 log.exception("Bad data sent from update server")
184 self.request.override_renderer = 'string'
218 self.request.override_renderer = 'string'
185 return _err('Bad data sent from update server')
219 return _err('Bad data sent from update server')
186
220
187 latest = data['versions'][0]
221 latest = data['versions'][0]
188
222
189 c.update_url = update_url
223 c.update_url = update_url
190 c.latest_data = latest
224 c.latest_data = latest
191 c.latest_ver = latest['version']
225 c.latest_ver = latest['version']
192 c.cur_ver = rhodecode.__version__
226 c.cur_ver = rhodecode.__version__
193 c.should_upgrade = False
227 c.should_upgrade = False
194
228
195 is_oudated = UpdateModel().is_outdated(c.cur_ver, c.latest_ver)
229 is_oudated = UpdateModel().is_outdated(c.cur_ver, c.latest_ver)
196 if is_oudated:
230 if is_oudated:
197 c.should_upgrade = True
231 c.should_upgrade = True
198 c.important_notices = latest['general']
232 c.important_notices = latest['general']
199 UpdateModel().store_version(latest['version'])
233 UpdateModel().store_version(latest['version'])
200 return self._get_template_context(c)
234 return self._get_template_context(c)
@@ -1,70 +1,89 b''
1
1
2 <div id="update_notice" style="display: none; margin: 0px 0px 30px 0px">
2 <div id="update_notice" style="display: none; margin: 0px 0px 30px 0px">
3 <div>${_('Checking for updates...')}</div>
3 <div>${_('Checking for updates...')}</div>
4 </div>
4 </div>
5
5
6
6
7 <div class="panel panel-default">
7 <div class="panel panel-default">
8 <div class="panel-heading">
8 <div class="panel-heading">
9 <h3 class="panel-title">${_('System Info')}</h3>
9 <h3 class="panel-title">${_('System Info')}</h3>
10 % if c.allowed_to_snapshot:
10 % if c.allowed_to_snapshot:
11 <a href="${h.route_path('admin_settings_system', _query={'snapshot':1})}" class="panel-edit">${_('create summary snapshot')}</a>
11 <a href="${h.route_path('admin_settings_system', _query={'snapshot':1})}" class="panel-edit">${_('create summary snapshot')}</a>
12 % endif
12 % endif
13 </div>
13 </div>
14 <div class="panel-body">
14 <div class="panel-body">
15 <dl class="dl-horizontal settings dt-400">
15 <dl class="dl-horizontal settings dt-400">
16 % for dt, dd, warn in c.data_items:
16 % for dt, dd, warn in c.data_items:
17 <dt>${dt}${':' if dt else '---'}</dt>
17 <dt>${dt}${':' if dt else '---'}</dt>
18 <dd>${dd}${'' if dt else '---'}
18 <dd>${dd}${'' if dt else '---'}
19 % if warn and warn['message']:
19 % if warn and warn['message']:
20 <div class="alert-${warn['type']}">
20 <div class="alert-${warn['type']}">
21 <strong>${warn['message']}</strong>
21 <strong>${warn['message']}</strong>
22 </div>
22 </div>
23 % endif
23 % endif
24 </dd>
24 </dd>
25 % endfor
25 % endfor
26 </dl>
26 </dl>
27 </div>
27 </div>
28 </div>
28 </div>
29
29
30 <div class="panel panel-default">
30 <div class="panel panel-default">
31 <div class="panel-heading">
31 <div class="panel-heading">
32 <h3 class="panel-title">${_('VCS Server')}</h3>
32 <h3 class="panel-title">${_('VCS Server')}</h3>
33 </div>
33 </div>
34 <div class="panel-body">
34 <div class="panel-body">
35 <dl class="dl-horizontal settings dt-400">
35 <dl class="dl-horizontal settings dt-400">
36 % for dt, dd in c.vcsserver_data_items:
36 % for dt, dd in c.vcsserver_data_items:
37 <dt>${dt}${':' if dt else '---'}</dt>
37 <dt>${dt}${':' if dt else '---'}</dt>
38 <dd>${dd}${'' if dt else '---'}</dd>
38 <dd>${dd}${'' if dt else '---'}</dd>
39 % endfor
39 % endfor
40 </dl>
40 </dl>
41 </div>
41 </div>
42 </div>
42 </div>
43
43
44 <div class="panel panel-default">
44 <div class="panel panel-default">
45 <div class="panel-heading">
45 <div class="panel-heading">
46 <h3 class="panel-title">${_('Python Packages')}</h3>
46 <h3 class="panel-title">${_('Python Packages')}</h3>
47 </div>
47 </div>
48 <div class="panel-body">
48 <div class="panel-body">
49 <table>
49 <table>
50 <th></th>
50 <th></th>
51 <th></th>
51 <th></th>
52 <th></th>
52 <th></th>
53 % for name, package_data in c.py_modules['human_value']:
53 % for name, package_data in c.py_modules['human_value']:
54 <tr>
54 <tr>
55 <td>${name.lower()}</td>
55 <td>${name.lower()}</td>
56 <td>${package_data['version']}</td>
56 <td>${package_data['version']}</td>
57 <td>(${package_data['location']})</td>
57 <td>(${package_data['location']})</td>
58 </tr>
58 </tr>
59 % endfor
59 % endfor
60 </table>
60 </table>
61
61
62 </div>
62 </div>
63 </div>
63 </div>
64
64
65 <div class="panel panel-default">
66 <div class="panel-heading">
67 <h3 class="panel-title">${_('Env Variables')}</h3>
68 </div>
69 <div class="panel-body">
70 <table>
71 <th></th>
72 <th></th>
73 % for env_key, env_val in c.env_data:
74 <tr>
75 <td style="vertical-align: top">${env_key}</td>
76 <td>${env_val}</td>
77 </tr>
78 % endfor
79 </table>
80
81 </div>
82 </div>
83
65 <script>
84 <script>
66 $('#check_for_update').click(function(e){
85 $('#check_for_update').click(function(e){
67 $('#update_notice').show();
86 $('#update_notice').show();
68 $('#update_notice').load("${h.route_path('admin_settings_system_update')}");
87 $('#update_notice').load("${h.route_path('admin_settings_system_update')}");
69 })
88 })
70 </script>
89 </script>
General Comments 0
You need to be logged in to leave comments. Login now