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 889BE1FF13D for ; Thu, 08 Jan 2026 23:54:42 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id F29438E98; Thu, 8 Jan 2026 23:54:40 +0100 (CET) Date: Thu, 8 Jan 2026 17:48:31 -0500 To: pve-devel@lists.proxmox.com, m.carrara@proxmox.com References: <20251121165858.818307-1-m.carrara@proxmox.com> In-Reply-To: <20251121165858.818307-1-m.carrara@proxmox.com> MIME-Version: 1.0 Message-ID: List-Id: Proxmox VE development discussion List-Post: From: Andrei Perepiolkin via pve-devel Precedence: list Cc: Andrei Perepiolkin X-Mailman-Version: 2.1.29 X-BeenThere: pve-devel@lists.proxmox.com List-Subscribe: , List-Unsubscribe: , List-Archive: Reply-To: Proxmox VE development discussion List-Help: Subject: Re: [pve-devel] [RFC pve-storage/proxmox-widget-toolkit/pve-manager master v2 00/10] GUI Support for Custom Storage Plugins Content-Type: multipart/mixed; boundary="===============0278247485215674095==" Errors-To: pve-devel-bounces@lists.proxmox.com Sender: "pve-devel" --===============0278247485215674095== Content-Type: message/rfc822 Content-Disposition: inline Return-Path: X-Original-To: pve-devel@lists.proxmox.com Delivered-To: pve-devel@lists.proxmox.com Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id E7281DC732 for ; Thu, 8 Jan 2026 23:54:38 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id B0EC28E5F for ; Thu, 8 Jan 2026 23:54:08 +0100 (CET) Received: from mout.kundenserver.de (mout.kundenserver.de [217.72.192.73]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (prime256v1) server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS for ; Thu, 8 Jan 2026 23:54:07 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=open-e.com; s=s1-ionos; t=1767912840; x=1768517640; i=andrei.perepiolkin@open-e.com; bh=0xp6XtU6C3RdfVvpI08x7nBEZC0ccsRfOWuaxpowBlU=; h=X-UI-Sender-Class:Message-ID:Date:MIME-Version:Subject:To: References:From:In-Reply-To:Content-Type: Content-Transfer-Encoding:cc:content-transfer-encoding: content-type:date:from:message-id:mime-version:reply-to:subject: to; b=d7afozpTH1goH5QoB6uPhWC3hWIbrdN0jsYWshMDn+Up82KiYqa/UKaT//1fAykQ Cj6bnZGnNxKGFVGjUQaCz1LtYdz8jJ5n7jDz/EJupn+/UXEN7cQYdS/qS6c5pqnkv bNcZ7ZmLGOAp167F+zN+fT5d0EbC6TTpxTouSUL4/JaoDF4N8ZUZWqj34Tvh+M7L4 F3LNUv92KzZXpL1pstJTIhuIyfLjgFQyUU4E9k0E5Hc8bwhKlvLirQBBmDNrqvchU QoofWpSUloKAfKYFiSHYlEyyk3YWL1qrbeQRz5L4fOXxsRV3Syesybq4GNB6wk4ED HSzGxNl3lsaPj0Mppw== X-UI-Sender-Class: 55c96926-9e95-11ee-ae09-1f7a4046a0f6 Received: from [10.137.0.75] ([149.102.246.30]) by mrelayeu.kundenserver.de (mreue108 [212.227.15.183]) with ESMTPSA (Nemesis) id 1MI5cP-1vbS7C43U7-00DuhW; Thu, 08 Jan 2026 23:48:34 +0100 Message-ID: Date: Thu, 8 Jan 2026 17:48:31 -0500 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [pve-devel] [RFC pve-storage/proxmox-widget-toolkit/pve-manager master v2 00/10] GUI Support for Custom Storage Plugins To: pve-devel@lists.proxmox.com, m.carrara@proxmox.com References: <20251121165858.818307-1-m.carrara@proxmox.com> Content-Language: en-US From: Andrei Perepiolkin In-Reply-To: <20251121165858.818307-1-m.carrara@proxmox.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: quoted-printable X-Provags-ID: V03:K1:f567POdYMQu0SazEnLpns5EDuu7C0f4o8w+ci4m57lyFRvdEJOu 6zW7pwwJQjcDV7q0jUt7/hznJExl7lY9+MA4lzQGw8yaSdifw1YW1aUQciKJiuJUgsKdHrJ SHaoNZEafRd0nnIN/z7KRtOnbMj5z111pPeaTHeigWNjdfoQiMPp52+PgpvMNPBcKxV0u7Q 4DDFHGz+Fl2Bnp0h7g9DQ== X-Spam-Flag: NO UI-OutboundReport: notjunk:1;M01:P0:FUFYnFz/ETw=;IjFsWi7Od5ubm8jhNSszrrusbNk DSBJDxAjZrsLL0yGpLqBb3lo9FekxM3zZYdk1ogv6j9QMi3ouAzUiwYdQIO/t0JW5h7aYzver OrYyOVK7BthgBhUP+XCIqloHLGgTft2bj9wGo1yUXgUD0+TDKsl8OcW9H/96jC+MOuwtZiHym gfwo3NCzN9iWNzqktkxvoEYw5xvPnF1Qx9BfM8+W7oBJp2swXgPAg4KPAEmbVnADmMN12PRxB tCXcyMuYWYi9mb5dArIdKq0D3HwDHre3wlBB+wWlNHOATKzzqB/YQxbfGekHQkW2lGyIT9KlZ DaNxENSqGL1++36f3K9i3BWoexaAj8lt8Iais3EZoYjrzPgPqjrPFl5T2OudJLt5+Shar+ntA 9bkY3fGvHij3Wa/eC2IhPwp1gA+XKW4pOsxfaAA0CAQKKP0TqiCjMo6GITPlZ4XpsiJE4RXMB hgYPEPTooNWTNk1MGI4lO6E41nG2HxMynnqJhQTpyFCPiGqkfzVfnAQ4hwM0pNGzCpxMMI71F j7WQT4mRb29UOcUnAnoCdrlzCtFZerKesU8OO2Qni7cNfvf8gtPk2/VmWNEc5OnpPZKdC3uuE IRdnqUPE9hqMHSv/MnpgO17KGcMKpt8vYGa+elA9gWJ02Q9VvEOsvD5xUeFk/ohant1uZXSnt mMAOuQ57JDmsus30qRQNP4MyeGsnB03V9GKvdu9bGVTzJJS1Xzdy3QxENv9YF2tak5krsM5iX ECIi/uv6bAo3qmTLxTO6uT/qXJzJyZOcZgxbM/HWk828CZNsQaSBD51bDgE3QEwubA03EWDi3 RjXzVa8Pd1yCnghJPdkqZxBcfS+VZCcsG38IcsuYioZOcyUFokcMe3tQG9USeaul4bOE7V6X/ b8HIBvbZQ02KLZZAMu4jwBPZfyNCGPYkjgqUvwNkrUH389k66Wv5AmgTXU0Ki0iVftBTwbOrC i64ZfHPTkGEL2CbxRoC2VE/cvWmqc13Qd8xCSI2+4NrwFWma5vxH0Uv1Ffm+Hw5A/R6xOzRId hLAExyaUemUC7634cz9EIhQQtn7cj1Dze1RUzmIo6EYpYsEjMvrQVNmpFb8nDtUe8G7SARe0S BZS9BUYAFt9P23segi0lH+WxBLCcv/WjZ8QJApl7RKG1Zb36Pd+acwrhARk1ek5ZaHeGYhKB8 UAdsGVGm2TxNNywk6vvCwZkydQ9YYerF1+YfTm1lYizcwMZUFuKPy2MW2TjBGOu0GD8ERgvjK zwgiy3LutDAC8PwapaYENhISDrrjKzFlg17BcHjVqPRgf3LI7yBzF0A8rUNxg9SmX+OpFqbxK 9SGRN/G4uQ0YDgmcE0YzxE5da2JO3/YKIkEkqx3u0J6DnhdTJdMg9xnHPnJxJH5AqwKtCl2a/ 9KjBNw3jN5TACeDuISr6Q1f/cdTlmhYSr+F6wZRrT/GhAG3/2kTJxXiApQLYJury8509xVRhk GeQJZmqNjIAw1EdaH+ssgdN5g1psy/fVWLGdjwpuLRc8gRMUBbRmkaHb+gFJDfcmHjqhviFPH rA0LyO/hylH1cqcdbi6Y5gfa/BS5hR6GsBuDatHsi0SlfQscvYJKhJkShTX63uJpd3dl57knt KzTyJ/uXP3XxRizbA4ASMytbhjrFQL6lMBLT+OggGOpQKosmiSsGaZTG9eUUxovm/zcRzgCUJ jmT61YSUeM6h9gXyVnFDZdV1tLTjwEKRqKBRRX6jjhqAMldnXA+Bq9zXiA6lr9jAXVv9U+5mn 7lWeaV5XKMZm2zvWQr5H7sLFRJ8lV0wU4Wg== X-SPAM-LEVEL: Spam detection results: 0 AWL -0.005 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DKIM_SIGNED 0.1 Message has a DKIM or DK signature, not necessarily valid DKIM_VALID -0.1 Message has at least one valid DKIM or DK signature DKIM_VALID_AU -0.1 Message has a valid DKIM or DK signature from author's domain DKIM_VALID_EF -0.1 Message has a valid DKIM or DK signature from envelope-from domain DMARC_PASS -0.1 DMARC pass policy RCVD_IN_DNSWL_NONE -0.0001 Sender listed at https://www.dnswl.org/, no trust RCVD_IN_MSPIKE_H2 0.001 Average reputation (+2) RCVD_IN_VALIDITY_CERTIFIED_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_RPBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_SAFE_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Hi Max, I like your idea of extending Proxmox with the capability to render a UI= =20 for adding and editing custom storage plugins. I'm curious =E2=80=94 was your patch approved or merged? Best regards, Andrei Perepiolkin 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 fo= r > 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 receive= s > 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 th= e > 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> 'Remote Path', > }, > 'sshfs-private-key' =3D> { > description =3D> "The private key 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 this RFC should be 1= 00% > 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 yo= u give > this RFC a spin, I'd appreciate it! > > Previous Versions > ----------------- > > rfc-v1: https://lore.proxmox.com/pve-devel/20250908180058.530119-1-m.car= rara@proxmox.com/ > > References > ---------- > > [sshfs-plugin]: https://git.proxmox.com/?p=3Dpve-storage-plugin-examples= .git;a=3Dtree;f=3Dplugin-sshfs;h=3Dc7543808f7226209650d1b8b6e449392bc1f0d2= d;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 exist= s > 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 > --===============0278247485215674095== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel --===============0278247485215674095==--