* [RFC storage, manager] schema-driven web UI dialog for custom storage plugins
@ 2026-07-10 16:25 Ciro Iriarte
0 siblings, 0 replies; only message in thread
From: Ciro Iriarte @ 2026-07-10 16:25 UTC (permalink / raw)
To: pve-devel
Hello,
I'd like feedback on a supported way for a custom storage plugin to
contribute its create/edit dialog to the web UI, so third-party plugins
no longer have to inject JavaScript into pve-manager's index.html.tpl.
Decision I am asking about
--------------------------
Should pve-storage let a plugin declare a GUI form schema that
pve-manager renders into the storage add/edit dialog, instead of the
plugin shipping ExtJS and patching index.html.tpl? If yes, I propose the
minimal contract below.
Background
----------
A custom storage plugin (PVE::Storage::Custom) registers its config
properties server-side via properties()/options(), but there is no
supported way to contribute the create/edit dialog. The only working
method today is to ship an ExtJS panel and inject a <script> into
/usr/share/pve-manager/index.html.tpl (via a packaging trigger), which:
- edits a file owned by pve-manager, re-broken on every upgrade, and
- depends on private manager6 internals (PVE.panel.StorageBase,
PVE.Utils.storageSchema) with no API-stability guarantee.
This is the JS-injection concern raised in #3420. That bug's 2022 fix
added the `type-text` property (a friendly grid label); the form
generation was deferred. In #3420 Thomas Lamprecht suggested following
the ACME DNS-Challenge provider pattern, "where we return a schema ...
and even generate the GUI's form fields." This proposes that deferred
half.
Most of the needed information already lives server-side: the registered
SectionConfig property carries type/format/default, and options() marks
which keys are `fixed` (immutable after create). The dialog is largely
re-encoding data the plugin already declares.
Proposed contract (pve-storage)
-------------------------------
- Add an optional plugin-provided GUI schema (JSON-serializable), e.g.
via plugindata() or a new method, carrying presentation metadata only:
field labels, grouping (general/advanced), a widget hint, enum display
text, placeholder, and the onlineHelp anchor.
- Widget type, required-ness, min/max, default, and immutable-on-edit are
derived from the already-registered property and the options() `fixed`
set -- not duplicated in the schema.
- Bump the storage APIVER/APIAGE.
Consumer (pve-manager)
----------------------
- Add a generic schema-driven storage InputPanel (extending the existing
storage base panel) that builds the create/edit dialog from the schema.
- Deliver the schema through the existing plugin metadata the GUI already
reads for the storage type list, so no index.html.tpl patching and no
third-party JS.
Scope / compatibility
---------------------
- Opt-in and backward compatible: a plugin with no schema behaves exactly
as today (raw type token, no dialog).
- Secret fields never round-trip the stored value (blank = unchanged).
- Common widgets only (text, integer, boolean, enum, password,
content-type) cover the typical plugin. A supported JS drop-in plus a
public registerStoragePlugin() escape hatch, for plugins that need a
custom widget or validator, could be a follow-up rather than part of
this.
Out of scope
------------
- Custom ExtJS widgets/validators (the escape-hatch follow-up above).
- Reworking built-in storage dialogs; they can adopt the generic panel
later but need not change for this.
If the contract looks acceptable, I'll follow up with an [RFC PATCH]
series against pve-storage and then pve-manager. My CLA is on file.
Tracking: https://bugzilla.proxmox.com/show_bug.cgi?id=7808 (and the
earlier #3420).
Thanks,
Ciro
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-07-10 16:26 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-10 16:25 [RFC storage, manager] schema-driven web UI dialog for custom storage plugins Ciro Iriarte
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox