From: Jakob Klocker <j.klocker@proxmox.com>
To: pve-devel@lists.proxmox.com
Cc: Jakob Klocker <j.klocker@proxmox.com>
Subject: [PATCH pve-manager 9/9] www: storage: display custom summary for failed plugins
Date: Fri, 31 Jul 2026 17:36:17 +0200 [thread overview]
Message-ID: <20260731153617.358265-10-j.klocker@proxmox.com> (raw)
In-Reply-To: <20260731153617.358265-1-j.klocker@proxmox.com>
Currently there is only a generic summary for storages, which doesn't
mention that a plugin failed to load.
Add a dedicated summary view for storages whose plugin failed to load.
Signed-off-by: Jakob Klocker <j.klocker@proxmox.com>
---
www/manager6/Makefile | 1 +
www/manager6/storage/Browser.js | 33 ++++++---
www/manager6/storage/PluginError.js | 111 ++++++++++++++++++++++++++++
3 files changed, 136 insertions(+), 9 deletions(-)
create mode 100644 www/manager6/storage/PluginError.js
diff --git a/www/manager6/Makefile b/www/manager6/Makefile
index eb0e9d9c..7eb187e9 100644
--- a/www/manager6/Makefile
+++ b/www/manager6/Makefile
@@ -370,6 +370,7 @@ JSSRC= \
storage/BTRFSEdit.js \
storage/NFSEdit.js \
storage/PBSEdit.js \
+ storage/PluginError.js \
storage/RBDEdit.js \
storage/StatusView.js \
storage/Summary.js \
diff --git a/www/manager6/storage/Browser.js b/www/manager6/storage/Browser.js
index d0237948..2e3cfb42 100644
--- a/www/manager6/storage/Browser.js
+++ b/www/manager6/storage/Browser.js
@@ -29,6 +29,30 @@ Ext.define('PVE.storage.Browser', {
let plugin = res.plugintype;
let isEsxi = plugin === 'esxi';
+ let pluginFailed = res.pluginstate === 'load-error';
+
+ Ext.apply(me, {
+ title: Ext.String.format(
+ gettext('Storage {0} on node {1}'),
+ `'${storeid}'`,
+ `'${nodename}'`,
+ ),
+ hstateid: 'storagetab',
+ });
+
+ if (pluginFailed) {
+ me.items = [
+ {
+ xtype: 'pveStoragePluginError',
+ title: gettext('Summary'),
+ iconCls: 'fa fa-book',
+ itemId: 'summary',
+ },
+ ];
+
+ me.callParent();
+ return;
+ }
me.items = !isEsxi
? [
@@ -43,15 +67,6 @@ Ext.define('PVE.storage.Browser', {
let caps = Ext.state.Manager.get('GuiCap');
- Ext.apply(me, {
- title: Ext.String.format(
- gettext('Storage {0} on node {1}'),
- `'${storeid}'`,
- `'${nodename}'`,
- ),
- hstateid: 'storagetab',
- });
-
if (
caps.storage['Datastore.Allocate'] ||
caps.storage['Datastore.AllocateSpace'] ||
diff --git a/www/manager6/storage/PluginError.js b/www/manager6/storage/PluginError.js
new file mode 100644
index 00000000..a797631a
--- /dev/null
+++ b/www/manager6/storage/PluginError.js
@@ -0,0 +1,111 @@
+Ext.define('PVE.storage.PluginError', {
+ extend: 'Ext.panel.Panel',
+ alias: 'widget.pveStoragePluginError',
+
+ scrollable: true,
+ bodyPadding: 5,
+ layout: { type: 'column' },
+ defaults: { padding: 5, columnWidth: 1 },
+
+ initComponent: function () {
+ let me = this;
+
+ let nodename = me.pveSelNode.data.node;
+ if (!nodename) {
+ throw 'no node name specified';
+ }
+ let storage = me.pveSelNode.data.storage;
+ if (!storage) {
+ throw 'no storage ID specified';
+ }
+
+ let res = me.pveSelNode.data;
+ let type = res.plugintype || gettext('unknown');
+ let content = res.content || '-';
+
+ let rows = [
+ {
+ xtype: 'pmxInfoWidget',
+ itemId: 'enabled',
+ title: gettext('Enabled'),
+ printBar: false,
+ },
+ { xtype: 'pmxInfoWidget', itemId: 'active', title: gettext('Active'), printBar: false },
+ {
+ xtype: 'pmxInfoWidget',
+ itemId: 'content',
+ title: gettext('Content'),
+ printBar: false,
+ },
+ { xtype: 'pmxInfoWidget', itemId: 'type', title: gettext('Type'), printBar: false },
+ {
+ xtype: 'pmxInfoWidget',
+ itemId: 'external',
+ title: gettext('External'),
+ printBar: false,
+ },
+ {
+ xtype: 'pmxInfoWidget',
+ itemId: 'plugstatus',
+ title: gettext('Plugin Status'),
+ printBar: false,
+ },
+ {
+ xtype: 'pmxInfoWidget',
+ itemId: 'plugin-url',
+ title: gettext('Plugin URL'),
+ printBar: false,
+ hidden: true,
+ },
+ ];
+
+ let explanation = Ext.String.format(
+ gettext(
+ "The plugin for storage type '{0}' could not be loaded on node '{1}', " +
+ 'so live status and usage are unavailable. Install or update a compatible ' +
+ 'version of the plugin to restore access.',
+ ),
+ Ext.htmlEncode(type),
+ Ext.htmlEncode(nodename),
+ );
+
+ Ext.apply(me, {
+ items: [
+ {
+ xtype: 'panel',
+ title: gettext('Status'),
+ layout: { type: 'vbox', align: 'stretch' },
+ bodyPadding: 5,
+ defaults: { padding: '2 25' },
+ items: rows,
+ listeners: {
+ afterrender: function (panel) {
+ panel.down('#enabled').updateValue(gettext('No'));
+ panel.down('#active').updateValue(gettext('No'));
+ panel
+ .down('#content')
+ .updateValue(PVE.Utils.format_content_types(content));
+ panel.down('#type').updateValue(PVE.Utils.format_storage_type(type));
+ panel.down('#external').updateValue(gettext('Yes'));
+ panel.down('#plugstatus').updateValue(gettext('Error loading Plugin'));
+
+ let url = res['plugin-url'];
+ if (url) {
+ let row = panel.down('#plugin-url');
+ row.updateValue(PVE.Utils.render_plugin_url(url, res.plugintype));
+ row.setHidden(false);
+ }
+ },
+ },
+ },
+ {
+ xtype: 'box',
+ padding: 15,
+ html: explanation,
+ },
+ ],
+ });
+
+ me.callParent();
+ },
+});
--
2.47.3
prev parent reply other threads:[~2026-07-31 15:37 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-31 15:36 [PATCH manager/storage 0/9] storage: plugins: display failed and outdated storage plugins in the GUI Jakob Klocker
2026-07-31 15:36 ` [PATCH pve-storage 1/9] storage: drop unused variable in storage_info Jakob Klocker
2026-07-31 15:36 ` [PATCH pve-storage 2/9] storage: add `plugin-url` to built-in plugins Jakob Klocker
2026-07-31 15:36 ` [PATCH pve-storage 3/9] storage: add `unknown` flag to parse_config Jakob Klocker
2026-07-31 15:36 ` [PATCH pve-storage 4/9] storage: plugins: cache and classify custom storage plugins Jakob Klocker
2026-07-31 15:36 ` [PATCH pve-storage 5/9] storage: expose plugin metadata in storage status Jakob Klocker
2026-07-31 15:36 ` [PATCH pve-manager 6/9] cluster: backend: include storages with unloadable plugins Jakob Klocker
2026-07-31 15:36 ` [PATCH pve-manager 7/9] www: storage: show plugin state/external/url in StatusView Jakob Klocker
2026-07-31 15:36 ` [PATCH pve-manager 8/9] www: storage: distinguish failed/outdated storage plugins in resource tree Jakob Klocker
2026-07-31 15:36 ` Jakob Klocker [this message]
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=20260731153617.358265-10-j.klocker@proxmox.com \
--to=j.klocker@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