From: "Max R. Carrara" <m.carrara@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [RFC pve-storage master v2 1/10] api: plugins/storage: add initial routes and endpoints
Date: Fri, 21 Nov 2025 17:58:30 +0100 [thread overview]
Message-ID: <20251121165858.818307-2-m.carrara@proxmox.com> (raw)
In-Reply-To: <20251121165858.818307-1-m.carrara@proxmox.com>
Add the following routes / endpoints:
* `GET plugins/storage`
Subdir index--lists the direct child path components (so, just
'plugin' currently).
* `GET plugins/storage/plugin`
Lists all installed storage plugins and their metadata.
Currently, this is just an array of objects, with each object
containing the plugin's `type()` and Perl module path.
* `GET plugins/storage/plugin/{type}`
Returns the metadata for a single plugin given by `{type}`.
Signed-off-by: Max R. Carrara <m.carrara@proxmox.com>
---
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 | 104 +++++++++++++++++++++++++
5 files changed, 194 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
diff --git a/src/PVE/API2/Makefile b/src/PVE/API2/Makefile
index fe316c5..01b7b28 100644
--- a/src/PVE/API2/Makefile
+++ b/src/PVE/API2/Makefile
@@ -5,3 +5,4 @@ install:
install -D -m 0644 Disks.pm ${DESTDIR}${PERLDIR}/PVE/API2/Disks.pm
make -C Storage install
make -C Disks install
+ make -C Plugins install
diff --git a/src/PVE/API2/Plugins/Makefile b/src/PVE/API2/Plugins/Makefile
new file mode 100644
index 0000000..f59e75b
--- /dev/null
+++ b/src/PVE/API2/Plugins/Makefile
@@ -0,0 +1,18 @@
+SOURCES = Storage.pm \
+
+
+SUBDIRS = Storage \
+
+
+INSTALL_PATH = ${DESTDIR}${PERLDIR}/PVE/API2/Plugins
+
+
+.PHONY: install
+install:
+ set -e && for SOURCE in ${SOURCES}; \
+ do install -D -m 0644 $$SOURCE ${INSTALL_PATH}/$$SOURCE; \
+ done
+ set -e && for SUBDIR in ${SUBDIRS}; \
+ do make -C $$SUBDIR install; \
+ done
+
diff --git a/src/PVE/API2/Plugins/Storage.pm b/src/PVE/API2/Plugins/Storage.pm
new file mode 100644
index 0000000..53b883f
--- /dev/null
+++ b/src/PVE/API2/Plugins/Storage.pm
@@ -0,0 +1,54 @@
+package PVE::API2::Plugins::Storage;
+
+use v5.36;
+
+use PVE::Storage;
+use PVE::Storage::Plugin;
+
+use PVE::API2::Plugins::Storage::Plugin;
+
+use PVE::RESTHandler;
+use base qw(PVE::RESTHandler);
+
+__PACKAGE__->register_method({
+ subclass => 'PVE::API2::Plugins::Storage::Plugin',
+ path => 'plugin',
+});
+
+# plugins/storage
+
+__PACKAGE__->register_method({
+ name => 'index',
+ path => '',
+ method => 'GET',
+ description => 'Directory index.',
+ permissions => {
+ user => 'all',
+ },
+ parameters => {
+ additionalProperties => 0,
+ properties => {},
+ },
+ returns => {
+ type => 'array',
+ items => {
+ type => "object",
+ additionalProperties => 0,
+ properties => {
+ subdir => {
+ type => 'string',
+ },
+ },
+ },
+ links => [{ rel => 'child', href => "{subdir}" }],
+ },
+ code => sub($param) {
+ my $result = [
+ { subdir => 'plugin' },
+ ];
+
+ return $result;
+ },
+});
+
+1;
diff --git a/src/PVE/API2/Plugins/Storage/Makefile b/src/PVE/API2/Plugins/Storage/Makefile
new file mode 100644
index 0000000..06473a2
--- /dev/null
+++ b/src/PVE/API2/Plugins/Storage/Makefile
@@ -0,0 +1,17 @@
+SOURCES = Plugin.pm \
+
+
+SUBDIRS =
+
+
+INSTALL_PATH = ${DESTDIR}${PERLDIR}/PVE/API2/Plugins/Storage
+
+.PHONY: install
+install:
+ set -e && for SOURCE in ${SOURCES}; \
+ do install -D -m 0644 $$SOURCE ${INSTALL_PATH}/$$SOURCE; \
+ done
+ set -e && for SUBDIR in ${SUBDIRS}; \
+ do make -C $$SUBDIR install; \
+ done
+
diff --git a/src/PVE/API2/Plugins/Storage/Plugin.pm b/src/PVE/API2/Plugins/Storage/Plugin.pm
new file mode 100644
index 0000000..fd0f734
--- /dev/null
+++ b/src/PVE/API2/Plugins/Storage/Plugin.pm
@@ -0,0 +1,104 @@
+package PVE::API2::Plugins::Storage::Plugin;
+
+use v5.36;
+
+use HTTP::Status qw(:constants);
+
+use PVE::Exception qw(raise);
+use PVE::Storage;
+use PVE::Storage::Plugin;
+use PVE::Tools qw(extract_param);
+
+use PVE::RESTHandler;
+use base qw(PVE::RESTHandler);
+
+my $ALL_PLUGIN_TYPES = PVE::Storage::Plugin->lookup_types();
+
+my $PLUGIN_METADATA_SCHEMA = {
+ type => 'object',
+ additionalProperties => 0,
+ properties => {
+ module => {
+ type => 'string',
+ optional => 0,
+ },
+ type => {
+ type => 'string',
+ optional => 0,
+ enum => $ALL_PLUGIN_TYPES,
+ },
+ },
+};
+
+# plugins/storage/plugin
+
+__PACKAGE__->register_method({
+ name => 'index',
+ path => '',
+ method => 'GET',
+ description => 'List all available storage plugins and their metadata.',
+ permissions => {
+ user => 'all',
+ },
+ parameters => {
+ additionalProperties => 0,
+ properties => {},
+ },
+ returns => {
+ type => 'array',
+ items => $PLUGIN_METADATA_SCHEMA,
+ },
+ code => sub($param) {
+ my $result = [];
+
+ for my $type ($ALL_PLUGIN_TYPES->@*) {
+ my $plugin = PVE::Storage::Plugin->lookup($type);
+
+ my $item = {
+ module => $plugin,
+ type => $type,
+ };
+
+ push($result->@*, $item);
+ }
+
+ return $result;
+ },
+});
+
+# plugins/storage/plugin/{type}
+
+__PACKAGE__->register_method({
+ name => 'info',
+ path => '{type}',
+ method => 'GET',
+ description => 'Fetch metadata of a storage plugin.',
+ permissions => {
+ user => 'all',
+ },
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ type => {
+ type => 'string',
+ },
+ },
+ },
+ returns => $PLUGIN_METADATA_SCHEMA,
+ code => sub($param) {
+ my $param_type = extract_param($param, 'type');
+
+ my $plugin = eval { PVE::Storage::Plugin->lookup($param_type) };
+ if ($@) {
+ raise("Plugin '$param_type' not found - $@", code => HTTP_NOT_FOUND);
+ }
+
+ my $result = {
+ module => $plugin,
+ type => $param_type,
+ };
+
+ return $result;
+ },
+});
+1;
--
2.47.3
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
next prev parent reply other threads:[~2025-11-21 16:59 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-21 16:58 [pve-devel] [RFC pve-storage/proxmox-widget-toolkit/pve-manager master v2 00/10] GUI Support for Custom Storage Plugins Max R. Carrara
2025-11-21 16:58 ` Max R. Carrara [this message]
2025-11-21 16:58 ` [pve-devel] [RFC pve-storage master v2 2/10] api: plugins/storage/plugin: include schema in plugin metadata Max R. Carrara
2025-11-21 16:58 ` [pve-devel] [RFC pve-storage master v2 3/10] api: plugins/storage/plugin: mark sensitive properties in schema Max R. Carrara
2025-11-21 16:58 ` [pve-devel] [RFC pve-storage master v2 4/10] api: plugins/storage/plugin: factor plugin metadata code into helper Max R. Carrara
2025-11-21 16:58 ` [pve-devel] [RFC pve-storage master v2 5/10] api: plugins/storage/plugin: add plugins' 'content' to their metadata Max R. Carrara
2025-11-21 16:58 ` [pve-devel] [RFC proxmox-widget-toolkit master v2 6/10] utils: introduce helper function getFieldDefFromPropertySchema Max R. Carrara
2025-11-21 16:58 ` [pve-devel] [RFC proxmox-widget-toolkit master v2 7/10] acme: use helper to construct ExtJS fields from property schemas Max R. Carrara
2025-11-21 16:58 ` [pve-devel] [RFC pve-manager master v2 08/10] api: add API routes 'plugins' and 'plugins/storage' Max R. Carrara
2025-11-21 16:58 ` [pve-devel] [RFC pve-manager master v2 09/10] ui: storage view: display error when no editor for storage type exists Max R. Carrara
2025-11-21 16:58 ` [pve-devel] [RFC pve-manager master v2 10/10] ui: storage: add basic UI integration for custom storage plugins Max R. Carrara
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=20251121165858.818307-2-m.carrara@proxmox.com \
--to=m.carrara@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