]>
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
22 xclass
: 'Ext.app.ViewController',
24 onControllerChange: function(field
) {
26 let vm
= this.getViewModel();
28 let value
= field
.getValue();
29 vm
.set('isSCSI', value
.match(/^scsi/));
30 vm
.set('isVirtIO', value
.match(/^virtio/));
35 fireIdChange: function() {
36 let view
= this.getView();
37 view
.fireEvent('diskidchange', view
, view
.bussel
.getConfId());
41 'field[name=controller]': {
42 change
: 'onControllerChange',
43 afterrender
: 'onControllerChange',
45 'field[name=deviceid]': {
46 change
: 'fireIdChange',
48 'field[name=scsiController]': {
49 change: function(f
, value
) {
50 let vm
= this.getViewModel();
51 vm
.set('isSCSISingle', value
=== 'virtio-scsi-single');
56 init: function(view
) {
57 var vm
= this.getViewModel();
59 vm
.set('isIncludedInBackup', true);
62 vm
.set('isSCSI', view
.confid
.match(/^scsi/));
63 vm
.set('isVirtIO', view
.confid
.match(/^virtio/));
68 onGetValues: function(values
) {
72 var confid
= me
.confid
|| values
.controller
+ values
.deviceid
;
75 me
.drive
.file
= me
.vmconfig
[values
.unusedId
];
76 confid
= values
.controller
+ values
.deviceid
;
77 } else if (me
.isCreate
) {
79 me
.drive
.file
= values
.hdimage
;
81 me
.drive
.file
= values
.hdstorage
+ ":" + values
.disksize
;
83 me
.drive
.format
= values
.diskformat
;
86 PVE
.Utils
.propertyStringSet(me
.drive
, !values
.backup
, 'backup', '0');
87 PVE
.Utils
.propertyStringSet(me
.drive
, values
.noreplicate
, 'replicate', 'no');
88 PVE
.Utils
.propertyStringSet(me
.drive
, values
.discard
, 'discard', 'on');
89 PVE
.Utils
.propertyStringSet(me
.drive
, values
.ssd
, 'ssd', 'on');
90 PVE
.Utils
.propertyStringSet(me
.drive
, values
.iothread
, 'iothread', 'on');
91 PVE
.Utils
.propertyStringSet(me
.drive
, values
.readOnly
, 'ro', 'on');
92 PVE
.Utils
.propertyStringSet(me
.drive
, values
.cache
, 'cache');
93 PVE
.Utils
.propertyStringSet(me
.drive
, values
.aio
, 'aio');
95 ['mbps_rd', 'mbps_wr', 'iops_rd', 'iops_wr'].forEach(name
=> {
96 let burst_name
= `${name}_max`;
97 PVE
.Utils
.propertyStringSet(me
.drive
, values
[name
], name
);
98 PVE
.Utils
.propertyStringSet(me
.drive
, values
[burst_name
], burst_name
);
101 params
[confid
] = PVE
.Parser
.printQemuDrive(me
.drive
);
106 updateVMConfig: function(vmconfig
) {
108 me
.vmconfig
= vmconfig
;
109 me
.bussel
?.updateVMConfig(vmconfig
);
112 setVMConfig: function(vmconfig
) {
115 me
.vmconfig
= vmconfig
;
118 me
.bussel
.setVMConfig(vmconfig
);
119 me
.scsiController
.setValue(vmconfig
.scsihw
);
121 if (me
.unusedDisks
) {
123 Ext
.Object
.each(vmconfig
, function(key
, value
) {
124 if (key
.match(/^unused\d+$/)) {
125 disklist
.push([key
, value
]);
128 me
.unusedDisks
.store
.loadData(disklist
);
129 me
.unusedDisks
.setValue(me
.confid
);
133 setDrive: function(drive
) {
139 var match
= drive
.file
.match(/^([^:]+):/);
141 values
.hdstorage
= match
[1];
144 values
.hdimage
= drive
.file
;
145 values
.backup
= PVE
.Parser
.parseBoolean(drive
.backup
, 1);
146 values
.noreplicate
= !PVE
.Parser
.parseBoolean(drive
.replicate
, 1);
147 values
.diskformat
= drive
.format
|| 'raw';
148 values
.cache
= drive
.cache
|| '__default__';
149 values
.discard
= drive
.discard
=== 'on';
150 values
.ssd
= PVE
.Parser
.parseBoolean(drive
.ssd
);
151 values
.iothread
= PVE
.Parser
.parseBoolean(drive
.iothread
);
152 values
.readOnly
= PVE
.Parser
.parseBoolean(drive
.ro
);
153 values
.aio
= drive
.aio
|| '__default__';
155 values
.mbps_rd
= drive
.mbps_rd
;
156 values
.mbps_wr
= drive
.mbps_wr
;
157 values
.iops_rd
= drive
.iops_rd
;
158 values
.iops_wr
= drive
.iops_wr
;
159 values
.mbps_rd_max
= drive
.mbps_rd_max
;
160 values
.mbps_wr_max
= drive
.mbps_wr_max
;
161 values
.iops_rd_max
= drive
.iops_rd_max
;
162 values
.iops_wr_max
= drive
.iops_wr_max
;
164 me
.setValues(values
);
167 setNodename: function(nodename
) {
169 me
.down('#hdstorage').setNodename(nodename
);
170 me
.down('#hdimage').setStorage(undefined, nodename
);
175 initComponent: function() {
183 let advancedColumn1
= [];
184 let advancedColumn2
= [];
186 if (!me
.confid
|| me
.unused
) {
187 me
.bussel
= Ext
.create('PVE.form.ControllerSelector', {
188 vmconfig
: me
.vmconfig
,
191 column1
.push(me
.bussel
);
193 me
.scsiController
= Ext
.create('Ext.form.field.Display', {
194 fieldLabel
: gettext('SCSI Controller'),
195 reference
: 'scsiController',
196 name
: 'scsiController',
197 bind
: me
.insideWizard
? {
198 value
: '{current.scsihw}',
203 renderer
: PVE
.Utils
.render_scsihw
,
207 column1
.push(me
.scsiController
);
211 me
.unusedDisks
= Ext
.create('Proxmox.form.KVComboBox', {
213 fieldLabel
: gettext('Disk image'),
214 matchFieldWidth
: false,
221 column1
.push(me
.unusedDisks
);
222 } else if (me
.isCreate
) {
224 xtype
: 'pveDiskStorageSelector',
225 storageContent
: 'images',
227 nodename
: me
.nodename
,
228 autoSelect
: me
.insideWizard
,
235 fieldLabel
: gettext('Disk image'),
242 xtype
: 'CacheTypeSelector',
244 value
: '__default__',
245 fieldLabel
: gettext('Cache'),
248 xtype
: 'proxmoxcheckbox',
249 fieldLabel
: gettext('Discard'),
250 reference
: 'discard',
254 xtype
: 'proxmoxcheckbox',
256 fieldLabel
: 'IO thread',
257 clearOnDisable
: true,
258 bind
: me
.insideWizard
|| me
.isCreate
? {
259 disabled
: '{!isVirtIO && !isSCSI}',
260 // Checkbox.setValue handles Arrays in a different way, therefore cast to bool
261 value
: '{!!isVirtIO || (isSCSI && isSCSISingle)}',
263 disabled
: '{!isVirtIO && !isSCSI}',
268 advancedColumn1
.push(
270 xtype
: 'proxmoxcheckbox',
271 fieldLabel
: gettext('SSD emulation'),
273 clearOnDisable
: true,
275 disabled
: '{isVirtIO}',
279 xtype
: 'proxmoxcheckbox',
280 name
: 'readOnly', // `ro` in the config, we map in get/set values
282 fieldLabel
: gettext('Read-only'),
283 clearOnDisable
: true,
285 disabled
: '{!isVirtIO && !isSCSI}',
290 advancedColumn2
.push(
292 xtype
: 'proxmoxcheckbox',
293 fieldLabel
: gettext('Backup'),
296 'data-qtip': gettext('Include volume in backup job'),
300 value
: '{isIncludedInBackup}',
304 xtype
: 'proxmoxcheckbox',
305 fieldLabel
: gettext('Skip replication'),
309 xtype
: 'proxmoxKVComboBox',
311 fieldLabel
: gettext('Async IO'),
313 value
: '__default__',
315 ['__default__', Proxmox
.Utils
.defaultText
+ ' (io_uring)'],
316 ['io_uring', 'io_uring'],
317 ['native', 'native'],
318 ['threads', 'threads'],
323 let labelWidth
= 140;
327 xtype
: 'numberfield',
331 fieldLabel
: gettext('Read limit') + ' (MB/s)',
332 labelWidth
: labelWidth
,
333 emptyText
: gettext('unlimited'),
336 xtype
: 'numberfield',
340 fieldLabel
: gettext('Write limit') + ' (MB/s)',
341 labelWidth
: labelWidth
,
342 emptyText
: gettext('unlimited'),
345 xtype
: 'proxmoxintegerfield',
349 fieldLabel
: gettext('Read limit') + ' (ops/s)',
350 labelWidth
: labelWidth
,
351 emptyText
: gettext('unlimited'),
354 xtype
: 'proxmoxintegerfield',
358 fieldLabel
: gettext('Write limit') + ' (ops/s)',
359 labelWidth
: labelWidth
,
360 emptyText
: gettext('unlimited'),
366 xtype
: 'numberfield',
370 fieldLabel
: gettext('Read max burst') + ' (MB)',
371 labelWidth
: labelWidth
,
372 emptyText
: gettext('default'),
375 xtype
: 'numberfield',
379 fieldLabel
: gettext('Write max burst') + ' (MB)',
380 labelWidth
: labelWidth
,
381 emptyText
: gettext('default'),
384 xtype
: 'proxmoxintegerfield',
388 fieldLabel
: gettext('Read max burst') + ' (ops)',
389 labelWidth
: labelWidth
,
390 emptyText
: gettext('default'),
393 xtype
: 'proxmoxintegerfield',
397 fieldLabel
: gettext('Write max burst') + ' (ops)',
398 labelWidth
: labelWidth
,
399 emptyText
: gettext('default'),
411 title
: gettext('Disk'),
413 reference
: 'diskpanel',
418 showAdvanced
: me
.showAdvanced
,
419 getValues
: () => ({}),
422 title
: gettext('Bandwidth'),
424 reference
: 'bwpanel',
427 showAdvanced
: me
.showAdvanced
,
428 getValues
: () => ({}),
437 setAdvancedVisible: function(visible
) {
438 this.lookup('diskpanel').setAdvancedVisible(visible
);
439 this.lookup('bwpanel').setAdvancedVisible(visible
);
443 Ext
.define('PVE.qemu.HDEdit', {
444 extend
: 'Proxmox.window.Edit',
453 initComponent: function() {
456 var nodename
= me
.pveSelNode
.data
.node
;
458 throw "no node name specified";
461 var unused
= me
.confid
&& me
.confid
.match(/^unused\d+$/);
463 me
.isCreate
= me
.confid
? unused
: true;
465 var ipanel
= Ext
.create('PVE.qemu.HDInputPanel', {
469 isCreate
: me
.isCreate
,
473 me
.subject
= gettext('Unused Disk');
474 } else if (me
.isCreate
) {
475 me
.subject
= gettext('Hard Disk');
477 me
.subject
= gettext('Hard Disk') + ' (' + me
.confid
+ ')';
483 /* 'data' is assigned an empty array in same file, and here we
484 * use it like an object
487 success: function(response
, options
) {
488 ipanel
.setVMConfig(response
.result
.data
);
490 var value
= response
.result
.data
[me
.confid
];
491 var drive
= PVE
.Parser
.parseQemuDrive(me
.confid
, value
);
493 Ext
.Msg
.alert(gettext('Error'), 'Unable to parse drive options');
497 ipanel
.setDrive(drive
);
498 me
.isValid(); // trigger validation