]> git.proxmox.com Git - proxmox-backup.git/blame - www/ServerStatus.js
Merge branch '3.2.6'
[proxmox-backup.git] / www / ServerStatus.js
CommitLineData
880fa939
DM
1Ext.define('pve-rrd-node', {
2 extend: 'Ext.data.Model',
3 fields: [
4 {
5 name: 'cpu',
6 // percentage
7 convert: function(value) {
8 return value*100;
8acd4d9a 9 },
880fa939
DM
10 },
11 {
12 name: 'iowait',
13 // percentage
14 convert: function(value) {
15 return value*100;
8acd4d9a 16 },
880fa939
DM
17 },
18 'netin',
19 'netout',
20 'memtotal',
21 'memused',
22 'swaptotal',
23 'swapused',
c94e1f65
DM
24 'total',
25 'used',
26 'read_ios',
27 'read_bytes',
28 'write_ios',
29 'write_bytes',
30 'io_ticks',
31 {
32 name: 'io_delay', calculate: function(data) {
33 let ios = 0;
34 if (data.read_ios !== undefined) { ios += data.read_ios; }
35 if (data.write_ios !== undefined) { ios += data.write_ios; }
8acd4d9a 36 if (ios === 0 || data.io_ticks === undefined) {
c94e1f65
DM
37 return undefined;
38 }
39 return (data.io_ticks*1000.0)/ios;
8acd4d9a 40 },
c94e1f65 41 },
880fa939 42 'loadavg',
8acd4d9a
TL
43 { type: 'date', dateFormat: 'timestamp', name: 'time' },
44 ],
880fa939 45});
ecb53af6
DM
46Ext.define('PBS.ServerStatus', {
47 extend: 'Ext.panel.Panel',
48 alias: 'widget.pbsServerStatus',
49
d0e3f5dd 50 title: gettext('Server Status'),
ecb53af6 51
880fa939 52 scrollable: true,
ecb53af6 53
82422c11
TL
54 showVersions: function() {
55 let me = this;
56
57 // Note: use simply text/html here, as ExtJS grid has problems with cut&paste
58 let panel = Ext.createWidget('component', {
59 autoScroll: true,
60 id: 'pkgversions',
61 padding: 5,
62 style: {
82422c11
TL
63 'white-space': 'pre',
64 'font-family': 'monospace',
65 },
66 });
67
68 let win = Ext.create('Ext.window.Window', {
69 title: gettext('Package versions'),
70 width: 600,
71 height: 600,
72 layout: 'fit',
73 modal: true,
74 items: [panel],
75 buttons: [
76 {
77 xtype: 'button',
78 iconCls: 'fa fa-clipboard',
e66d75ca
GG
79 handler: async function(button) {
80 let el = document.getElementById('pkgversions');
81 await navigator.clipboard.writeText(el.textContent);
82422c11
TL
82 },
83 text: gettext('Copy'),
84 },
85 {
86 text: gettext('Ok'),
87 handler: function() {
88 this.up('window').close();
89 },
90 },
91 ],
92 });
93
94 Proxmox.Utils.API2Request({
95 waitMsgTarget: me,
96 url: `/nodes/localhost/apt/versions`,
97 method: 'GET',
98 failure: function(response, opts) {
99 win.close();
100 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
101 },
102 success: function(response, opts) {
103 let text = '';
104 Ext.Array.each(response.result.data, function(rec) {
105 let version = "not correctly installed";
106 let pkg = rec.Package;
107 if (rec.OldVersion && rec.OldVersion !== 'unknown') {
108 version = rec.OldVersion;
109 }
110 if (rec.ExtraInfo) {
111 text += `${pkg}: ${version} (${rec.ExtraInfo})\n`;
112 } else {
113 text += `${pkg}: ${version}\n`;
114 }
115 });
116
117 win.show();
118 panel.update(Ext.htmlEncode(text));
119 },
120 });
121 },
122
ecb53af6
DM
123 initComponent: function() {
124 var me = this;
125
126 var node_command = function(cmd) {
127 Proxmox.Utils.API2Request({
128 params: { command: cmd },
129 url: '/nodes/localhost/status',
130 method: 'POST',
131 waitMsgTarget: me,
132 failure: function(response, opts) {
133 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
8acd4d9a 134 },
ecb53af6
DM
135 });
136 };
137
138 var restartBtn = Ext.create('Proxmox.button.Button', {
139 text: gettext('Reboot'),
140 dangerous: true,
141 confirmMsg: gettext("Reboot backup server?"),
142 handler: function() {
143 node_command('reboot');
144 },
8acd4d9a 145 iconCls: 'fa fa-undo',
ecb53af6
DM
146 });
147
148 var shutdownBtn = Ext.create('Proxmox.button.Button', {
149 text: gettext('Shutdown'),
150 dangerous: true,
151 confirmMsg: gettext("Shutdown backup server?"),
152 handler: function() {
153 node_command('shutdown');
154 },
8acd4d9a 155 iconCls: 'fa fa-power-off',
ecb53af6
DM
156 });
157
653e2031
DC
158 var consoleBtn = Ext.create('Proxmox.button.Button', {
159 text: gettext('Console'),
160 iconCls: 'fa fa-terminal',
161 handler: function() {
162 Proxmox.Utils.openXtermJsViewer('shell', 0, Proxmox.NodeName);
8acd4d9a 163 },
653e2031
DC
164 });
165
82422c11
TL
166 let version_btn = new Ext.Button({
167 text: gettext('Package versions'),
168 iconCls: 'fa fa-gift',
169 handler: function() {
170 Proxmox.Utils.checked_command(function() { me.showVersions(); });
171 },
172 });
173
174 me.tbar = [version_btn, '-', consoleBtn, '-', restartBtn, shutdownBtn, '->', { xtype: 'proxmoxRRDTypeSelector' }];
880fa939
DM
175
176 var rrdstore = Ext.create('Proxmox.data.RRDStore', {
177 rrdurl: "/api2/json/nodes/localhost/rrd",
8acd4d9a 178 model: 'pve-rrd-node',
880fa939
DM
179 });
180
181 me.items = {
182 xtype: 'container',
183 itemId: 'itemcontainer',
184 layout: 'column',
185 minWidth: 700,
01284de0
DC
186 listeners: {
187 resize: function(panel) {
188 Proxmox.Utils.updateColumns(panel);
189 },
190 },
880fa939
DM
191 defaults: {
192 minHeight: 320,
193 padding: 5,
8acd4d9a 194 columnWidth: 1,
880fa939
DM
195 },
196 items: [
197 {
198 xtype: 'proxmoxRRDChart',
199 title: gettext('CPU usage'),
8acd4d9a 200 fields: ['cpu', 'iowait'],
947f4525 201 fieldTitles: [gettext('CPU usage'), gettext('IO wait')],
8acd4d9a 202 store: rrdstore,
880fa939
DM
203 },
204 {
205 xtype: 'proxmoxRRDChart',
206 title: gettext('Server load'),
207 fields: ['loadavg'],
208 fieldTitles: [gettext('Load average')],
8acd4d9a 209 store: rrdstore,
880fa939
DM
210 },
211 {
212 xtype: 'proxmoxRRDChart',
213 title: gettext('Memory usage'),
8acd4d9a 214 fields: ['memtotal', 'memused'],
880fa939 215 fieldTitles: [gettext('Total'), gettext('RAM usage')],
16e60558
TL
216 unit: 'bytes',
217 powerOfTwo: true,
8acd4d9a 218 store: rrdstore,
880fa939
DM
219 },
220 {
221 xtype: 'proxmoxRRDChart',
222 title: gettext('Swap usage'),
8acd4d9a 223 fields: ['swaptotal', 'swapused'],
880fa939 224 fieldTitles: [gettext('Total'), gettext('Swap usage')],
16e60558
TL
225 unit: 'bytes',
226 powerOfTwo: true,
8acd4d9a 227 store: rrdstore,
880fa939
DM
228 },
229 {
230 xtype: 'proxmoxRRDChart',
231 title: gettext('Network traffic'),
8acd4d9a
TL
232 fields: ['netin', 'netout'],
233 store: rrdstore,
880fa939
DM
234 },
235 {
236 xtype: 'proxmoxRRDChart',
237 title: gettext('Root Disk usage'),
8acd4d9a 238 fields: ['total', 'used'],
880fa939 239 fieldTitles: [gettext('Total'), gettext('Disk usage')],
8acd4d9a 240 store: rrdstore,
880fa939 241 },
91e5bb49
DM
242 {
243 xtype: 'proxmoxRRDChart',
244 title: gettext('Root Disk Transfer Rate (bytes/second)'),
8acd4d9a 245 fields: ['read_bytes', 'write_bytes'],
91e5bb49 246 fieldTitles: [gettext('Read'), gettext('Write')],
8acd4d9a 247 store: rrdstore,
91e5bb49
DM
248 },
249 {
250 xtype: 'proxmoxRRDChart',
251 title: gettext('Root Disk Input/Output Operations per Second (IOPS)'),
8acd4d9a 252 fields: ['read_ios', 'write_ios'],
91e5bb49 253 fieldTitles: [gettext('Read'), gettext('Write')],
8acd4d9a 254 store: rrdstore,
91e5bb49
DM
255 },
256 {
257 xtype: 'proxmoxRRDChart',
258 title: gettext('Root Disk IO Delay (ms)'),
c94e1f65
DM
259 fields: ['io_delay'],
260 fieldTitles: [gettext('IO Delay')],
8acd4d9a 261 store: rrdstore,
91e5bb49 262 },
8acd4d9a 263 ],
880fa939
DM
264 };
265
266 me.listeners = {
267 activate: function() {
268 rrdstore.startUpdate();
269 },
270 destroy: function() {
271 rrdstore.stopUpdate();
272 },
273 };
ecb53af6
DM
274
275 me.callParent();
01284de0
DC
276
277 let sp = Ext.state.Manager.getProvider();
278 me.mon(sp, 'statechange', function(provider, key, value) {
279 if (key !== 'summarycolumns') {
280 return;
281 }
282 Proxmox.Utils.updateColumns(me.getComponent('itemcontainer'));
283 });
8acd4d9a 284 },
ecb53af6
DM
285
286});