]> git.proxmox.com Git - pve-manager.git/blame - www/manager6/ceph/Status.js
adapt the health message list to luminous
[pve-manager.git] / www / manager6 / ceph / Status.js
CommitLineData
bd39c945 1Ext.define('PVE.node.CephStatus', {
946730cd
DC
2 extend: 'Ext.panel.Panel',
3 alias: 'widget.pveNodeCephStatus',
4
ba93a9c6 5 onlineHelp: 'chapter_pveceph',
bd39c945 6
946730cd
DC
7 scrollable: true,
8
9 bodyPadding: '10 0 0 0',
10
11 defaults: {
12 width: 762,
13 userCls: 'inline-block',
14 padding: '0 0 10 10'
15 },
16
17 items: [
18 {
19 xtype: 'panel',
20 title: gettext('Health'),
21 bodyPadding: '0 10 10 10',
22 minHeight: 210,
23 layout: {
24 type: 'hbox',
25 align: 'top'
26 },
27 items: [
28 {
29 flex: 1,
30 itemId: 'overallhealth',
31 xtype: 'pveHealthWidget',
32 title: gettext('Status')
33 },
34 {
35 flex: 2,
36 itemId: 'warnings',
37 stateful: true,
38 stateId: 'ceph-status-warnings',
39 padding: '15 0 0 0',
40 xtype: 'grid',
41 minHeight: 100,
42 // since we load the store manually,
43 // to show the emptytext, we have to
44 // specify an empty store
45 store: { data:[] },
46 emptyText: gettext('No Warnings/Errors'),
47 columns: [
48 {
49 dataIndex: 'severity',
50 header: gettext('Severity'),
51 align: 'center',
52 width: 70,
53 renderer: function(value) {
54 var health = PVE.Utils.map_ceph_health[value];
55 var classes = PVE.Utils.get_health_icon(health);
56
57 return '<i class="fa fa-fw ' + classes + '"></i>';
58 },
59 sorter: {
60 sorterFn: function(a,b) {
61 var healthArr = ['HEALTH_ERR', 'HEALTH_WARN', 'HEALTH_OK'];
62 return healthArr.indexOf(b.data.severity) - healthArr.indexOf(a.data.severity);
63 }
64 }
65 },
66 {
67 dataIndex: 'summary',
68 header: gettext('Summary'),
69 flex: 1
e932cd5f
DC
70 },
71 {
72 xtype: 'actioncolumn',
73 width: 40,
74 align: 'center',
75 tooltip: gettext('Detail'),
76 items: [
77 {
78 iconCls: 'x-fa fa-info-circle',
79 handler: function(grid, rowindex, colindex, item, e, record) {
80 var win = Ext.create('Ext.window.Window', {
81 title: gettext('Detail'),
82 resizable: true,
83 width: 650,
84 height: 400,
85 layout: {
86 type: 'fit'
87 },
88 items: [{
89 scrollable: true,
90 padding: '10',
91 xtype: 'box',
92 html: record.data.detail
93 }]
94 });
95 win.show();
96 }
97 }
98 ]
946730cd
DC
99 }
100 ]
101 }
102 ]
103 },
104 {
105 xtype: 'pveCephStatusDetail',
106 itemId: 'statusdetail',
107 title: gettext('Status')
108 },
109 {
110 xtype: 'panel',
111 title: gettext('Performance'),
112 bodyPadding: '0 10 10 10',
113 layout: {
114 type: 'hbox',
115 align: 'center'
116 },
117 items: [
118 {
119 flex: 1,
120 xtype: 'pveGauge',
121 itemId: 'space',
122 title: gettext('Usage')
123 },
124 {
125 flex: 2,
126 xtype: 'container',
127 defaults: {
128 padding: '0 0 0 30',
129 height: 100
130 },
131 items: [
132 {
133 itemId: 'reads',
134 xtype: 'pveRunningChart',
135 title: gettext('Reads'),
136 renderer: PVE.Utils.render_bandwidth
137 },
138 {
139 itemId: 'writes',
140 xtype: 'pveRunningChart',
141 title: gettext('Writes'),
142 renderer: PVE.Utils.render_bandwidth
143 },
144 {
145 itemId: 'iops',
146 xtype: 'pveRunningChart',
147 hidden: true,
2ce6111f 148 title: 'IOPS', // do not localize
946730cd
DC
149 renderer: Ext.util.Format.numberRenderer('0,000')
150 },
151 {
152 itemId: 'readiops',
153 xtype: 'pveRunningChart',
154 hidden: true,
8f8ec25d 155 title: 'IOPS: ' + gettext('Reads'),
946730cd
DC
156 renderer: Ext.util.Format.numberRenderer('0,000')
157 },
158 {
159 itemId: 'writeiops',
160 xtype: 'pveRunningChart',
161 hidden: true,
8f8ec25d 162 title: 'IOPS: ' + gettext('Writes'),
946730cd
DC
163 renderer: Ext.util.Format.numberRenderer('0,000')
164 }
165 ]
166 }
167 ]
bd39c945 168 }
946730cd 169 ],
bd39c945 170
e932cd5f
DC
171 generateCheckData: function(health) {
172 var result = [];
173 var checks = health.checks || {};
174 var keys = Ext.Object.getKeys(checks).sort();
175
176 Ext.Array.forEach(keys, function(key) {
177 var details = checks[key].detail || [];
178 result.push({
179 id: key,
180 summary: checks[key].message,
181 detail: details.join("<br>\n"),
182 severity: checks[key].severity
183 });
184 });
185
186 return result;
187 },
188
946730cd
DC
189 updateAll: function(store, records, success) {
190 if (!success || records.length === 0) {
191 return;
192 }
bd39c945 193
946730cd
DC
194 var me = this;
195 var rec = records[0];
bd39c945 196
946730cd 197 // add health panel
dfe6d184 198 me.down('#overallhealth').updateHealth(PVE.Utils.render_ceph_health(rec.data.health || {}));
946730cd 199 // add errors to gridstore
e932cd5f 200 me.down('#warnings').getStore().loadRawData(me.generateCheckData(rec.data.health || {}), false);
bd39c945 201
946730cd 202 // update detailstatus panel
4a0bb017
DC
203 me.getComponent('statusdetail').updateAll(
204 rec.data.health || {},
205 rec.data.monmap || {},
206 rec.data.pgmap || {},
207 rec.data.osdmap || {},
208 rec.data.quorum_names || []);
bd39c945 209
946730cd
DC
210 // add performance data
211 var used = rec.data.pgmap.bytes_used;
212 var total = rec.data.pgmap.bytes_total;
bd39c945 213
946730cd
DC
214 var text = Ext.String.format(gettext('{0} of {1}'),
215 PVE.Utils.render_size(used),
216 PVE.Utils.render_size(total)
217 );
bd39c945 218
946730cd
DC
219 // update the usage widget
220 me.down('#space').updateValue(used/total, text);
bd39c945 221
946730cd 222 // TODO: logic for jewel (iops splitted in read/write)
bd39c945 223
946730cd
DC
224 var iops = rec.data.pgmap.op_per_sec;
225 var readiops = rec.data.pgmap.read_op_per_sec;
6783a330 226 var writeiops = rec.data.pgmap.write_op_per_sec;
946730cd
DC
227 var reads = rec.data.pgmap.read_bytes_sec || 0;
228 var writes = rec.data.pgmap.write_bytes_sec || 0;
bd39c945 229
946730cd
DC
230 if (iops !== undefined && me.version !== 'hammer') {
231 me.change_version('hammer');
232 } else if((readiops !== undefined || writeiops !== undefined) && me.version !== 'jewel') {
233 me.change_version('jewel');
234 }
235 // update the graphs
236 me.reads.addDataPoint(reads);
237 me.writes.addDataPoint(writes);
238 me.iops.addDataPoint(iops);
239 me.readiops.addDataPoint(readiops);
240 me.writeiops.addDataPoint(writeiops);
241 },
242
243 change_version: function(version) {
244 var me = this;
245 me.version = version;
246 me.sp.set('ceph-version', version);
247 me.iops.setVisible(version === 'hammer');
248 me.readiops.setVisible(version === 'jewel');
249 me.writeiops.setVisible(version === 'jewel');
250 },
bd39c945 251
946730cd
DC
252 initComponent: function() {
253 var me = this;
bd39c945 254
946730cd
DC
255 var nodename = me.pveSelNode.data.node;
256 if (!nodename) {
257 throw "no node name specified";
258 }
bd39c945 259
946730cd
DC
260 me.callParent();
261 me.store = Ext.create('PVE.data.UpdateStore', {
262 storeid: 'ceph-status-' + nodename,
263 interval: 5000,
264 proxy: {
265 type: 'pve',
266 url: '/api2/json/nodes/' + nodename + '/ceph/status'
bd39c945
DM
267 }
268 });
269
946730cd
DC
270 // save references for the updatefunction
271 me.iops = me.down('#iops');
272 me.readiops = me.down('#readiops');
273 me.writeiops = me.down('#writeiops');
274 me.reads = me.down('#reads');
275 me.writes = me.down('#writes');
276
277 // get ceph version
278 me.sp = Ext.state.Manager.getProvider();
279 me.version = me.sp.get('ceph-version');
280 me.change_version(me.version);
281
282 PVE.Utils.monStoreErrors(me,me.store);
283 me.mon(me.store, 'load', me.updateAll, me);
284 me.on('destroy', me.store.stopUpdate);
285 me.store.startUpdate();
bd39c945 286 }
946730cd 287
bd39c945 288});