]> git.proxmox.com Git - pve-manager.git/blob - www/manager6/ceph/FS.js
added basic ability to install ceph via gui
[pve-manager.git] / www / manager6 / ceph / FS.js
1 /*jslint confusion: true */
2 Ext.define('PVE.CephCreateFS', {
3 extend: 'Proxmox.window.Edit',
4 alias: 'widget.pveCephCreateFS',
5
6 showTaskViewer: true,
7 onlineHelp: 'pveceph_fs_create',
8
9 subject: 'Ceph FS',
10 isCreate: true,
11 method: 'POST',
12
13 setFSName: function(fsName) {
14 var me = this;
15
16 if (fsName === '' || fsName === undefined) {
17 fsName = 'cephfs';
18 }
19
20 me.url = "/nodes/" + me.nodename + "/ceph/fs/" + fsName;
21 },
22
23 items: [
24 {
25 xtype: 'textfield',
26 fieldLabel: gettext('Name'),
27 name: 'name',
28 value: 'cephfs',
29 listeners: {
30 change: function(f, value) {
31 this.up('pveCephCreateFS').setFSName(value);
32 }
33 },
34 submitValue: false, // already encoded in apicall URL
35 emptyText: 'cephfs'
36 },
37 {
38 xtype: 'proxmoxintegerfield',
39 fieldLabel: 'Placement Groups',
40 name: 'pg_num',
41 value: 128,
42 emptyText: 128,
43 minValue: 8,
44 maxValue: 32768,
45 allowBlank: false
46 },
47 {
48 xtype: 'proxmoxcheckbox',
49 fieldLabel: gettext('Add Storage'),
50 value: true,
51 name: 'add-storage'
52 }
53 ],
54
55 initComponent : function() {
56 var me = this;
57
58 if (!me.nodename) {
59 throw "no node name specified";
60 }
61 me.setFSName();
62
63 me.callParent();
64 }
65 });
66
67 Ext.define('PVE.CephCreateMDS', {
68 extend: 'Proxmox.window.Edit',
69 alias: 'widget.pveCephCreateMDS',
70
71 showProgress: true,
72 onlineHelp: 'pveceph_fs_mds',
73
74 subject: 'Ceph MDS',
75 isCreate: true,
76 method: 'POST',
77
78 setNode: function(nodename) {
79 var me = this;
80
81 me.nodename = nodename;
82 me.url = "/nodes/" + nodename + "/ceph/mds/" + nodename;
83 },
84
85 items: [
86 {
87 xtype: 'pveNodeSelector',
88 fieldLabel: gettext('Node'),
89 selectCurNode: true,
90 submitValue: false,
91 allowBlank: false,
92 listeners: {
93 change: function(f, value) {
94 this.up('pveCephCreateMDS').setNode(value);
95 }
96 }
97 }
98 ],
99
100 initComponent : function() {
101 var me = this;
102
103 if (!me.nodename) {
104 throw "no node name specified";
105 }
106 me.setNode(me.nodename);
107
108 me.callParent();
109 }
110 });
111
112 Ext.define('PVE.NodeCephFSPanel', {
113 extend: 'Ext.panel.Panel',
114 xtype: 'pveNodeCephFSPanel',
115 mixins: ['Proxmox.Mixin.CBind'],
116
117 title: gettext('CephFS'),
118 onlineHelp: 'pveceph_fs',
119
120 border: false,
121 defaults: {
122 border: false,
123 cbind: {
124 nodename: '{nodename}'
125 }
126 },
127
128 viewModel: {
129 parent: null,
130 data: {
131 cephfsConfigured: false,
132 mdsCount: 0
133 },
134 formulas: {
135 canCreateFS: function(get) {
136 return (!get('cephfsConfigured') && get('mdsCount') > 0);
137 }
138 }
139 },
140
141 items: [
142 {
143 xtype: 'grid',
144 emptyText: Ext.String.format(gettext('No {0} configured.'), 'CephFS'),
145 controller: {
146 xclass: 'Ext.app.ViewController',
147
148 init: function(view) {
149 view.rstore = Ext.create('Proxmox.data.UpdateStore', {
150 autoLoad: true,
151 xtype: 'update',
152 interval: 5 * 1000,
153 autoStart: true,
154 storeid: 'pve-ceph-fs',
155 model: 'pve-ceph-fs'
156 });
157 view.setStore(Ext.create('Proxmox.data.DiffStore', {
158 rstore: view.rstore,
159 sorters: {
160 property: 'name',
161 order: 'DESC'
162 }
163 }));
164 var regex = new RegExp("not (installed|initialized)", "i");
165 PVE.Utils.handleStoreErrorOrMask(view, view.rstore, regex, function(me, error){
166 me.rstore.stopUpdate();
167 PVE.Utils.showCephInstallOrMask(me.ownerCt, error.statusText, view.nodename,
168 function(win){
169 me.mon(win, 'cephInstallWindowClosed', function(){
170 me.rstore.startUpdate();
171 });
172 }
173 );
174 });
175 view.rstore.on('load', this.onLoad, this);
176 view.on('destroy', view.rstore.stopUpdate);
177 },
178
179 onCreate: function() {
180 var view = this.getView();
181 view.rstore.stopUpdate();
182 var win = Ext.create('PVE.CephCreateFS', {
183 autoShow: true,
184 nodename: view.nodename,
185 listeners: {
186 destroy: function() {
187 view.rstore.startUpdate();
188 }
189 }
190 });
191 },
192
193 onLoad: function(store, records, success) {
194 var vm = this.getViewModel();
195 if (!(success && records && records.length > 0)) {
196 vm.set('cephfsConfigured', false);
197 return;
198 }
199 vm.set('cephfsConfigured', true);
200 }
201 },
202 tbar: [
203 {
204 text: gettext('Create CephFS'),
205 reference: 'createButton',
206 handler: 'onCreate',
207 bind: {
208 // only one CephFS per Ceph cluster makes sense for now
209 disabled: '{!canCreateFS}'
210 }
211 }
212 ],
213 columns: [
214 {
215 header: gettext('Name'),
216 flex: 1,
217 dataIndex: 'name'
218 },
219 {
220 header: 'Data Pool',
221 flex: 1,
222 dataIndex: 'data_pool'
223 },
224 {
225 header: 'Metadata Pool',
226 flex: 1,
227 dataIndex: 'metadata_pool'
228 }
229 ],
230 cbind: {
231 nodename: '{nodename}'
232 }
233 },
234 {
235 xtype: 'grid',
236 title: gettext('Metadata Servers'),
237 emptyText: Ext.String.format(gettext('No {0} configured.'), 'MDS'),
238 controller: {
239 xclass: 'Ext.app.ViewController',
240
241 init: function(view) {
242 view.rstore = Ext.create('Proxmox.data.UpdateStore', {
243 autoLoad: true,
244 xtype: 'update',
245 interval: 3 * 1000,
246 autoStart: true,
247 storeid: 'pve-ceph-mds',
248 model: 'pve-ceph-mds'
249 });
250 view.setStore(Ext.create('Proxmox.data.DiffStore', {
251 rstore: view.rstore,
252 sorters: {
253 property: 'id',
254 order: 'DESC'
255 }
256 }));
257 var regex = new RegExp("not (installed|initialized)", "i");
258 PVE.Utils.handleStoreErrorOrMask(view, view.rstore, regex, function(me, error){
259 me.rstore.stopUpdate();
260 PVE.Utils.showCephInstallOrMask(me.ownerCt, error.statusText, view.nodename,
261 function(win){
262 me.mon(win, 'cephInstallWindowClosed', function(){
263 me.rstore.startUpdate();
264 });
265 }
266 );
267 });
268 view.rstore.on('load', this.onLoad, this);
269 view.on('destroy', view.rstore.stopUpdate);
270 },
271 onLoad: function(store, records, success) {
272 var vm = this.getViewModel();
273 if (!success || !records) {
274 vm.set('mdsCount', 0);
275 return;
276 }
277 vm.set('mdsCount', records.length);
278 },
279 onCreateMDS: function() {
280 var view = this.getView();
281 view.rstore.stopUpdate();
282 var win = Ext.create('PVE.CephCreateMDS', {
283 autoShow: true,
284 nodename: view.nodename,
285 listeners: {
286 destroy: function() {
287 view.rstore.startUpdate();
288 }
289 }
290 });
291 }
292 },
293 tbar: [
294 {
295 text: gettext('Create MDS'),
296 reference: 'createButton',
297 handler: 'onCreateMDS'
298 },
299 {
300 text: gettext('Destroy MDS'),
301 xtype: 'proxmoxStdRemoveButton',
302 getUrl: function(rec) {
303 if (!rec.data.host) {
304 Ext.Msg.alert(gettext('Error'), "entry has no host");
305 return;
306 }
307 return "/nodes/" + rec.data.host + "/ceph/mds/" + rec.data.name;
308 },
309 callback: function(options, success, response) {
310 if (!success) {
311 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
312 return;
313 }
314 var upid = response.result.data;
315 var win = Ext.create('Proxmox.window.TaskProgress', { upid: upid });
316 win.show();
317 }
318 }
319 ],
320 columns: [
321 {
322 header: gettext('Name'),
323 flex: 1,
324 dataIndex: 'name'
325 },
326 {
327 header: gettext('Host'),
328 flex: 1,
329 dataIndex: 'host'
330 },
331 {
332 header: gettext('Address'),
333 flex: 1,
334 dataIndex: 'addr'
335 },
336 {
337 header: gettext('State'),
338 flex: 1,
339 dataIndex: 'state'
340 }
341 ],
342 cbind: {
343 nodename: '{nodename}'
344 }
345 }
346 ]
347 }, function() {
348 Ext.define('pve-ceph-mds', {
349 extend: 'Ext.data.Model',
350 fields: [ 'name', 'host', 'addr', 'state' ],
351 proxy: {
352 type: 'proxmox',
353 url: "/api2/json/nodes/localhost/ceph/mds"
354 },
355 idProperty: 'name'
356 });
357 Ext.define('pve-ceph-fs', {
358 extend: 'Ext.data.Model',
359 fields: [ 'name', 'data_pool', 'metadata_pool' ],
360 proxy: {
361 type: 'proxmox',
362 url: "/api2/json/nodes/localhost/ceph/fs"
363 },
364 idProperty: 'name'
365 });
366 });