From: Dominik Csapak <d.csapak@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH manager v6 13/15] ui: allow configuring pci and usb mapping
Date: Wed, 14 Jun 2023 10:46:19 +0200 [thread overview]
Message-ID: <20230614084622.1446211-20-d.csapak@proxmox.com> (raw)
In-Reply-To: <20230614084622.1446211-1-d.csapak@proxmox.com>
uses the new ResourceMapTree to add the CRUD interfaces for the
mappings.
We add both of them into a single panel, since the datacenter menu
already has many entries, and without a proper summary for the group, we
cannot really put them in a category
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
changes from v5:
* add onlineHelp
www/manager6/Makefile | 2 +
www/manager6/StateProvider.js | 1 +
www/manager6/dc/Config.js | 46 ++++++++++++++-
www/manager6/dc/PCIMapView.js | 106 ++++++++++++++++++++++++++++++++++
www/manager6/dc/USBMapView.js | 98 +++++++++++++++++++++++++++++++
5 files changed, 251 insertions(+), 2 deletions(-)
create mode 100644 www/manager6/dc/PCIMapView.js
create mode 100644 www/manager6/dc/USBMapView.js
diff --git a/www/manager6/Makefile b/www/manager6/Makefile
index 0cb922d6..2d884f4a 100644
--- a/www/manager6/Makefile
+++ b/www/manager6/Makefile
@@ -174,6 +174,8 @@ JSSRC= \
dc/UserTagAccessEdit.js \
dc/RegisteredTagsEdit.js \
dc/RealmSyncJob.js \
+ dc/PCIMapView.js \
+ dc/USBMapView.js \
lxc/CmdMenu.js \
lxc/Config.js \
lxc/CreateWizard.js \
diff --git a/www/manager6/StateProvider.js b/www/manager6/StateProvider.js
index fafbb112..d62d33b2 100644
--- a/www/manager6/StateProvider.js
+++ b/www/manager6/StateProvider.js
@@ -47,6 +47,7 @@ Ext.define('PVE.StateProvider', {
hprefix: 'v1',
compDict: {
+ 'resource-map': 55,
tfa: 54,
sdn: 53,
cloudinit: 52,
diff --git a/www/manager6/dc/Config.js b/www/manager6/dc/Config.js
index 72a9bec1..a3c6e06a 100644
--- a/www/manager6/dc/Config.js
+++ b/www/manager6/dc/Config.js
@@ -262,8 +262,50 @@ Ext.define('PVE.dc.Config', {
iconCls: 'fa fa-bar-chart',
itemId: 'metricservers',
onlineHelp: 'external_metric_server',
- },
- {
+ });
+ }
+
+ if (caps.mapping['Mapping.Audit'] ||
+ caps.mapping['Mapping.Use'] ||
+ caps.mapping['Mapping.Modify']) {
+ me.items.push(
+ {
+ xtype: 'container',
+ onlineHelp: 'resource_mapping',
+ title: gettext('Resource Mappings'),
+ itemId: 'resources',
+ iconCls: 'fa fa-folder-o',
+ layout: {
+ type: 'vbox',
+ align: 'stretch',
+ multi: true,
+ },
+ scrollable: true,
+ defaults: {
+ collapsible: true,
+ animCollapse: false,
+ margin: '7 10 3 10',
+ },
+ items: [
+ {
+ collapsible: true,
+ xtype: 'pveDcPCIMapView',
+ title: gettext('PCI Devices'),
+ flex: 1,
+ },
+ {
+ collapsible: true,
+ xtype: 'pveDcUSBMapView',
+ title: gettext('USB Devices'),
+ flex: 1,
+ },
+ ],
+ },
+ );
+ }
+
+ if (caps.dc['Sys.Audit']) {
+ me.items.push({
xtype: 'pveDcSupport',
title: gettext('Support'),
itemId: 'support',
diff --git a/www/manager6/dc/PCIMapView.js b/www/manager6/dc/PCIMapView.js
new file mode 100644
index 00000000..3efa19d8
--- /dev/null
+++ b/www/manager6/dc/PCIMapView.js
@@ -0,0 +1,106 @@
+Ext.define('pve-resource-pci-tree', {
+ extend: 'Ext.data.Model',
+ idProperty: 'internalId',
+ fields: ['type', 'text', 'path', 'id', 'subsystem-id', 'iommugroup', 'description', 'digest'],
+});
+
+Ext.define('PVE.dc.PCIMapView', {
+ extend: 'PVE.tree.ResourceMapTree',
+ alias: 'widget.pveDcPCIMapView',
+
+ editWindowClass: 'PVE.window.PCIMapEditWindow',
+ baseUrl: '/cluster/mapping/pci',
+ mapIconCls: 'pve-itype-icon-pci',
+ getStatusCheckUrl: (node) => `/nodes/${node}/hardware/pci?pci-class-blacklist=`,
+ entryIdProperty: 'path',
+
+ checkValidity: function(data, node) {
+ let me = this;
+ let ids = {};
+ data.forEach((entry) => {
+ ids[entry.id] = entry;
+ });
+ me.getRootNode()?.cascade(function(rec) {
+ if (rec.data.node !== node || rec.data.type !== 'map') {
+ return;
+ }
+
+ let id = rec.data.path;
+ if (!id.match(/\.\d$/)) {
+ id += '.0';
+ }
+ let device = ids[id];
+ if (!device) {
+ rec.set('valid', 0);
+ rec.set('errmsg', Ext.String.format(gettext("Cannot find PCI id {0}"), id));
+ rec.commit();
+ return;
+ }
+
+
+ let deviceId = `${device.vendor}:${device.device}`.replace(/0x/g, '');
+ let subId = `${device.subsystem_vendor}:${device.subsystem_device}`.replace(/0x/g, '');
+
+ let toCheck = {
+ id: deviceId,
+ 'subsystem-id': subId,
+ iommugroup: device.iommugroup !== -1 ? device.iommugroup : undefined,
+ };
+
+ let valid = 1;
+ let errors = [];
+ let errText = gettext("Configuration for {0} not correct ('{1}' != '{2}')");
+ for (const [key, validValue] of Object.entries(toCheck)) {
+ if (`${rec.data[key]}` !== `${validValue}`) {
+ errors.push(Ext.String.format(errText, key, rec.data[key] ?? '', validValue));
+ valid = 0;
+ }
+ }
+
+ rec.set('valid', valid);
+ rec.set('errmsg', errors.join('<br>'));
+ rec.commit();
+ });
+ },
+
+ store: {
+ sorters: 'text',
+ model: 'pve-resource-pci-tree',
+ data: {},
+ },
+
+ columns: [
+ {
+ xtype: 'treecolumn',
+ text: gettext('ID/Node/Path'),
+ dataIndex: 'text',
+ width: 200,
+ },
+ {
+ text: gettext('Vendor/Device'),
+ dataIndex: 'id',
+ },
+ {
+ text: gettext('Subsystem Vendor/Device'),
+ dataIndex: 'subsystem-id',
+ },
+ {
+ text: gettext('IOMMU group'),
+ dataIndex: 'iommugroup',
+ },
+ {
+ header: gettext('Status'),
+ dataIndex: 'valid',
+ flex: 1,
+ renderer: 'renderStatus',
+ },
+ {
+ header: gettext('Comment'),
+ dataIndex: 'description',
+ renderer: function(value, _meta, record) {
+ return value ?? record.data.comment;
+ },
+ flex: 1,
+ },
+ ],
+});
diff --git a/www/manager6/dc/USBMapView.js b/www/manager6/dc/USBMapView.js
new file mode 100644
index 00000000..953e2425
--- /dev/null
+++ b/www/manager6/dc/USBMapView.js
@@ -0,0 +1,98 @@
+Ext.define('pve-resource-usb-tree', {
+ extend: 'Ext.data.Model',
+ idProperty: 'internalId',
+ fields: ['type', 'text', 'path', 'id', 'description', 'digest'],
+});
+
+Ext.define('PVE.dc.USBMapView', {
+ extend: 'PVE.tree.ResourceMapTree',
+ alias: 'widget.pveDcUSBMapView',
+
+ editWindowClass: 'PVE.window.USBMapEditWindow',
+ baseUrl: '/cluster/mapping/usb',
+ mapIconCls: 'fa fa-usb',
+ getStatusCheckUrl: (node) => `/nodes/${node}/hardware/usb`,
+ entryIdProperty: 'id',
+
+ checkValidity: function(data, node) {
+ let me = this;
+ let ids = {};
+ let paths = {};
+ data.forEach((entry) => {
+ ids[`${entry.vendid}:${entry.prodid}`] = entry;
+ paths[`${entry.busnum}-${entry.usbpath}`] = entry;
+ });
+ me.getRootNode()?.cascade(function(rec) {
+ if (rec.data.node !== node || rec.data.type !== 'map') {
+ return;
+ }
+
+ let device;
+ if (rec.data.path) {
+ device = paths[rec.data.path];
+ }
+ device ??= ids[rec.data.id];
+
+ if (!device) {
+ rec.set('valid', 0);
+ rec.set('errmsg', Ext.String.format(gettext("Cannot find USB device {0}"), rec.data.id));
+ rec.commit();
+ return;
+ }
+
+
+ let deviceId = `${device.vendid}:${device.prodid}`.replace(/0x/g, '');
+
+ let toCheck = {
+ id: deviceId,
+ };
+
+ let valid = 1;
+ let errors = [];
+ let errText = gettext("Configuration for {0} not correct ('{1}' != '{2}')");
+ for (const [key, validValue] of Object.entries(toCheck)) {
+ if (rec.data[key] !== validValue) {
+ errors.push(Ext.String.format(errText, key, rec.data[key] ?? '', validValue));
+ valid = 0;
+ }
+ }
+
+ rec.set('valid', valid);
+ rec.set('errmsg', errors.join('<br>'));
+ rec.commit();
+ });
+ },
+
+ store: {
+ sorters: 'text',
+ model: 'pve-resource-usb-tree',
+ data: {},
+ },
+
+ columns: [
+ {
+ xtype: 'treecolumn',
+ text: gettext('ID/Node/Vendor&Device'),
+ dataIndex: 'text',
+ width: 200,
+ },
+ {
+ text: gettext('Path'),
+ dataIndex: 'path',
+ },
+ {
+ header: gettext('Status'),
+ dataIndex: 'valid',
+ flex: 1,
+ renderer: 'renderStatus',
+ },
+ {
+ header: gettext('Comment'),
+ dataIndex: 'description',
+ renderer: function(value, _meta, record) {
+ return value ?? record.data.comment;
+ },
+ flex: 1,
+ },
+ ],
+});
--
2.30.2
next prev parent reply other threads:[~2023-06-14 8:47 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-14 8:46 [pve-devel] [PATCH qemu-server/manger/docs v6] cluster mapping Dominik Csapak
2023-06-14 8:46 ` [pve-devel] [PATCH qemu-server v6 1/6] enable cluster mapped USB devices for guests Dominik Csapak
2023-06-16 7:50 ` Fabian Grünbichler
2023-06-14 8:46 ` [pve-devel] [PATCH qemu-server v6 2/6] enable cluster mapped PCI " Dominik Csapak
2023-06-16 7:49 ` Fabian Grünbichler
2023-06-14 8:46 ` [pve-devel] [PATCH qemu-server v6 3/6] check_local_resources: extend for mapped resources Dominik Csapak
2023-06-14 8:46 ` [pve-devel] [PATCH qemu-server v6 4/6] api: migrate preconditions: use new check_local_resources info Dominik Csapak
2023-06-14 8:46 ` [pve-devel] [PATCH qemu-server v6 5/6] migration: check for mapped resources Dominik Csapak
2023-06-14 8:46 ` [pve-devel] [PATCH qemu-server v6 6/6] add test for mapped pci devices Dominik Csapak
2023-06-14 8:46 ` [pve-devel] [PATCH manager v6 01/15] pvesh: fix parameters for proxyto_callback Dominik Csapak
2023-06-16 9:27 ` [pve-devel] applied: " Wolfgang Bumiller
2023-06-14 8:46 ` [pve-devel] [PATCH manager v6 02/15] api: add resource map api endpoints for PCI and USB Dominik Csapak
2023-06-16 7:50 ` Fabian Grünbichler
2023-06-14 8:46 ` [pve-devel] [PATCH manager v6 03/15] ui: parser: add helper for lists of property strings Dominik Csapak
2023-06-14 8:46 ` [pve-devel] [PATCH manager v6 04/15] ui: form/USBSelector: make it more flexible with nodename Dominik Csapak
2023-06-14 8:46 ` [pve-devel] [PATCH manager v6 05/15] ui: form: add PCIMapSelector Dominik Csapak
2023-06-14 8:46 ` [pve-devel] [PATCH manager v6 06/15] ui: form: add USBMapSelector Dominik Csapak
2023-06-14 8:46 ` [pve-devel] [PATCH manager v6 07/15] ui: qemu/PCIEdit: rework panel to add a mapped configuration Dominik Csapak
2023-06-14 8:46 ` [pve-devel] [PATCH manager v6 08/15] ui: qemu/USBEdit: add 'mapped' device case Dominik Csapak
2023-06-14 8:46 ` [pve-devel] [PATCH manager v6 09/15] ui: form: add MultiPCISelector Dominik Csapak
2023-06-14 8:46 ` [pve-devel] [PATCH manager v6 10/15] ui: add edit window for pci mappings Dominik Csapak
2023-06-14 8:46 ` [pve-devel] [PATCH manager v6 11/15] ui: add edit window for usb mappings Dominik Csapak
2023-06-14 8:46 ` [pve-devel] [PATCH manager v6 12/15] ui: add ResourceMapTree Dominik Csapak
2023-06-14 8:46 ` Dominik Csapak [this message]
2023-06-14 8:46 ` [pve-devel] [PATCH manager v6 14/15] ui: window/Migrate: allow mapped devices Dominik Csapak
2023-06-14 8:46 ` [pve-devel] [PATCH manager v6 15/15] ui: improve permission handling for hardware Dominik Csapak
2023-06-14 8:46 ` [pve-devel] [PATCH docs v6 1/1] qemu: add documentation about cluster device mapping Dominik Csapak
2023-06-14 12:01 ` [pve-devel] [PATCH qemu-server/manger/docs v6] cluster mapping Markus Frank
2023-06-16 7:51 ` Fabian Grünbichler
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=20230614084622.1446211-20-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