]> git.proxmox.com Git - pve-manager.git/blob - www/manager6/ceph/StatusDetail.js
ui: ceph: downgrade remapped from error to warning/working
[pve-manager.git] / www / manager6 / ceph / StatusDetail.js
1 Ext.define('PVE.ceph.StatusDetail', {
2 extend: 'Ext.panel.Panel',
3 alias: 'widget.pveCephStatusDetail',
4
5 layout: {
6 type: 'hbox',
7 align: 'stretch'
8 },
9
10 bodyPadding: '0 5',
11 defaults: {
12 xtype: 'box',
13 style: {
14 'text-align':'center'
15 }
16 },
17
18 items: [{
19 flex: 1,
20 itemId: 'osds',
21 maxHeight: 250,
22 scrollable: true,
23 padding: '0 10 5 10',
24 data: {
25 total: 0,
26 upin: 0,
27 upout: 0,
28 downin: 0,
29 downout: 0,
30 oldosds: []
31 },
32 tpl: [
33 '<h3>' + 'OSDs' + '</h3>',
34 '<table class="osds">',
35 '<tr><td></td>',
36 '<td><i class="fa fa-fw good fa-circle"></i>',
37 gettext('In'),
38 '</td>',
39 '<td><i class="fa fa-fw warning fa-circle-o"></i>',
40 gettext('Out'),
41 '</td>',
42 '</tr>',
43 '<tr>',
44 '<td><i class="fa fa-fw good fa-arrow-circle-up"></i>',
45 gettext('Up'),
46 '</td>',
47 '<td>{upin}</td>',
48 '<td>{upout}</td>',
49 '</tr>',
50 '<tr>',
51 '<td><i class="fa fa-fw critical fa-arrow-circle-down"></i>',
52 gettext('Down'),
53 '</td>',
54 '<td>{downin}</td>',
55 '<td>{downout}</td>',
56 '</tr>',
57 '</table>',
58 '<br /><div>',
59 gettext('Total'),
60 ': {total}',
61 '</div><br />',
62 '<tpl if="oldosds.length &gt; 0">',
63 '<i class="fa fa-refresh warning"></i> ' + gettext('Outdated OSDs') + "<br>",
64 '<div class="osds">',
65 '<tpl for="oldosds">',
66 '<div class="left-aligned">osd.{id}:</div>',
67 '<div class="right-aligned">{version}</div><br />',
68 '<div style="clear:both"></div>',
69 '</tpl>',
70 '</div>',
71 '</tpl>'
72 ]
73 },
74 {
75 flex: 1,
76 border: false,
77 itemId: 'pgchart',
78 xtype: 'polar',
79 height: 184,
80 innerPadding: 5,
81 insetPadding: 5,
82 colors: [
83 '#CFCFCF',
84 '#21BF4B',
85 '#FFCC00',
86 '#FF6C59'
87 ],
88 store: { },
89 series: [
90 {
91 type: 'pie',
92 donut: 60,
93 angleField: 'count',
94 tooltip: {
95 trackMouse: true,
96 renderer: function(tooltip, record, ctx) {
97 var html = record.get('text');
98 html += '<br>';
99 record.get('states').forEach(function(state) {
100 html += '<br>' +
101 state.state_name + ': ' + state.count.toString();
102 });
103 tooltip.setHtml(html);
104 }
105 },
106 subStyle: {
107 strokeStyle: false
108 }
109 }
110 ]
111 },
112 {
113 flex: 1.6,
114 itemId: 'pgs',
115 padding: '0 10',
116 maxHeight: 250,
117 scrollable: true,
118 data: {
119 states: []
120 },
121 tpl: [
122 '<h3>' + 'PGs' + '</h3>',
123 '<tpl for="states">',
124 '<div class="left-aligned"><i class ="fa fa-circle {cls}"></i> {state_name}:</div>',
125 '<div class="right-aligned">{count}</div><br />',
126 '<div style="clear:both"></div>',
127 '</tpl>'
128 ]
129 }],
130
131 // similar to mgr dashboard
132 pgstates: {
133 // clean
134 clean: 1,
135 active: 1,
136
137 // working
138 activating: 2,
139 backfill_wait: 2,
140 backfilling: 2,
141 creating: 2,
142 deep: 2,
143 degraded: 2,
144 forced_backfill: 2,
145 forced_recovery: 2,
146 peered: 2,
147 peering: 2,
148 recovering: 2,
149 recovery_wait: 2,
150 remapped: 2,
151 repair: 2,
152 scrubbing: 2,
153 snaptrim: 2,
154 snaptrim_wait: 2,
155
156 // error
157 backfill_toofull: 3,
158 backfill_unfound: 3,
159 down: 3,
160 incomplete: 3,
161 inconsistent: 3,
162 recovery_toofull: 3,
163 recovery_unfound: 3,
164 snaptrim_error: 3,
165 stale: 3,
166 undersized: 3
167 },
168
169 statecategories: [
170 {
171 text: gettext('Unknown'),
172 count: 0,
173 states: [],
174 cls: 'faded'
175 },
176 {
177 text: gettext('Clean'),
178 cls: 'good'
179 },
180 {
181 text: gettext('Working'),
182 cls: 'warning'
183 },
184 {
185 text: gettext('Error'),
186 cls: 'critical'
187 }
188 ],
189
190 updateAll: function(metadata, status) {
191 var me = this;
192 me.suspendLayout = true;
193
194 var maxversion = "0";
195 Object.values(metadata.version || {}).forEach(function(version) {
196 if (PVE.Utils.compare_ceph_versions(version, maxversion) > 0) {
197 maxversion = version;
198 }
199 });
200
201 var oldosds = [];
202
203 if (metadata.osd) {
204 metadata.osd.forEach(function(osd) {
205 var version = PVE.Utils.parse_ceph_version(osd);
206 if (version != maxversion) {
207 oldosds.push({
208 id: osd.id,
209 version: version
210 });
211 }
212 });
213 }
214
215 // update PGs sorted
216 var pgmap = status.pgmap || {};
217 var pgs_by_state = pgmap.pgs_by_state || [];
218 pgs_by_state.sort(function(a,b){
219 return (a.state_name < b.state_name)?-1:(a.state_name === b.state_name)?0:1;
220 });
221
222 me.statecategories.forEach(function(cat) {
223 cat.count = 0;
224 cat.states = [];
225 });
226
227 pgs_by_state.forEach(function(state) {
228 var i;
229 var states = state.state_name.split(/[^a-z]+/);
230 var result = 0;
231 for (i = 0; i < states.length; i++) {
232 if (me.pgstates[states[i]] > result) {
233 result = me.pgstates[states[i]];
234 }
235 }
236 // for the list
237 state.cls = me.statecategories[result].cls;
238
239 me.statecategories[result].count += state.count;
240 me.statecategories[result].states.push(state);
241 });
242
243 me.getComponent('pgchart').getStore().setData(me.statecategories);
244 me.getComponent('pgs').update({states: pgs_by_state});
245
246 var downinregex = /(\d+) osds down/;
247 var downin_osds = 0;
248
249 var health = status.health || {};
250 // we collect monitor/osd information from the checks
251 Ext.Object.each(health.checks, function(key, value, obj) {
252 var found = null;
253 if (key === 'OSD_DOWN') {
254 found = value.summary.message.match(downinregex);
255 if (found !== null) {
256 downin_osds = parseInt(found[1],10);
257 }
258 }
259 });
260
261 var osdmap = status.osdmap || {};
262 if (typeof osdmap.osdmap != "undefined") {
263 osdmap = osdmap.osdmap;
264 }
265 // update osds counts
266 var total_osds = osdmap.num_osds || 0;
267 var in_osds = osdmap.num_in_osds || 0;
268 var up_osds = osdmap.num_up_osds || 0;
269 var out_osds = total_osds - in_osds;
270 var down_osds = total_osds - up_osds;
271
272 var downout_osds = down_osds - downin_osds;
273 var upin_osds = in_osds - downin_osds;
274 var upout_osds = up_osds - upin_osds;
275 var osds = {
276 total: total_osds,
277 upin: upin_osds,
278 upout: upout_osds,
279 downin: downin_osds,
280 downout: downout_osds,
281 oldosds: oldosds
282 };
283 var osdcomponent = me.getComponent('osds');
284 osdcomponent.update(Ext.apply(osdcomponent.data, osds));
285
286 me.suspendLayout = false;
287 me.updateLayout();
288 }
289 });
290