-/*jslint confusion: true */
/* 'change' property is assigned a string and then a function */
Ext.define('PVE.qemu.HDInputPanel', {
- extend: 'PVE.panel.InputPanel',
+ extend: 'Proxmox.panel.InputPanel',
alias: 'widget.pveQemuHDInputPanel',
onlineHelp: 'qm_hard_disk',
vmconfig: {}, // used to select usused disks
+ viewModel: {},
+
controller: {
xclass: 'Ext.app.ViewController',
onControllerChange: function(field) {
+ let me = this;
var value = field.getValue();
var allowIOthread = value.match(/^(virtio|scsi)/);
- this.lookup('iothread').setDisabled(!allowIOthread);
+ me.lookup('iothread').setDisabled(!allowIOthread);
if (!allowIOthread) {
- this.lookup('iothread').setValue(false);
+ me.lookup('iothread').setValue(false);
}
- var scsi = value.match(/^scsi/);
- this.lookup('discard').setDisabled(!scsi);
- if (!scsi) {
- this.lookup('discard').setValue(false);
+ var virtio = value.match(/^virtio/);
+ me.lookup('ssd').setDisabled(virtio);
+ if (virtio) {
+ me.lookup('ssd').setValue(false);
}
- this.lookup('scsiController').setVisible(scsi);
+
+ me.lookup('scsiController').setVisible(value.match(/^scsi/));
+
+ me.fireIdChange();
+ },
+
+ fireIdChange: function() {
+ let view = this.getView();
+ view.fireEvent('diskidchange', view, view.bussel.getConfId());
},
control: {
'field[name=controller]': {
change: 'onControllerChange',
- afterrender: 'onControllerChange'
+ afterrender: 'onControllerChange',
+ },
+ 'field[name=deviceid]': {
+ change: 'fireIdChange',
},
- 'field[name=iothread]' : {
+ 'field[name=iothread]': {
change: function(f, value) {
if (!this.getView().insideWizard) {
return;
}
var vmScsiType = value ? 'virtio-scsi-single': 'virtio-scsi-pci';
this.lookupReference('scsiController').setValue(vmScsiType);
- }
+ },
+ },
+ },
+
+ init: function(view) {
+ var vm = this.getViewModel();
+ if (view.isCreate) {
+ vm.set('isIncludedInBackup', true);
}
- }
+ },
},
onGetValues: function(values) {
var me = this;
var params = {};
- var confid = me.confid || (values.controller + values.deviceid);
+ var confid = me.confid || values.controller + values.deviceid;
if (me.unused) {
me.drive.file = me.vmconfig[values.unusedId];
me.drive.format = values.diskformat;
}
- if (values.nobackup) {
- me.drive.backup = 'no';
- } else {
- delete me.drive.backup;
- }
+ PVE.Utils.propertyStringSet(me.drive, !values.backup, 'backup', '0');
+ PVE.Utils.propertyStringSet(me.drive, values.noreplicate, 'replicate', 'no');
+ PVE.Utils.propertyStringSet(me.drive, values.discard, 'discard', 'on');
+ PVE.Utils.propertyStringSet(me.drive, values.ssd, 'ssd', 'on');
+ PVE.Utils.propertyStringSet(me.drive, values.iothread, 'iothread', 'on');
+ PVE.Utils.propertyStringSet(me.drive, values.cache, 'cache');
- if (values.noreplicate) {
- me.drive.replicate = 'no';
- } else {
- delete me.drive.replicate;
- }
-
- if (values.discard) {
- me.drive.discard = 'on';
- } else {
- delete me.drive.discard;
- }
+ var names = ['mbps_rd', 'mbps_wr', 'iops_rd', 'iops_wr'];
+ Ext.Array.each(names, function(name) {
+ var burst_name = name + '_max';
+ PVE.Utils.propertyStringSet(me.drive, values[name], name);
+ PVE.Utils.propertyStringSet(me.drive, values[burst_name], burst_name);
+ });
- if (values.iothread) {
- me.drive.iothread = 'on';
- } else {
- delete me.drive.iothread;
- }
-
- if (values.cache) {
- me.drive.cache = values.cache;
- } else {
- delete me.drive.cache;
- }
-
- if (values.scsihw) {
- params.scsihw = values.scsihw;
- }
params[confid] = PVE.Parser.printQemuDrive(me.drive);
}
values.hdimage = drive.file;
- values.nobackup = !PVE.Parser.parseBoolean(drive.backup, 1);
+ values.backup = PVE.Parser.parseBoolean(drive.backup, 1);
values.noreplicate = !PVE.Parser.parseBoolean(drive.replicate, 1);
values.diskformat = drive.format || 'raw';
values.cache = drive.cache || '__default__';
- values.discard = (drive.discard === 'on');
+ values.discard = drive.discard === 'on';
+ values.ssd = PVE.Parser.parseBoolean(drive.ssd);
values.iothread = PVE.Parser.parseBoolean(drive.iothread);
+ values.mbps_rd = drive.mbps_rd;
+ values.mbps_wr = drive.mbps_wr;
+ values.iops_rd = drive.iops_rd;
+ values.iops_wr = drive.iops_wr;
+ values.mbps_rd_max = drive.mbps_rd_max;
+ values.mbps_wr_max = drive.mbps_wr_max;
+ values.iops_rd_max = drive.iops_rd_max;
+ values.iops_wr_max = drive.iops_wr_max;
+
me.setValues(values);
},
me.down('#hdimage').setStorage(undefined, nodename);
},
- initComponent : function() {
+ hasAdvanced: true,
+
+ initComponent: function() {
var me = this;
+ var labelWidth = 140;
+
me.drive = {};
- me.column1 = [];
- me.column2 = [];
+ let column1 = [];
+ let column2 = [];
+
+ let advancedColumn1 = [];
+ let advancedColumn2 = [];
if (!me.confid || me.unused) {
me.bussel = Ext.create('PVE.form.ControllerSelector', {
- vmconfig: me.insideWizard ? {ide2: 'cdrom'} : {}
+ vmconfig: me.insideWizard ? { ide2: 'cdrom' } : {},
});
- me.column1.push(me.bussel);
+ column1.push(me.bussel);
me.scsiController = Ext.create('Ext.form.field.Display', {
- name: 'scsihw',
fieldLabel: gettext('SCSI Controller'),
reference: 'scsiController',
+ bind: me.insideWizard ? {
+ value: '{current.scsihw}',
+ } : undefined,
renderer: PVE.Utils.render_scsihw,
- // do not change a VM wide option after creation
- submitValue: me.insideWizard,
- hidden: true
+ submitValue: false,
+ hidden: true,
});
- me.column1.push(me.scsiController);
+ column1.push(me.scsiController);
}
if (me.unused) {
fieldLabel: gettext('Disk image'),
matchFieldWidth: false,
listConfig: {
- width: 350
+ width: 350,
},
data: [],
- allowBlank: false
+ allowBlank: false,
});
- me.column1.push(me.unusedDisks);
+ column1.push(me.unusedDisks);
} else if (me.isCreate) {
- me.column1.push({
+ column1.push({
xtype: 'pveDiskStorageSelector',
storageContent: 'images',
name: 'disk',
nodename: me.nodename,
- autoSelect: me.insideWizard
+ autoSelect: me.insideWizard,
});
} else {
- me.column1.push({
+ column1.push({
xtype: 'textfield',
disabled: true,
submitValue: false,
fieldLabel: gettext('Disk image'),
- name: 'hdimage'
+ name: 'hdimage',
});
}
- me.column2.push({
- xtype: 'CacheTypeSelector',
- name: 'cache',
- value: '__default__',
- fieldLabel: gettext('Cache')
- },
- {
- xtype: 'proxmoxcheckbox',
- fieldLabel: gettext('No backup'),
- name: 'nobackup'
- },
- {
- xtype: 'proxmoxcheckbox',
- hidden: me.insideWizard,
- fieldLabel: gettext('Skip replication'),
- name: 'noreplicate'
- },
- {
- xtype: 'proxmoxcheckbox',
- fieldLabel: gettext('Discard'),
- disabled: me.confid && !me.confid.match(/^scsi/),
- reference: 'discard',
- name: 'discard'
- },
- {
- xtype: 'proxmoxcheckbox',
- disabled: me.confid && !me.confid.match(/^(virtio|scsi)/),
- fieldLabel: 'IO thread',
- reference: 'iothread',
- name: 'iothread'
- });
+ column2.push(
+ {
+ xtype: 'CacheTypeSelector',
+ name: 'cache',
+ value: '__default__',
+ fieldLabel: gettext('Cache'),
+ },
+ {
+ xtype: 'proxmoxcheckbox',
+ fieldLabel: gettext('Discard'),
+ reference: 'discard',
+ name: 'discard',
+ },
+ );
+
+ advancedColumn1.push(
+ {
+ xtype: 'proxmoxcheckbox',
+ disabled: me.confid && me.confid.match(/^virtio/),
+ fieldLabel: gettext('SSD emulation'),
+ labelWidth: labelWidth,
+ name: 'ssd',
+ reference: 'ssd',
+ },
+ {
+ xtype: 'proxmoxcheckbox',
+ disabled: me.confid && !me.confid.match(/^(virtio|scsi)/),
+ fieldLabel: 'IO thread',
+ labelWidth: labelWidth,
+ reference: 'iothread',
+ name: 'iothread',
+ },
+ );
+
+ advancedColumn2.push(
+ {
+ xtype: 'proxmoxcheckbox',
+ fieldLabel: gettext('Backup'),
+ autoEl: {
+ tag: 'div',
+ 'data-qtip': gettext('Include volume in backup job'),
+ },
+ labelWidth: labelWidth,
+ name: 'backup',
+ bind: {
+ value: '{isIncludedInBackup}',
+ },
+ },
+ {
+ xtype: 'proxmoxcheckbox',
+ fieldLabel: gettext('Skip replication'),
+ labelWidth: labelWidth,
+ name: 'noreplicate',
+ },
+ );
+
+ let bwColumn1 = [
+ {
+ xtype: 'numberfield',
+ name: 'mbps_rd',
+ minValue: 1,
+ step: 1,
+ fieldLabel: gettext('Read limit') + ' (MB/s)',
+ labelWidth: labelWidth,
+ emptyText: gettext('unlimited'),
+ },
+ {
+ xtype: 'numberfield',
+ name: 'mbps_wr',
+ minValue: 1,
+ step: 1,
+ fieldLabel: gettext('Write limit') + ' (MB/s)',
+ labelWidth: labelWidth,
+ emptyText: gettext('unlimited'),
+ },
+ {
+ xtype: 'proxmoxintegerfield',
+ name: 'iops_rd',
+ minValue: 10,
+ step: 10,
+ fieldLabel: gettext('Read limit') + ' (ops/s)',
+ labelWidth: labelWidth,
+ emptyText: gettext('unlimited'),
+ },
+ {
+ xtype: 'proxmoxintegerfield',
+ name: 'iops_wr',
+ minValue: 10,
+ step: 10,
+ fieldLabel: gettext('Write limit') + ' (ops/s)',
+ labelWidth: labelWidth,
+ emptyText: gettext('unlimited'),
+ },
+ ];
+
+ let bwColumn2 = [
+ {
+ xtype: 'numberfield',
+ name: 'mbps_rd_max',
+ minValue: 1,
+ step: 1,
+ fieldLabel: gettext('Read max burst') + ' (MB)',
+ labelWidth: labelWidth,
+ emptyText: gettext('default'),
+ },
+ {
+ xtype: 'numberfield',
+ name: 'mbps_wr_max',
+ minValue: 1,
+ step: 1,
+ fieldLabel: gettext('Write max burst') + ' (MB)',
+ labelWidth: labelWidth,
+ emptyText: gettext('default'),
+ },
+ {
+ xtype: 'proxmoxintegerfield',
+ name: 'iops_rd_max',
+ minValue: 10,
+ step: 10,
+ fieldLabel: gettext('Read max burst') + ' (ops)',
+ labelWidth: labelWidth,
+ emptyText: gettext('default'),
+ },
+ {
+ xtype: 'proxmoxintegerfield',
+ name: 'iops_wr_max',
+ minValue: 10,
+ step: 10,
+ fieldLabel: gettext('Write max burst') + ' (ops)',
+ labelWidth: labelWidth,
+ emptyText: gettext('default'),
+ },
+ ];
+
+ me.items = [
+ {
+ xtype: 'tabpanel',
+ plain: true,
+ bodyPadding: 10,
+ border: 0,
+ items: [
+ {
+ title: gettext('Disk'),
+ xtype: 'inputpanel',
+ reference: 'diskpanel',
+ column1,
+ column2,
+ advancedColumn1,
+ advancedColumn2,
+ showAdvanced: me.showAdvanced,
+ getValues: () => ({}),
+ },
+ {
+ title: gettext('Bandwidth'),
+ xtype: 'inputpanel',
+ reference: 'bwpanel',
+ column1: bwColumn1,
+ column2: bwColumn2,
+ showAdvanced: me.showAdvanced,
+ getValues: () => ({}),
+ },
+ ],
+ },
+ ];
me.callParent();
- }
+ },
+
+ setAdvancedVisible: function(visible) {
+ this.lookup('diskpanel').setAdvancedVisible(visible);
+ this.lookup('bwpanel').setAdvancedVisible(visible);
+ },
});
-/*jslint confusion: false */
Ext.define('PVE.qemu.HDEdit', {
- extend: 'PVE.window.Edit',
+ extend: 'Proxmox.window.Edit',
isAdd: true,
- initComponent : function() {
+ backgroundDelay: 5,
+
+ width: 600,
+ bodyPadding: 0,
+
+ initComponent: function() {
var me = this;
var nodename = me.pveSelNode.data.node;
confid: me.confid,
nodename: nodename,
unused: unused,
- isCreate: me.isCreate
+ isCreate: me.isCreate,
});
- var subject;
if (unused) {
me.subject = gettext('Unused Disk');
} else if (me.isCreate) {
me.subject = gettext('Hard Disk') + ' (' + me.confid + ')';
}
- me.items = [ ipanel ];
+ me.items = [ipanel];
me.callParent();
- /*jslint confusion: true*/
/* 'data' is assigned an empty array in same file, and here we
* use it like an object
*/
ipanel.setDrive(drive);
me.isValid(); // trigger validation
}
- }
+ },
});
- /*jslint confusion: false*/
- }
+ },
});