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