[pve-devel] [PATCH cluster 4/5] Add cluster join API version check

Thomas Lamprecht t.lamprecht at proxmox.com
Thu Nov 21 15:35:16 CET 2019


On 11/20/19 5:43 PM, Stefan Reiter wrote:
> Adds API call GET /cluster/config/apiversion to retrieve remote clusters
> join-API version (0 is assumed for versions without this endpoint).
> 
> Warn user if remote version differs, and select new fallback method only
> if available. This ensures full compatibility between nodes/clusters
> with and without new fallback behaviour.
> 
> Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
> ---
> 
> Technically optional, but needed to ensure full compatibility across versions
> before and after this series.

can we have a APIVERSION and APIAGE ?
I.e., APIVERSION for newest feature set and APIAGE for oldest (APIVERSION - APIAGE)
still compatible? It has bitten us in storage plugin ABI so I'd like to start here
out with this.

> 
>  data/PVE/API2/ClusterConfig.pm | 18 ++++++++++++++++++
>  data/PVE/Cluster/Setup.pm      | 16 ++++++++++++++--
>  2 files changed, 32 insertions(+), 2 deletions(-)
> 
> diff --git a/data/PVE/API2/ClusterConfig.pm b/data/PVE/API2/ClusterConfig.pm
> index 2d15f97..bff0c48 100644
> --- a/data/PVE/API2/ClusterConfig.pm
> +++ b/data/PVE/API2/ClusterConfig.pm
> @@ -58,11 +58,29 @@ __PACKAGE__->register_method({
>  	    { name => 'totem' },
>  	    { name => 'join' },
>  	    { name => 'qdevice' },
> +	    { name => 'apiversion' },
>  	];
>  
>  	return $result;
>      }});
>  
> +__PACKAGE__->register_method ({
> +    name => 'join_api_version',
> +    path => 'apiversion',
> +    method => 'GET',
> +    description => "Return the version of the cluster join API available on this node.",
> +    permissions => {
> +	check => ['perm', '/', [ 'Sys.Audit' ]],
> +    },
> +    parameters => {
> +	additionalProperties => 0,
> +	properties => {},
> +    },
> +    returns => { type => 'integer' },
> +    code => sub {
> +	return PVE::Cluster::Setup::JOIN_API_VERSION;
> +    }});
> +
>  __PACKAGE__->register_method ({
>      name => 'create',
>      path => '',
> diff --git a/data/PVE/Cluster/Setup.pm b/data/PVE/Cluster/Setup.pm
> index 9850299..c6f6c9e 100644
> --- a/data/PVE/Cluster/Setup.pm
> +++ b/data/PVE/Cluster/Setup.pm
> @@ -19,6 +19,8 @@ use PVE::JSONSchema;
>  use PVE::Network;
>  use PVE::Tools;
>  
> +use constant JOIN_API_VERSION => 1;
> +
>  my $pmxcfs_base_dir = PVE::Cluster::base_dir();
>  my $pmxcfs_auth_dir = PVE::Cluster::auth_dir();
>  
> @@ -660,6 +662,13 @@ sub join {
>      # login raises an exception on failure, so if we get here we're good
>      print "Login succeeded.\n";
>  
> +    # check cluster join API version and warn user
> +    my $apiver = eval { $conn->get("/cluster/config/apiversion"); } // 0;
> +    warn "warning: local join API version (" . JOIN_API_VERSION . ") differs"
> +       . " from remote ($apiver), make sure all nodes are upgraded to the"
> +       . " latest version. Cluster join might fail!\n"
> +	if $apiver != JOIN_API_VERSION;
> +
>      my $args = {};
>      $args->{force} = $param->{force} if defined($param->{force});
>      $args->{nodeid} = $param->{nodeid} if $param->{nodeid};
> @@ -668,8 +677,11 @@ sub join {
>  	$args->{"link$link"} = PVE::Corosync::print_corosync_link($links->{$link});
>      }
>  
> -    # this will be used as fallback if no links are specified
> -    $args->{new_node_ip} = $local_ip_address;
> +    # specify fallback if no links are given according to remote api version
> +    if (!%$links) {
> +	$args->{link0} = $local_ip_address if $apiver == 0;
> +	$args->{new_node_ip} = $local_ip_address if $apiver >= 1;
> +    }
>  
>      print "No local links given, will attempt fallback to $local_ip_address\n"
>  	if !%$links;
> 





More information about the pve-devel mailing list