]> git.proxmox.com Git - pve-manager.git/blame - www/manager6/qemu/HDEdit.js
ui: ceph install wizard: fix config exists note position
[pve-manager.git] / www / manager6 / qemu / HDEdit.js
CommitLineData
d5e771ce 1/* 'change' property is assigned a string and then a function */
df15b3da 2Ext.define('PVE.qemu.HDInputPanel', {
ef4ef788 3 extend: 'Proxmox.panel.InputPanel',
85806e47 4 alias: 'widget.pveQemuHDInputPanel',
c8802a60 5 onlineHelp: 'qm_hard_disk',
df15b3da
DM
6
7 insideWizard: false,
8
9 unused: false, // ADD usused disk imaged
10
11 vmconfig: {}, // used to select usused disks
12
8e1df0ac
AL
13 viewModel: {},
14
180d7ef5
DM
15 controller: {
16
17 xclass: 'Ext.app.ViewController',
18
19 onControllerChange: function(field) {
20 var value = field.getValue();
ed1ac8f4
TL
21
22 var allowIOthread = value.match(/^(virtio|scsi)/);
23 this.lookup('iothread').setDisabled(!allowIOthread);
24 if (!allowIOthread) {
25 this.lookup('iothread').setValue(false);
26 }
36958639 27
f9261fde
NC
28 var virtio = value.match(/^virtio/);
29 this.lookup('ssd').setDisabled(virtio);
30 if (virtio) {
31 this.lookup('ssd').setValue(false);
32 }
33
75357e9f 34 this.lookup('scsiController').setVisible(value.match(/^scsi/));
180d7ef5
DM
35 },
36
37 control: {
9cac6b75 38 'field[name=controller]': {
180d7ef5 39 change: 'onControllerChange',
f6710aac 40 afterrender: 'onControllerChange',
9cac6b75 41 },
8058410f 42 'field[name=iothread]': {
2414ef15
EK
43 change: function(f, value) {
44 if (!this.getView().insideWizard) {
45 return;
46 }
47 var vmScsiType = value ? 'virtio-scsi-single': 'virtio-scsi-pci';
48 this.lookupReference('scsiController').setValue(vmScsiType);
f6710aac
TL
49 },
50 },
8e1df0ac
AL
51 },
52
53 init: function(view) {
54 var vm = this.getViewModel();
55 if (view.isCreate) {
56 vm.set('isIncludedInBackup', true);
57 }
f6710aac 58 },
180d7ef5
DM
59 },
60
df15b3da
DM
61 onGetValues: function(values) {
62 var me = this;
63
9a8a5735 64 var params = {};
53e3ea84 65 var confid = me.confid || values.controller + values.deviceid;
7a6e0635 66
df15b3da
DM
67 if (me.unused) {
68 me.drive.file = me.vmconfig[values.unusedId];
69 confid = values.controller + values.deviceid;
d5e771ce 70 } else if (me.isCreate) {
df15b3da
DM
71 if (values.hdimage) {
72 me.drive.file = values.hdimage;
73 } else {
74 me.drive.file = values.hdstorage + ":" + values.disksize;
75 }
76 me.drive.format = values.diskformat;
77 }
7a6e0635 78
87178934 79 PVE.Utils.propertyStringSet(me.drive, !values.backup, 'backup', '0');
e4e36020
DC
80 PVE.Utils.propertyStringSet(me.drive, values.noreplicate, 'replicate', 'no');
81 PVE.Utils.propertyStringSet(me.drive, values.discard, 'discard', 'on');
82 PVE.Utils.propertyStringSet(me.drive, values.ssd, 'ssd', 'on');
83 PVE.Utils.propertyStringSet(me.drive, values.iothread, 'iothread', 'on');
84 PVE.Utils.propertyStringSet(me.drive, values.cache, 'cache');
df15b3da 85
c2233c8f
DC
86 var names = ['mbps_rd', 'mbps_wr', 'iops_rd', 'iops_wr'];
87 Ext.Array.each(names, function(name) {
c2233c8f 88 var burst_name = name + '_max';
e4e36020
DC
89 PVE.Utils.propertyStringSet(me.drive, values[name], name);
90 PVE.Utils.propertyStringSet(me.drive, values[burst_name], burst_name);
c2233c8f
DC
91 });
92
93
df15b3da 94 params[confid] = PVE.Parser.printQemuDrive(me.drive);
7a6e0635
TL
95
96 return params;
df15b3da
DM
97 },
98
99 setVMConfig: function(vmconfig) {
100 var me = this;
101
102 me.vmconfig = vmconfig;
103
104 if (me.bussel) {
7206af4b 105 me.bussel.setVMConfig(vmconfig);
42bd6556 106 me.scsiController.setValue(vmconfig.scsihw);
df15b3da
DM
107 }
108 if (me.unusedDisks) {
7a6e0635 109 var disklist = [];
df15b3da
DM
110 Ext.Object.each(vmconfig, function(key, value) {
111 if (key.match(/^unused\d+$/)) {
112 disklist.push([key, value]);
113 }
114 });
115 me.unusedDisks.store.loadData(disklist);
116 me.unusedDisks.setValue(me.confid);
117 }
118 },
119
120 setDrive: function(drive) {
121 var me = this;
122
123 me.drive = drive;
124
125 var values = {};
126 var match = drive.file.match(/^([^:]+):/);
127 if (match) {
128 values.hdstorage = match[1];
129 }
130
131 values.hdimage = drive.file;
87178934 132 values.backup = PVE.Parser.parseBoolean(drive.backup, 1);
1b6f87ab 133 values.noreplicate = !PVE.Parser.parseBoolean(drive.replicate, 1);
df15b3da 134 values.diskformat = drive.format || 'raw';
ac7db8f7 135 values.cache = drive.cache || '__default__';
53e3ea84 136 values.discard = drive.discard === 'on';
f9261fde 137 values.ssd = PVE.Parser.parseBoolean(drive.ssd);
df15b3da
DM
138 values.iothread = PVE.Parser.parseBoolean(drive.iothread);
139
c2233c8f
DC
140 values.mbps_rd = drive.mbps_rd;
141 values.mbps_wr = drive.mbps_wr;
142 values.iops_rd = drive.iops_rd;
143 values.iops_wr = drive.iops_wr;
144 values.mbps_rd_max = drive.mbps_rd_max;
145 values.mbps_wr_max = drive.mbps_wr_max;
146 values.iops_rd_max = drive.iops_rd_max;
147 values.iops_wr_max = drive.iops_wr_max;
148
df15b3da
DM
149 me.setValues(values);
150 },
151
152 setNodename: function(nodename) {
153 var me = this;
771aec96
DC
154 me.down('#hdstorage').setNodename(nodename);
155 me.down('#hdimage').setStorage(undefined, nodename);
df15b3da
DM
156 },
157
8058410f 158 initComponent: function() {
df15b3da
DM
159 var me = this;
160
c2233c8f
DC
161 var labelWidth = 140;
162
df15b3da
DM
163 me.drive = {};
164
165 me.column1 = [];
166 me.column2 = [];
167
546d09c2
DC
168 me.advancedColumn1 = [];
169 me.advancedColumn2 = [];
170
df15b3da 171 if (!me.confid || me.unused) {
42902182 172 me.bussel = Ext.create('PVE.form.ControllerSelector', {
8058410f 173 vmconfig: me.insideWizard ? { ide2: 'cdrom' } : {},
df15b3da
DM
174 });
175 me.column1.push(me.bussel);
2414ef15 176
42bd6556
EK
177 me.scsiController = Ext.create('Ext.form.field.Display', {
178 fieldLabel: gettext('SCSI Controller'),
179 reference: 'scsiController',
471d03aa 180 bind: me.insideWizard ? {
f6710aac 181 value: '{current.scsihw}',
471d03aa 182 } : undefined,
42bd6556 183 renderer: PVE.Utils.render_scsihw,
471d03aa 184 submitValue: false,
f6710aac 185 hidden: true,
42bd6556
EK
186 });
187 me.column1.push(me.scsiController);
df15b3da
DM
188 }
189
190 if (me.unused) {
09cacce7 191 me.unusedDisks = Ext.create('Proxmox.form.KVComboBox', {
7a6e0635 192 name: 'unusedId',
df15b3da
DM
193 fieldLabel: gettext('Disk image'),
194 matchFieldWidth: false,
195 listConfig: {
f6710aac 196 width: 350,
df15b3da
DM
197 },
198 data: [],
f6710aac 199 allowBlank: false,
df15b3da
DM
200 });
201 me.column1.push(me.unusedDisks);
d5e771ce 202 } else if (me.isCreate) {
771aec96
DC
203 me.column1.push({
204 xtype: 'pveDiskStorageSelector',
df15b3da 205 storageContent: 'images',
771aec96 206 name: 'disk',
df15b3da 207 nodename: me.nodename,
f6710aac 208 autoSelect: me.insideWizard,
df15b3da 209 });
df15b3da
DM
210 } else {
211 me.column1.push({
212 xtype: 'textfield',
213 disabled: true,
214 submitValue: false,
215 fieldLabel: gettext('Disk image'),
f6710aac 216 name: 'hdimage',
df15b3da
DM
217 });
218 }
219
f9261fde
NC
220 me.column2.push(
221 {
222 xtype: 'CacheTypeSelector',
223 name: 'cache',
224 value: '__default__',
f6710aac 225 fieldLabel: gettext('Cache'),
f9261fde 226 },
546d09c2
DC
227 {
228 xtype: 'proxmoxcheckbox',
229 fieldLabel: gettext('Discard'),
546d09c2 230 reference: 'discard',
f6710aac
TL
231 name: 'discard',
232 },
f9261fde
NC
233 );
234
235 me.advancedColumn1.push(
236 {
237 xtype: 'proxmoxcheckbox',
238 disabled: me.confid && me.confid.match(/^virtio/),
239 fieldLabel: gettext('SSD emulation'),
240 labelWidth: labelWidth,
241 name: 'ssd',
f6710aac 242 reference: 'ssd',
546d09c2
DC
243 },
244 {
245 xtype: 'proxmoxcheckbox',
246 disabled: me.confid && !me.confid.match(/^(virtio|scsi)/),
247 fieldLabel: 'IO thread',
248 labelWidth: labelWidth,
249 reference: 'iothread',
f6710aac 250 name: 'iothread',
c2233c8f
DC
251 },
252 {
253 xtype: 'numberfield',
254 name: 'mbps_rd',
255 minValue: 1,
256 step: 1,
257 fieldLabel: gettext('Read limit') + ' (MB/s)',
258 labelWidth: labelWidth,
f6710aac 259 emptyText: gettext('unlimited'),
c2233c8f
DC
260 },
261 {
262 xtype: 'numberfield',
263 name: 'mbps_wr',
264 minValue: 1,
265 step: 1,
266 fieldLabel: gettext('Write limit') + ' (MB/s)',
267 labelWidth: labelWidth,
f6710aac 268 emptyText: gettext('unlimited'),
c2233c8f
DC
269 },
270 {
271 xtype: 'proxmoxintegerfield',
272 name: 'iops_rd',
273 minValue: 10,
274 step: 10,
275 fieldLabel: gettext('Read limit') + ' (ops/s)',
276 labelWidth: labelWidth,
f6710aac 277 emptyText: gettext('unlimited'),
c2233c8f
DC
278 },
279 {
280 xtype: 'proxmoxintegerfield',
281 name: 'iops_wr',
282 minValue: 10,
283 step: 10,
284 fieldLabel: gettext('Write limit') + ' (ops/s)',
285 labelWidth: labelWidth,
f6710aac
TL
286 emptyText: gettext('unlimited'),
287 },
546d09c2
DC
288 );
289
290 me.advancedColumn2.push(
291 {
292 xtype: 'proxmoxcheckbox',
0bead056
TL
293 fieldLabel: gettext('Backup'),
294 autoEl: {
295 tag: 'div',
296 'data-qtip': gettext('Include volume in backup job'),
297 },
546d09c2 298 labelWidth: labelWidth,
8e1df0ac
AL
299 name: 'backup',
300 bind: {
301 value: '{isIncludedInBackup}',
302 },
546d09c2
DC
303 },
304 {
305 xtype: 'proxmoxcheckbox',
306 fieldLabel: gettext('Skip replication'),
307 labelWidth: labelWidth,
f6710aac 308 name: 'noreplicate',
c2233c8f
DC
309 },
310 {
311 xtype: 'numberfield',
312 name: 'mbps_rd_max',
313 minValue: 1,
314 step: 1,
315 fieldLabel: gettext('Read max burst') + ' (MB)',
316 labelWidth: labelWidth,
f6710aac 317 emptyText: gettext('default'),
c2233c8f
DC
318 },
319 {
320 xtype: 'numberfield',
321 name: 'mbps_wr_max',
322 minValue: 1,
323 step: 1,
324 fieldLabel: gettext('Write max burst') + ' (MB)',
325 labelWidth: labelWidth,
f6710aac 326 emptyText: gettext('default'),
c2233c8f
DC
327 },
328 {
329 xtype: 'proxmoxintegerfield',
330 name: 'iops_rd_max',
331 minValue: 10,
332 step: 10,
333 fieldLabel: gettext('Read max burst') + ' (ops)',
334 labelWidth: labelWidth,
f6710aac 335 emptyText: gettext('default'),
c2233c8f
DC
336 },
337 {
338 xtype: 'proxmoxintegerfield',
339 name: 'iops_wr_max',
340 minValue: 10,
341 step: 10,
342 fieldLabel: gettext('Write max burst') + ' (ops)',
343 labelWidth: labelWidth,
f6710aac
TL
344 emptyText: gettext('default'),
345 },
546d09c2
DC
346 );
347
df15b3da 348 me.callParent();
f6710aac 349 },
df15b3da
DM
350});
351
352Ext.define('PVE.qemu.HDEdit', {
9fccc702 353 extend: 'Proxmox.window.Edit',
df15b3da
DM
354
355 isAdd: true,
356
7cb345b8
WL
357 backgroundDelay: 5,
358
8058410f 359 initComponent: function() {
df15b3da
DM
360 var me = this;
361
362 var nodename = me.pveSelNode.data.node;
7a6e0635
TL
363 if (!nodename) {
364 throw "no node name specified";
df15b3da
DM
365 }
366
367 var unused = me.confid && me.confid.match(/^unused\d+$/);
368
d5e771ce 369 me.isCreate = me.confid ? unused : true;
df15b3da
DM
370
371 var ipanel = Ext.create('PVE.qemu.HDInputPanel', {
372 confid: me.confid,
373 nodename: nodename,
374 unused: unused,
f6710aac 375 isCreate: me.isCreate,
df15b3da
DM
376 });
377
df15b3da
DM
378 if (unused) {
379 me.subject = gettext('Unused Disk');
d5e771ce 380 } else if (me.isCreate) {
df15b3da
DM
381 me.subject = gettext('Hard Disk');
382 } else {
383 me.subject = gettext('Hard Disk') + ' (' + me.confid + ')';
384 }
385
8058410f 386 me.items = [ipanel];
df15b3da
DM
387
388 me.callParent();
d5e771ce
EK
389 /* 'data' is assigned an empty array in same file, and here we
390 * use it like an object
391 */
df15b3da
DM
392 me.load({
393 success: function(response, options) {
394 ipanel.setVMConfig(response.result.data);
395 if (me.confid) {
396 var value = response.result.data[me.confid];
397 var drive = PVE.Parser.parseQemuDrive(me.confid, value);
398 if (!drive) {
185a77e5 399 Ext.Msg.alert(gettext('Error'), 'Unable to parse drive options');
df15b3da
DM
400 me.close();
401 return;
402 }
403 ipanel.setDrive(drive);
404 me.isValid(); // trigger validation
405 }
f6710aac 406 },
df15b3da 407 });
f6710aac 408 },
df15b3da 409});