]>
Commit | Line | Data |
---|---|---|
0b659b8e DC |
1 | Ext.define('PVE.dc.Health', { |
2 | extend: 'Ext.panel.Panel', | |
3 | alias: 'widget.pveDcHealth', | |
4 | ||
8f8ec25d | 5 | title: gettext('Health'), |
0b659b8e | 6 | |
5da98a05 | 7 | bodyPadding: 10, |
769d716b | 8 | height: 250, |
701acf20 DC |
9 | layout: { |
10 | type: 'hbox', | |
f6710aac | 11 | align: 'stretch', |
701acf20 | 12 | }, |
0b659b8e DC |
13 | |
14 | defaults: { | |
701acf20 | 15 | flex: 1, |
0b659b8e DC |
16 | xtype: 'box', |
17 | style: { | |
8058410f | 18 | 'text-align': 'center', |
f6710aac | 19 | }, |
0b659b8e DC |
20 | }, |
21 | ||
b8786899 DC |
22 | nodeList: [], |
23 | nodeIndex: 0, | |
0b659b8e DC |
24 | |
25 | updateStatus: function(store, records, success) { | |
26 | var me = this; | |
27 | if (!success) { | |
28 | return; | |
29 | } | |
30 | ||
31 | var cluster = { | |
428bc4a2 | 32 | iconCls: PVE.Utils.get_health_icon('good', true), |
f6710aac | 33 | text: gettext("Standalone node - no cluster defined"), |
0b659b8e DC |
34 | }; |
35 | ||
36 | var nodes = { | |
37 | online: 0, | |
f6710aac | 38 | offline: 0, |
0b659b8e DC |
39 | }; |
40 | ||
41 | // by default we have one node | |
42 | var numNodes = 1; | |
43 | var i; | |
44 | ||
45 | for (i = 0; i < records.length; i++) { | |
46 | var item = records[i]; | |
47 | if (item.data.type === 'node') { | |
48 | nodes[item.data.online === 1 ? 'online':'offline']++; | |
8058410f | 49 | } else if (item.data.type === 'cluster') { |
0b659b8e DC |
50 | cluster.text = gettext("Cluster") + ": "; |
51 | cluster.text += item.data.name + ", "; | |
52 | cluster.text += gettext("Quorate") + ": "; | |
e7ade592 | 53 | cluster.text += Proxmox.Utils.format_boolean(item.data.quorate); |
0b659b8e | 54 | if (item.data.quorate != 1) { |
428bc4a2 | 55 | cluster.iconCls = PVE.Utils.get_health_icon('critical', true); |
0b659b8e DC |
56 | } |
57 | ||
58 | numNodes = item.data.nodes; | |
59 | } | |
60 | } | |
61 | ||
62 | if (numNodes !== (nodes.online + nodes.offline)) { | |
63 | nodes.offline = numNodes - nodes.online; | |
64 | } | |
65 | ||
046e640c | 66 | me.getComponent('clusterstatus').updateHealth(cluster); |
0b659b8e DC |
67 | me.getComponent('nodestatus').update(nodes); |
68 | }, | |
69 | ||
70 | updateCeph: function(store, records, success) { | |
71 | var me = this; | |
72 | var cephstatus = me.getComponent('ceph'); | |
73 | if (!success || records.length < 1) { | |
d43f7042 | 74 | // if ceph status is already visible |
ec505260 | 75 | // don't stop to update |
d43f7042 DC |
76 | if (cephstatus.isVisible()) { |
77 | return; | |
78 | } | |
0b659b8e | 79 | |
ec505260 | 80 | // try all nodes until we either get a successful api call, |
b8786899 DC |
81 | // or we tried all nodes |
82 | if (++me.nodeIndex >= me.nodeList.length) { | |
0b659b8e | 83 | me.cephstore.stopUpdate(); |
b8786899 DC |
84 | } else { |
85 | store.getProxy().setUrl('/api2/json/nodes/' + me.nodeList[me.nodeIndex].node + '/ceph/status'); | |
0b659b8e | 86 | } |
b8786899 | 87 | |
0b659b8e DC |
88 | return; |
89 | } | |
90 | ||
dfe6d184 | 91 | var state = PVE.Utils.render_ceph_health(records[0].data.health || {}); |
046e640c | 92 | cephstatus.updateHealth(state); |
0b659b8e DC |
93 | cephstatus.setVisible(true); |
94 | }, | |
95 | ||
96 | listeners: { | |
97 | destroy: function() { | |
98 | var me = this; | |
99 | me.cephstore.stopUpdate(); | |
f6710aac | 100 | }, |
0b659b8e DC |
101 | }, |
102 | ||
103 | items: [ | |
104 | { | |
105 | itemId: 'clusterstatus', | |
046e640c | 106 | xtype: 'pveHealthWidget', |
f6710aac | 107 | title: gettext('Status'), |
0b659b8e DC |
108 | }, |
109 | { | |
110 | itemId: 'nodestatus', | |
111 | data: { | |
112 | online: 0, | |
f6710aac | 113 | offline: 0, |
0b659b8e DC |
114 | }, |
115 | tpl: [ | |
116 | '<h3>' + gettext('Nodes') + '</h3><br />', | |
117 | '<div style="width: 150px;margin: auto;font-size: 12pt">', | |
118 | '<div class="left-aligned">', | |
119 | '<i class="good fa fa-fw fa-check"> </i>', | |
120 | gettext('Online'), | |
121 | '</div>', | |
122 | '<div class="right-aligned">{online}</div>', | |
123 | '<br /><br />', | |
124 | '<div class="left-aligned">', | |
125 | '<i class="critical fa fa-fw fa-times"> </i>', | |
126 | gettext('Offline'), | |
127 | '</div>', | |
128 | '<div class="right-aligned">{offline}</div>', | |
f6710aac TL |
129 | '</div>', |
130 | ], | |
0b659b8e DC |
131 | }, |
132 | { | |
133 | itemId: 'ceph', | |
134 | width: 250, | |
135 | columnWidth: undefined, | |
c359b437 | 136 | userCls: 'pointer', |
2ce6111f | 137 | title: 'Ceph', |
046e640c | 138 | xtype: 'pveHealthWidget', |
c359b437 DC |
139 | hidden: true, |
140 | listeners: { | |
141 | element: 'el', | |
142 | click: function() { | |
c359b437 | 143 | var sp = Ext.state.Manager.getProvider(); |
8058410f | 144 | sp.set('dctab', { value: 'ceph' }, true); |
f6710aac TL |
145 | }, |
146 | }, | |
147 | }, | |
0b659b8e DC |
148 | ], |
149 | ||
150 | initComponent: function() { | |
151 | var me = this; | |
152 | ||
b8786899 DC |
153 | me.nodeList = PVE.data.ResourceStore.getNodes(); |
154 | me.nodeIndex = 0; | |
0c7c0d6b | 155 | me.cephstore = Ext.create('Proxmox.data.UpdateStore', { |
0b659b8e DC |
156 | interval: 3000, |
157 | storeid: 'pve-cluster-ceph', | |
158 | proxy: { | |
56a353b9 | 159 | type: 'proxmox', |
f6710aac TL |
160 | url: '/api2/json/nodes/' + me.nodeList[me.nodeIndex].node + '/ceph/status', |
161 | }, | |
0b659b8e DC |
162 | }); |
163 | me.callParent(); | |
0b659b8e | 164 | me.mon(me.cephstore, 'load', me.updateCeph, me); |
b8786899 | 165 | me.cephstore.startUpdate(); |
f6710aac | 166 | }, |
0b659b8e | 167 | }); |