]>
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 | ||
fc3a208b EK |
266 | if (values.noreplicate) { |
267 | me.mpdata.replicate = '0'; | |
268 | } | |
269 | delete me.mpdata.noreplicate; | |
270 | ||
ab2fac2f DM |
271 | var res = {}; |
272 | res[confid] = PVE.Parser.printLxcMountPoint(me.mpdata); | |
273 | return res; | |
274 | }, | |
275 | ||
276 | setMountPoint: function(mp) { | |
277 | var me = this; | |
278 | ||
279 | me.mpdata = mp; | |
280 | if (!Ext.isDefined(me.mpdata.acl)) { | |
281 | me.mpdata.acl = 'Default'; | |
282 | } | |
283 | ||
284 | if (mp.type === 'bind') { | |
285 | me.quota.setDisabled(true); | |
286 | me.quota.setValue(false); | |
17ab437f WB |
287 | me.acl.setDisabled(true); |
288 | me.acl.setValue('Default'); | |
494b650e | 289 | me.hdstoragesel.setDisabled(true); |
20d9d1f3 DC |
290 | if (me.confid !== 'rootfs') { |
291 | me.backup.setDisabled(true); | |
292 | } | |
ab2fac2f DM |
293 | } |
294 | ||
fc3a208b EK |
295 | if (mp.replicate) { // check box reverses the config option |
296 | mp.noreplicate = !PVE.Parser.parseBoolean(mp.replicate, 1); | |
297 | delete mp.replicate; | |
298 | } | |
299 | ||
ab2fac2f DM |
300 | me.setValues(mp); |
301 | }, | |
302 | ||
303 | setVMConfig: function(vmconfig) { | |
304 | var me = this; | |
305 | ||
306 | me.vmconfig = vmconfig; | |
307 | ||
308 | if (me.mpsel) { | |
309 | var i; | |
310 | for (i = 0; i != 8; ++i) { | |
311 | var name = "mp" + i; | |
312 | if (!Ext.isDefined(vmconfig[name])) { | |
313 | me.mpsel.setValue(name); | |
314 | break; | |
315 | } | |
316 | } | |
317 | } | |
318 | ||
319 | if (me.unusedDisks) { | |
320 | var disklist = []; | |
321 | Ext.Object.each(vmconfig, function(key, value) { | |
322 | if (key.match(/^unused\d+$/)) { | |
323 | disklist.push([key, value]); | |
324 | } | |
325 | }); | |
326 | me.unusedDisks.store.loadData(disklist); | |
327 | me.unusedDisks.setValue(me.confid); | |
328 | } | |
329 | }, | |
330 | ||
331 | setNodename: function(nodename) { | |
332 | var me = this; | |
333 | me.hdstoragesel.setNodename(nodename); | |
334 | me.hdfilesel.setStorage(undefined, nodename); | |
335 | }, | |
336 | ||
337 | initComponent : function() { | |
338 | var me = this; | |
339 | ||
340 | var isroot = me.confid === 'rootfs'; | |
341 | ||
342 | me.mpdata = {}; | |
343 | ||
344 | me.column1 = []; | |
345 | ||
346 | if (!me.confid || me.unused) { | |
347 | var names = []; | |
348 | var i; | |
349 | for (i = 0; i != 8; ++i) { | |
350 | var name = 'mp' + i; | |
351 | names.push([name, name]); | |
352 | } | |
353 | me.mpsel = Ext.create('PVE.form.KVComboBox', { | |
354 | name: 'mpsel', | |
355 | fieldLabel: gettext('Mount Point'), | |
356 | matchFieldWidth: false, | |
357 | allowBlank: false, | |
0b409147 | 358 | comboItems: names, |
ab2fac2f DM |
359 | validator: function(value) { |
360 | if (!me.rendered) { | |
361 | return; | |
362 | } | |
363 | if (Ext.isDefined(me.vmconfig[value])) { | |
364 | return "Mount point is already in use."; | |
365 | } | |
366 | return true; | |
367 | }, | |
368 | listeners: { | |
369 | change: function(field, value) { | |
370 | field.validate(); | |
371 | } | |
372 | } | |
373 | }); | |
374 | me.column1.push(me.mpsel); | |
375 | } | |
376 | ||
377 | // we always have this around, but only visible when creating a new mp | |
378 | // since this handles per-filesystem capabilities | |
379 | me.hdstoragesel = Ext.create('PVE.form.StorageSelector', { | |
380 | name: 'storage', | |
381 | nodename: me.nodename, | |
382 | fieldLabel: gettext('Storage'), | |
383 | storageContent: 'rootdir', | |
384 | allowBlank: false, | |
385 | autoSelect: true, | |
d5e771ce | 386 | hidden: me.unused || !me.isCreate, |
ab2fac2f DM |
387 | listeners: { |
388 | change: function(f, value) { | |
e7f0e95e EK |
389 | if (!value) { // initial store loading fires an unwanted 'change' |
390 | return; | |
391 | } | |
ab2fac2f DM |
392 | if (me.mpdata.type === 'bind') { |
393 | me.quota.setDisabled(true); | |
394 | me.quota.setValue(false); | |
17ab437f WB |
395 | me.acl.setDisabled(true); |
396 | me.acl.setValue('Default'); | |
20d9d1f3 DC |
397 | if (!isroot) { |
398 | me.backup.setDisabled(true); | |
399 | } | |
ab2fac2f DM |
400 | return; |
401 | } | |
402 | var rec = f.store.getById(value); | |
dcbb4ba1 DC |
403 | if (rec && |
404 | (rec.data.type === 'zfs' || | |
405 | rec.data.type === 'zfspool')) { | |
ab2fac2f DM |
406 | me.quota.setDisabled(true); |
407 | me.quota.setValue(false); | |
408 | } else { | |
409 | me.quota.setDisabled(false); | |
410 | } | |
d5e771ce | 411 | if (me.unused || !me.isCreate) { |
ab2fac2f DM |
412 | return; |
413 | } | |
414 | if (rec.data.type === 'iscsi') { | |
415 | me.hdfilesel.setStorage(value); | |
416 | me.hdfilesel.setDisabled(false); | |
417 | me.hdfilesel.setVisible(true); | |
418 | me.hdsizesel.setDisabled(true); | |
419 | me.hdsizesel.setVisible(false); | |
420 | } else if (rec.data.type === 'lvm' || | |
421 | rec.data.type === 'lvmthin' || | |
422 | rec.data.type === 'rbd' || | |
423 | rec.data.type === 'sheepdog' || | |
424 | rec.data.type === 'zfs' || | |
425 | rec.data.type === 'zfspool') { | |
426 | me.hdfilesel.setDisabled(true); | |
427 | me.hdfilesel.setVisible(false); | |
428 | me.hdsizesel.setDisabled(false); | |
429 | me.hdsizesel.setVisible(true); | |
430 | } else { | |
431 | me.hdfilesel.setDisabled(true); | |
432 | me.hdfilesel.setVisible(false); | |
433 | me.hdsizesel.setDisabled(false); | |
434 | me.hdsizesel.setVisible(true); | |
435 | } | |
436 | } | |
437 | } | |
438 | }); | |
439 | me.column1.push(me.hdstoragesel); | |
440 | ||
441 | if (me.unused) { | |
442 | me.unusedDisks = Ext.create('PVE.form.KVComboBox', { | |
443 | name: 'unusedId', | |
444 | fieldLabel: gettext('Disk image'), | |
445 | matchFieldWidth: false, | |
446 | listConfig: { | |
447 | width: 350 | |
448 | }, | |
449 | data: [], | |
450 | allowBlank: false, | |
451 | listeners: { | |
452 | change: function(f, value) { | |
453 | // make sure our buttons are enabled/disabled when switching | |
454 | // between images on different storages: | |
455 | var disk = me.vmconfig[value]; | |
456 | var storage = disk.split(':')[0]; | |
457 | me.hdstoragesel.setValue(storage); | |
458 | } | |
459 | } | |
460 | }); | |
461 | me.column1.push(me.unusedDisks); | |
d5e771ce | 462 | } else if (me.isCreate) { |
ab2fac2f DM |
463 | me.hdfilesel = Ext.create('PVE.form.FileSelector', { |
464 | name: 'file', | |
465 | nodename: me.nodename, | |
466 | storageContent: 'images', | |
467 | fieldLabel: gettext('Disk image'), | |
468 | disabled: true, | |
469 | hidden: true, | |
470 | allowBlank: false | |
471 | }); | |
472 | me.hdsizesel = Ext.createWidget('numberfield', { | |
473 | name: 'disksize', | |
474 | minValue: 0.1, | |
475 | maxValue: 128*1024, | |
476 | decimalPrecision: 3, | |
477 | value: '8', | |
478 | step: 1, | |
479 | fieldLabel: gettext('Disk size') + ' (GB)', | |
480 | allowBlank: false | |
481 | }); | |
482 | me.column1.push(me.hdfilesel); | |
483 | me.column1.push(me.hdsizesel); | |
484 | } else { | |
485 | me.column1.push({ | |
486 | xtype: 'textfield', | |
487 | disabled: true, | |
488 | submitValue: false, | |
489 | fieldLabel: gettext('Disk image'), | |
490 | name: 'file' | |
491 | }); | |
492 | } | |
493 | ||
17ab437f WB |
494 | me.acl = Ext.createWidget('pveKVComboBox', { |
495 | name: 'acl', | |
496 | fieldLabel: gettext('ACLs'), | |
497 | comboItems: [['Default', 'Default'], ['1', 'On'], ['0', 'Off']], | |
498 | value: 'Default', | |
499 | allowBlank: true | |
500 | }); | |
501 | ||
ab2fac2f DM |
502 | me.quota = Ext.createWidget('pvecheckbox', { |
503 | name: 'quota', | |
504 | defaultValue: 0, | |
505 | fieldLabel: gettext('Enable quota') | |
506 | }); | |
507 | ||
508 | me.column2 = [ | |
0915ec99 DC |
509 | me.acl, |
510 | me.quota | |
511 | ]; | |
512 | ||
513 | if (!isroot) { | |
cbe73a89 | 514 | me.column2.splice(1, 0, { |
ab2fac2f DM |
515 | xtype: 'pvecheckbox', |
516 | name: 'ro', | |
517 | defaultValue: 0, | |
518 | fieldLabel: gettext('Read-only'), | |
519 | hidden: me.insideWizard | |
0915ec99 | 520 | }); |
ab2fac2f | 521 | |
47e36cf6 DC |
522 | me.backup = Ext.createWidget('pvecheckbox',{ |
523 | xtype: 'pvecheckbox', | |
524 | name: 'backup', | |
525 | fieldLabel: gettext('Backup') | |
526 | }); | |
527 | if (me.mpdata.type !== 'bind') { | |
528 | me.column2.push(me.backup); | |
529 | } | |
fc3a208b EK |
530 | me.column2.push({ |
531 | xtype: 'pvecheckbox', | |
532 | name: 'noreplicate', | |
533 | fieldLabel: gettext('Skip replication') | |
534 | }); | |
ab2fac2f DM |
535 | me.column2.push({ |
536 | xtype: 'textfield', | |
537 | name: 'mp', | |
538 | value: '', | |
539 | emptyText: gettext('/some/path'), | |
540 | allowBlank: false, | |
541 | hidden: isroot, | |
542 | fieldLabel: gettext('Path') | |
543 | }); | |
544 | } | |
545 | ||
546 | me.callParent(); | |
547 | } | |
548 | }); |