Signed-off-by: Filip Schauer <f.scha...@proxmox.com>
---
 www/manager6/Makefile               |   2 +
 www/manager6/data/PermPathStore.js  |   1 +
 www/manager6/dc/Config.js           |  10 ++
 www/manager6/dc/HWRNGMapView.js     |  76 ++++++++++++++
 www/manager6/window/HWRNGMapEdit.js | 149 ++++++++++++++++++++++++++++
 5 files changed, 238 insertions(+)
 create mode 100644 www/manager6/dc/HWRNGMapView.js
 create mode 100644 www/manager6/window/HWRNGMapEdit.js

diff --git a/www/manager6/Makefile b/www/manager6/Makefile
index c94a5cdf..01a95c7e 100644
--- a/www/manager6/Makefile
+++ b/www/manager6/Makefile
@@ -138,6 +138,7 @@ JSSRC=                                                      
\
        window/TreeSettingsEdit.js                      \
        window/PCIMapEdit.js                            \
        window/USBMapEdit.js                            \
+       window/HWRNGMapEdit.js                          \
        window/GuestImport.js                           \
        ha/Fencing.js                                   \
        ha/GroupEdit.js                                 \
@@ -188,6 +189,7 @@ JSSRC=                                                      
\
        dc/RealmSyncJob.js                              \
        dc/PCIMapView.js                                \
        dc/USBMapView.js                                \
+       dc/HWRNGMapView.js                              \
        lxc/CmdMenu.js                                  \
        lxc/Config.js                                   \
        lxc/CreateWizard.js                             \
diff --git a/www/manager6/data/PermPathStore.js 
b/www/manager6/data/PermPathStore.js
index 8785a1d7..8212b17d 100644
--- a/www/manager6/data/PermPathStore.js
+++ b/www/manager6/data/PermPathStore.js
@@ -10,6 +10,7 @@ Ext.define('PVE.data.PermPathStore', {
        { 'value': '/access/realm' },
        { 'value': '/mapping' },
        { 'value': '/mapping/notifications' },
+       { 'value': '/mapping/hwrng' },
        { 'value': '/mapping/pci' },
        { 'value': '/mapping/usb' },
        { 'value': '/nodes' },
diff --git a/www/manager6/dc/Config.js b/www/manager6/dc/Config.js
index 74728c83..3650f290 100644
--- a/www/manager6/dc/Config.js
+++ b/www/manager6/dc/Config.js
@@ -329,6 +329,16 @@ Ext.define('PVE.dc.Config', {
                            title: gettext('USB Devices'),
                            flex: 1,
                        },
+                       {
+                           xtype: 'splitter',
+                           collapsible: false,
+                           performCollapse: false,
+                       },
+                       {
+                           xtype: 'pveDcHWRNGMapView',
+                           title: gettext('Hardware RNG Devices'),
+                           flex: 1,
+                       },
                    ],
                },
            );
diff --git a/www/manager6/dc/HWRNGMapView.js b/www/manager6/dc/HWRNGMapView.js
new file mode 100644
index 00000000..27c0d2fc
--- /dev/null
+++ b/www/manager6/dc/HWRNGMapView.js
@@ -0,0 +1,76 @@
+Ext.define('pve-resource-hwrng-tree', {
+    extend: 'Ext.data.Model',
+    idProperty: 'internalId',
+    fields: ['type', 'text', 'path', 'description', 'digest'],
+});
+
+Ext.define('PVE.dc.HWRNGMapView', {
+    extend: 'PVE.tree.ResourceMapTree',
+    alias: 'widget.pveDcHWRNGMapView',
+
+    editWindowClass: 'PVE.window.HWRNGMapEditWindow',
+    baseUrl: '/cluster/mapping/hwrng',
+    mapIconCls: 'pve-itype-icon-die',
+    getStatusCheckUrl: (node) => `/nodes/${node}/hardware/hwrng`,
+    entryIdProperty: 'path',
+
+    checkValidity: function(data, node) {
+       let me = this;
+       let paths = {};
+       data.forEach((entry) => {
+           paths[entry.path] = 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];
+           }
+
+           if (!device) {
+               rec.set('valid', false);
+               rec.set(
+                   'errmsg',
+                   Ext.String.format(gettext("Cannot find Hardware RNG device 
{0}"), rec.data.id),
+               );
+               rec.commit();
+               return;
+           }
+
+           rec.set('valid', true);
+           rec.commit();
+       });
+    },
+
+    store: {
+       sorters: 'text',
+       model: 'pve-resource-hwrng-tree',
+       data: {},
+    },
+
+    columns: [
+       {
+           xtype: 'treecolumn',
+           text: gettext('ID/Node/Path'),
+           dataIndex: 'text',
+           width: 200,
+       },
+       {
+           header: gettext('Status'),
+           dataIndex: 'valid',
+           flex: 1,
+           renderer: 'renderStatus',
+       },
+       {
+           header: gettext('Comment'),
+           dataIndex: 'description',
+           renderer: function(value, _meta, record) {
+               return Ext.String.htmlEncode(value ?? record.data.comment);
+           },
+           flex: 1,
+       },
+    ],
+});
diff --git a/www/manager6/window/HWRNGMapEdit.js 
b/www/manager6/window/HWRNGMapEdit.js
new file mode 100644
index 00000000..aef4e2af
--- /dev/null
+++ b/www/manager6/window/HWRNGMapEdit.js
@@ -0,0 +1,149 @@
+Ext.define('PVE.window.HWRNGMapEditWindow', {
+    extend: 'Proxmox.window.Edit',
+    mixins: ['Proxmox.Mixin.CBind'],
+
+    width: 800,
+
+    subject: gettext('Hardware RNG mapping'),
+
+    onlineHelp: 'resource_mapping',
+
+    method: 'POST',
+
+    cbindData: function(initialConfig) {
+       let me = this;
+       me.isCreate = !me.name;
+       me.method = me.isCreate ? 'POST' : 'PUT';
+       me.hideMapping = !!me.entryOnly;
+       me.hideComment = me.name && !me.entryOnly;
+       me.hideNodeSelector = me.nodename || me.entryOnly;
+       me.hideNode = !me.nodename || !me.hideNodeSelector;
+       return {
+           name: me.name,
+           nodename: me.nodename,
+       };
+    },
+
+    submitUrl: function(_url, data) {
+       let me = this;
+       let name = me.isCreate ? '' : me.name;
+       return `/cluster/mapping/hwrng/${name}`;
+    },
+
+    controller: {
+       xclass: 'Ext.app.ViewController',
+
+       onGetValues: function(values) {
+           let me = this;
+           let view = me.getView();
+           values.node ??= view.nodename;
+
+           let name = values.name;
+           let description = values.description;
+           delete values.description;
+           delete values.name;
+           values.path = '/dev/hwrng';
+
+           let map = [];
+           if (me.originalMap) {
+               map = PVE.Parser.filterPropertyStringList(me.originalMap, (e) 
=> e.node !== values.node);
+           }
+           if (view.isCreate) {
+               map.push(PVE.Parser.printPropertyString(values));
+           }
+
+           values = { map };
+           if (description) {
+               values.description = description;
+           }
+
+           if (view.isCreate) {
+               values.id = name;
+           }
+
+           return values;
+       },
+
+       onSetValues: function(values) {
+           let me = this;
+           let view = me.getView();
+           me.originalMap = [...values.map];
+           let configuredNodes = [];
+           PVE.Parser.filterPropertyStringList(values.map, (e) => {
+               configuredNodes.push(e.node);
+               if (e.node === view.nodename) {
+                   values = e;
+               }
+               return false;
+           });
+
+           me.lookup('nodeselector').disallowedNodes = configuredNodes;
+
+           return values;
+       },
+    },
+
+    items: [
+       {
+           xtype: 'inputpanel',
+           onGetValues: function(values) {
+               return this.up('window').getController().onGetValues(values);
+           },
+
+           onSetValues: function(values) {
+               return this.up('window').getController().onSetValues(values);
+           },
+
+           column1: [
+               {
+                   xtype: 'pmxDisplayEditField',
+                   fieldLabel: gettext('Name'),
+                   cbind: {
+                       editable: '{!name}',
+                       value: '{name}',
+                       submitValue: '{isCreate}',
+                   },
+                   name: 'name',
+                   allowBlank: false,
+               },
+               {
+                   xtype: 'displayfield',
+                   fieldLabel: gettext('Mapping on Node'),
+                   labelWidth: 120,
+                   name: 'node',
+                   cbind: {
+                       value: '{nodename}',
+                       disabled: '{hideNode}',
+                       hidden: '{hideNode}',
+                   },
+                   allowBlank: false,
+               },
+               {
+                   xtype: 'pveNodeSelector',
+                   reference: 'nodeselector',
+                   fieldLabel: gettext('Mapping on Node'),
+                   labelWidth: 120,
+                   name: 'node',
+                   cbind: {
+                       disabled: '{hideNodeSelector}',
+                       hidden: '{hideNodeSelector}',
+                   },
+                   allowBlank: false,
+               },
+           ],
+
+           columnB: [
+               {
+                   xtype: 'proxmoxtextfield',
+                   fieldLabel: gettext('Comment'),
+                   submitValue: true,
+                   name: 'description',
+                   cbind: {
+                       disabled: '{hideComment}',
+                       hidden: '{hideComment}',
+                   },
+               },
+           ],
+       },
+    ],
+});
-- 
2.39.5



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

Reply via email to