]>
Commit | Line | Data |
---|---|---|
c9163348 DM |
1 | Ext.define('PVE.CephCreateOsd', { |
2 | extend: 'PVE.window.Edit', | |
3 | alias: ['widget.pveCephCreateOsd'], | |
4 | ||
5 | subject: 'Ceph OSD', | |
6 | ||
93a1f20f DM |
7 | showProgress: true, |
8 | ||
c9163348 DM |
9 | initComponent : function() { |
10 | /*jslint confusion: true */ | |
11 | var me = this; | |
12 | ||
13 | if (!me.nodename) { | |
14 | throw "no node name specified"; | |
15 | } | |
16 | ||
17 | me.create = true; | |
18 | ||
19 | Ext.applyIf(me, { | |
20 | url: "/nodes/" + me.nodename + "/ceph/osd", | |
21 | method: 'POST', | |
22 | items: [ | |
23 | { | |
24 | xtype: 'pveCephDiskSelector', | |
25 | name: 'dev', | |
26 | nodename: me.nodename, | |
27 | value: me.dev, | |
28 | diskType: 'unused', | |
29 | fieldLabel: gettext('Disk'), | |
30 | allowBlank: false | |
31 | }, | |
32 | { | |
33 | xtype: 'pveCephDiskSelector', | |
34 | name: 'journal_dev', | |
35 | nodename: me.nodename, | |
36 | diskType: 'journal_disks', | |
37 | fieldLabel: gettext('Journal Disk'), | |
38 | value: '', | |
39 | autoSelect: false, | |
40 | allowBlank: true, | |
41 | emptyText: 'use OSD disk' | |
42 | } | |
43 | ] | |
44 | }); | |
45 | ||
46 | me.callParent(); | |
47 | } | |
48 | }); | |
49 | ||
50 | Ext.define('PVE.CephRemoveOsd', { | |
51 | extend: 'PVE.window.Edit', | |
52 | alias: ['widget.pveCephRemoveOsd'], | |
53 | ||
54 | isRemove: true, | |
55 | ||
93a1f20f DM |
56 | showProgress: true, |
57 | ||
c9163348 DM |
58 | initComponent : function() { |
59 | /*jslint confusion: true */ | |
60 | var me = this; | |
61 | ||
62 | if (!me.nodename) { | |
63 | throw "no node name specified"; | |
64 | } | |
65 | if (me.osdid === undefined || me.osdid < 0) { | |
66 | throw "no osdid specified"; | |
67 | } | |
68 | ||
69 | me.create = true; | |
70 | ||
71 | me.title = gettext('Remove') + ': ' + 'Ceph OSD osd.' + me.osdid; | |
72 | ||
73 | Ext.applyIf(me, { | |
74 | url: "/nodes/" + me.nodename + "/ceph/osd/" + me.osdid, | |
75 | method: 'DELETE', | |
76 | items: [ | |
77 | { | |
78 | xtype: 'pvecheckbox', | |
79 | name: 'cleanup', | |
80 | checked: true, | |
81 | labelWidth: 130, | |
82 | fieldLabel: gettext('Remove Partitions') | |
83 | } | |
84 | ] | |
85 | }); | |
86 | ||
87 | me.callParent(); | |
88 | } | |
89 | }); | |
90 | ||
91 | Ext.define('PVE.node.CephOsdTree', { | |
92 | extend: 'Ext.tree.Panel', | |
93 | alias: ['widget.pveNodeCephOsdTree'], | |
94 | ||
95 | initComponent: function() { | |
96 | /*jslint confusion: true */ | |
97 | var me = this; | |
98 | ||
99 | var nodename = me.pveSelNode.data.node; | |
100 | if (!nodename) { | |
101 | throw "no node name specified"; | |
102 | } | |
103 | ||
104 | var sm = Ext.create('Ext.selection.TreeModel', {}); | |
105 | ||
106 | var set_button_status; // defined later | |
107 | ||
108 | var reload = function() { | |
109 | PVE.Utils.API2Request({ | |
110 | url: "/nodes/" + nodename + "/ceph/osd", | |
111 | waitMsgTarget: me, | |
112 | method: 'GET', | |
113 | failure: function(response, opts) { | |
114 | PVE.Utils.setErrorMask(me, response.htmlStatus); | |
115 | }, | |
116 | success: function(response, opts) { | |
117 | sm.deselectAll(); | |
118 | me.setRootNode(response.result.data.root); | |
119 | me.expandAll(); | |
120 | set_button_status(); | |
121 | } | |
122 | }); | |
123 | }; | |
124 | ||
125 | var osd_cmd = function(cmd) { | |
126 | var rec = sm.getSelection()[0]; | |
127 | if (!(rec && (rec.data.id >= 0) && rec.data.host)) { | |
128 | return; | |
129 | } | |
130 | PVE.Utils.API2Request({ | |
131 | url: "/nodes/" + rec.data.host + "/ceph/osd/" + | |
132 | rec.data.id + '/' + cmd, | |
133 | waitMsgTarget: me, | |
134 | method: 'POST', | |
135 | success: reload, | |
136 | failure: function(response, opts) { | |
137 | Ext.Msg.alert(gettext('Error'), response.htmlStatus); | |
138 | } | |
139 | }); | |
140 | }; | |
141 | ||
142 | var service_cmd = function(cmd) { | |
143 | var rec = sm.getSelection()[0]; | |
144 | if (!(rec && rec.data.name && rec.data.host)) { | |
145 | return; | |
146 | } | |
147 | PVE.Utils.API2Request({ | |
148 | url: "/nodes/" + rec.data.host + "/ceph/" + cmd, | |
149 | params: { service: rec.data.name }, | |
150 | waitMsgTarget: me, | |
151 | method: 'POST', | |
93a1f20f DM |
152 | success: function(response, options) { |
153 | var upid = response.result.data; | |
154 | var win = Ext.create('PVE.window.TaskProgress', { upid: upid }); | |
155 | win.show(); | |
156 | me.mon(win, 'close', reload, me); | |
157 | }, | |
c9163348 DM |
158 | failure: function(response, opts) { |
159 | Ext.Msg.alert(gettext('Error'), response.htmlStatus); | |
160 | } | |
161 | }); | |
162 | }; | |
163 | ||
164 | var start_btn = new Ext.Button({ | |
165 | text: gettext('Start'), | |
166 | disabled: true, | |
167 | handler: function(){ service_cmd('start'); } | |
168 | }); | |
169 | ||
170 | var stop_btn = new Ext.Button({ | |
171 | text: gettext('Stop'), | |
172 | disabled: true, | |
173 | handler: function(){ service_cmd('stop'); } | |
174 | }); | |
175 | ||
176 | var osd_out_btn = new Ext.Button({ | |
177 | text: 'Out', | |
178 | disabled: true, | |
179 | handler: function(){ osd_cmd('out'); } | |
180 | }); | |
181 | ||
182 | var osd_in_btn = new Ext.Button({ | |
183 | text: 'In', | |
184 | disabled: true, | |
185 | handler: function(){ osd_cmd('in'); } | |
186 | }); | |
187 | ||
188 | var remove_btn = new Ext.Button({ | |
189 | text: gettext('Remove'), | |
190 | disabled: true, | |
191 | handler: function(){ | |
192 | var rec = sm.getSelection()[0]; | |
193 | if (!(rec && (rec.data.id >= 0) && rec.data.host)) { | |
194 | return; | |
195 | } | |
196 | ||
197 | var win = Ext.create('PVE.CephRemoveOsd', { | |
198 | nodename: rec.data.host, | |
199 | osdid: rec.data.id | |
200 | }); | |
201 | win.show(); | |
202 | me.mon(win, 'close', reload, me); | |
203 | } | |
204 | }); | |
205 | ||
206 | set_button_status = function() { | |
207 | var rec = sm.getSelection()[0]; | |
208 | ||
209 | if (!rec) { | |
210 | start_btn.setDisabled(true); | |
211 | stop_btn.setDisabled(true); | |
212 | remove_btn.setDisabled(true); | |
213 | osd_out_btn.setDisabled(true); | |
214 | osd_in_btn.setDisabled(true); | |
215 | return; | |
216 | } | |
217 | ||
218 | var isOsd = (rec.data.host && (rec.data.type === 'osd') && (rec.data.id >= 0)); | |
219 | ||
220 | start_btn.setDisabled(!(isOsd && (rec.data.status !== 'up'))); | |
221 | stop_btn.setDisabled(!(isOsd && (rec.data.status !== 'down'))); | |
222 | remove_btn.setDisabled(!(isOsd && (rec.data.status === 'down'))); | |
223 | ||
224 | osd_out_btn.setDisabled(!(isOsd && rec.data['in'])); | |
225 | osd_in_btn.setDisabled(!(isOsd && !rec.data['in'])); | |
226 | }; | |
227 | ||
228 | sm.on('selectionchange', set_button_status); | |
229 | ||
230 | var reload_btn = new Ext.Button({ | |
231 | text: gettext('Reload'), | |
232 | handler: reload | |
233 | }); | |
234 | ||
235 | Ext.apply(me, { | |
236 | tbar: [ reload_btn, start_btn, stop_btn, osd_out_btn, osd_in_btn, remove_btn ], | |
237 | rootVisible: false, | |
238 | fields: ['name', 'type', 'status', 'host', 'in', | |
239 | { type: 'integer', name: 'id' }, | |
240 | { type: 'number', name: 'reweight' }, | |
241 | { type: 'number', name: 'percent_used' }, | |
242 | { type: 'integer', name: 'bytes_used' }, | |
243 | { type: 'integer', name: 'total_space' }, | |
244 | { type: 'integer', name: 'apply_latency_ms' }, | |
245 | { type: 'integer', name: 'commit_latency_ms' }, | |
246 | { type: 'number', name: 'crush_weight' }], | |
247 | stateful: false, | |
248 | selModel: sm, | |
249 | columns: [ | |
250 | { | |
251 | xtype: 'treecolumn', | |
252 | text: 'Name', | |
253 | dataIndex: 'name', | |
254 | width: 150 | |
255 | }, | |
256 | { | |
257 | text: 'Type', | |
258 | dataIndex: 'type', | |
259 | align: 'right', | |
260 | width: 60 | |
261 | }, | |
262 | { | |
263 | text: 'Status', | |
264 | dataIndex: 'status', | |
265 | align: 'right', | |
266 | renderer: function(value, metaData, rec) { | |
267 | if (!value) { | |
268 | return value; | |
269 | } | |
270 | var data = rec.data; | |
271 | return value + '/' + (data['in'] ? 'in' : 'out'); | |
272 | }, | |
273 | width: 60 | |
274 | }, | |
275 | { | |
276 | text: 'weight', | |
277 | dataIndex: 'crush_weight', | |
278 | align: 'right', | |
279 | renderer: function(value, metaData, rec) { | |
280 | if (rec.data.type !== 'osd') { | |
281 | return ''; | |
282 | } | |
283 | return value; | |
284 | }, | |
285 | width: 60 | |
286 | }, | |
287 | { | |
288 | text: 'reweight', | |
289 | dataIndex: 'reweight', | |
290 | align: 'right', | |
291 | renderer: function(value, metaData, rec) { | |
292 | if (rec.data.type !== 'osd') { | |
293 | return ''; | |
294 | } | |
295 | return value; | |
296 | }, | |
297 | width: 60 | |
298 | }, | |
299 | { | |
300 | header: gettext('Used'), | |
301 | columns: [ | |
302 | { | |
303 | text: '%', | |
304 | dataIndex: 'percent_used', | |
305 | align: 'right', | |
306 | renderer: function(value, metaData, rec) { | |
307 | if (rec.data.type !== 'osd') { | |
308 | return ''; | |
309 | } | |
310 | return Ext.util.Format.number(value, '0.00'); | |
311 | }, | |
312 | width: 80 | |
313 | }, | |
314 | { | |
315 | text: gettext('Total'), | |
316 | dataIndex: 'total_space', | |
317 | align: 'right', | |
318 | renderer: function(value, metaData, rec) { | |
319 | if (rec.data.type !== 'osd') { | |
320 | return ''; | |
321 | } | |
322 | return PVE.Utils.render_size(value); | |
323 | }, | |
324 | width: 100 | |
325 | } | |
326 | ] | |
327 | }, | |
328 | { | |
329 | header: gettext('Latency (ms)'), | |
330 | columns: [ | |
331 | { | |
332 | text: 'Apply', | |
333 | dataIndex: 'apply_latency_ms', | |
334 | align: 'right', | |
335 | renderer: function(value, metaData, rec) { | |
336 | if (rec.data.type !== 'osd') { | |
337 | return ''; | |
338 | } | |
339 | return value; | |
340 | }, | |
341 | width: 60 | |
342 | }, | |
343 | { | |
344 | text: 'Commit', | |
345 | dataIndex: 'commit_latency_ms', | |
346 | align: 'right', | |
347 | renderer: function(value, metaData, rec) { | |
348 | if (rec.data.type !== 'osd') { | |
349 | return ''; | |
350 | } | |
351 | return value; | |
352 | }, | |
353 | width: 60 | |
354 | } | |
355 | ] | |
356 | } | |
357 | ], | |
358 | listeners: { | |
359 | show: function() { | |
360 | reload(); | |
361 | } | |
362 | } | |
363 | }); | |
364 | ||
365 | me.callParent(); | |
366 | ||
367 | reload(); | |
368 | } | |
369 | }); |