]>
Commit | Line | Data |
---|---|---|
ab2fac2f DM |
1 | /*jslint confusion: true */ |
2 | var labelWidth = 120; | |
3 | ||
4 | Ext.define('PVE.lxc.MemoryEdit', { | |
5 | extend: 'PVE.window.Edit', | |
6 | ||
7 | initComponent : function() { | |
8 | var me = this; | |
9 | ||
10 | Ext.apply(me, { | |
11 | subject: gettext('Memory'), | |
12 | items: Ext.create('PVE.lxc.MemoryInputPanel') | |
13 | }); | |
14 | ||
15 | me.callParent(); | |
16 | ||
17 | me.load(); | |
18 | } | |
19 | }); | |
20 | ||
21 | ||
22 | Ext.define('PVE.lxc.CPUEdit', { | |
23 | extend: 'PVE.window.Edit', | |
24 | ||
25 | initComponent : function() { | |
26 | var me = this; | |
27 | ||
28 | Ext.apply(me, { | |
29 | subject: gettext('CPU'), | |
30 | items: Ext.create('PVE.lxc.CPUInputPanel') | |
31 | }); | |
32 | ||
33 | me.callParent(); | |
34 | ||
35 | me.load(); | |
36 | } | |
37 | }); | |
38 | ||
39 | Ext.define('PVE.lxc.MountPointEdit', { | |
40 | extend: 'PVE.window.Edit', | |
41 | ||
42 | initComponent : function() { | |
43 | var me = this; | |
44 | ||
45 | var nodename = me.pveSelNode.data.node; | |
46 | if (!nodename) { | |
47 | throw "no node name specified"; | |
48 | } | |
49 | ||
50 | var unused = me.confid && me.confid.match(/^unused\d+$/); | |
51 | ||
d5e771ce | 52 | me.isCreate = me.confid ? unused : true; |
ab2fac2f DM |
53 | |
54 | var ipanel = Ext.create('PVE.lxc.MountPointInputPanel', { | |
55 | confid: me.confid, | |
56 | nodename: nodename, | |
57 | unused: unused, | |
d5e771ce | 58 | isCreate: me.isCreate |
ab2fac2f DM |
59 | }); |
60 | ||
61 | var subject; | |
62 | if (unused) { | |
185a77e5 | 63 | subject = gettext('Unused Disk'); |
d5e771ce | 64 | } else if (me.isCreate) { |
ab2fac2f DM |
65 | subject = gettext('Mount Point'); |
66 | } else { | |
67 | subject = gettext('Mount Point') + ' (' + me.confid + ')'; | |
68 | } | |
69 | ||
70 | Ext.apply(me, { | |
71 | subject: subject, | |
72 | items: ipanel | |
73 | }); | |
74 | ||
75 | me.callParent(); | |
76 | ||
77 | me.load({ | |
78 | success: function(response, options) { | |
79 | ipanel.setVMConfig(response.result.data); | |
80 | if (me.confid) { | |
81 | var value = response.result.data[me.confid]; | |
82 | var mp = PVE.Parser.parseLxcMountPoint(value); | |
83 | ||
84 | if (!mp) { | |
185a77e5 | 85 | Ext.Msg.alert(gettext('Error'), 'Unable to parse mount point options'); |
ab2fac2f DM |
86 | me.close(); |
87 | return; | |
88 | } | |
89 | ||
90 | ipanel.setMountPoint(mp); | |
91 | me.isValid(); // trigger validation | |
92 | } | |
93 | } | |
94 | }); | |
95 | } | |
96 | }); | |
97 | ||
98 | Ext.define('PVE.lxc.CPUInputPanel', { | |
99 | extend: 'PVE.panel.InputPanel', | |
100 | alias: 'widget.pveLxcCPUInputPanel', | |
101 | ||
cb38d277 DC |
102 | onlineHelp: 'pct_cpu', |
103 | ||
ab2fac2f DM |
104 | insideWizard: false, |
105 | ||
92b5029f DM |
106 | onGetValues: function(values) { |
107 | var me = this; | |
108 | ||
fe4f00ad TL |
109 | PVE.Utils.delete_if_default(values, 'cores', '', me.insideWizard); |
110 | // cpu{limit,unit} aren't in the wizard so create is always false | |
111 | PVE.Utils.delete_if_default(values, 'cpulimit', '0', 0); | |
112 | PVE.Utils.delete_if_default(values, 'cpuunits', '1024', 0); | |
92b5029f DM |
113 | |
114 | return values; | |
115 | }, | |
116 | ||
ab2fac2f DM |
117 | initComponent : function() { |
118 | var me = this; | |
119 | ||
92b5029f DM |
120 | var column1 = [ |
121 | { | |
8a7e5598 | 122 | xtype: 'pveIntegerField', |
92b5029f DM |
123 | name: 'cores', |
124 | minValue: 1, | |
125 | maxValue: 128, | |
92b5029f DM |
126 | value: me.insideWizard ? 1 : '', |
127 | fieldLabel: gettext('Cores'), | |
128 | allowBlank: true, | |
129 | emptyText: gettext('unlimited') | |
130 | } | |
131 | ]; | |
132 | ||
133 | var column2 = [ | |
ab2fac2f DM |
134 | { |
135 | xtype: 'numberfield', | |
136 | name: 'cpulimit', | |
137 | minValue: 0, | |
92b5029f | 138 | value: '', |
ab2fac2f DM |
139 | step: 1, |
140 | fieldLabel: gettext('CPU limit'), | |
141 | labelWidth: labelWidth, | |
92b5029f DM |
142 | allowBlank: true, |
143 | emptyText: gettext('unlimited') | |
ab2fac2f DM |
144 | }, |
145 | { | |
8a7e5598 | 146 | xtype: 'pveIntegerField', |
ab2fac2f DM |
147 | name: 'cpuunits', |
148 | fieldLabel: gettext('CPU units'), | |
149 | value: 1024, | |
150 | minValue: 8, | |
151 | maxValue: 500000, | |
152 | labelWidth: labelWidth, | |
153 | allowBlank: false | |
154 | } | |
155 | ]; | |
156 | ||
157 | if (me.insideWizard) { | |
92b5029f | 158 | me.column1 = column1; |
ab2fac2f | 159 | } else { |
92b5029f DM |
160 | me.column1 = column1; |
161 | me.column2 = column2; | |
ab2fac2f DM |
162 | } |
163 | ||
164 | me.callParent(); | |
165 | } | |
166 | }); | |
167 | ||
168 | Ext.define('PVE.lxc.MemoryInputPanel', { | |
169 | extend: 'PVE.panel.InputPanel', | |
170 | alias: 'widget.pveLxcMemoryInputPanel', | |
171 | ||
cb38d277 DC |
172 | onlineHelp: 'pct_memory', |
173 | ||
ab2fac2f DM |
174 | insideWizard: false, |
175 | ||
176 | initComponent : function() { | |
177 | var me = this; | |
178 | ||
179 | var items = [ | |
180 | { | |
8a7e5598 | 181 | xtype: 'pveIntegerField', |
ab2fac2f DM |
182 | name: 'memory', |
183 | minValue: 32, | |
184 | maxValue: 512*1024, | |
185 | value: '512', | |
186 | step: 32, | |
187 | fieldLabel: gettext('Memory') + ' (MB)', | |
188 | labelWidth: labelWidth, | |
189 | allowBlank: false | |
190 | }, | |
191 | { | |
8a7e5598 | 192 | xtype: 'pveIntegerField', |
ab2fac2f DM |
193 | name: 'swap', |
194 | minValue: 0, | |
195 | maxValue: 128*1024, | |
196 | value: '512', | |
197 | step: 32, | |
198 | fieldLabel: gettext('Swap') + ' (MB)', | |
199 | labelWidth: labelWidth, | |
200 | allowBlank: false | |
201 | } | |
202 | ]; | |
203 | ||
204 | if (me.insideWizard) { | |
205 | me.column1 = items; | |
206 | } else { | |
207 | me.items = items; | |
208 | } | |
209 | ||
210 | me.callParent(); | |
211 | } | |
212 | }); | |
213 | ||
214 | Ext.define('PVE.lxc.MountPointInputPanel', { | |
215 | extend: 'PVE.panel.InputPanel', | |
216 | alias: 'widget.pveLxcMountPointInputPanel', | |
217 | ||
218 | insideWizard: false, | |
219 | ||
c8802a60 | 220 | onlineHelp: 'pct_container_storage', |
7f1ac74c | 221 | |
ab2fac2f DM |
222 | unused: false, // ADD usused disk imaged |
223 | ||
224 | vmconfig: {}, // used to select usused disks | |
225 | ||
226 | onGetValues: function(values) { | |
227 | var me = this; | |
228 | ||
229 | var confid = me.confid || values.mpsel; | |
230 | ||
231 | if (me.unused) { | |
232 | me.mpdata.file = me.vmconfig[values.unusedId]; | |
233 | confid = values.mpsel; | |
d5e771ce | 234 | } else if (me.isCreate) { |
ab2fac2f DM |
235 | me.mpdata.file = values.storage + ':' + values.disksize; |
236 | } | |
237 | ||
238 | if (confid !== 'rootfs') { | |
239 | me.mpdata.mp = values.mp; | |
240 | } | |
241 | ||
242 | if (values.ro) { | |
243 | me.mpdata.ro = 1; | |
244 | } else { | |
245 | delete me.mpdata.ro; | |
246 | } | |
247 | ||
248 | if (values.quota) { | |
249 | me.mpdata.quota = 1; | |
250 | } else { | |
251 | delete me.mpdata.quota; | |
252 | } | |
253 | ||
254 | if (values.acl === 'Default') { | |
255 | delete me.mpdata.acl; | |
256 | } else { | |
257 | me.mpdata.acl = values.acl; | |
258 | } | |
259 | ||
47e36cf6 DC |
260 | if (values.backup) { |
261 | me.mpdata.backup = 1; | |
262 | } else { | |
263 | delete me.mpdata.backup; | |
264 | } | |
265 | ||
ab2fac2f DM |
266 | var res = {}; |
267 | res[confid] = PVE.Parser.printLxcMountPoint(me.mpdata); | |
268 | return res; | |
269 | }, | |
270 | ||
271 | setMountPoint: function(mp) { | |
272 | var me = this; | |
273 | ||
274 | me.mpdata = mp; | |
275 | if (!Ext.isDefined(me.mpdata.acl)) { | |
276 | me.mpdata.acl = 'Default'; | |
277 | } | |
278 | ||
279 | if (mp.type === 'bind') { | |
280 | me.quota.setDisabled(true); | |
281 | me.quota.setValue(false); | |
17ab437f | 282 | me.acl.setDisabled(true); |
47e36cf6 | 283 | me.backup.setDisabled(true); |
17ab437f | 284 | me.acl.setValue('Default'); |
494b650e | 285 | me.hdstoragesel.setDisabled(true); |
ab2fac2f DM |
286 | } |
287 | ||
288 | me.setValues(mp); | |
289 | }, | |
290 | ||
291 | setVMConfig: function(vmconfig) { | |
292 | var me = this; | |
293 | ||
294 | me.vmconfig = vmconfig; | |
295 | ||
296 | if (me.mpsel) { | |
297 | var i; | |
298 | for (i = 0; i != 8; ++i) { | |
299 | var name = "mp" + i; | |
300 | if (!Ext.isDefined(vmconfig[name])) { | |
301 | me.mpsel.setValue(name); | |
302 | break; | |
303 | } | |
304 | } | |
305 | } | |
306 | ||
307 | if (me.unusedDisks) { | |
308 | var disklist = []; | |
309 | Ext.Object.each(vmconfig, function(key, value) { | |
310 | if (key.match(/^unused\d+$/)) { | |
311 | disklist.push([key, value]); | |
312 | } | |
313 | }); | |
314 | me.unusedDisks.store.loadData(disklist); | |
315 | me.unusedDisks.setValue(me.confid); | |
316 | } | |
317 | }, | |
318 | ||
319 | setNodename: function(nodename) { | |
320 | var me = this; | |
321 | me.hdstoragesel.setNodename(nodename); | |
322 | me.hdfilesel.setStorage(undefined, nodename); | |
323 | }, | |
324 | ||
325 | initComponent : function() { | |
326 | var me = this; | |
327 | ||
328 | var isroot = me.confid === 'rootfs'; | |
329 | ||
330 | me.mpdata = {}; | |
331 | ||
332 | me.column1 = []; | |
333 | ||
334 | if (!me.confid || me.unused) { | |
335 | var names = []; | |
336 | var i; | |
337 | for (i = 0; i != 8; ++i) { | |
338 | var name = 'mp' + i; | |
339 | names.push([name, name]); | |
340 | } | |
341 | me.mpsel = Ext.create('PVE.form.KVComboBox', { | |
342 | name: 'mpsel', | |
343 | fieldLabel: gettext('Mount Point'), | |
344 | matchFieldWidth: false, | |
345 | allowBlank: false, | |
0b409147 | 346 | comboItems: names, |
ab2fac2f DM |
347 | validator: function(value) { |
348 | if (!me.rendered) { | |
349 | return; | |
350 | } | |
351 | if (Ext.isDefined(me.vmconfig[value])) { | |
352 | return "Mount point is already in use."; | |
353 | } | |
354 | return true; | |
355 | }, | |
356 | listeners: { | |
357 | change: function(field, value) { | |
358 | field.validate(); | |
359 | } | |
360 | } | |
361 | }); | |
362 | me.column1.push(me.mpsel); | |
363 | } | |
364 | ||
365 | // we always have this around, but only visible when creating a new mp | |
366 | // since this handles per-filesystem capabilities | |
367 | me.hdstoragesel = Ext.create('PVE.form.StorageSelector', { | |
368 | name: 'storage', | |
369 | nodename: me.nodename, | |
370 | fieldLabel: gettext('Storage'), | |
371 | storageContent: 'rootdir', | |
372 | allowBlank: false, | |
373 | autoSelect: true, | |
d5e771ce | 374 | hidden: me.unused || !me.isCreate, |
ab2fac2f DM |
375 | listeners: { |
376 | change: function(f, value) { | |
e7f0e95e EK |
377 | if (!value) { // initial store loading fires an unwanted 'change' |
378 | return; | |
379 | } | |
ab2fac2f DM |
380 | if (me.mpdata.type === 'bind') { |
381 | me.quota.setDisabled(true); | |
382 | me.quota.setValue(false); | |
17ab437f | 383 | me.acl.setDisabled(true); |
47e36cf6 | 384 | me.backup.setDisabled(true); |
17ab437f | 385 | me.acl.setValue('Default'); |
ab2fac2f DM |
386 | return; |
387 | } | |
388 | var rec = f.store.getById(value); | |
389 | if (rec.data.type === 'zfs' || | |
390 | rec.data.type === 'zfspool') { | |
391 | me.quota.setDisabled(true); | |
392 | me.quota.setValue(false); | |
393 | } else { | |
394 | me.quota.setDisabled(false); | |
395 | } | |
d5e771ce | 396 | if (me.unused || !me.isCreate) { |
ab2fac2f DM |
397 | return; |
398 | } | |
399 | if (rec.data.type === 'iscsi') { | |
400 | me.hdfilesel.setStorage(value); | |
401 | me.hdfilesel.setDisabled(false); | |
402 | me.hdfilesel.setVisible(true); | |
403 | me.hdsizesel.setDisabled(true); | |
404 | me.hdsizesel.setVisible(false); | |
405 | } else if (rec.data.type === 'lvm' || | |
406 | rec.data.type === 'lvmthin' || | |
407 | rec.data.type === 'rbd' || | |
408 | rec.data.type === 'sheepdog' || | |
409 | rec.data.type === 'zfs' || | |
410 | rec.data.type === 'zfspool') { | |
411 | me.hdfilesel.setDisabled(true); | |
412 | me.hdfilesel.setVisible(false); | |
413 | me.hdsizesel.setDisabled(false); | |
414 | me.hdsizesel.setVisible(true); | |
415 | } else { | |
416 | me.hdfilesel.setDisabled(true); | |
417 | me.hdfilesel.setVisible(false); | |
418 | me.hdsizesel.setDisabled(false); | |
419 | me.hdsizesel.setVisible(true); | |
420 | } | |
421 | } | |
422 | } | |
423 | }); | |
424 | me.column1.push(me.hdstoragesel); | |
425 | ||
426 | if (me.unused) { | |
427 | me.unusedDisks = Ext.create('PVE.form.KVComboBox', { | |
428 | name: 'unusedId', | |
429 | fieldLabel: gettext('Disk image'), | |
430 | matchFieldWidth: false, | |
431 | listConfig: { | |
432 | width: 350 | |
433 | }, | |
434 | data: [], | |
435 | allowBlank: false, | |
436 | listeners: { | |
437 | change: function(f, value) { | |
438 | // make sure our buttons are enabled/disabled when switching | |
439 | // between images on different storages: | |
440 | var disk = me.vmconfig[value]; | |
441 | var storage = disk.split(':')[0]; | |
442 | me.hdstoragesel.setValue(storage); | |
443 | } | |
444 | } | |
445 | }); | |
446 | me.column1.push(me.unusedDisks); | |
d5e771ce | 447 | } else if (me.isCreate) { |
ab2fac2f DM |
448 | me.hdfilesel = Ext.create('PVE.form.FileSelector', { |
449 | name: 'file', | |
450 | nodename: me.nodename, | |
451 | storageContent: 'images', | |
452 | fieldLabel: gettext('Disk image'), | |
453 | disabled: true, | |
454 | hidden: true, | |
455 | allowBlank: false | |
456 | }); | |
457 | me.hdsizesel = Ext.createWidget('numberfield', { | |
458 | name: 'disksize', | |
459 | minValue: 0.1, | |
460 | maxValue: 128*1024, | |
461 | decimalPrecision: 3, | |
462 | value: '8', | |
463 | step: 1, | |
464 | fieldLabel: gettext('Disk size') + ' (GB)', | |
465 | allowBlank: false | |
466 | }); | |
467 | me.column1.push(me.hdfilesel); | |
468 | me.column1.push(me.hdsizesel); | |
469 | } else { | |
470 | me.column1.push({ | |
471 | xtype: 'textfield', | |
472 | disabled: true, | |
473 | submitValue: false, | |
474 | fieldLabel: gettext('Disk image'), | |
475 | name: 'file' | |
476 | }); | |
477 | } | |
478 | ||
17ab437f WB |
479 | me.acl = Ext.createWidget('pveKVComboBox', { |
480 | name: 'acl', | |
481 | fieldLabel: gettext('ACLs'), | |
482 | comboItems: [['Default', 'Default'], ['1', 'On'], ['0', 'Off']], | |
483 | value: 'Default', | |
484 | allowBlank: true | |
485 | }); | |
486 | ||
ab2fac2f DM |
487 | me.quota = Ext.createWidget('pvecheckbox', { |
488 | name: 'quota', | |
489 | defaultValue: 0, | |
490 | fieldLabel: gettext('Enable quota') | |
491 | }); | |
492 | ||
493 | me.column2 = [ | |
494 | { | |
495 | xtype: 'pvecheckbox', | |
496 | name: 'ro', | |
497 | defaultValue: 0, | |
498 | fieldLabel: gettext('Read-only'), | |
499 | hidden: me.insideWizard | |
500 | }, | |
17ab437f | 501 | me.acl, |
ab2fac2f DM |
502 | me.quota |
503 | ]; | |
504 | ||
505 | if (!isroot) { | |
47e36cf6 DC |
506 | me.backup = Ext.createWidget('pvecheckbox',{ |
507 | xtype: 'pvecheckbox', | |
508 | name: 'backup', | |
509 | fieldLabel: gettext('Backup') | |
510 | }); | |
511 | if (me.mpdata.type !== 'bind') { | |
512 | me.column2.push(me.backup); | |
513 | } | |
ab2fac2f DM |
514 | me.column2.push({ |
515 | xtype: 'textfield', | |
516 | name: 'mp', | |
517 | value: '', | |
518 | emptyText: gettext('/some/path'), | |
519 | allowBlank: false, | |
520 | hidden: isroot, | |
521 | fieldLabel: gettext('Path') | |
522 | }); | |
523 | } | |
524 | ||
525 | me.callParent(); | |
526 | } | |
527 | }); |