]>
Commit | Line | Data |
---|---|---|
1 | // require("js/omv/tree/Panel.js") | |
2 | // require("js/omv/module/admin/storage/zfs/TreePanel.js") | |
3 | // require("js/omv/workspace/window/Grid.js") | |
4 | // require("js/omv/form/field/CheckboxGrid.js") | |
5 | ||
6 | Ext.define("OMV.module.admin.storage.zfs.AddPool", { | |
7 | extend: "OMV.workspace.window.Form", | |
8 | requires: [ | |
9 | "OMV.data.Store", | |
10 | "OMV.data.Model", | |
11 | "OMV.data.proxy.Rpc", | |
12 | "OMV.form.field.CheckboxGrid" | |
13 | ], | |
14 | ||
15 | rpcService: "ZFS", | |
16 | rpcSetMethod: "addPool", | |
17 | title: _("Create ZFS pool"), | |
18 | autoLoadData: false, | |
19 | hideResetButton: true, | |
20 | width: 550, | |
21 | height: 260, | |
22 | ||
23 | getFormItems: function() { | |
24 | var me = this; | |
25 | return [{ | |
26 | xtype: "textfield", | |
27 | name: "name", | |
28 | fieldLabel: _("Name") | |
29 | },{ | |
30 | xtype: "combo", | |
31 | name: "pooltype", | |
32 | fieldLabel: _("Pool type"), | |
33 | queryMode: "local", | |
34 | store: Ext.create("Ext.data.ArrayStore", { | |
35 | fields: [ "value", "text" ], | |
36 | data: [ | |
37 | [ "basic", _("Basic") ], | |
38 | [ "mirror", _("Mirror") ], | |
39 | [ "raidz1", _("RAID-Z1") ], | |
40 | [ "raidz2", _("RAID-Z2") ], | |
41 | [ "raidz3", _("RAID-Z3") ] | |
42 | ] | |
43 | }), | |
44 | displayField: "text", | |
45 | valueField: "value", | |
46 | allowBlank: false, | |
47 | editable: false, | |
48 | triggerAction: "all", | |
49 | value: "raidz1", | |
50 | listeners: { | |
51 | scope: me, | |
52 | change: function(combo, value) { | |
53 | var devicesField = this.findField("devices"); | |
54 | switch(value) { | |
55 | case "basic": | |
56 | devicesField.minSelections = 1; | |
57 | break; | |
58 | case "mirror": | |
59 | devicesField.minSelections = 2; | |
60 | break; | |
61 | case "raidz1": | |
62 | devicesField.minSelections = 3; | |
63 | break; | |
64 | case "raidz2": | |
65 | devicesField.minSelections = 4; | |
66 | case "raidz3": | |
67 | devicesField.minSelections = 5; | |
68 | break; | |
69 | default: | |
70 | devicesField.minSelections = 2; | |
71 | break; | |
72 | } | |
73 | devicesField.validate(); | |
74 | } | |
75 | } | |
76 | },{ | |
77 | xtype: "checkboxgridfield", | |
78 | name: "devices", | |
79 | fieldLabel: _("Devices"), | |
80 | valueField: "devicefile", | |
81 | minSelections: 3, // Min. number of devices for RAIDZ-1 | |
82 | useStringValue: true, | |
83 | height: 130, | |
84 | store: Ext.create("OMV.data.Store", { | |
85 | autoLoad: true, | |
86 | model: OMV.data.Model.createImplicit({ | |
87 | idProperty: "devicefile", | |
88 | fields: [ | |
89 | { name: "devicefile", type: "string" }, | |
90 | { name: "size", type: "string" }, | |
91 | { name: "vendor", type: "string" }, | |
92 | { name: "serialnumber", type: "string" } | |
93 | ] | |
94 | }), | |
95 | proxy: { | |
96 | type: "rpc", | |
97 | appendSortParams: false, | |
98 | rpcData: { | |
99 | service: "RaidMgmt", | |
100 | method: "getCandidates" | |
101 | } | |
102 | }, | |
103 | sorters: [{ | |
104 | direction: "ASC", | |
105 | property: "devicefile" | |
106 | }] | |
107 | }), | |
108 | gridConfig: { | |
109 | stateful: true, | |
110 | stateId: "1866b5d0-327e-11e4-8c21-0800200c9a66", | |
111 | columns: [{ | |
112 | text: _("Device"), | |
113 | sortable: true, | |
114 | dataIndex: "devicefile", | |
115 | stateId: "devicefile", | |
116 | flex: 1 | |
117 | },{ | |
118 | xtype: "binaryunitcolumn", | |
119 | text: _("Capacity"), | |
120 | sortable: true, | |
121 | dataIndex: "size", | |
122 | stateId: "size", | |
123 | width: 50, | |
124 | flex: 1 | |
125 | },{ | |
126 | text: _("Vendor"), | |
127 | sortable: true, | |
128 | dataIndex: "vendor", | |
129 | stateId: "vendor", | |
130 | flex: 1 | |
131 | },{ | |
132 | text: _("Serial Number"), | |
133 | sortable: true, | |
134 | dataIndex: "serialnumber", | |
135 | stateId: "serialnumber", | |
136 | flex: 1 | |
137 | }] | |
138 | } | |
139 | }]; | |
140 | }, | |
141 | ||
142 | doSubmit: function() { | |
143 | var me = this; | |
144 | OMV.MessageBox.show({ | |
145 | title: _("Confirmation"), | |
146 | msg: _("Do you really want to create the ZFS pool?"), | |
147 | buttons: Ext.Msg.YESNO, | |
148 | fn: function(answer) { | |
149 | if(answer === "no") | |
150 | return; | |
151 | me.superclass.doSubmit.call(me); | |
152 | }, | |
153 | scope: me, | |
154 | icon: Ext.Msg.QUESTION | |
155 | }); | |
156 | } | |
157 | }); | |
158 | ||
159 | Ext.define("OMV.module.admin.storage.zfs.AddObject", { | |
160 | extend: "OMV.workspace.window.Form", | |
161 | uses: [ | |
162 | "OMV.data.Store", | |
163 | "OMV.data.Model", | |
164 | "OMV.data.proxy.Rpc", | |
165 | "OMV.data.reader.RpcArray" | |
166 | ], | |
167 | ||
168 | rpcService: "ZFS", | |
169 | rpcSetMethod: "addObject", | |
170 | width: 420, | |
171 | ||
172 | getFormItems: function() { | |
173 | var me = this; | |
174 | return [{ | |
175 | xtype: "combo", | |
176 | name: "type", | |
177 | fieldLabel: _("Object Type"), | |
178 | queryMode: "local", | |
179 | store: [ | |
180 | [ "filesystem", "Filesystem" ], | |
181 | [ "snapshot", "Snapshot" ], | |
182 | [ "volume", "Volume" ] | |
183 | ], | |
184 | allowBlank: true, | |
185 | editable: false, | |
186 | triggerAction: "all", | |
187 | value: "filesystem", | |
188 | listeners: { | |
189 | scope: me, | |
190 | change: function(combo, value) { | |
191 | var sizeField = this.findField("size"); | |
192 | switch(value) { | |
193 | case "volume": | |
194 | sizeField.show(); | |
195 | sizeField.allowBlank = false; | |
196 | break; | |
197 | default: | |
198 | sizeField.hide(); | |
199 | sizeField.allowBlank = true; | |
200 | break; | |
201 | } | |
202 | sizeField.validate(); | |
203 | } | |
204 | } | |
205 | },{ | |
206 | xtype: "textfield", | |
207 | name: "path", | |
208 | fieldLabel: _("Prefix"), | |
209 | allowBlank: false, | |
210 | readOnly: true | |
211 | },{ | |
212 | xtype: "textfield", | |
213 | name: "name", | |
214 | fieldLabel: _("Name"), | |
215 | allowBlank: false, | |
216 | plugins: [{ | |
217 | ptype: "fieldinfo", | |
218 | text: _("Name of the new object. Prefix will prepend the name. Please omit leading /") | |
219 | }] | |
220 | },{ | |
221 | xtype: "textfield", | |
222 | name: "size", | |
223 | hidden: true, | |
224 | fieldLabel: _("Size"), | |
225 | allowBlank: true, | |
226 | plugins: [{ | |
227 | ptype: "fieldinfo", | |
228 | text: _("Size of the volume e.g. 5mb,100gb,1tb etc") | |
229 | }] | |
230 | }]; | |
231 | } | |
232 | }); | |
233 | ||
234 | ||
235 | ||
236 | Ext.define("OMV.module.admin.storage.zfs.EditProperties", { | |
237 | extend: "OMV.workspace.window.Grid", | |
238 | requires: [ | |
239 | "OMV.data.Store", | |
240 | "OMV.data.Model", | |
241 | "OMV.data.proxy.Rpc" | |
242 | ], | |
243 | ||
244 | rpcService: "ZFS", | |
245 | rpcSetMethod: "setProperties", | |
246 | ||
247 | title: _("Edit properties"), | |
248 | width: 500, | |
249 | height: 305, | |
250 | ||
251 | getGridConfig: function() { | |
252 | var me = this; | |
253 | ||
254 | var rowEditing = Ext.create('Ext.grid.plugin.RowEditing', { | |
255 | clicksToEdit: 1, | |
256 | pluginId: 'rowEditing', | |
257 | listeners: { | |
258 | validateedit: function(editor, e, eOpts) { | |
259 | e.record.set("modified", "true"); | |
260 | }, | |
261 | beforeedit: function(editor, e, eOpts) { | |
262 | if (e.record.get("property") === "mountpoint") { | |
263 | e.grid.getPlugin('rowEditing').editor.form.findField("value").disable(); | |
264 | e.grid.getPlugin('rowEditing').editor.form.findField("property").disable(); | |
265 | } else if (e.record.get("newproperty") === "false") { | |
266 | e.grid.getPlugin('rowEditing').editor.form.findField("value").enable(); | |
267 | e.grid.getPlugin('rowEditing').editor.form.findField("property").disable(); | |
268 | } else { | |
269 | e.grid.getPlugin('rowEditing').editor.form.findField("value").enable(); | |
270 | e.grid.getPlugin('rowEditing').editor.form.findField("property").enable(); | |
271 | } | |
272 | } | |
273 | ||
274 | } | |
275 | }); | |
276 | ||
277 | var store = Ext.create("OMV.data.Store", { | |
278 | autoLoad: true, | |
279 | model: OMV.data.Model.createImplicit({ | |
280 | fields: [ | |
281 | { name: "property", type: "string" }, | |
282 | { name: "value", type: "string" }, | |
283 | { name: "source", type: "string" }, | |
284 | { name: "modified", type: "string" }, | |
285 | { name: "newproperty", type: "string", defaultValue: "false" } | |
286 | ] | |
287 | }), | |
288 | proxy: { | |
289 | type: "rpc", | |
290 | rpcData: { | |
291 | service: "ZFS", | |
292 | method: "getProperties", | |
293 | params: { | |
294 | name: me.name, | |
295 | type: me.type | |
296 | } | |
297 | } | |
298 | } | |
299 | }); | |
300 | ||
301 | return { | |
302 | border: false, | |
303 | stateful: true, | |
304 | stateId: "8c3dc800-bdbb-11e3-b1b6-0800200c9a66", | |
305 | selType: 'rowmodel', | |
306 | plugins: [rowEditing], | |
307 | store: store, | |
308 | tbar: [{ | |
309 | text: "Add property", | |
310 | icon: "images/add.png", | |
311 | iconCls: Ext.baseCSSPrefix + "btn-icon-16x16", | |
312 | handler: function(view) { | |
313 | Ext.define('Property', { | |
314 | extend: 'Ext.data.Model', | |
315 | fields: [ | |
316 | "property", | |
317 | "value", | |
318 | "source", | |
319 | "modified", | |
320 | "newproperty" | |
321 | ] | |
322 | }); | |
323 | var newProperty = Ext.create("Property", { | |
324 | property: "", | |
325 | value: "", | |
326 | source: "local", | |
327 | modified: "true", | |
328 | newproperty: "true" | |
329 | }); | |
330 | rowEditing.cancelEdit(); | |
331 | store.insert(0, newProperty); | |
332 | rowEditing.startEdit(); | |
333 | } | |
334 | }], | |
335 | columns: [{ | |
336 | text: _("Property"), | |
337 | sortable: true, | |
338 | dataIndex: "property", | |
339 | stateId: "property", | |
340 | editor: { | |
341 | xtype: "textfield", | |
342 | allowBlank: false, | |
343 | } | |
344 | },{ | |
345 | text: _("Value"), | |
346 | sortable: true, | |
347 | dataIndex: "value", | |
348 | stateId: "value", | |
349 | flex: 1, | |
350 | readOnly: true, | |
351 | editor: { | |
352 | xtype: "textfield", | |
353 | allowBlank: false, | |
354 | } | |
355 | },{ | |
356 | text: _("Source"), | |
357 | sortable: true, | |
358 | dataIndex: "source", | |
359 | stateId: "source", | |
360 | },{ | |
361 | xtype: 'actioncolumn', | |
362 | header: 'Inherit', | |
363 | icon: "images/checkmark.png", | |
364 | tooltip: "Inherit", | |
365 | handler: function(view, rowIndex, colIndex, item, e, record, row) { | |
366 | OMV.RpcObserver.request({ | |
367 | msg : _("Updating property..."), | |
368 | rpcData : { | |
369 | service: "ZFS", | |
370 | method: "inherit", | |
371 | params: { | |
372 | name: me.name, | |
373 | type: me.type, | |
374 | property: record.get("property") | |
375 | } | |
376 | }, | |
377 | finish : function() { | |
378 | view.getStore().reload(); | |
379 | } | |
380 | }); | |
381 | }, | |
382 | isDisabled: function(view, rowIdx, colIdx, item, record) { | |
383 | var src = record.get("source"); | |
384 | if(src === "local") { | |
385 | return false; | |
386 | } else { | |
387 | return true; | |
388 | } | |
389 | } | |
390 | },{ | |
391 | text: _("New"), | |
392 | dataIndex: "newproperty", | |
393 | stateId: "newproperty", | |
394 | sortable: false, | |
395 | hidden: true | |
396 | },{ | |
397 | text: _("Modified"), | |
398 | sortable: false, | |
399 | dataIndex: "modified", | |
400 | stateId: "modified", | |
401 | hidden: true | |
402 | }], | |
403 | }; | |
404 | }, | |
405 | ||
406 | getRpcSetParams: function() { | |
407 | var me = this; | |
408 | var properties = []; | |
409 | var values = me.getValues(); | |
410 | Ext.Array.each(values, function(value) { | |
411 | if(value.modified === "false") | |
412 | return; | |
413 | properties.push({ | |
414 | "property": value.property, | |
415 | "value": value.value, | |
416 | }); | |
417 | }); | |
418 | return { | |
419 | name: me.name, | |
420 | type: me.type, | |
421 | properties: properties | |
422 | }; | |
423 | } | |
424 | ||
425 | }); | |
426 | ||
427 | ||
428 | Ext.define("OMV.module.admin.storage.zfs.CreateShare", { | |
429 | extend: "OMV.workspace.window.Form", | |
430 | uses: [ | |
431 | "OMV.data.Store", | |
432 | "OMV.data.Model", | |
433 | "OMV.data.proxy.Rpc", | |
434 | "OMV.data.reader.RpcArray" | |
435 | ], | |
436 | ||
437 | rpcService: "ZFS", | |
438 | rpcSetMethod: "createShare", | |
439 | width: 500, | |
440 | ||
441 | getFormItems: function() { | |
442 | var me = this; | |
443 | return [{ | |
444 | xtype: "textfield", | |
445 | name: "sharename", | |
446 | fieldLabel: _("Name"), | |
447 | allowBlank: false, | |
448 | },{ | |
449 | xtype: "textfield", | |
450 | name: "mountpoint", | |
451 | fieldLabel: _("Path"), | |
452 | allowBlank: false, | |
453 | readOnly: true | |
454 | },{ | |
455 | xtype: "combo", | |
456 | name: "mode", | |
457 | fieldLabel: _("Permissions"), | |
458 | queryMode: "local", | |
459 | store: Ext.create("Ext.data.ArrayStore", { | |
460 | fields: [ "value", "text" ], | |
461 | data: [ | |
462 | [ "700", _("Administrator: read/write, Users: no access, Others: no access") ], | |
463 | [ "750", _("Administrator: read/write, Users: read-only, Others: no access") ], | |
464 | [ "770", _("Administrator: read/write, Users: read/write, Others: no access") ], | |
465 | [ "755", _("Administrator: read/write, Users: read-only, Others: read-only") ], | |
466 | [ "775", _("Administrator: read/write, Users: read/write, Others: read-only") ], | |
467 | [ "777", _("Everyone: read/write") ] | |
468 | ] | |
469 | }), | |
470 | displayField: "text", | |
471 | valueField: "value", | |
472 | allowBlank: false, | |
473 | editable: false, | |
474 | showItemTooltip: true, | |
475 | triggerAction: "all", | |
476 | value: "775", | |
477 | plugins: [{ | |
478 | ptype: "fieldinfo", | |
479 | text: _("The file mode of the shared folder path.") | |
480 | }] | |
481 | },{ | |
482 | xtype: "textarea", | |
483 | name: "comment", | |
484 | fieldLabel: _("Comment"), | |
485 | allowBlank: true | |
486 | },{ | |
487 | xtype: "textarea", | |
488 | name: "name", | |
489 | hidden: true | |
490 | },{ | |
491 | xtype: "textarea", | |
492 | name: "type", | |
493 | hidden: true | |
494 | }]; | |
495 | } | |
496 | }); | |
497 | ||
498 | ||
499 | ||
500 | Ext.define("OMV.module.admin.storage.zfs.Overview", { | |
501 | extend: "OMV.module.admin.storage.zfs.TreePanel", | |
502 | ||
503 | rpcService: "ZFS", | |
504 | rpcGetMethod: "getObjectTree", | |
505 | requires: [ | |
506 | "OMV.data.Store", | |
507 | "OMV.data.Model", | |
508 | "OMV.data.proxy.Rpc" | |
509 | ], | |
510 | ||
511 | rootVisible: false, | |
512 | stateful: true, | |
513 | stateId: "cec54550-bc2a-11e3-a5e2-0800200c9a66", | |
514 | ||
515 | columns: [{ | |
516 | text: _("Name"), | |
517 | xtype: 'treecolumn', | |
518 | dataIndex: 'name', | |
519 | sortable: true, | |
520 | flex: 2, | |
521 | stateId: 'name' | |
522 | },{ | |
523 | text: _("Type"), | |
524 | dataIndex: 'type', | |
525 | sortable: true, | |
526 | flex: 1, | |
527 | stateId: 'type' | |
528 | },{ | |
529 | text: _("Share"), | |
530 | xtype: 'actioncolumn', | |
531 | tooltip: 'Create shared folder', | |
532 | align: 'center', | |
533 | icon: 'images/checkmark.png', | |
534 | handler: function(view, rowIndex, colIndex, item, e, record, row) { | |
535 | var me = this; | |
536 | Ext.create("OMV.module.admin.storage.zfs.CreateShare", { | |
537 | title: _("Create shared folder"), | |
538 | rpcGetMethod: "getSharedParams", | |
539 | rpcGetParams: { | |
540 | name: record.get('path'), | |
541 | type: record.get('type') | |
542 | } | |
543 | }).show(); | |
544 | }, | |
545 | isDisabled: function(view, rowIdx, colIdx, item, record) { | |
546 | var src = record.get("type"); | |
547 | if((src === "Filesystem") && (record.get("shared") === "false")) { | |
548 | return false; | |
549 | } else { | |
550 | return true; | |
551 | } | |
552 | } | |
553 | ||
554 | ||
555 | },{ | |
556 | text: _("Details"), | |
557 | xtype: 'actioncolumn', | |
558 | tooltip: 'Details', | |
559 | align: 'center', | |
560 | icon: 'images/zfs_mag.png' | |
561 | },{ | |
562 | text: _("Shared"), | |
563 | dataIndex: 'shared', | |
564 | sortable: false, | |
565 | stateId: 'shared', | |
566 | hidden: true | |
567 | }], | |
568 | ||
569 | initComponent: function() { | |
570 | var me = this; | |
571 | this.width = 600; | |
572 | Ext.apply(me, { | |
573 | store: Ext.create("Ext.data.TreeStore", { | |
574 | autoLoad: true, | |
575 | model: OMV.data.Model.createImplicit({ | |
576 | fields: [ | |
577 | { name: "name", type: "string" }, | |
578 | { name: "type", type: "string" }, | |
579 | { name: "id", type: "string" }, | |
580 | { name: "path", type: "string" }, | |
581 | { name: "origin", type: "string", defaultValue: "none" }, | |
582 | { name: "shared", type: "string", defaultValue: "false" } | |
583 | ] | |
584 | }), | |
585 | proxy: { | |
586 | type: "rpc", | |
587 | rpcData: { | |
588 | service: "ZFS", | |
589 | method: "getObjectTree", | |
590 | } | |
591 | }, | |
592 | folderSort: true | |
593 | }) | |
594 | }); | |
595 | me.callParent(arguments); | |
596 | }, | |
597 | ||
598 | onAddButton: function() { | |
599 | var me = this; | |
600 | Ext.create("OMV.module.admin.storage.zfs.AddPool", { | |
601 | listeners: { | |
602 | scope: me, | |
603 | submit: function() { | |
604 | this.doReload(); | |
605 | } | |
606 | } | |
607 | }).show(); | |
608 | }, | |
609 | ||
610 | onAddObjButton: function() { | |
611 | var me = this; | |
612 | var sm = me.getSelectionModel(); | |
613 | var records = sm.getSelection(); | |
614 | var record = records[0]; | |
615 | Ext.create("OMV.module.admin.storage.zfs.AddObject", { | |
616 | title: _("Add Object"), | |
617 | rpcGetMethod: "passParam", | |
618 | rpcGetParams: { | |
619 | key: "path", | |
620 | value: record.get('path') | |
621 | }, | |
622 | listeners: { | |
623 | scope: me, | |
624 | submit: function() { | |
625 | this.doReload(); | |
626 | } | |
627 | } | |
628 | }).show(); | |
629 | }, | |
630 | ||
631 | onEditButton: function() { | |
632 | var me = this; | |
633 | var sm = me.getSelectionModel(); | |
634 | var records = sm.getSelection(); | |
635 | var record = records[0]; | |
636 | Ext.create("OMV.module.admin.storage.zfs.EditProperties", { | |
637 | name: record.get("path"), | |
638 | type: record.get("type") | |
639 | }).show(); | |
640 | }, | |
641 | ||
642 | doDeletion: function(record) { | |
643 | var me = this; | |
644 | OMV.Rpc.request({ | |
645 | scope: me, | |
646 | callback: me.onDeletion, | |
647 | rpcData: { | |
648 | service: "ZFS", | |
649 | method: "deleteObject", | |
650 | params: { | |
651 | name: record.get('path'), | |
652 | type: record.get('type') | |
653 | } | |
654 | } | |
655 | }); | |
656 | } | |
657 | ||
658 | }); | |
659 | ||
660 | OMV.WorkspaceManager.registerPanel({ | |
661 | id: "overview", | |
662 | path: "/storage/zfs", | |
663 | text: _("Overview"), | |
664 | position: 10, | |
665 | className: "OMV.module.admin.storage.zfs.Overview" | |
666 | }); | |
667 | ||
668 | ||
669 |