]> git.proxmox.com Git - pve-storage.git/commitdiff
plugin loader: add an APIAGE
authorWolfgang Bumiller <w.bumiller@proxmox.com>
Fri, 16 Nov 2018 12:54:44 +0000 (13:54 +0100)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Mon, 19 Nov 2018 09:47:46 +0000 (10:47 +0100)
With the addition of the map/unmap_volume() methods we made
an (actually unnecessary) API version bump.
All current users of these methods fall back to path() when
they return undef, so plugins implementing version 1 are
in fact compatible currently. (In fact, the default
Plugin::map_volume() could fall back to it on its own, but
doesn't currently).

For now let's just allow plugins older plugins to also be
loaded by introducing an API age variable. With it, if we
have a reason to break older plugins, we can have a
deprecation period during which older plugins cause a
warning instead of refusing to load altogether.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
PVE/Storage.pm

index a5f7fdb6a4f106cb03b25987e82f222e848b9ed8..64b3fc9a3ac36d113bff9cad98eca4264296f653 100755 (executable)
@@ -38,6 +38,10 @@ use PVE::Storage::DRBDPlugin;
 
 # Storage API version. Icrement it on changes in storage API interface.
 use constant APIVER => 2;
+# Age is the number of versions we're backward compatible with.
+# This is like having 'current=APIVER' and age='APIAGE' in libtool,
+# see https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html
+use constant APIAGE => 1;
 
 # load standard plugins
 PVE::Storage::DirPlugin->register();
@@ -65,18 +69,28 @@ if ( -d '/usr/share/perl5/PVE/Storage/Custom' ) {
 
        eval {
            require $file;
+
+           # Check perl interface:
+           die "not derived from PVE::Storage::Plugin\n"
+               if !$modname->isa('PVE::Storage::Plugin');
+           die "does not provide an api() method\n"
+               if !$modname->can('api');
+           # Check storage API version and that file is really storage plugin.
+           my $version = $modname->api();
+           die "implements an API version newer than current\n"
+               if $version > APIVER;
+           die "API version too old, pluse update the plugin\n"
+               if $version < (APIVER-APIAGE);
+           import $file;
+           $modname->register();
+
+           # If we got this far and the API version is not the same, make some
+           # noise:
+           warn "Plugin \"$modname\" is implementing an older storage API, an upgrade is recommended\n"
+               if $version != APIVER;
        };
        if ($@) {
-           warn $@;
-       # Check storage API version and that file is really storage plugin.
-       } elsif ($modname->isa('PVE::Storage::Plugin') && $modname->can('api') && $modname->api() == APIVER) {
-            eval {
-               import $file;
-               $modname->register();
-            };
-            warn $@ if $@;
-       } else {
-           warn "Error loading storage plugin \"$modname\" because of API version mismatch. Please, update it.\n"
+           warn "Error loading storage plugin \"$modname\": $@";
        }
     });
 }