From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [45.144.208.40]) by lore.proxmox.com (Postfix) with ESMTPS id CE7151FF09C for ; Mon, 21 Sep 2026 09:55:11 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 83ACE215BB; Mon, 21 Sep 2026 09:54:53 +0200 (CEST) X-ICL-RepId: 01a0b568-a63d-78b8-a224-de2ad7dcb0be X-ICL-Out-Info: HUtFAUMHWwJACUgATUQeDx5WFlZNRAJCTQBKHV8HUhxCC0kdXAdcEhVdRV8YVApyBlYKXQVSD1cCFxtfAkIPEhZdRUUCRQVaFV0dQUNUB10FXVhBDgpZEhhcFFxQWB5GElYNXQkZGkFeUBtfAkIPHBNWFRMdQxkPKwhKBEMHRQJeCyUTCVNWRB9LFlsIUw5AXloUXBhTS18ZXUUPXwdZBEAASQtcAV8HQABWB1sDXQpdClVfGFQKcgZWCl0FUg9XAhcbXwJCDwxQTQFDCAoIRwNNF14yUwRfEVAW Dkim-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vornheder.cloud; s=sig1; t=1789749930; x=1792341930; bh=vWB0BEzdZ+5QFq/IibD2DNq/AcvOSpD/isX8xqcujDY=; h=From:To:Subject:Date:Message-ID:MIME-Version:x-icloud-hme; b=h9O3lCcszLIyDMtDhXVCp0CoOtXQx9vKMke0BrGSaua3mTIxTyKGwVlNewLK1s9rflGBiyQnqpEOCBeiUHW9jhGLXa4s4Btbct1b6QDvgVUWEHj9XtO8FC+i2I0G0dF2+gm3FNBpkhTHY1HAhP09WCzF5qdGe2ac83GScPlPO8J+a6eC8LLZPUGe3qe7gOOVn2ZGp3ujn5Fq5M+9Hc04jvSLan2HjxPMrh1iyBg+Kf3CJMUR4te1YKmr75EScPmqgCZurXt2M80L31nDw1aSoCljuYZmmNqCNIg/6pEPk7Ob8l0aJ2BMxgGGCmg8DeJJrA3NPlDwkY9u0xNoxwPsTw== mail-alias-created-date: 1637499663896 From: Luca Vornheder To: pve-devel@lists.proxmox.com Subject: [PATCH manager 2/3] fix #7656: ui: node: add opt-in IPMI SEL log tab Date: Fri, 18 Sep 2026 18:45:08 +0200 Message-ID: <20260918164509.46468-3-luca@vornheder.cloud> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260918164509.46468-1-luca@vornheder.cloud> References: <20260918164509.46468-1-luca@vornheder.cloud> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Authority-Info-Out: v=2.4 cv=FY46BZ+6 c=1 sm=1 tr=0 ts=6aad6aa9 cx=c_apl:c_pps:t_out a=bsP7O+dXZ5uKcj+dsLqiMw==:117 a=bsP7O+dXZ5uKcj+dsLqiMw==:17 a=MKtGQD3n3ToA:10 a=1oJP67jkp3AA:10 a=VdqzKS8jKosA:10 a=VkNPw1HP01LnGYTKEx00:22 a=-0eDO12thCSCGjff-G4A:9 a=O8hF6Hzn-FEA:10 X-Proofpoint-ORIG-GUID: VRIvT9XVb2ZA3wWzeakz7nVpF1YaduFv X-Proofpoint-GUID: VRIvT9XVb2ZA3wWzeakz7nVpF1YaduFv X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTE4MDI0MCBTYWx0ZWRfX+epQ+0zpqnau CZupY+DdlFYbdpGs5NmTZgZSeMZ9iwHqDlCiTHON8ibVUQI/zqiSPGjjagnNKS9Jwa65qL0yHGA t1uAnVWCwxN7FdexDj/z4/3+qb+28bjwxOTNmOTCToF1uo3np++n63fvBiK8lNerSQxc/BdReS/ cNxngLR075EE4+w0mvSVZckkXB9cu4RP+XUCBFQhvhiktsjyKxOKIWilTM+/AVMmd7uz58xWzzt wjtUs0Ri5ipjt1UEt4lDTkqvON0ztrInOWnMODEwcSOtas8gpV/lvhvnnsrwCvKYxDjRY6FgSL8 wc5cmEZHSg3WQpsMBU8idyse7Llax+hdU2e6Og9SE0BCFGCab/JbRTgoTQYA4g= X-JNJ: AAAAAAAB4gYN3Aj3WepuivzKmDnKuaiT3mEFPcSRL1ELhZ2JlVUwsMstqIfi/J+BPIrZ/8BFMVwFql6aACrw/obfPw0N0SuFQJ8XS7J6FBNYoFNrqrPSEkBn4vAT8euOlKTRyzln7x0E0LajuXnKeCe0L6d/eTp2LdnQwLOeddACL8RJXhJNtzGNBEx4b1oxfhi9x1O6RIsaXzLTUKAy5zOTvnFtzxNy+Bw/N9KLSqgEdHcyf2LaaUy611qbQvViZ/2X+boIp8+slTPMcYhXpAL7S+ElPWiSfeR3dEQ0LR9CRLqdeJsTtv0J4G5MEwgz81Ik3CjQwBUvhYc0zhlTx5B3FoXK0KR5j8f520jvn7zUR+uiH7NnUxEZ+roqyAliDKjr5jI9FqajFHPND28JBv/igq8YNjGP3Ta/QyiJyaCfV/GxxIQBZAH5uIB5o0bzZWmt6tU/f0g3hOsEmYEaCFXAt+dmQ5dGtrxHb3ZzuhmLMgFH8Yybc48w/UOvndMeA6oDuw9vS+d7L8OB8+SW+aB9s1kTmEscmgihrpHZl7QUtbKl0yiIFLr9Mz8sxfdyyVE1AUKpmHnUxdXflQfdYVuaUOrg/tBHnMiS7fWGEu9QHiVP27qwLp/FHC5meDqBpppcEbVivQJUGER2zP9ai6AMJgwex62Hg+PvSOK8WZYw1zPGzzMHWTorlq6bKrVq/VXcvfLnxFq0LS63bqHD+kI5DrUqoeLtKBdtgZjm//ZEvW08xRU4E1Bs1GGvb657QKg= X-SPAM-LEVEL: Spam detection results: 0 AWL 0.075 Adjusted score from AWL reputation of From: address DKIM_INVALID 0.1 DKIM or DK signature exists, but is not valid DKIM_SIGNED 0.1 Message has a DKIM or DK signature, not necessarily valid DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) SPF_HELO_PASS -0.001 SPF: HELO matches SPF record SPF_PASS -0.001 SPF: sender matches SPF record X-MailFrom: luca@vornheder.cloud X-Mailman-Rule-Hits: nonmember-moderation X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation Message-ID-Hash: KC7QMF25GNEOFCBNUERTMAWY3D4SD77Q X-Message-ID-Hash: KC7QMF25GNEOFCBNUERTMAWY3D4SD77Q X-Mailman-Approved-At: Mon, 21 Sep 2026 09:54:43 +0200 CC: Luca Vornheder X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Add an 'IPMI' tab next to the system log of a node, listing the entries of the node's IPMI System Event Log, with a reload and an export button. The tab is enabled per node through a new 'IPMI SEL Log' row in the node options. Its edit window notes that this is a technology preview and that 'ipmitool' needs to be installed. While the feature is disabled, the tab shows a hint instead of an error. Signed-off-by: Luca Vornheder --- www/manager6/Makefile | 1 + www/manager6/node/Config.js | 9 ++ www/manager6/node/IPMI.js | 134 +++++++++++++++++++++++++++ www/manager6/node/NodeOptionsView.js | 31 +++++++ 4 files changed, 175 insertions(+) create mode 100644 www/manager6/node/IPMI.js diff --git a/www/manager6/Makefile b/www/manager6/Makefile index d2ea786..d83fa20 100644 --- a/www/manager6/Makefile +++ b/www/manager6/Makefile @@ -244,6 +244,7 @@ JSSRC= \ node/CmdMenu.js \ node/Config.js \ node/Directory.js \ + node/IPMI.js \ node/LVM.js \ node/LVMThin.js \ node/StatusView.js \ diff --git a/www/manager6/node/Config.js b/www/manager6/node/Config.js index 217ee28..ee8277e 100644 --- a/www/manager6/node/Config.js +++ b/www/manager6/node/Config.js @@ -257,6 +257,15 @@ Ext.define('PVE.node.Config', { url: '/api2/extjs/nodes/' + nodename + '/journal', }); + me.items.push({ + xtype: 'pveNodeIPMIView', + title: gettext('IPMI'), + iconCls: 'fa fa-server', + groups: ['services'], + itemId: 'ipmi-sel', + nodename: nodename, + }); + if (caps.nodes['Sys.Modify']) { me.items.push({ xtype: 'proxmoxNodeAPT', diff --git a/www/manager6/node/IPMI.js b/www/manager6/node/IPMI.js new file mode 100644 index 0000000..48228ae --- /dev/null +++ b/www/manager6/node/IPMI.js @@ -0,0 +1,134 @@ +Ext.define('PVE.node.IPMIView', { + extend: 'Ext.grid.Panel', + alias: 'widget.pveNodeIPMIView', + + onlineHelp: 'proxmox_node_management', + + stateful: true, + stateId: 'grid-node-ipmi-sel', + + // we drive all loading/error/disabled feedback ourselves via emptyText and + // setErrorMask below, so the grid's own spinner must stay out of the way + loadMask: false, + + viewConfig: { + loadMask: false, + emptyText: gettext('No entries found'), + deferEmptyText: false, + }, + + columns: [ + { + header: gettext('ID'), + dataIndex: 'id', + width: 60, + }, + { + header: gettext('Timestamp'), + dataIndex: 'timestamp', + width: 160, + }, + { + header: gettext('Sensor'), + dataIndex: 'sensor', + width: 200, + }, + { + header: gettext('Event'), + dataIndex: 'description', + flex: 1, + }, + { + header: gettext('Direction'), + dataIndex: 'direction', + width: 100, + }, + ], + + tbar: [ + { + text: gettext('Reload'), + iconCls: 'fa fa-refresh', + handler: function () { + this.up('grid').reload(); + }, + }, + { + itemId: 'exportBtn', + text: gettext('Export'), + iconCls: 'fa fa-download', + disabled: true, + handler: function () { + let me = this.up('grid'); + Proxmox.Utils.downloadAsFile( + `/api2/json/nodes/${me.nodename}/ipmi-sel?download=1`, + ); + }, + }, + ], + + reload: function () { + let me = this; + me.getStore().load(); + }, + + listeners: { + activate: function () { + this.reload(); + }, + }, + + initComponent: function () { + let me = this; + + me.nodename = me.pveSelNode.data.node; + if (!me.nodename) { + throw 'no node name specified'; + } + + Ext.apply(me, { + store: { + fields: ['id', 'timestamp', 'sensor', 'description', 'direction'], + proxy: { + type: 'proxmox', + url: `/api2/json/nodes/${me.nodename}/ipmi-sel`, + }, + }, + }); + + me.callParent(); + + let store = me.getStore(); + let view = me.getView(); + let exportBtn = me.down('#exportBtn'); + + me.mon(store, 'beforeload', () => Proxmox.Utils.setErrorMask(me, false)); + + // only works with the 'proxmox' proxy + me.mon(store.proxy, 'afterload', (proxy, request, success) => { + if (success) { + Proxmox.Utils.setErrorMask(me, false); + exportBtn.setDisabled(false); + return; + } + + exportBtn.setDisabled(true); + + let error = request._operation.getError(); + + if (error && error.status === 501) { + // feature disabled for this node -- not an error, just say so + view.emptyText = Ext.htmlEncode( + gettext( + "IPMI SEL log is not enabled for this node. Enable it in the" + + " node's 'Options' tab first.", + ), + ); + view.refresh(); + return; + } + + Proxmox.Utils.setErrorMask(me, Proxmox.Utils.getResponseErrorMessage(error)); + }); + }, +}); diff --git a/www/manager6/node/NodeOptionsView.js b/www/manager6/node/NodeOptionsView.js index 5e9ce79..98fdb70 100644 --- a/www/manager6/node/NodeOptionsView.js +++ b/www/manager6/node/NodeOptionsView.js @@ -55,6 +55,37 @@ Ext.define('Proxmox.node.NodeOptionsView', { xtype: 'pmxLocationEditWindow', }, }, + 'ipmi-sel': { + required: true, + defaultValue: 0, + header: gettext('IPMI SEL Log'), + renderer: Proxmox.Utils.format_boolean, + editor: { + xtype: 'proxmoxWindowEdit', + subject: gettext('IPMI SEL Log'), + fieldDefaults: { + labelWidth: 130, + }, + items: [ + { + xtype: 'displayfield', + userCls: 'pmx-hint', + value: gettext( + "Technology preview. Requires 'ipmitool' to be installed on" + + ' this node.', + ), + }, + { + xtype: 'proxmoxcheckbox', + name: 'ipmi-sel', + uncheckedValue: 0, + defaultValue: 0, + checked: false, + fieldLabel: gettext('IPMI SEL Log'), + }, + ], + }, + }, }, gridRows: [ -- 2.50.1 (Apple Git-155)