public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: "Max Carrara" <m.carrara@proxmox.com>
To: "Proxmox VE development discussion" <pve-devel@lists.proxmox.com>
Subject: Re: [pve-devel] [PATCH v1 pve-storage 2/8] pluginbase: add high-level plugin API description
Date: Thu, 03 Apr 2025 16:05:14 +0200	[thread overview]
Message-ID: <D8X27CNS8UVI.OJ5BZRP2N01J@proxmox.com> (raw)
In-Reply-To: <1743662987.9zy3v4thrh.astroid@yuna.none>

On Thu Apr 3, 2025 at 9:12 AM CEST, Fabian Grünbichler wrote:
> On April 2, 2025 6:31 pm, Max Carrara wrote:
> > On Mon Mar 31, 2025 at 5:13 PM CEST, Fabian Grünbichler wrote:
> >> On March 26, 2025 3:20 pm, Max Carrara wrote:
> >> > Add a short paragraph in DESCRIPTION serving as an introduction as
> >> > well as the GENERAL PARAMETERS and CACHING EXPENSIVE OPERATIONS
> >> > sections.
> >> > 
> >> > These sections are added in order to avoid repeatedly describing the
> >> > same parameters as well as to elaborate on / clarify a couple terms,
> >> > e.g. what the $cache parameter does or what a volume in our case is.
> >> > 
> >> > Signed-off-by: Max Carrara <m.carrara@proxmox.com>
> >> > ---
> >> >  src/PVE/Storage/PluginBase.pm | 77 +++++++++++++++++++++++++++++++++++
> >> >  1 file changed, 77 insertions(+)
> >> > 
> >> > diff --git a/src/PVE/Storage/PluginBase.pm b/src/PVE/Storage/PluginBase.pm
> >> > index e56aa72..16977f3 100644
> >> > --- a/src/PVE/Storage/PluginBase.pm
> >> > +++ b/src/PVE/Storage/PluginBase.pm
> >> > @@ -4,6 +4,83 @@ C<PVE::Storage::PluginBase> - Storage Plugin API Interface
> >> >  
> >> >  =head1 DESCRIPTION
> >> >  
> >> > +This module documents the public Storage Plugin API of PVE and serves
> >> > +as a base for C<L<PVE::Storage::Plugin>>. Plugins must B<always> inherit from
> >> > +C<L<PVE::Storage::Plugin>>, as this module is for documentation purposes
> >> > +only.
> >>
> >> does this make sense? if we now provide a clean base for the structure
> >> of plugins, why shouldn't plugins be able to use that, but instead have
> >> to inherit from PVE::Storage::Plugin which has a lot of extra stuff that
> >> makes things messy?
> >>
> >> granted, switching over to load from PluginBase could be done as a
> >> follow up or with 9.0 (or not at all, if there is a rationale)..
> >>
> >> after this series we have:
> >>
> >> SectionConfig
> >> -> PluginBase (not an actual base plugin w.r.t. SectionConfig, and not
> >> something you base plugins on as a result)
> >> --> Plugin (a combination of base plugin and base of all our
> >> directory-based plugins)
> >> ---> other plugins, including third party ones
> >>
> >> which seems unfortunate, even if the contents of PluginBase are helpful
> >> when implementing your own..
> >>
> >> IMHO this should either be
> >>
> >> SectionConfig
> >> -> PluginBase (actual base plugin, with SectionConfig implementations
> >> moved over from current Plugin.pm as needed)
> >> --> PluginTemplate (what's currently PluginBase in this series - nicely
> >> documented parent of third party plugins, not actually registered, just
> >> contains the storage.cfg interface without the low-level SectionConfig
> >> things)
> >> ---> NewThirdPartyPlugin (clean slate implementation just using the
> >> nicely documented interfaces, guaranteed to not use any helpers from
> >> Plugin since it's not a (grand)parent)
> >> --> Plugin (base of built-in plugins, probably base of existing third
> >> party plugins, should ideally have a different name in the future!)
> >> ---> DirPlugin
> >> ---> ...
> >> ---> ExistingThirdPartyPlugin (this might rely on helpers from Plugin,
> >> so we can't just rename that one unless we wait for 9.0)
> >>
> >> or
> >>
> >> SectionConfig
> >> -> PluginBase (actual base plugin + docs of Plugin API)
> >> --> Plugin (base of our plugins and existing third party ones, dir-related helpers, ..)
> >> ---> other plugins, including third party ones
> >> --> NewThirdPartyPlugin (clean slate as above)
> > 
> > I agree with your point here -- for now, `::PluginBase` should IMO still
> > only be about documentation and enumerating what's part of the Plugin
> > API, *but* adding more layers inbetween can still be done eventually.
> > 
> > However, I think we shouldn't have two different parents for internal
> > and external plugins, as it would introduce yet another thing we'd have
> > to track wrt. APIAGE resets etc. Maybe it's not actually an issue in
> > this case, but ...
>
> the API would be defined by the "public"/external/top-level base
> obviously, not by our intermediate shared base ;)

Fair point :P

>
> > That actually gives me an idea that's similar to your first suggestion:
> > 
> > As of this series, the hierarchy would be as follows:
> > 
> > PluginBase
> > └── Plugin
> >     ├── ExistingThirdPartyPlugin
> >     ├── DirPlugin
> >     └── ...
> > 
> > We could keep `PluginBase` as it is, since IMO having the docs and the
> > SectionConfig-related stuff in one place is fine, unless we really want
> > to keep the docs separate from the rest of the code. (Would seem a bit
> > redundant to introduce another inheritance layer in that case, but I
> > personally don't mind.)
>
> I don't mind having the SectionConfig and the "skeleton" in one module,
> provided they are clearly separated. the SectionConfig methods are
> inherited anyway and any third party plugin must uphold the invariant of
> not messing with them..
>
> > Then, we eventually introduce `PluginTemplate` on the same layer as
> > `Plugin`. `PluginTemplate` would only contain implementations for the
> > most basic methods (and not provide defaults for file-based storages).
>
> do you have something in mind for this "Template"? and if those methods
> were so generic and basic at the same time, why shouldn't they live in
> PluginBase itself? ;) I am not yet convinced an extra layer like this
> makes much sense, but I am happy to listen to (concrete) arguments why
> it should exist. IMHO the less code inherited by external plugins the
> better, else we always have to not touch that code for ages to avoid
> breaking them..

No that's a good point; this entire idea here could actually also be
done without introducing `PluginTemplate`.

>
> > PluginBase
> > ├── Plugin
> > │   ├── ExistingThirdPartyPlugin
> > │   ├── DirPlugin
> > │   └── ...
> > └── PluginTemplate
> > 
> > The idea behind this is that we could then "migrate" each plugin and
> > base it off `PluginTemplate` instead. Helpers that are shared between
> > plugins could go into `PVE::Storage::Common::*` instead of being
> > implicitly becoming part of plugins' modules due to inheritance.
>
> the issue with that is that we've now just moved the problem - what are
> the stability guarantees for PVE::Storage::Common::* ? are external
> plugins allowed/supposed to use them? I do think we want to keep some
> amount of "PVE-specific, internal" helper code (whether in the plugins
> themselves or in some standalone helper module) that are off-limits for
> external plugins, if just to avoid writing us into a corner. the easiest
> way to achieve that is to migrate external plugins away from Plugin.pm
> (which we can enforce at plugin loading time at some point after a
> deprecation period).

Yeah I agree, I'm just not entirely sure yet which *exact* approach here
would be the best.

If you'd like, we can revisit this topic once it becomes relevant; for
now I think we can move forward with the inheritance structure that this
series proposes, that is:

SectionConfig
└── PluginBase
    └── Plugin
        ├── DirPlugin
        ├── ...
        ├── ExistingThirdPartyPlugin
        └── ...

In a future series, I'd then proceed with moving the
SectionConfig-related stuff to PluginBase (and perhaps other
"fundamental" stuff; yet to be decided what). When that happens, I'll
also see what "migration approach" would be the best, what internal /
external helpers to have, stability guarantees, etc.

The only thing I would definitely want to avoid is introducing another
inheritance layer somewhere, as it's already somewhat hard to keep track
of things.

>
> obviously for helpers that we deem stable enough moving them to Common
> and wrapping them in their old location in Plugin would be a viable
> migration strategy.

I agree here as well; that's something I attempted a long while ago.
I'm looking forward to revisiting that 👀

>
> > PluginBase
> > ├── Plugin
> > │   ├── ...
> > │   └── ExistingThirdPartyPlugin
> > └── PluginTemplate
> >     ├── ...
> >     └── DirPlugin (cleaned up)
> > 
> > That way we could step by step "disentangle" the existing plugins from
> > each other without having to constantly keep the original behaviour(s)
> > of `Plugin` in the back of one's head and account for them. Instead,
> > each plugin would implement precisely what it itself needs.
> > 
> > Since both the old `Plugin` and the new `PluginTemplate` share the same
> > interface, namely `PluginBase`, we could still support the old `Plugin`
> > until everything's been moved over and third-party devs have had enough
> > time to adapt their own code, too.
>
> see above - we can do all of that without introducing PluginTemplate as
> well, including at some point no longer allowing third party plugins to
> re-use Plugin but force them to be based of PluginBase.
>
> > While doing all this, we could also rework parts of the API that didn't
> > age that gracefully, perhaps deprecate certain old methods, introduce
> > new methods, etc. as we'd have a "clean" break, sotospeak.
>
> this could also be done without moving all plugins over to
> PluginTemplate, although it might be a bit more messy/dangerous.
>
> > So, to summarize my idea:
> > - Keep `PluginBase` as it is right now, but also include
> >   SectionConfig-related code
> > - Introduce `PluginTemplate` with minimal implementation later down the
> >   line on the same inheritance layer as `Plugin`
> > - Slowly migrate our plugins, basing them off of `PluginTemplate` while
> >   tossing out old code, making them independent from one another, and
> >   collecting shared helpers in `PVE::Storage::Common::*`
> > 
> > I'd really like to hear your thoughts on this, because I'm not sure if
> > this is *actually* feasible or provides any ROI down the line. One
> > alternative that I can think of is to just keep the inheritance
> > hierarchy as it is (as in this series) and disentangle the plugins as
> > they are right now, without changing their parent (so, almost the same
> > as your second idea). I did start breaking apart our plugins like that
> > last year, but that was too much all at once [1].
> > 
> > [1]: https://lore.proxmox.com/pve-devel/20240717094034.124857-1-m.carrara@proxmox.com/
>
>
> _______________________________________________
> pve-devel mailing list
> pve-devel@lists.proxmox.com
> https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

  reply	other threads:[~2025-04-03 14:06 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-03-26 14:20 [pve-devel] [PATCH v1 pve-storage 0/8] Base Module + Documentation for PVE::Storage::Plugin API Max Carrara
2025-03-26 14:20 ` [pve-devel] [PATCH v1 pve-storage 1/8] pluginbase: introduce PVE::Storage::PluginBase with doc scaffold Max Carrara
2025-03-31 15:13   ` Fabian Grünbichler
2025-04-02 16:31     ` Max Carrara
2025-04-03  7:12       ` Fabian Grünbichler
2025-04-03 14:05         ` Max Carrara
2025-03-26 14:20 ` [pve-devel] [PATCH v1 pve-storage 2/8] pluginbase: add high-level plugin API description Max Carrara
2025-03-31 15:13   ` Fabian Grünbichler
2025-04-02 16:31     ` Max Carrara
2025-04-03  7:12       ` Fabian Grünbichler
2025-04-03 14:05         ` Max Carrara [this message]
2025-03-26 14:20 ` [pve-devel] [PATCH v1 pve-storage 3/8] pluginbase: document SectionConfig methods Max Carrara
2025-03-31 15:13   ` Fabian Grünbichler
2025-04-02 16:31     ` Max Carrara
2025-03-26 14:20 ` [pve-devel] [PATCH v1 pve-storage 4/8] pluginbase: document general plugin methods Max Carrara
2025-03-28 12:50   ` Maximiliano Sandoval
2025-03-31 15:12   ` Fabian Grünbichler
2025-04-02 16:31     ` Max Carrara
2025-03-26 14:20 ` [pve-devel] [PATCH v1 pve-storage 5/8] pluginbase: document hooks Max Carrara
2025-03-28 13:07   ` Maximiliano Sandoval
2025-03-31 15:12   ` Fabian Grünbichler
2025-03-26 14:20 ` [pve-devel] [PATCH v1 pve-storage 6/8] pluginbase: document image operation methods Max Carrara
2025-03-31 15:12   ` Fabian Grünbichler
2025-04-02 16:32     ` Max Carrara
2025-04-03  7:23       ` Fabian Grünbichler
2025-04-03 14:05         ` Max Carrara
2025-03-26 14:20 ` [pve-devel] [PATCH v1 pve-storage 7/8] pluginbase: document volume operations Max Carrara
2025-03-31 15:12   ` Fabian Grünbichler
2025-04-02 16:32     ` Max Carrara
2025-03-26 14:20 ` [pve-devel] [PATCH v1 pve-storage 8/8] pluginbase: document import and export methods Max Carrara
2025-04-01  8:40   ` Fabian Grünbichler
2025-04-01  9:40     ` Fiona Ebner
2025-04-02 16:32     ` Max 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=D8X27CNS8UVI.OJ5BZRP2N01J@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
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal