]> git.proxmox.com Git - pve-manager-legacy.git/commitdiff
gui: add qemu/PCIEdit
authorDominik Csapak <d.csapak@proxmox.com>
Thu, 22 Nov 2018 10:35:45 +0000 (11:35 +0100)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Thu, 22 Nov 2018 12:31:31 +0000 (13:31 +0100)
this patch adds the PCIEdit window and InputPanel uses PCISelector
and MDevSelector

when we detect an iommugroup of -1, we put a warning on top to inform
the user that IOMMU is not activated (but let him add the devices
regardless, so that he can use it after IOMMU is activated)

also puts a warning if he selects a device that shares an iommugroup
with a different device (but not the same device with different
function). that detection is not perfect, but we cannot do really
better

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
www/manager6/Makefile
www/manager6/qemu/PCIEdit.js [new file with mode: 0644]

index d900ec88573e3d70b7e0cec53a197f373177ff97..d005d71401db3f7ac8c6bd44e1c3b005776a1443 100644 (file)
@@ -139,6 +139,7 @@ JSSRC=                                                      \
        qemu/Config.js                                  \
        qemu/CreateWizard.js                            \
        qemu/USBEdit.js                                 \
+       qemu/PCIEdit.js                                 \
        qemu/SerialEdit.js                                      \
        qemu/AgentIPView.js                             \
        qemu/CloudInit.js                               \
diff --git a/www/manager6/qemu/PCIEdit.js b/www/manager6/qemu/PCIEdit.js
new file mode 100644 (file)
index 0000000..40a7d8c
--- /dev/null
@@ -0,0 +1,233 @@
+Ext.define('PVE.qemu.PCIInputPanel', {
+    extend: 'Proxmox.panel.InputPanel',
+
+    onlineHelp: 'qm_pci_passthrough',
+
+    setVMConfig: function(vmconfig) {
+       var me = this;
+       me.vmconfig = vmconfig;
+
+       var hostpci = me.vmconfig[me.confid] || '';
+
+       var values = PVE.Parser.parsePropertyString(hostpci, 'host');
+       if (values.host && values.host.length < 6) { // 00:00 format not 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);
+
+       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'));
+       }
+
+       if (values.romfile) {
+           me.down('field[name=romfile]').setVisible(true);
+       }
+    },
+
+    onGetValues: function(values) {
+       var me = this;
+       var ret = {};
+       if(!me.confid) {
+           var i;
+           for (i = 0; i < 5; i++) {
+               if (!me.vmconfig['hostpci' +  i.toString()]) {
+                   me.confid = 'hostpci' + i.toString();
+                   break;
+               }
+           }
+       }
+       if (values.multifunction) {
+           // modify host to skip the '.X'
+           values.host = values.host.substring(0,5);
+           delete values.multifunction;
+       }
+
+       if (values.rombar) {
+           delete values.rombar;
+       } else {
+           values.rombar = 0;
+       }
+
+       ret[me.confid] = PVE.Parser.printPropertyString(values, 'host');
+       return ret;
+    },
+
+    initComponent: function() {
+       var me = this;
+
+       me.nodename = me.pveSelNode.data.node;
+       if (!me.nodename) {
+           throw "no node name specified";
+       }
+
+       me.column1 = [
+           {
+               xtype: 'pvePCISelector',
+               fieldLabel: gettext('Device'),
+               name: 'host',
+               nodename: me.nodename,
+               allowBlank: false,
+               onLoadCallBack: function(store, records, success) {
+                   if (!success || !records.length) {
+                       return;
+                   }
+
+                   var first = records[0];
+                   if (first.data.iommugroup === -1) {
+                       // no iommu groups
+                       var 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: 'pve-hint'
+                       });
+                       me.items.insert(0, warning);
+                       me.updateLayout(); // insert does not trigger that
+                   }
+               },
+               listeners: {
+                   change: function(pcisel, value) {
+                       if (!value) {
+                           return;
+                       }
+                       var pcidev = pcisel.getStore().getById(value);
+                       var mdevfield = me.down('field[name=mdev]');
+                       mdevfield.setDisabled(!pcidev || !pcidev.data.mdev);
+                       if (!pcidev) {
+                           return;
+                       }
+                       var id = pcidev.data.id.substring(0,5); // 00:00
+                       var iommu = pcidev.data.iommugroup;
+                       // try to find out if there are more devices
+                       // in that iommu group
+                       if (iommu !== -1) {
+                           var count = 0;
+                           pcisel.getStore().each(function(record) {
+                               if (record.data.iommugroup === iommu &&
+                                   record.data.id.substring(0,5) !== id)
+                               {
+                                   count++;
+                                   return false;
+                               }
+                           });
+                           var 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: 'pve-hint'
+                               });
+                               me.items.insert(0, warning);
+                               me.updateLayout(); // insert does not trigger that
+                           } else if (!count && warning) {
+                               me.remove(warning);
+                           }
+                       }
+                       if (pcidev.data.mdev) {
+                           mdevfield.setPciID(value);
+                       }
+                   }
+               }
+           },
+           {
+               xtype: 'proxmoxcheckbox',
+               fieldLabel: gettext('All Functions'),
+               name: 'multifunction'
+           }
+       ];
+
+       me.column2 = [
+           {
+               xtype: 'pveMDevSelector',
+               name: 'mdev',
+               disabled: true,
+               fieldLabel: gettext('MDev Type'),
+               nodename: me.nodename,
+               listeners: {
+                   change: function(field, value) {
+                       var mf = me.down('field[name=multifunction]');
+                       if (!!value) {
+                           mf.setValue(false);
+                       }
+                       mf.setDisabled(!!value);
+                   }
+               }
+           },
+           {
+               xtype: 'proxmoxcheckbox',
+               fieldLabel: gettext('Primary GPU'),
+               name: 'x-vga'
+           }
+       ];
+
+       me.advancedColumn1 = [
+           {
+               xtype: 'proxmoxcheckbox',
+               fieldLabel: 'ROM-Bar',
+               name: 'rombar'
+           },
+           {
+               xtype: 'displayfield',
+               submitValue: true,
+               hidden: true,
+               fieldLabel: 'ROM-File',
+               name: 'romfile'
+           }
+       ];
+
+       me.advancedColumn2 = [
+           {
+               xtype: 'proxmoxcheckbox',
+               fieldLabel: 'PCI-Express',
+               name: 'pcie'
+           }
+       ];
+
+       me.callParent();
+    }
+});
+
+Ext.define('PVE.qemu.PCIEdit', {
+    extend: 'Proxmox.window.Edit',
+
+    vmconfig: undefined,
+
+    isAdd: true,
+
+    subject: gettext('PCI Device'),
+
+
+    initComponent : function() {
+       var me = this;
+
+       me.isCreate = !me.confid;
+
+       var ipanel = Ext.create('PVE.qemu.PCIInputPanel', {
+           confid: me.confid,
+           pveSelNode: me.pveSelNode
+       });
+
+       Ext.apply(me, {
+           items: [ ipanel ]
+       });
+
+       me.callParent();
+
+       me.load({
+           success: function(response) {
+               ipanel.setVMConfig(response.result.data);
+           }
+       });
+    }
+});