From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 9F25374524 for ; Mon, 21 Jun 2021 15:56:37 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id CC6361C48A for ; Mon, 21 Jun 2021 15:55:46 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id D46251C35B for ; Mon, 21 Jun 2021 15:55:37 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id AF6D542AFD for ; Mon, 21 Jun 2021 15:55:37 +0200 (CEST) From: Dominik Csapak To: pve-devel@lists.proxmox.com Date: Mon, 21 Jun 2021 15:55:32 +0200 Message-Id: <20210621135534.14807-20-d.csapak@proxmox.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210621135534.14807-1-d.csapak@proxmox.com> References: <20210621135534.14807-1-d.csapak@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.798 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pve-devel] [PATCH manager 6/8] ui: qemu/PCIEdit: rework panel to add a mapped configuration X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 21 Jun 2021 13:56:37 -0000 reworks the panel to use a controller, so that we can easily add the selector for mapped pci devices shows now a selection between 'raw' and 'mapped' devices, where 'raw' ones work like before, and 'mapped' ones take the values form the hardware map config Signed-off-by: Dominik Csapak --- www/manager6/qemu/PCIEdit.js | 231 +++++++++++++++++++++++------------ 1 file changed, 155 insertions(+), 76 deletions(-) diff --git a/www/manager6/qemu/PCIEdit.js b/www/manager6/qemu/PCIEdit.js index e1c6aea7..920513c3 100644 --- a/www/manager6/qemu/PCIEdit.js +++ b/www/manager6/qemu/PCIEdit.js @@ -3,71 +3,106 @@ Ext.define('PVE.qemu.PCIInputPanel', { onlineHelp: 'qm_pci_passthrough', - setVMConfig: function(vmconfig) { - var me = this; - me.vmconfig = vmconfig; + controller: { + xclass: 'Ext.app.ViewController', + + setVMConfig: function(vmconfig) { + let me = this; + let view = me.getView(); + me.vmconfig = vmconfig; - var hostpci = me.vmconfig[me.confid] || ''; + let hostpci = me.vmconfig[view.confid] || ''; - var values = PVE.Parser.parsePropertyString(hostpci, 'host'); - if (values.host) { - if (!values.host.match(/^[0-9a-f]{4}:/i)) { // add optional domain - values.host = "0000:" + values.host; + let values = PVE.Parser.parsePropertyString(hostpci, 'host'); + if (values.host) { + if (values.host.includes(':')) { + values.type = 'raw'; + if (!values.host.match(/^[0-9a-f]{4}:/i)) { // add optional domain + values.host = "0000:" + values.host; + } + if (values.host.length < 11) { // 0000:00:00 format not 0000:00:00.0 + values.host += ".0"; + values.multifunction = true; + } + } else { + values.hostmapped = values.host; + delete values.host; + values.type = 'mapped'; + } } - if (values.host.length < 11) { // 0000:00:00 format not 0000:00:00.0 - values.host += ".0"; - values.multifunction = true; + + values['x-vga'] = PVE.Parser.parseBoolean(values['x-vga'], 0); + values.pcie = PVE.Parser.parseBoolean(values.pcie, 0); + values.rombar = PVE.Parser.parseBoolean(values.rombar, 1); + + view.setValues(values); + if (!me.vmconfig.machine || me.vmconfig.machine.indexOf('q35') === -1) { + // machine is not set to some variant of q35, so we disable pcie + let pcie = me.lookup('pcie'); + pcie.setDisabled(true); + pcie.setBoxLabel(gettext('Q35 only')); } - } - values['x-vga'] = PVE.Parser.parseBoolean(values['x-vga'], 0); - values.pcie = PVE.Parser.parseBoolean(values.pcie, 0); - values.rombar = PVE.Parser.parseBoolean(values.rombar, 1); + if (values.romfile) { + me.lookup('romfile').setVisible(true); + } + }, - me.setValues(values); - if (!me.vmconfig.machine || me.vmconfig.machine.indexOf('q35') === -1) { - // machine is not set to some variant of q35, so we disable pcie - var pcie = me.down('field[name=pcie]'); - pcie.setDisabled(true); - pcie.setBoxLabel(gettext('Q35 only')); - } + onGetValues: function(values) { + let me = this; + let view = me.getView(); + if (!view.confid) { + for (let i = 0; i < 5; i++) { + if (!me.vmconfig['hostpci' + i.toString()]) { + view.confid = 'hostpci' + i.toString(); + break; + } + } + // FIXME: what if no confid was found?? + } - if (values.romfile) { - me.down('field[name=romfile]').setVisible(true); - } - }, + if (values.hostmapped) { + values.host = values.hostmapped; + delete values.hostmapped; + } else { + values.host.replace(/^0000:/, ''); // remove optional '0000' domain - onGetValues: function(values) { - let me = this; - if (!me.confid) { - for (let i = 0; i < 5; i++) { - if (!me.vmconfig['hostpci' + i.toString()]) { - me.confid = 'hostpci' + i.toString(); - break; + if (values.multifunction) { + values.host = values.host.substring(0, values.host.indexOf('.')); // skip the '.X' + delete values.multifunction; } } - // FIXME: what if no confid was found?? - } - values.host.replace(/^0000:/, ''); // remove optional '0000' domain - if (values.multifunction) { - values.host = values.host.substring(0, values.host.indexOf('.')); // skip the '.X' - delete values.multifunction; - } + if (values.rombar) { + delete values.rombar; + } else { + values.rombar = 0; + } - if (values.rombar) { - delete values.rombar; - } else { - values.rombar = 0; - } + if (!values.romfile) { + delete values.romfile; + } - if (!values.romfile) { - delete values.romfile; - } + delete values.type; - let ret = {}; - ret[me.confid] = PVE.Parser.printPropertyString(values, 'host'); - return ret; + let ret = {}; + ret[view.confid] = PVE.Parser.printPropertyString(values, 'host'); + return ret; + }, + }, + + viewModel: { + data: { + isMapped: true, + }, + }, + + setVMConfig: function(vmconfig) { + return this.getController().setVMConfig(vmconfig); + }, + + onGetValues: function(values) { + return this.getController().onGetValues(values); }, initComponent: function() { @@ -78,28 +113,77 @@ Ext.define('PVE.qemu.PCIInputPanel', { throw "no node name specified"; } + me.columnT = [ + { + xtype: 'displayfield', + reference: 'iommu_warning', + hidden: true, + columnWidth: 1, + padding: '0 0 10 0', + value: 'No IOMMU detected, please activate it.' + + 'See Documentation for further information.', + userCls: 'pmx-hint', + }, + { + xtype: 'displayfield', + reference: 'group_warning', + hidden: true, + columnWidth: 1, + padding: '0 0 10 0', + itemId: 'iommuwarning', + value: 'The selected Device is not in a seperate IOMMU group, make sure this is intended.', + userCls: 'pmx-hint', + }, + ]; + me.column1 = [ + { + xtype: 'radiofield', + name: 'type', + inputValue: 'mapped', + boxLabel: gettext('Mapped Device'), + bind: { + value: '{isMapped}', + }, + }, + { + xtype: 'pvePCIMapSelector', + fieldLabel: gettext('Device'), + reference: 'mapped_selector', + name: 'hostmapped', + labelAlign: 'right', + nodename: me.nodename, + allowBlank: false, + bind: { + disabled: '{!isMapped}', + }, + }, + { + xtype: 'radiofield', + name: 'type', + inputValue: 'raw', + checked: true, + boxLabel: gettext('Raw Device'), + }, { xtype: 'pvePCISelector', fieldLabel: gettext('Device'), name: 'host', + reference: 'selector', nodename: me.nodename, + labelAlign: 'right', allowBlank: false, + disabled: true, + bind: { + disabled: '{isMapped}', + }, onLoadCallBack: function(store, records, success) { if (!success || !records.length) { return; } - if (records.every((val) => val.data.iommugroup === -1)) { // no IOMMU groups - let warning = Ext.create('Ext.form.field.Display', { - columnWidth: 1, - padding: '0 0 10 0', - value: 'No IOMMU detected, please activate it.' + - 'See Documentation for further information.', - userCls: 'pmx-hint', - }); - me.items.insert(0, warning); - me.updateLayout(); // insert does not trigger that - } + me.lookup('iommu_warning').setVisible( + records.every((val) => val.data.iommugroup === -1), + ); }, listeners: { change: function(pcisel, value) { @@ -129,27 +213,20 @@ Ext.define('PVE.qemu.PCIInputPanel', { } return true; }); - let warning = me.down('#iommuwarning'); - if (count && !warning) { - warning = Ext.create('Ext.form.field.Display', { - columnWidth: 1, - padding: '0 0 10 0', - itemId: 'iommuwarning', - value: 'The selected Device is not in a seperate IOMMU group, make sure this is intended.', - userCls: 'pmx-hint', - }); - me.items.insert(0, warning); - me.updateLayout(); // insert does not trigger that - } else if (!count && warning) { - me.remove(warning); - } + me.lookup('group_warning').setVisible(count > 0); }, }, }, { xtype: 'proxmoxcheckbox', fieldLabel: gettext('All Functions'), + reference: 'all_functions', + disabled: true, + labelAlign: 'right', name: 'multifunction', + bind: { + disabled: '{isMapped}', + }, }, ]; @@ -188,6 +265,7 @@ Ext.define('PVE.qemu.PCIInputPanel', { submitValue: true, hidden: true, fieldLabel: 'ROM-File', + reference: 'romfile', name: 'romfile', }, ]; @@ -196,6 +274,7 @@ Ext.define('PVE.qemu.PCIInputPanel', { { xtype: 'proxmoxcheckbox', fieldLabel: 'PCI-Express', + reference: 'pcie', name: 'pcie', }, ]; -- 2.20.1