add dc health panel
this adds a dc health panel which will be used in the cluster dashboard it shows the overall cluster status (or simply ok if no cluster defined) with a symbol and text then it shows the number of online and offline nodes optionally it shows then the overall ceph health of the connected node if the api call for ceph fails 3 times, we stop it the ceph status is hidden by default for updating the cluster and node status, we have to call updateStatus as a callback from a store which loads the /api2/json/cluster/status call we do not have our own store for this, because we will be using the store which handles this in the component above Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
This commit is contained in:
parent
a3a29cc8d2
commit
0b659b8ef9
@ -188,6 +188,7 @@ JSSRC= \
|
||||
ha/Groups.js \
|
||||
ha/Fencing.js \
|
||||
dc/Summary.js \
|
||||
dc/Health.js \
|
||||
dc/OptionView.js \
|
||||
dc/StorageView.js \
|
||||
dc/UserEdit.js \
|
||||
|
184
www/manager6/dc/Health.js
Normal file
184
www/manager6/dc/Health.js
Normal file
@ -0,0 +1,184 @@
|
||||
Ext.define('PVE.dc.Health', {
|
||||
extend: 'Ext.panel.Panel',
|
||||
alias: 'widget.pveDcHealth',
|
||||
|
||||
title: gettext('Datacenter Health'),
|
||||
|
||||
bodyPadding: '0 20 0 20',
|
||||
height: 200,
|
||||
layout: 'column',
|
||||
|
||||
defaults: {
|
||||
columnWidth: 0.5,
|
||||
xtype: 'box',
|
||||
style: {
|
||||
'text-align':'center'
|
||||
}
|
||||
},
|
||||
|
||||
cepherrors: 0,
|
||||
|
||||
updateStatus: function(store, records, success) {
|
||||
var me = this;
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
|
||||
var cluster = {
|
||||
iconCls:'good fa-check-circle',
|
||||
text: gettext("Standalone node - no cluster defined")
|
||||
};
|
||||
|
||||
var nodes = {
|
||||
online: 0,
|
||||
offline: 0
|
||||
};
|
||||
|
||||
// by default we have one node
|
||||
var numNodes = 1;
|
||||
var i;
|
||||
|
||||
for (i = 0; i < records.length; i++) {
|
||||
var item = records[i];
|
||||
if (item.data.type === 'node') {
|
||||
nodes[item.data.online === 1 ? 'online':'offline']++;
|
||||
} else if(item.data.type === 'cluster') {
|
||||
cluster.text = gettext("Cluster") + ": ";
|
||||
cluster.text += item.data.name + ", ";
|
||||
cluster.text += gettext("Quorate") + ": ";
|
||||
cluster.text += PVE.Utils.format_boolean(item.data.quorate);
|
||||
if (item.data.quorate != 1) {
|
||||
cluster.iconCls = 'critical fa-times-circle';
|
||||
}
|
||||
|
||||
numNodes = item.data.nodes;
|
||||
}
|
||||
}
|
||||
|
||||
if (numNodes !== (nodes.online + nodes.offline)) {
|
||||
nodes.offline = numNodes - nodes.online;
|
||||
}
|
||||
|
||||
me.getComponent('clusterstatus').update(cluster);
|
||||
me.getComponent('nodestatus').update(nodes);
|
||||
},
|
||||
|
||||
updateCeph: function(store, records, success) {
|
||||
var me = this;
|
||||
var cephstatus = me.getComponent('ceph');
|
||||
if (!success || records.length < 1) {
|
||||
me.cepherrors++;
|
||||
cephstatus.setVisible(false);
|
||||
|
||||
// after 3 unsuccessful tries of
|
||||
// /nodes/localhost/ceph/status
|
||||
// we give up (there probably is no ceph installed)
|
||||
if (me.cepherrors >= 3) {
|
||||
me.cephstore.stopUpdate();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
me.cepherrors = 0;
|
||||
|
||||
var cephstate = {
|
||||
iconCls: 'faded fa-question-circle',
|
||||
text: ''
|
||||
};
|
||||
|
||||
switch (records[0].data.health.overall_status) {
|
||||
case 'HEALTH_OK':
|
||||
cephstate.iconCls = 'good fa-check-circle';
|
||||
break;
|
||||
case 'HEALTH_WARN':
|
||||
cephstate.iconCls = 'warning fa-info-circle';
|
||||
break;
|
||||
case 'HEALTH_ERR':
|
||||
cephstate.iconCls = 'critical fa-times-circle';
|
||||
break;
|
||||
default:
|
||||
cephstate.iconCls = 'faded fa-question-circle';
|
||||
break;
|
||||
}
|
||||
cephstate.text = records[0].data.health.overall_status;
|
||||
cephstatus.update(cephstate);
|
||||
cephstatus.setVisible(true);
|
||||
},
|
||||
|
||||
listeners: {
|
||||
destroy: function() {
|
||||
var me = this;
|
||||
me.cephstore.stopUpdate();
|
||||
}
|
||||
},
|
||||
|
||||
items: [
|
||||
{
|
||||
itemId: 'clusterstatus',
|
||||
data: {
|
||||
iconCls: 'faded fa-question-circle',
|
||||
text: ''
|
||||
},
|
||||
tpl: [
|
||||
'<h3>' + gettext('Status') + '</h3>',
|
||||
'<i class="fa fa-5x {iconCls}"></i>',
|
||||
'<br /><br/>',
|
||||
'{text}'
|
||||
]
|
||||
},
|
||||
{
|
||||
itemId: 'nodestatus',
|
||||
data: {
|
||||
online: 0,
|
||||
offline: 0
|
||||
},
|
||||
tpl: [
|
||||
'<h3>' + gettext('Nodes') + '</h3><br />',
|
||||
'<div style="width: 150px;margin: auto;font-size: 12pt">',
|
||||
'<div class="left-aligned">',
|
||||
'<i class="good fa fa-fw fa-check"> </i>',
|
||||
gettext('Online'),
|
||||
'</div>',
|
||||
'<div class="right-aligned">{online}</div>',
|
||||
'<br /><br />',
|
||||
'<div class="left-aligned">',
|
||||
'<i class="critical fa fa-fw fa-times"> </i>',
|
||||
gettext('Offline'),
|
||||
'</div>',
|
||||
'<div class="right-aligned">{offline}</div>',
|
||||
'</div>'
|
||||
]
|
||||
},
|
||||
{
|
||||
itemId: 'ceph',
|
||||
width: 250,
|
||||
columnWidth: undefined,
|
||||
data: {
|
||||
text: '',
|
||||
iconCls: 'faded fa-question-circle'
|
||||
},
|
||||
tpl: [
|
||||
'<h3>Ceph</h3>',
|
||||
'<i class="fa fa-5x {iconCls}"></i><br /><br />',
|
||||
gettext("Health") + ': {text}'
|
||||
],
|
||||
hidden: true
|
||||
}
|
||||
],
|
||||
|
||||
initComponent: function() {
|
||||
var me = this;
|
||||
|
||||
me.cephstore = Ext.create('PVE.data.UpdateStore', {
|
||||
interval: 3000,
|
||||
storeid: 'pve-cluster-ceph',
|
||||
proxy: {
|
||||
type: 'pve',
|
||||
url: '/api2/json/nodes/localhost/ceph/status'
|
||||
}
|
||||
});
|
||||
me.callParent();
|
||||
me.cephstore.startUpdate();
|
||||
me.mon(me.cephstore, 'load', me.updateCeph, me);
|
||||
}
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user