]>
git.proxmox.com Git - pve-manager.git/blob - www/manager6/qemu/HDEdit.js
1 /* 'change' property is assigned a string and then a function */
2 Ext
.define('PVE.qemu.HDInputPanel', {
3 extend
: 'Proxmox.panel.InputPanel',
4 alias
: 'widget.pveQemuHDInputPanel',
5 onlineHelp
: 'qm_hard_disk',
9 unused
: false, // ADD usused disk imaged
11 vmconfig
: {}, // used to select usused disks
21 xclass
: 'Ext.app.ViewController',
23 onControllerChange: function(field
) {
25 let vm
= this.getViewModel();
27 let value
= field
.getValue();
28 vm
.set('isSCSI', value
.match(/^scsi/));
29 vm
.set('isVirtIO', value
.match(/^virtio/));
34 fireIdChange: function() {
35 let view
= this.getView();
36 view
.fireEvent('diskidchange', view
, view
.bussel
.getConfId());
40 'field[name=controller]': {
41 change
: 'onControllerChange',
42 afterrender
: 'onControllerChange',
44 'field[name=deviceid]': {
45 change
: 'fireIdChange',
47 'field[name=iothread]': {
48 change: function(f
, value
) {
49 if (!this.getView().insideWizard
) {
52 var vmScsiType
= value
? 'virtio-scsi-single': 'virtio-scsi-pci';
53 this.lookupReference('scsiController').setValue(vmScsiType
);
58 init: function(view
) {
59 var vm
= this.getViewModel();
61 vm
.set('isIncludedInBackup', true);
64 vm
.set('isSCSI', view
.confid
.match(/^scsi/));
65 vm
.set('isVirtIO', view
.confid
.match(/^virtio/));
70 onGetValues: function(values
) {
74 var confid
= me
.confid
|| values
.controller
+ values
.deviceid
;
77 me
.drive
.file
= me
.vmconfig
[values
.unusedId
];
78 confid
= values
.controller
+ values
.deviceid
;
79 } else if (me
.isCreate
) {
81 me
.drive
.file
= values
.hdimage
;
83 me
.drive
.file
= values
.hdstorage
+ ":" + values
.disksize
;
85 me
.drive
.format
= values
.diskformat
;
88 PVE
.Utils
.propertyStringSet(me
.drive
, !values
.backup
, 'backup', '0');
89 PVE
.Utils
.propertyStringSet(me
.drive
, values
.noreplicate
, 'replicate', 'no');
90 PVE
.Utils
.propertyStringSet(me
.drive
, values
.discard
, 'discard', 'on');
91 PVE
.Utils
.propertyStringSet(me
.drive
, values
.ssd
, 'ssd', 'on');
92 PVE
.Utils
.propertyStringSet(me
.drive
, values
.iothread
, 'iothread', 'on');
93 PVE
.Utils
.propertyStringSet(me
.drive
, values
.readOnly
, 'ro', 'on');
94 PVE
.Utils
.propertyStringSet(me
.drive
, values
.cache
, 'cache');
95 PVE
.Utils
.propertyStringSet(me
.drive
, values
.aio
, 'aio');
97 ['mbps_rd', 'mbps_wr', 'iops_rd', 'iops_wr'].forEach(name
=> {
98 let burst_name
= `${name}_max`;
99 PVE
.Utils
.propertyStringSet(me
.drive
, values
[name
], name
);
100 PVE
.Utils
.propertyStringSet(me
.drive
, values
[burst_name
], burst_name
);
103 params
[confid
] = PVE
.Parser
.printQemuDrive(me
.drive
);
108 updateVMConfig: function(vmconfig
) {
110 me
.vmconfig
= vmconfig
;
111 me
.bussel
?.updateVMConfig(vmconfig
);
114 setVMConfig: function(vmconfig
) {
117 me
.vmconfig
= vmconfig
;
120 me
.bussel
.setVMConfig(vmconfig
);
121 me
.scsiController
.setValue(vmconfig
.scsihw
);
123 if (me
.unusedDisks
) {
125 Ext
.Object
.each(vmconfig
, function(key
, value
) {
126 if (key
.match(/^unused\d+$/)) {
127 disklist
.push([key
, value
]);
130 me
.unusedDisks
.store
.loadData(disklist
);
131 me
.unusedDisks
.setValue(me
.confid
);
135 setDrive: function(drive
) {
141 var match
= drive
.file
.match(/^([^:]+):/);
143 values
.hdstorage
= match
[1];
146 values
.hdimage
= drive
.file
;
147 values
.backup
= PVE
.Parser
.parseBoolean(drive
.backup
, 1);
148 values
.noreplicate
= !PVE
.Parser
.parseBoolean(drive
.replicate
, 1);
149 values
.diskformat
= drive
.format
|| 'raw';
150 values
.cache
= drive
.cache
|| '__default__';
151 values
.discard
= drive
.discard
=== 'on';
152 values
.ssd
= PVE
.Parser
.parseBoolean(drive
.ssd
);
153 values
.iothread
= PVE
.Parser
.parseBoolean(drive
.iothread
);
154 values
.readOnly
= PVE
.Parser
.parseBoolean(drive
.ro
);
155 values
.aio
= drive
.aio
|| '__default__';
157 values
.mbps_rd
= drive
.mbps_rd
;
158 values
.mbps_wr
= drive
.mbps_wr
;
159 values
.iops_rd
= drive
.iops_rd
;
160 values
.iops_wr
= drive
.iops_wr
;
161 values
.mbps_rd_max
= drive
.mbps_rd_max
;
162 values
.mbps_wr_max
= drive
.mbps_wr_max
;
163 values
.iops_rd_max
= drive
.iops_rd_max
;
164 values
.iops_wr_max
= drive
.iops_wr_max
;
166 me
.setValues(values
);
169 setNodename: function(nodename
) {
171 me
.down('#hdstorage').setNodename(nodename
);
172 me
.down('#hdimage').setStorage(undefined, nodename
);
177 initComponent: function() {
185 let advancedColumn1
= [];
186 let advancedColumn2
= [];
188 if (!me
.confid
|| me
.unused
) {
189 me
.bussel
= Ext
.create('PVE.form.ControllerSelector', {
190 vmconfig
: me
.vmconfig
,
193 column1
.push(me
.bussel
);
195 me
.scsiController
= Ext
.create('Ext.form.field.Display', {
196 fieldLabel
: gettext('SCSI Controller'),
197 reference
: 'scsiController',
198 bind
: me
.insideWizard
? {
199 value
: '{current.scsihw}',
204 renderer
: PVE
.Utils
.render_scsihw
,
208 column1
.push(me
.scsiController
);
212 me
.unusedDisks
= Ext
.create('Proxmox.form.KVComboBox', {
214 fieldLabel
: gettext('Disk image'),
215 matchFieldWidth
: false,
222 column1
.push(me
.unusedDisks
);
223 } else if (me
.isCreate
) {
225 xtype
: 'pveDiskStorageSelector',
226 storageContent
: 'images',
228 nodename
: me
.nodename
,
229 autoSelect
: me
.insideWizard
,
236 fieldLabel
: gettext('Disk image'),
243 xtype
: 'CacheTypeSelector',
245 value
: '__default__',
246 fieldLabel
: gettext('Cache'),
249 xtype
: 'proxmoxcheckbox',
250 fieldLabel
: gettext('Discard'),
251 reference
: 'discard',
256 advancedColumn1
.push(
258 xtype
: 'proxmoxcheckbox',
259 fieldLabel
: gettext('SSD emulation'),
261 clearOnDisable
: true,
263 disabled
: '{isVirtIO}',
267 xtype
: 'proxmoxcheckbox',
269 fieldLabel
: 'IO thread',
270 clearOnDisable
: true,
272 disabled
: '{!isVirtIO && !isSCSI}',
276 xtype
: 'proxmoxcheckbox',
277 name
: 'readOnly', // `ro` in the config, we map in get/set values
279 fieldLabel
: gettext('Read-only'),
280 clearOnDisable
: true,
282 disabled
: '{!isVirtIO && !isSCSI}',
287 advancedColumn2
.push(
289 xtype
: 'proxmoxcheckbox',
290 fieldLabel
: gettext('Backup'),
293 'data-qtip': gettext('Include volume in backup job'),
297 value
: '{isIncludedInBackup}',
301 xtype
: 'proxmoxcheckbox',
302 fieldLabel
: gettext('Skip replication'),
306 xtype
: 'proxmoxKVComboBox',
308 fieldLabel
: gettext('Async IO'),
310 value
: '__default__',
312 ['__default__', Proxmox
.Utils
.defaultText
+ ' (io_uring)'],
313 ['io_uring', 'io_uring'],
314 ['native', 'native'],
315 ['threads', 'threads'],
320 let labelWidth
= 140;
324 xtype
: 'numberfield',
328 fieldLabel
: gettext('Read limit') + ' (MB/s)',
329 labelWidth
: labelWidth
,
330 emptyText
: gettext('unlimited'),
333 xtype
: 'numberfield',
337 fieldLabel
: gettext('Write limit') + ' (MB/s)',
338 labelWidth
: labelWidth
,
339 emptyText
: gettext('unlimited'),
342 xtype
: 'proxmoxintegerfield',
346 fieldLabel
: gettext('Read limit') + ' (ops/s)',
347 labelWidth
: labelWidth
,
348 emptyText
: gettext('unlimited'),
351 xtype
: 'proxmoxintegerfield',
355 fieldLabel
: gettext('Write limit') + ' (ops/s)',
356 labelWidth
: labelWidth
,
357 emptyText
: gettext('unlimited'),
363 xtype
: 'numberfield',
367 fieldLabel
: gettext('Read max burst') + ' (MB)',
368 labelWidth
: labelWidth
,
369 emptyText
: gettext('default'),
372 xtype
: 'numberfield',
376 fieldLabel
: gettext('Write max burst') + ' (MB)',
377 labelWidth
: labelWidth
,
378 emptyText
: gettext('default'),
381 xtype
: 'proxmoxintegerfield',
385 fieldLabel
: gettext('Read max burst') + ' (ops)',
386 labelWidth
: labelWidth
,
387 emptyText
: gettext('default'),
390 xtype
: 'proxmoxintegerfield',
394 fieldLabel
: gettext('Write max burst') + ' (ops)',
395 labelWidth
: labelWidth
,
396 emptyText
: gettext('default'),
408 title
: gettext('Disk'),
410 reference
: 'diskpanel',
415 showAdvanced
: me
.showAdvanced
,
416 getValues
: () => ({}),
419 title
: gettext('Bandwidth'),
421 reference
: 'bwpanel',
424 showAdvanced
: me
.showAdvanced
,
425 getValues
: () => ({}),
434 setAdvancedVisible: function(visible
) {
435 this.lookup('diskpanel').setAdvancedVisible(visible
);
436 this.lookup('bwpanel').setAdvancedVisible(visible
);
440 Ext
.define('PVE.qemu.HDEdit', {
441 extend
: 'Proxmox.window.Edit',
450 initComponent: function() {
453 var nodename
= me
.pveSelNode
.data
.node
;
455 throw "no node name specified";
458 var unused
= me
.confid
&& me
.confid
.match(/^unused\d+$/);
460 me
.isCreate
= me
.confid
? unused
: true;
462 var ipanel
= Ext
.create('PVE.qemu.HDInputPanel', {
466 isCreate
: me
.isCreate
,
470 me
.subject
= gettext('Unused Disk');
471 } else if (me
.isCreate
) {
472 me
.subject
= gettext('Hard Disk');
474 me
.subject
= gettext('Hard Disk') + ' (' + me
.confid
+ ')';
480 /* 'data' is assigned an empty array in same file, and here we
481 * use it like an object
484 success: function(response
, options
) {
485 ipanel
.setVMConfig(response
.result
.data
);
487 var value
= response
.result
.data
[me
.confid
];
488 var drive
= PVE
.Parser
.parseQemuDrive(me
.confid
, value
);
490 Ext
.Msg
.alert(gettext('Error'), 'Unable to parse drive options');
494 ipanel
.setDrive(drive
);
495 me
.isValid(); // trigger validation