]>
git.proxmox.com Git - pve-manager.git/blob - www/manager6/ceph/Status.js
1 Ext
.define('PVE.node.CephStatus', {
2 extend
: 'Ext.panel.Panel',
3 alias
: 'widget.pveNodeCephStatus',
5 onlineHelp
: 'chapter_pveceph',
22 title
: gettext('Health'),
24 plugins
: 'responsive',
50 itemId
: 'overallhealth',
51 xtype
: 'pveHealthWidget',
52 title
: gettext('Status')
55 itemId
: 'versioninfo',
63 'text-align': 'center',
67 '<b>', gettext('Highest Version in Cluster'), '</b>',
69 '{version} (git: {git})',
79 stateId
: 'ceph-status-warnings',
81 // since we load the store manually,
82 // to show the emptytext, we have to
83 // specify an empty store
85 emptyText
: gettext('No Warnings/Errors'),
88 dataIndex
: 'severity',
89 header
: gettext('Severity'),
92 renderer: function(value
) {
93 var health
= PVE
.Utils
.map_ceph_health
[value
];
94 var classes
= PVE
.Utils
.get_health_icon(health
);
96 return '<i class="fa fa-fw ' + classes
+ '"></i>';
99 sorterFn: function(a
,b
) {
100 var healthArr
= ['HEALTH_ERR', 'HEALTH_WARN', 'HEALTH_OK'];
101 return healthArr
.indexOf(b
.data
.severity
) - healthArr
.indexOf(a
.data
.severity
);
106 dataIndex
: 'summary',
107 header
: gettext('Summary'),
111 xtype
: 'actioncolumn',
114 tooltip
: gettext('Detail'),
117 iconCls
: 'x-fa fa-info-circle',
118 handler: function(grid
, rowindex
, colindex
, item
, e
, record
) {
119 var win
= Ext
.create('Ext.window.Window', {
120 title
: gettext('Detail'),
133 '<span>' + Ext
.htmlEncode(record
.data
.summary
) + '</span>',
134 '<pre>' + Ext
.htmlEncode(record
.data
.detail
) + '</pre>'
148 xtype
: 'pveCephStatusDetail',
149 itemId
: 'statusdetail',
150 plugins
: 'responsive',
161 title
: gettext('Status')
164 title
: gettext('Services'),
165 xtype
: 'pveCephServices',
167 plugins
: 'responsive',
185 title
: gettext('Performance'),
195 xtype
: 'proxmoxGauge',
197 title
: gettext('Usage')
209 xtype
: 'pveRunningChart',
210 title
: gettext('Reads'),
211 renderer
: PVE
.Utils
.render_bandwidth
215 xtype
: 'pveRunningChart',
216 title
: gettext('Writes'),
217 renderer
: PVE
.Utils
.render_bandwidth
221 xtype
: 'pveRunningChart',
223 title
: 'IOPS', // do not localize
224 renderer
: Ext
.util
.Format
.numberRenderer('0,000')
228 xtype
: 'pveRunningChart',
230 title
: 'IOPS: ' + gettext('Reads'),
231 renderer
: Ext
.util
.Format
.numberRenderer('0,000')
235 xtype
: 'pveRunningChart',
237 title
: 'IOPS: ' + gettext('Writes'),
238 renderer
: Ext
.util
.Format
.numberRenderer('0,000')
246 generateCheckData: function(health
) {
248 var checks
= health
.checks
|| {};
249 var keys
= Ext
.Object
.getKeys(checks
).sort();
251 Ext
.Array
.forEach(keys
, function(key
) {
252 var details
= checks
[key
].detail
|| [];
255 summary
: checks
[key
].summary
.message
,
256 detail
: Ext
.Array
.reduce(
258 function(first
, second
) {
259 return first
+ '\n' + second
.message
;
263 severity
: checks
[key
].severity
270 updateAll: function(store
, records
, success
) {
271 if (!success
|| records
.length
=== 0) {
276 var rec
= records
[0];
277 me
.status
= rec
.data
;
280 me
.down('#overallhealth').updateHealth(PVE
.Utils
.render_ceph_health(rec
.data
.health
|| {}));
281 // add errors to gridstore
282 me
.down('#warnings').getStore().loadRawData(me
.generateCheckData(rec
.data
.health
|| {}), false);
285 me
.getComponent('services').updateAll(me
.metadata
|| {}, rec
.data
);
287 // update detailstatus panel
288 me
.getComponent('statusdetail').updateAll(me
.metadata
|| {}, rec
.data
);
290 // add performance data
291 var used
= rec
.data
.pgmap
.bytes_used
;
292 var total
= rec
.data
.pgmap
.bytes_total
;
294 var text
= Ext
.String
.format(gettext('{0} of {1}'),
295 PVE
.Utils
.render_size(used
),
296 PVE
.Utils
.render_size(total
)
299 // update the usage widget
300 me
.down('#space').updateValue(used
/total
, text
);
302 // TODO: logic for jewel (iops split in read/write)
304 var iops
= rec
.data
.pgmap
.op_per_sec
;
305 var readiops
= rec
.data
.pgmap
.read_op_per_sec
;
306 var writeiops
= rec
.data
.pgmap
.write_op_per_sec
;
307 var reads
= rec
.data
.pgmap
.read_bytes_sec
|| 0;
308 var writes
= rec
.data
.pgmap
.write_bytes_sec
|| 0;
310 if (iops
!== undefined && me
.version
!== 'hammer') {
311 me
.change_version('hammer');
312 } else if((readiops
!== undefined || writeiops
!== undefined) && me
.version
!== 'jewel') {
313 me
.change_version('jewel');
316 me
.reads
.addDataPoint(reads
);
317 me
.writes
.addDataPoint(writes
);
318 me
.iops
.addDataPoint(iops
);
319 me
.readiops
.addDataPoint(readiops
);
320 me
.writeiops
.addDataPoint(writeiops
);
323 change_version: function(version
) {
325 me
.version
= version
;
326 me
.sp
.set('ceph-version', version
);
327 me
.iops
.setVisible(version
=== 'hammer');
328 me
.readiops
.setVisible(version
=== 'jewel');
329 me
.writeiops
.setVisible(version
=== 'jewel');
332 initComponent: function() {
335 var nodename
= me
.pveSelNode
.data
.node
;
338 var baseurl
= '/api2/json' + (nodename
? '/nodes/' + nodename
: '/cluster') + '/ceph';
339 me
.store
= Ext
.create('Proxmox.data.UpdateStore', {
340 storeid
: 'ceph-status-' + (nodename
|| 'cluster'),
344 url
: baseurl
+ '/status'
348 me
.metadatastore
= Ext
.create('Proxmox.data.UpdateStore', {
349 storeid
: 'ceph-metadata-' + (nodename
|| 'cluster'),
353 url
: '/api2/json/cluster/ceph/metadata'
357 // save references for the updatefunction
358 me
.iops
= me
.down('#iops');
359 me
.readiops
= me
.down('#readiops');
360 me
.writeiops
= me
.down('#writeiops');
361 me
.reads
= me
.down('#reads');
362 me
.writes
= me
.down('#writes');
365 me
.sp
= Ext
.state
.Manager
.getProvider();
366 me
.version
= me
.sp
.get('ceph-version');
367 me
.change_version(me
.version
);
369 var regex
= new RegExp("not (installed|initialized)", "i");
370 PVE
.Utils
.handleStoreErrorOrMask(me
, me
.store
, regex
, function(me
, error
){
371 me
.store
.stopUpdate();
372 PVE
.Utils
.showCephInstallOrMask(me
, error
.statusText
, (nodename
|| 'localhost'),
374 me
.mon(win
, 'cephInstallWindowClosed', function(){
375 me
.store
.startUpdate();
381 me
.mon(me
.store
, 'load', me
.updateAll
, me
);
382 me
.mon(me
.metadatastore
, 'load', function(store
, records
, success
) {
383 if (!success
|| records
.length
< 1) {
386 var rec
= records
[0];
387 me
.metadata
= rec
.data
;
390 me
.getComponent('services').updateAll(rec
.data
, me
.status
|| {});
392 // update detailstatus panel
393 me
.getComponent('statusdetail').updateAll(rec
.data
, me
.status
|| {});
396 let maxversiontext
= "";
398 for (const [nodename
, data
] of Object
.entries(me
.metadata
.node
)) {
399 let version
= data
.version
.parts
;
400 if (PVE
.Utils
.compare_ceph_versions(version
, maxversion
) > 0) {
401 maxversion
= version
;
402 git
= data
.buildcommit
.substr(0,8);
403 maxversiontext
= data
.version
.str
;
407 me
.down('#versioninfo').update({
408 version
: maxversiontext
,
413 me
.on('destroy', me
.store
.stopUpdate
);
414 me
.on('destroy', me
.metadatastore
.stopUpdate
);
415 me
.store
.startUpdate();
416 me
.metadatastore
.startUpdate();