public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Luca Vornheder <luca@vornheder.cloud>
To: pve-devel@lists.proxmox.com
Cc: Luca Vornheder <luca@vornheder.cloud>
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	[thread overview]
Message-ID: <20260918164509.46468-3-luca@vornheder.cloud> (raw)
In-Reply-To: <20260918164509.46468-1-luca@vornheder.cloud>

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 <luca@vornheder.cloud>
---
 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)




  parent reply	other threads:[~2026-09-21  7:55 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-18 16:45 [PATCH manager 0/3] add opt-in IPMI SEL log tab for nodes Luca Vornheder
2026-09-18 16:45 ` [PATCH manager 1/3] api: nodes: add opt-in endpoint to read the local IPMI SEL Luca Vornheder
2026-09-18 16:45 ` Luca Vornheder [this message]
2026-09-18 16:45 ` [PATCH manager 3/3] d/control: recommend ipmitool Luca Vornheder

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=20260918164509.46468-3-luca@vornheder.cloud \
    --to=luca@vornheder.cloud \
    --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
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal