From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: <pve-devel-bounces@lists.proxmox.com> Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id 2B47F1FF173 for <inbox@lore.proxmox.com>; Mon, 10 Feb 2025 16:38:30 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 9F535118C0; Mon, 10 Feb 2025 16:38:00 +0100 (CET) From: Filip Schauer <f.schauer@proxmox.com> To: pve-devel@lists.proxmox.com Date: Mon, 10 Feb 2025 16:37:29 +0100 Message-Id: <20250210153734.103381-7-f.schauer@proxmox.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250210153734.103381-1-f.schauer@proxmox.com> References: <20250210153734.103381-1-f.schauer@proxmox.com> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL -0.022 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pve-devel] [PATCH manager v3 06/11] ui: allow use of mapped hardware RNGs as entropy sources for VMs X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion <pve-devel.lists.proxmox.com> List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pve-devel>, <mailto:pve-devel-request@lists.proxmox.com?subject=unsubscribe> List-Archive: <http://lists.proxmox.com/pipermail/pve-devel/> List-Post: <mailto:pve-devel@lists.proxmox.com> List-Help: <mailto:pve-devel-request@lists.proxmox.com?subject=help> List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel>, <mailto:pve-devel-request@lists.proxmox.com?subject=subscribe> Reply-To: Proxmox VE development discussion <pve-devel@lists.proxmox.com> Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pve-devel-bounces@lists.proxmox.com Sender: "pve-devel" <pve-devel-bounces@lists.proxmox.com> Signed-off-by: Filip Schauer <f.schauer@proxmox.com> --- www/manager6/Makefile | 1 + www/manager6/form/HWRNGMapSelector.js | 99 +++++++++++++++++++++++++++ www/manager6/qemu/HardwareView.js | 9 ++- www/manager6/qemu/RNGEdit.js | 79 ++++++++++++++------- 4 files changed, 159 insertions(+), 29 deletions(-) create mode 100644 www/manager6/form/HWRNGMapSelector.js diff --git a/www/manager6/Makefile b/www/manager6/Makefile index 01a95c7e..d148a1c9 100644 --- a/www/manager6/Makefile +++ b/www/manager6/Makefile @@ -44,6 +44,7 @@ JSSRC= \ form/GuestIDSelector.js \ form/HashAlgorithmSelector.js \ form/HotplugFeatureSelector.js \ + form/HWRNGMapSelector.js \ form/IPProtocolSelector.js \ form/IPRefSelector.js \ form/MDevSelector.js \ diff --git a/www/manager6/form/HWRNGMapSelector.js b/www/manager6/form/HWRNGMapSelector.js new file mode 100644 index 00000000..1c795d2d --- /dev/null +++ b/www/manager6/form/HWRNGMapSelector.js @@ -0,0 +1,99 @@ +Ext.define('PVE.form.HWRNGMapSelector', { + extend: 'Proxmox.form.ComboGrid', + alias: 'widget.pveHWRNGMapSelector', + + store: { + fields: ['name', 'path'], + filterOnLoad: true, + sorters: [ + { + property: 'name', + direction: 'ASC', + }, + ], + }, + + allowBlank: false, + autoSelect: false, + displayField: 'id', + valueField: 'id', + + listConfig: { + width: 800, + columns: [ + { + header: gettext('Name'), + dataIndex: 'id', + flex: 1, + }, + { + header: gettext('Status'), + dataIndex: 'errors', + flex: 2, + renderer: function(value) { + let me = this; + + if (!Ext.isArray(value) || !value?.length) { + return `<i class="fa fa-check-circle good"></i> ${gettext('Mapping matches host data')}`; + } + + let errors = []; + + value.forEach((error) => { + let iconCls; + switch (error?.severity) { + case 'warning': + iconCls = 'fa-exclamation-circle warning'; + break; + case 'error': + iconCls = 'fa-times-circle critical'; + break; + } + + let message = error?.message; + let icon = `<i class="fa ${iconCls}"></i>`; + if (iconCls !== undefined) { + errors.push(`${icon} ${message}`); + } + }); + + return errors.join('<br>'); + }, + }, + { + header: gettext('Comment'), + dataIndex: 'description', + flex: 1, + renderer: Ext.String.htmlEncode, + }, + ], + }, + + setNodename: function(nodename) { + var me = this; + + if (!nodename || me.nodename === nodename) { + return; + } + + me.nodename = nodename; + + me.store.setProxy({ + type: 'proxmox', + url: `/api2/json/cluster/mapping/hwrng?check-node=${nodename}`, + }); + + me.store.load(); + }, + + initComponent: function() { + var me = this; + + var nodename = me.nodename; + me.nodename = undefined; + + me.callParent(); + + me.setNodename(nodename); + }, +}); diff --git a/www/manager6/qemu/HardwareView.js b/www/manager6/qemu/HardwareView.js index c6d193fc..8085e288 100644 --- a/www/manager6/qemu/HardwareView.js +++ b/www/manager6/qemu/HardwareView.js @@ -315,8 +315,8 @@ Ext.define('PVE.qemu.HardwareView', { rows.rng0 = { group: 45, tdCls: 'pve-itype-icon-die', - editor: caps.nodes['Sys.Console'] ? 'PVE.qemu.RNGEdit' : undefined, - never_delete: !caps.nodes['Sys.Console'], + editor: caps.vms['VM.Config.HWType'] || caps.mapping['Mapping.Use'] ? 'PVE.qemu.RNGEdit' : undefined, + never_delete: !caps.vms['VM.Config.HWType'] && !caps.mapping['Mapping.Use'], header: gettext("VirtIO RNG"), }; @@ -588,7 +588,6 @@ Ext.define('PVE.qemu.HardwareView', { }); // heuristic only for disabling some stuff, the backend has the final word. - const noSysConsolePerm = !caps.nodes['Sys.Console']; const noHWPerm = !caps.nodes['Sys.Console'] && !caps.mapping['Mapping.Use']; const noVMConfigHWTypePerm = !caps.vms['VM.Config.HWType']; const noVMConfigNetPerm = !caps.vms['VM.Config.Network']; @@ -601,7 +600,7 @@ Ext.define('PVE.qemu.HardwareView', { me.down('#addAudio').setDisabled(noVMConfigHWTypePerm || isAtLimit('audio')); me.down('#addSerial').setDisabled(noVMConfigHWTypePerm || isAtLimit('serial')); me.down('#addNet').setDisabled(noVMConfigNetPerm || isAtLimit('net')); - me.down('#addRng').setDisabled(noSysConsolePerm || isAtLimit('rng')); + me.down('#addRng').setDisabled(noVMConfigHWTypePerm || isAtLimit('rng')); efidisk_menuitem.setDisabled(noVMConfigDiskPerm || isAtLimit('efidisk')); me.down('#addTpmState').setDisabled(noVMConfigDiskPerm || isAtLimit('tpmstate')); me.down('#addCloudinitDrive').setDisabled(noVMConfigCDROMPerm || noVMConfigCloudinitPerm || hasCloudInit); @@ -745,7 +744,7 @@ Ext.define('PVE.qemu.HardwareView', { text: gettext("VirtIO RNG"), itemId: 'addRng', iconCls: 'pve-itype-icon-die', - disabled: !caps.nodes['Sys.Console'], + disabled: !caps.vms['VM.Config.HWType'] && !caps.mapping['Mapping.Use'], handler: editorFactory('RNGEdit'), }, ], diff --git a/www/manager6/qemu/RNGEdit.js b/www/manager6/qemu/RNGEdit.js index e34e2c08..fab8c1b0 100644 --- a/www/manager6/qemu/RNGEdit.js +++ b/www/manager6/qemu/RNGEdit.js @@ -1,9 +1,19 @@ Ext.define('PVE.qemu.RNGInputPanel', { extend: 'Proxmox.panel.InputPanel', xtype: 'pveRNGInputPanel', + mixins: ['Proxmox.Mixin.CBind'], onlineHelp: 'qm_virtio_rng', + cbindData: function(initialConfig) { + let me = this; + if (!me.pveSelNode) { + throw "no pveSelNode given"; + } + + return { nodename: me.pveSelNode.data.node }; + }, + onGetValues: function(values) { if (values.max_bytes === "") { values.max_bytes = "0"; @@ -23,6 +33,10 @@ Ext.define('PVE.qemu.RNGInputPanel', { values.max_bytes = null; } + if (values.mapping) { + values.source = 'mapped'; + } + this.callParent(arguments); }, @@ -35,27 +49,49 @@ Ext.define('PVE.qemu.RNGInputPanel', { limitWarning.setHidden(!!newVal); }, }, - '#source': { - change: function(el, newVal) { - let limitWarning = this.lookupReference('sourceWarning'); - limitWarning.setHidden(newVal !== '/dev/random'); - }, - }, }, }, items: [{ - itemId: 'source', - name: 'source', - xtype: 'proxmoxKVComboBox', - value: '/dev/urandom', - fieldLabel: gettext('Entropy source'), - labelWidth: 130, - comboItems: [ - ['/dev/urandom', '/dev/urandom'], - ['/dev/random', '/dev/random'], - ['/dev/hwrng', '/dev/hwrng'], - ], + xtype: 'fieldcontainer', + defaultType: 'radiofield', + layout: 'fit', + items: [{ + name: 'source', + inputValue: '/dev/urandom', + boxLabel: '/dev/urandom', + checked: true, + }, + { + name: 'source', + inputValue: '/dev/random', + boxLabel: '/dev/random', + }, + { + name: 'source', + inputValue: 'mapped', + boxLabel: gettext('Use mapped Hardware RNG device'), + reference: 'mapped', + submitValue: false, + listeners: { + change: function(f, value) { + let me = this; + if (!me.rendered) { + return; + } + me.up().down('field[name=mapping]').setDisabled(!value); + }, + }, + }, + { + xtype: 'pveHWRNGMapSelector', + name: 'mapping', + cbind: { nodename: '{nodename}' }, + allowBlank: false, + fieldLabel: gettext('Choose Device'), + labelAlign: 'right', + disabled: true, + }], }, { xtype: 'numberfield', @@ -77,13 +113,6 @@ Ext.define('PVE.qemu.RNGInputPanel', { labelWidth: 130, emptyText: '1000', }, - { - xtype: 'displayfield', - reference: 'sourceWarning', - value: gettext('Using /dev/random as entropy source is discouraged, as it can lead to host entropy starvation. /dev/urandom is preferred, and does not lead to a decrease in security in practice.'), - userCls: 'pmx-hint', - hidden: true, - }, { xtype: 'displayfield', reference: 'limitWarning', @@ -95,11 +124,13 @@ Ext.define('PVE.qemu.RNGInputPanel', { Ext.define('PVE.qemu.RNGEdit', { extend: 'Proxmox.window.Edit', + mixins: ['Proxmox.Mixin.CBind'], subject: gettext('VirtIO RNG'), items: [{ xtype: 'pveRNGInputPanel', + cbind: { pveSelNode: '{pveSelNode}' }, }], initComponent: function() { -- 2.39.5 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel