]> git.proxmox.com Git - pve-manager.git/blob - www/manager6/dc/Health.js
ui: realm: clarify that the sync jobs really are for the realm
[pve-manager.git] / www / manager6 / dc / Health.js
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">&nbsp;</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">&nbsp;</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 });