From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id 700961FF13C for ; Thu, 19 Mar 2026 11:46:34 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 6C5611A5FF; Thu, 19 Mar 2026 11:46:47 +0100 (CET) Mime-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=UTF-8 Date: Thu, 19 Mar 2026 11:46:08 +0100 Message-Id: From: "Max R. Carrara" Subject: Re: [pve-devel] [RFC pve-storage/proxmox-widget-toolkit/pve-manager master v2 00/10] GUI Support for Custom Storage Plugins To: "Andrei Perepiolkin" , X-Mailer: aerc 0.18.2-0-ge037c095a049 References: <20251121165858.818307-1-m.carrara@proxmox.com> <32e444a7-f273-4b3d-b91c-c76c1828d86d@open-e.com> In-Reply-To: <32e444a7-f273-4b3d-b91c-c76c1828d86d@open-e.com> X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1773917125985 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.086 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 Message-ID-Hash: M3CJ5R6BXDARS3IMDUUGYUOCQCCTOJHT X-Message-ID-Hash: M3CJ5R6BXDARS3IMDUUGYUOCQCCTOJHT X-MailFrom: m.carrara@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: On Tue Feb 10, 2026 at 9:57 PM CET, Andrei Perepiolkin wrote: > Hi Max, > > > I finally got myself to test code and Im stuck on making deb packages: > > For pve-storage error looks like: > Hi Andrei, sorry for the late reply -- seems like you'll need a lot of our other packages installed on your system. In particular, the patches for pve-manager depend on the patches made to libpve-storage-perl. Since we have tests that run during package builds, generate docs, generate completions for bash and zsh, etc. you get these errors. So, since there's a version break, you'll need to install the newly built version of libpve-storage-perl first before building pve-manager. The simplest way around this would probably be to build this in a VM where you have Proxmox VE with the latest packages installed: Build libpve-storage-perl on there first, install it, and then build pve-manager. There are other ways to build this too, like in a Debian container for example, but that isn't as straightforward as just putting it all into a VM. That being said, perhaps we can pass through the PERL5LIB env var or something in the future, to make builds a little easier. (Or add a flag to disable generating bash / zsh completions and the like. *gestures vaguely*) Hope this helps! Let me know if there's anything else I can help you with. PS: The patches should hopefully still apply; otherwise, just let me know and I'll rebase them ASAP. > ........ > > make[3]: Entering directory > '/root/build/pve-storage/libpve-storage-perl-9.1.0/PVE' > make[3]: Nothing to be done for 'clean'. > make[3]: Leaving directory > '/root/build/pve-storage/libpve-storage-perl-9.1.0/PVE' > make -C udev-rbd clean > make[3]: Entering directory > '/root/build/pve-storage/libpve-storage-perl-9.1.0/udev-rbd' > make[3]: Nothing to be done for 'clean'. > make[3]: Leaving directory > '/root/build/pve-storage/libpve-storage-perl-9.1.0/udev-rbd' > make[2]: Leaving directory > '/root/build/pve-storage/libpve-storage-perl-9.1.0' > =C2=A0=C2=A0 dh_clean > make[1]: Leaving directory > '/root/build/pve-storage/libpve-storage-perl-9.1.0' > =C2=A0debian/rules binary > make[1]: Entering directory > '/root/build/pve-storage/libpve-storage-perl-9.1.0' > dh binary > =C2=A0=C2=A0 dh_update_autotools_config > =C2=A0=C2=A0 dh_autoreconf > =C2=A0=C2=A0 dh_auto_configure > =C2=A0=C2=A0 dh_auto_build > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 make -j16 "INSTALL=3Dinstall = --strip-program=3Dtrue" > make[2]: Entering directory > '/root/build/pve-storage/libpve-storage-perl-9.1.0' > make[2]: Nothing to be done for 'all'. > make[2]: Leaving directory > '/root/build/pve-storage/libpve-storage-perl-9.1.0' > =C2=A0=C2=A0 dh_auto_test > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 make -j16 test > make[2]: Entering directory > '/root/build/pve-storage/libpve-storage-perl-9.1.0' > perl -I. -T -e "use PVE::CLI::pvesm; PVE::CLI::pvesm->verify_api();" > 400 internal error - unable to verify schema > properties.control_port.type: value 'int' does not have a value in the > enumeration 'string, object, coderef, array, boolean, number, integer, > null, any' > properties.data_port.type: value 'int' does not have a value in the > enumeration 'string, object, coderef, array, boolean, number, integer, > null, any' > properties.luns_per_target.type: value 'int' does not have a value in > the enumeration 'string, object, coderef, array, boolean, number, > integer, null, any' > make[2]: *** [Makefile:16: test] Error 255 > make[2]: Leaving directory > '/root/build/pve-storage/libpve-storage-perl-9.1.0' > dh_auto_test: error: make -j16 test returned exit code 2 > make[1]: *** [debian/rules:13: binary] Error 255 > make[1]: Leaving directory > '/root/build/pve-storage/libpve-storage-perl-9.1.0' > dpkg-buildpackage: error: debian/rules binary subprocess returned exit > status 2 > make: *** [Makefile:31: libpve-storage-perl_9.1.0_all.deb] Error 2 > > > > For pve-manager: > > ..... > > test -z "${PVE_DOC_INSTANTVIEW}" || man -l pvesr.1 > Note: Writing pvenode.1 > test -z "${PVE_DOC_INSTANTVIEW}" || man -l pvenode.1 > Can't locate PVE/API2/Plugins/Storage.pm in @INC (you may need to > install the PVE::API2::Plugins::Storage module) (@INC entries checked: > .. . /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.40.1 > /usr/local/share/perl/5.40.1 /usr/lib/x86_64-linux-gnu/perl5/5.40 > /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl-base > /usr/lib/x86_64-linux-gnu/perl/5.40 /usr/share/perl/5.40 > /usr/local/lib/site_perl) at ../PVE/API2/Plugins.pm line 8. > BEGIN failed--compilation aborted at ../PVE/API2/Plugins.pm line 8. > Compilation failed in require at ../PVE/API2.pm line 20. > BEGIN failed--compilation aborted at ../PVE/API2.pm line 20. > Compilation failed in require at ../PVE/Service/pveproxy.pm line 13. > BEGIN failed--compilation aborted at ../PVE/Service/pveproxy.pm line 13. > Compilation failed in require at -e line 1. > BEGIN failed--compilation aborted at -e line 1. > Can't locate PVE/API2/Plugins/Storage.pm in @INC (you may need to > install the PVE::API2::Plugins::Storage module) (@INC entries checked: > .. . /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.40.1 > /usr/local/share/perl/5.40.1 /usr/lib/x86_64-linux-gnu/perl5/5.40 > /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl-base > /usr/lib/x86_64-linux-gnu/perl/5.40 /usr/share/perl/5.40 > /usr/local/lib/site_perl) at ../PVE/API2/Plugins.pm line 8. > BEGIN failed--compilation aborted at ../PVE/API2/Plugins.pm line 8. > Compilation failed in require at ../PVE/API2.pm line 20. > BEGIN failed--compilation aborted at ../PVE/API2.pm line 20. > Compilation failed in require at ../PVE/CLI/pvesh.pm line 16. > BEGIN failed--compilation aborted at ../PVE/CLI/pvesh.pm line 16. > Compilation failed in require at -e line 1. > BEGIN failed--compilation aborted at -e line 1. > make[3]: *** [/usr/share/pve-doc-generator/pve-doc-generator.mk:38: > pveproxy.8-synopsis.adoc] Error 2 > make[3]: *** Waiting for unfinished jobs.... > make[3]: *** [/usr/share/pve-doc-generator/pve-doc-generator.mk:34: > pvesh.1-synopsis.adoc] Error 2 > Note: Writing vzdump.1 > test -z "${PVE_DOC_INSTANTVIEW}" || man -l vzdump.1 > Can't locate PVE/API2/Plugins/Storage.pm in @INC (you may need to > install the PVE::API2::Plugins::Storage module) (@INC entries checked: > .. . /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.40.1 > /usr/local/share/perl/5.40.1 /usr/lib/x86_64-linux-gnu/perl5/5.40 > /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl-base > /usr/lib/x86_64-linux-gnu/perl/5.40 /usr/share/perl/5.40 > /usr/local/lib/site_perl) at ../PVE/API2/Plugins.pm line 8. > BEGIN failed--compilation aborted at ../PVE/API2/Plugins.pm line 8. > Compilation failed in require at ../PVE/API2.pm line 20. > BEGIN failed--compilation aborted at ../PVE/API2.pm line 20. > Compilation failed in require at ../PVE/Service/pvedaemon.pm line 8. > BEGIN failed--compilation aborted at ../PVE/Service/pvedaemon.pm line 8. > Compilation failed in require at -e line 1. > BEGIN failed--compilation aborted at -e line 1. > make[3]: *** [/usr/share/pve-doc-generator/pve-doc-generator.mk:38: > pvedaemon.8-synopsis.adoc] Error 2 > Note: Writing pveceph.1 > test -z "${PVE_DOC_INSTANTVIEW}" || man -l pveceph.1 > make[3]: Leaving directory '/root/build/pve-manager/pve-manager-9.1.5/bin= ' > make[2]: *** [Makefile:16: all] Error 2 > make[2]: Leaving directory '/root/build/pve-manager/pve-manager-9.1.5' > dh_auto_build: error: make -j16 "INSTALL=3Dinstall --strip-program=3Dtrue= " > returned exit code 2 > make[1]: *** [debian/rules:7: build] Error 2 > make[1]: Leaving directory '/root/build/pve-manager/pve-manager-9.1.5' > dpkg-buildpackage: error: debian/rules build subprocess returned exit > status 2 > make: *** [Makefile:42: pve-manager_9.1.5_all.deb] Error 2 > > > > I've managed to make deb package for proxmox-widget-toolkit. > > My strategy is to: > 1. apply your patches to code in repositories > 2. make deb packages > 3. install deb packages on system and test it > > May be you can recommend something or point me to the guide regarding > making deb packages with applied patches. > Ive installed dev repositories according to > https://pve.proxmox.com/wiki/Developer_Documentation > > But I think Im mising something related to linkage or something else > > Im building packages on proxmox 9.1 updated to 9.5 > > > Best regards, > > Andrei > > On 1/9/26 04:19, Max R. Carrara wrote: > > On Thu Jan 8, 2026 at 11:48 PM CET, Andrei Perepiolkin wrote: >> Hi Max= , >> >> >> I like your idea of extending Proxmox with the > capability to >> render a UI for adding and editing custom storage > plugins. >> >> I'm curious =E2=80=94 was your patch approved or merged? >= > >> >> > Best regards, >> >> Andrei Perepiolkin > > Hello Andrei! > > I'm very > glad you like it! The RFC is still awaiting comments / > feedback / > review, mostly because it is / was holiday season. > > However, if you'd > like to see this merged or iterated on faster, I'd > highly appreciate > any feedback and/or testing! :) > > If you want to try it out for > yourself, let me know if you need any > help applying or building the > patches. It should work with any third- > party plugin out of the box, > including yours. > > Best regards, Max > >> >> On 11/21/25 11:58, Max R. > Carrara wrote: >>> GUI Support for Custom Storage Plugins - v2 >>> > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >>> >>> This is a= complete > refresh of my previous RFC that aims to be >>> much less greenfield-y > and instead tries to reuse as much >>> existing code as possible while > remaining as forward-compatible >>> as possible. >>> >>> Normally I > would provide a more detailed changelog under each >>> patch, but since > so much has changed since rfc-v1, I'll instead >>> sum up the biggest > changes here: >>> >>> - The API routes are changed to be a little more > flexible=E2=80=94routes >>> regarding views etc. are completely omitted. = See > patches #01 and >>> #08 for more information. >>> >>> - The schemas of > plugins are returned as part of their metadata. >>> A "schema" for a > storage plugin in this context is simply a >>> hashmap consisting of the > plugin's properties' JSON schemas. See >>> patch #02 for a complete and > detailed explanation. >>> >>> - Existing UI code concerned with building > the fields of ACME >>> DNS challenge plugins is factored out, made more > generic and >>> also receives some additional features so that it can be > used in >>> different places. See patches #05 and #06 for details. >>> > >>> - Instead of making separate versions of all of the storage- >>> > related UI components (panels etc.), only one new input panel is >>> > added, while the remaining necessary functionality is integrated >>> > into the existing code. See patch #09 for further details. >>> >>> >>> > The Result ---------- >>> >>> Instead of having to provide a separate > "view definition", >>> storage entries for custom storage plugins can > now be created >>> and edited in the UI *without* needing to provide any > extra UI / >>> layouting hints. >>> >>> So, if one now installs > something like the SSHFS example plugin >>> [sshfs-plugin], the > resulting UI is about ~80% there in terms of >>> look and feel compared > to the forms of built-in plugins: >>> >>> - Default values are displayed > as grey text inside fields - >>> Descriptions of properties are provided > as little pop-up quips >>> when hovering over a field - "fixed" > properties are >>> automatically taken into account and made read-only > when editing >>> a storage entry - "sensitive" properties are > automatically >>> treated as password fields - Optional / non-optional > properties >>> are handled - The min- / maxLength of strings and the > min- / >>> maximum of numeric fields is taken into account in the UI - > The >>> "Backup Retention" tab is automatically masked / unmasked >>> > depending on whether the storage plugin supports backups or not >>> >>> > This is mostly everything that I managed to squeeze out of the >>> > existing SectionConfig schemas / data. >>> >>> Additionally, something > that's neat is that the `title` key of >>> every property is now used as > its field's label in the UI. That >>> means we can provide labels for > all of our built-in properties >>> while third-party developers may > provide theirs for their own >>> properties. As a quick example, this is > what that would look >>> like for the SSHFS plugin [sshfs-plugin]: >>> > >>> sub properties { return { 'remote-path' =3D> { description =3D> >>> > "Path on the remote filesystem used for SSHFS. Must be >>> absolute.", > type =3D> 'string', format =3D> 'pve-storage-path', >>> title =3D> 'Remot= e > Path', }, 'sshfs-private-key' =3D> { description >>> =3D> "The private ke= y > to use for SSHFS.", type =3D> 'string', title >>> =3D> 'Private Key', }, = }; > } >>> >>> >>> This becomes even more flexible for third-party devs once > we >>> switch over to property isolation=E2=80=94something the code in th= is RFC > >>> should be 100% forward-compatible with. Then they wouldn't be >>> > bound to our provided labels. >>> >>> In terms of overall looks, the > remaining 20% consist of some >>> polish on the frontend for the most > part, but honestly, that can >>> be done once this RFC becomes an actual > series. I felt that this >>> was in an adequate enough state to publish > for now=E2=80=94please let me >>> know what you think if you give this RF= C a > spin, I'd appreciate >>> it! >>> >>> Previous Versions ----------------- > >>> >>> rfc-v1: https://lore.proxmox.com/pve- >>> > devel/20250908180058.530119-1-m.carrara@proxmox.com/ >>> >>> References > ---------- >>> >>> [sshfs-plugin]: > https://git.proxmox.com/?p=3Dpve-storage-plugin- >>> > examples.git;a=3Dtree;f=3Dplugin- >>> > sshfs;h=3Dc7543808f7226209650d1b8b6e449392bc1f0d2d;hb=3Drefs/heads/ >>> > master >>> >>> Summary of Changes ------------------ >>> >>> > pve-storage: >>> >>> Max R. Carrara (5): api: plugins/storage: add > initial routes and >>> endpoints api: plugins/storage/plugin: include > schema in plugin >>> metadata api: plugins/storage/plugin: mark > sensitive properties >>> in schema api: plugins/storage/plugin: factor > plugin metadata >>> code into helper api: plugins/storage/plugin: add > plugins' >>> 'content' to their metadata >>> >>> src/PVE/API2/Makefile | > 1 + src/PVE/API2/ >>> Plugins/Makefile | 18 +++ src/PVE/API2/Plugins/ > >>> Storage.pm | 54 ++++++++ src/PVE/API2/Plugins/Storage/ >>> Makefile > | 17 +++ src/PVE/API2/Plugins/Storage/Plugin.pm | 163 >>> > +++++++++++++++++++++++++ 5 files changed, 253 insertions(+) >>> create > mode 100644 src/PVE/API2/Plugins/Makefile create mode >>> 100644 > src/PVE/API2/Plugins/Storage.pm create mode 100644 src/ >>> > PVE/API2/Plugins/Storage/Makefile create mode 100644 src/PVE/ >>> > API2/Plugins/Storage/Plugin.pm >>> >>> >>> proxmox-widget-toolkit: >>> > >>> Max R. Carrara (2): utils: introduce helper function >>> > getFieldDefFromPropertySchema acme: use helper to construct >>> ExtJS > fields from property schemas >>> >>> src/Utils.js | 106 > ++++++++++++++++++++++++++++++ >>> +++++ src/window/ACMEPluginEdit.js | > 42 +++++--------- 2 files >>> changed, 119 insertions(+), 29 > deletions(-) >>> >>> >>> pve-manager: >>> >>> Max R. Carrara (3): api: > add API routes 'plugins' and 'plugins/ >>> storage' ui: storage view: > display error when no editor for >>> storage type exists ui: storage: > add basic UI integration for >>> custom storage plugins >>> >>> > PVE/API2.pm | 6 ++ PVE/API2/ >>> Makefile | 1 + PVE/API2/ >>> Plugins.pm > | 61 +++++++++++++ www/manager6/ >>> Makefile | 1 + > www/manager6/dc/StorageView.js >>> | 132 +++++++++++++++++++++-------- > www/manager6/storage/ >>> Base.js | 1 + > www/manager6/storage/CustomEdit.js | 110 ++ >>> ++++++++++++++++++++++ 7 > files changed, 278 insertions(+), 34 >>> deletions(-) create mode 100644 > PVE/API2/Plugins.pm create mode >>> 100644 > www/manager6/storage/CustomEdit.js >>> > >