From: Dominik Csapak <d.csapak@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH v5 07/15] ui: qemu/PCIEdit: rework panel to add a mapped configuration
Date: Tue, 6 Jun 2023 15:52:14 +0200 [thread overview]
Message-ID: <20230606135222.984747-16-d.csapak@proxmox.com> (raw)
In-Reply-To: <20230606135222.984747-1-d.csapak@proxmox.com>
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 <d.csapak@proxmox.com>
---
www/manager6/qemu/PCIEdit.js | 323 ++++++++++++++++++++++++-----------
1 file changed, 219 insertions(+), 104 deletions(-)
diff --git a/www/manager6/qemu/PCIEdit.js b/www/manager6/qemu/PCIEdit.js
index 2f67aece..d98f410d 100644
--- a/www/manager6/qemu/PCIEdit.js
+++ b/www/manager6/qemu/PCIEdit.js
@@ -3,71 +3,164 @@ Ext.define('PVE.qemu.PCIInputPanel', {
onlineHelp: 'qm_pci_passthrough_vm_config',
- 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'));
- }
+ selectorEnable: function(selector) {
+ let me = this;
+ me.pciDevChange(selector, selector.getValue());
+ },
- if (values.romfile) {
- me.down('field[name=romfile]').setVisible(true);
- }
- },
+ pciDevChange: function(pcisel, value) {
+ let me = this;
+ let mdevfield = me.lookup('mdev');
+ if (!value) {
+ if (!pcisel.isDisabled()) {
+ mdevfield.setDisabled(true);
+ }
+ return;
+ }
+ let pciDev = pcisel.getStore().getById(value);
- onGetValues: function(values) {
- let me = this;
- if (!me.confid) {
- for (let i = 0; i < PVE.Utils.hardware_counts.hostpci; i++) {
- if (!me.vmconfig['hostpci' + i.toString()]) {
- me.confid = 'hostpci' + i.toString();
- break;
+ mdevfield.setDisabled(!pciDev || !pciDev.data.mdev);
+ if (!pciDev) {
+ return;
+ }
+
+ let path = value;
+ if (pciDev.data.map) {
+ // find local mapping
+ for (const entry of pciDev.data.map) {
+ let mapping = PVE.Parser.parsePropertyString(entry);
+ if (mapping.node === pcisel.up('inputpanel').nodename) {
+ path = mapping.path.split(';')[0];
+ break;
+ }
+ }
+ if (path.indexOf('.') === -1) {
+ path += '.0';
}
}
- // 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 (pciDev.data.mdev) {
+ mdevfield.setPciID(path);
+ }
+ if (pcisel.reference === 'selector') {
+ let iommu = pciDev.data.iommugroup;
+ if (iommu === -1) {
+ return;
+ }
+ // try to find out if there are more devices in that iommu group
+ let id = path.substring(0, 5); // 00:00
+ let count = 0;
+ pcisel.getStore().each(({ data }) => {
+ if (data.iommugroup === iommu && data.id.substring(0, 5) !== id) {
+ count++;
+ return false;
+ }
+ return true;
+ });
+ me.lookup('group_warning').setVisible(count > 0);
+ }
+ },
- if (values.rombar) {
- delete values.rombar;
- } else {
- values.rombar = 0;
- }
+ onGetValues: function(values) {
+ let me = this;
+ let view = me.getView();
+ if (!view.confid) {
+ for (let i = 0; i < PVE.Utils.hardware_counts.hostpci; i++) {
+ if (!me.vmconfig['hostpci' + i.toString()]) {
+ view.confid = 'hostpci' + i.toString();
+ break;
+ }
+ }
+ // FIXME: what if no confid was found??
+ }
- if (!values.romfile) {
- delete values.romfile;
- }
+ if (values.hostmapped) {
+ values.host = values.hostmapped;
+ delete values.hostmapped;
+ } else {
+ 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.romfile) {
+ delete values.romfile;
+ }
+
+ delete values.type;
+
+ let ret = {};
+ ret[view.confid] = PVE.Parser.printPropertyString(values, 'host');
+ return ret;
+ },
+ },
- let ret = {};
- ret[me.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,78 +171,97 @@ 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}',
+ },
+ listeners: {
+ change: 'pciDevChange',
+ enable: 'selectorEnable',
+ },
+ },
+ {
+ 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) {
- if (!value) {
- return;
- }
- let pciDev = pcisel.getStore().getById(value);
- let mdevfield = me.down('field[name=mdev]');
- mdevfield.setDisabled(!pciDev || !pciDev.data.mdev);
- if (!pciDev) {
- return;
- }
- if (pciDev.data.mdev) {
- mdevfield.setPciID(value);
- }
- let iommu = pciDev.data.iommugroup;
- if (iommu === -1) {
- return;
- }
- // try to find out if there are more devices in that iommu group
- let id = pciDev.data.id.substring(0, 5); // 00:00
- let count = 0;
- pcisel.getStore().each(({ data }) => {
- if (data.iommugroup === iommu && data.id.substring(0, 5) !== id) {
- count++;
- return false;
- }
- 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);
- }
- },
+ change: 'pciDevChange',
+ enable: 'selectorEnable',
},
},
{
xtype: 'proxmoxcheckbox',
fieldLabel: gettext('All Functions'),
+ reference: 'all_functions',
+ disabled: true,
+ labelAlign: 'right',
name: 'multifunction',
+ bind: {
+ disabled: '{isMapped}',
+ },
},
];
@@ -157,6 +269,7 @@ Ext.define('PVE.qemu.PCIInputPanel', {
{
xtype: 'pveMDevSelector',
name: 'mdev',
+ reference: 'mdev',
disabled: true,
fieldLabel: gettext('MDev Type'),
nodename: me.nodename,
@@ -188,6 +301,7 @@ Ext.define('PVE.qemu.PCIInputPanel', {
submitValue: true,
hidden: true,
fieldLabel: 'ROM-File',
+ reference: 'romfile',
name: 'romfile',
},
{
@@ -214,6 +328,7 @@ Ext.define('PVE.qemu.PCIInputPanel', {
{
xtype: 'proxmoxcheckbox',
fieldLabel: 'PCI-Express',
+ reference: 'pcie',
name: 'pcie',
},
{
--
2.30.2
next prev parent reply other threads:[~2023-06-06 14:01 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-06 13:51 [pve-devel] [PATCH access-control/guest-common/qemu-server/manager v5] cluster mapping Dominik Csapak
2023-06-06 13:52 ` [pve-devel] [PATCH access-control v5 1/1] add privileges and paths for cluster resource mapping Dominik Csapak
2023-06-07 17:03 ` [pve-devel] applied: " Thomas Lamprecht
2023-06-06 13:52 ` [pve-devel] [PATCH guest-common v5 1/1] add PCI/USB Mapping configs Dominik Csapak
2023-06-07 17:17 ` [pve-devel] applied: " Thomas Lamprecht
2023-06-06 13:52 ` [pve-devel] [PATCH qemu-server v5 1/6] enable cluster mapped USB devices for guests Dominik Csapak
2023-06-13 12:23 ` Wolfgang Bumiller
2023-06-06 13:52 ` [pve-devel] [PATCH qemu-server v5 2/6] enable cluster mapped PCI " Dominik Csapak
2023-06-06 13:52 ` [pve-devel] [PATCH qemu-server v5 3/6] check_local_resources: extend for mapped resources Dominik Csapak
2023-06-13 12:43 ` Wolfgang Bumiller
2023-06-06 13:52 ` [pve-devel] [PATCH qemu-server v5 4/6] api: migrate preconditions: use new check_local_resources info Dominik Csapak
2023-06-13 12:46 ` Wolfgang Bumiller
2023-06-06 13:52 ` [pve-devel] [PATCH qemu-server v5 5/6] migration: check for mapped resources Dominik Csapak
2023-06-06 13:52 ` [pve-devel] [PATCH qemu-server v5 6/6] add test for mapped pci devices Dominik Csapak
2023-06-06 13:52 ` [pve-devel] [PATCH v5 01/15] pvesh: fix parameters for proxyto_callback Dominik Csapak
2023-06-06 13:52 ` [pve-devel] [PATCH v5 02/15] api: add resource map api endpoints for PCI and USB Dominik Csapak
2023-06-13 11:26 ` Wolfgang Bumiller
2023-06-06 13:52 ` [pve-devel] [PATCH v5 03/15] ui: parser: add helpers for lists of property strings Dominik Csapak
2023-06-06 13:52 ` [pve-devel] [PATCH v5 04/15] ui: form/USBSelector: make it more flexible with nodename Dominik Csapak
2023-06-06 13:52 ` [pve-devel] [PATCH v5 05/15] ui: form: add PCIMapSelector Dominik Csapak
2023-06-06 13:52 ` [pve-devel] [PATCH v5 06/15] ui: form: add USBMapSelector Dominik Csapak
2023-06-06 13:52 ` Dominik Csapak [this message]
2023-06-06 13:52 ` [pve-devel] [PATCH v5 08/15] ui: qemu/USBEdit: add 'mapped' device case Dominik Csapak
2023-06-06 13:52 ` [pve-devel] [PATCH v5 09/15] ui: form: add MultiPCISelector Dominik Csapak
2023-06-06 13:52 ` [pve-devel] [PATCH v5 10/15] ui: add edit window for pci mappings Dominik Csapak
2023-06-06 13:52 ` [pve-devel] [PATCH v5 11/15] ui: add edit window for usb mappings Dominik Csapak
2023-06-06 13:52 ` [pve-devel] [PATCH v5 12/15] ui: add ResourceMapTree Dominik Csapak
2023-06-06 13:52 ` [pve-devel] [PATCH v5 13/15] ui: allow configuring pci and usb mapping Dominik Csapak
2023-06-06 13:52 ` [pve-devel] [PATCH v5 14/15] ui: window/Migrate: allow mapped devices Dominik Csapak
2023-06-06 13:52 ` [pve-devel] [PATCH v5 15/15] ui: improve permission handling for hardware Dominik Csapak
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230606135222.984747-16-d.csapak@proxmox.com \
--to=d.csapak@proxmox.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox