]> git.proxmox.com Git - pve-manager.git/blame - www/manager6/lxc/ResourceEdit.js
Use emptyText to inform the user of the value that will set be when the field is...
[pve-manager.git] / www / manager6 / lxc / ResourceEdit.js
CommitLineData
ab2fac2f
DM
1/*jslint confusion: true */
2var labelWidth = 120;
3
4Ext.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
22Ext.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
39Ext.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
98Ext.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
168Ext.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
214Ext.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});