allows to add a single host mapping for pci entries

Signed-off-by: Dominik Csapak <d.csa...@proxmox.com>
---
 www/manager6/Makefile            |   1 +
 www/manager6/form/PCISelector.js |  17 +-
 www/manager6/window/PCIEdit.js   | 323 +++++++++++++++++++++++++++++++
 3 files changed, 340 insertions(+), 1 deletion(-)
 create mode 100644 www/manager6/window/PCIEdit.js

diff --git a/www/manager6/Makefile b/www/manager6/Makefile
index f5ae5364..dad2e6ca 100644
--- a/www/manager6/Makefile
+++ b/www/manager6/Makefile
@@ -115,6 +115,7 @@ JSSRC=                                                      
\
        window/ScheduleSimulator.js                     \
        window/Wizard.js                                \
        window/GuestDiskReassign.js                             \
+       window/PCIEdit.js                               \
        ha/Fencing.js                                   \
        ha/GroupEdit.js                                 \
        ha/GroupSelector.js                             \
diff --git a/www/manager6/form/PCISelector.js b/www/manager6/form/PCISelector.js
index 4e0a778f..39e111f0 100644
--- a/www/manager6/form/PCISelector.js
+++ b/www/manager6/form/PCISelector.js
@@ -3,7 +3,22 @@ Ext.define('PVE.form.PCISelector', {
     xtype: 'pvePCISelector',
 
     store: {
-       fields: ['id', 'vendor_name', 'device_name', 'vendor', 'device', 
'iommugroup', 'mdev'],
+       fields: [
+           'id', 'vendor_name', 'device_name', 'vendor', 'device', 
'iommugroup', 'mdev',
+           'subsystem_vendor', 'subsystem_device',
+           {
+               name: 'subsystem-vendor',
+               calculate: function(data) {
+                   return data.subsystem_vendor;
+               },
+           },
+           {
+               name: 'subsystem-device',
+               calculate: function(data) {
+                   return data.subsystem_device;
+               },
+           },
+       ],
        filterOnLoad: true,
        sorters: [
            {
diff --git a/www/manager6/window/PCIEdit.js b/www/manager6/window/PCIEdit.js
new file mode 100644
index 00000000..475b91f1
--- /dev/null
+++ b/www/manager6/window/PCIEdit.js
@@ -0,0 +1,323 @@
+Ext.define('PVE.node.PCIEditWindow', {
+    extend: 'Proxmox.window.Edit',
+
+    mixins: ['Proxmox.Mixin.CBind'],
+
+    title: gettext('Add PCI mapping'),
+
+    onlineHelp: 'qm_pci_passthrough',
+
+    method: 'POST',
+
+    cbindData: function(initialConfig) {
+       let me = this;
+       me.isCreate = !me.name || !me.nodename;
+       me.method = me.isCreate ? 'POST' : 'PUT';
+       return {
+           name: me.name,
+           nodename: me.nodename,
+       };
+    },
+
+    submitUrl: function(_url, data) {
+       let me = this;
+       let name = me.isCreate ? '' : me.name;
+       return `/nodes/${data.node}/hardware/mapping/pci/${name}`;
+    },
+
+    controller: {
+       xclass: 'Ext.app.ViewController',
+
+       onGetValues: function(values) {
+           let me = this;
+
+           if (values.iommugroup === -1) {
+               delete values.iommugroup;
+           }
+
+           if (values.multifunction) {
+               values.path = values.path.substring(0, 
values.path.indexOf('.')); // skip the '.X'
+               delete values.multifunction;
+           }
+
+           return values;
+       },
+
+       checkIommu: function(store, records, success) {
+           let me = this;
+           if (!success || !records.length) {
+               return;
+           }
+           me.lookup('iommu_warning').setVisible(
+               records.every((val) => val.data.iommugroup === -1),
+           );
+       },
+
+       allFunctionsChange: function(_, value) {
+           let me = this;
+           if (value) {
+               let pcisel = me.lookup('pciselector');
+               let pcivalue = pcisel.getValue();
+               // replace the function by .0 so that we get the correct 
vendor/device
+               pcivalue = pcivalue.replace(/.$/, "0");
+               pcisel.setValue(pcivalue);
+           }
+       },
+
+       pciChange: function(pcisel, value) {
+           let me = this;
+           if (!value) {
+               return;
+           }
+           let allField = me.lookup('all_functions');
+           let all_functions = !!allField.getValue();
+
+           // if we set the saved value without the function
+           if (value.indexOf('.') === -1) {
+               all_functions = true;
+               allField.setValue(true);
+               allField.resetOriginalValue();
+
+               value += '.0';
+               pcisel.setValue(value);
+               pcisel.resetOriginalValue();
+           } else if (all_functions) {
+               // replace the function by .0 so that we get the correct 
vendor/device
+               let newvalue = value.replace(/.$/, "0");
+               if (newvalue !== value) {
+                   pcisel.setValue(value);
+               }
+           }
+
+           let pciDev = pcisel.getStore().getById(value);
+           if (!pciDev) {
+               return;
+           }
+           let iommu = pciDev.data.iommugroup;
+           // 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;
+           });
+
+           me.lookup('group_warning').setVisible(count > 0);
+
+           let fields = [
+               'vendor',
+               'device',
+               'subsystem-vendor',
+               'subsystem-device',
+               'mdev',
+               'iommugroup',
+           ];
+
+           fields.forEach((fieldName) => {
+               let field = me.lookup(fieldName);
+               let oldValue = field.getValue();
+               if (oldValue !== pciDev.data[fieldName]) {
+                   field.setValue(pciDev.data[fieldName]);
+               }
+           });
+       },
+
+       mdevChange: function(mdevField, value) {
+           let val = Proxmox.Utils.format_boolean(!!value);
+           this.lookup('mdev-display').setValue(val);
+       },
+
+       nodeChange: function(_field, value) {
+           this.lookup('pciselector').setNodename(value);
+       },
+
+       init: function(view) {
+           let me = this;
+
+           if (!view.nodename) {
+               //throw "no nodename given";
+           }
+       },
+
+       control: {
+           'field[name=multifunction]': {
+               change: 'allFunctionsChange',
+           },
+           'field[name=path]': {
+               change: 'pciChange',
+           },
+           'field[name=mdev]': {
+               change: 'mdevChange',
+           },
+           'pveNodeSelector': {
+               change: 'nodeChange',
+           },
+       },
+    },
+
+    items: [
+       {
+           xtype: 'inputpanel',
+           onGetValues: function(values) {
+               return this.up('window').getController().onGetValues(values);
+           },
+
+           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',
+               },
+           ],
+
+           column1: [
+               {
+                   xtype: 'pmxDisplayEditField',
+                   fieldLabel: gettext('Name'),
+                   labelWidth: 120,
+                   cbind: {
+                       editable: '{!name}',
+                       value: '{name}',
+                       submitValue: '{isCreate}',
+                   },
+                   name: 'name',
+                   allowBlank: false,
+               },
+               {
+                   xtype: 'pmxDisplayEditField',
+                   fieldLabel: gettext('Node'),
+                   labelWidth: 120,
+                   name: 'node',
+                   editConfig: {
+                       xtype: 'pveNodeSelector',
+                   },
+                   cbind: {
+                       editable: '{!nodename}',
+                       value: '{nodename}',
+                   },
+                   submitValue: true,
+                   allowBlank: false,
+               },
+               {
+                   xtype: 'displayfield',
+                   fieldLabel: gettext('Vendor'),
+                   labelWidth: 120,
+                   submitValue: true,
+                   reference: 'vendor',
+                   name: 'vendor',
+               },
+               {
+                   xtype: 'displayfield',
+                   fieldLabel: gettext('Subsystem Vendor'),
+                   labelWidth: 120,
+                   submitValue: true,
+                   reference: 'subsystem-vendor',
+                   name: 'subsystem-vendor',
+                   cbind: {
+                       deleteEmpty: '{!isCreate}',
+                   },
+               },
+               {
+                   xtype: 'proxmoxtextfield',
+                   reference: 'mdev',
+                   hidden: true,
+                   name: 'mdev',
+                   cbind: {
+                       deleteEmpty: '{!isCreate}',
+                   },
+               },
+               {
+                   xtype: 'displayfield',
+                   fieldLabel: gettext('Mediated Devices'),
+                   labelWidth: 120,
+                   value: Proxmox.Utils.noText,
+                   reference: 'mdev-display',
+                   name: 'mdev-display',
+               },
+           ],
+
+           column2: [
+               {
+                   xtype: 'pvePCISelector',
+                   fieldLabel: gettext('Device'),
+                   labelWidth: 120,
+                   reference: 'pciselector',
+                   name: 'path',
+                   cbind: {
+                       nodename: '{nodename}',
+                   },
+                   allowBlank: false,
+                   onLoadCallBack: 'checkIommu',
+               },
+               {
+                   xtype: 'proxmoxcheckbox',
+                   fieldLabel: gettext('All Functions'),
+                   labelWidth: 120,
+                   reference: 'all_functions',
+                   name: 'multifunction',
+               },
+               {
+                   xtype: 'displayfield',
+                   fieldLabel: gettext('Device'),
+                   labelWidth: 120,
+                   submitValue: true,
+                   reference: 'device',
+                   name: 'device',
+               },
+               {
+                   xtype: 'displayfield',
+                   fieldLabel: gettext('Subsystem Device'),
+                   labelWidth: 120,
+                   submitValue: true,
+                   reference: 'subsystem-device',
+                   name: 'subsystem-device',
+                   cbind: {
+                       deleteEmpty: '{!isCreate}',
+                   },
+               },
+               {
+                   xtype: 'displayfield',
+                   fieldLabel: gettext('IOMMU group'),
+                   labelWidth: 120,
+                   submitValue: true,
+                   reference: 'iommugroup',
+                   name: 'iommugroup',
+                   cbind: {
+                       deleteEmpty: '{!isCreate}',
+                   },
+               },
+           ],
+
+           columnB: [
+               {
+                   xtype: 'proxmoxtextfield',
+                   fieldLabel: gettext('Comment'),
+                   labelWidth: 120,
+                   submitValue: true,
+                   name: 'comment',
+                   cbind: {
+                       deleteEmpty: '{!isCreate}',
+                   },
+               },
+           ],
+       },
+    ],
+});
-- 
2.30.2



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to