[pve-devel] [RFC cluster v2 04/10] api: add joint cluster endpoint

Thomas Lamprecht t.lamprecht at proxmox.com
Wed Dec 6 16:35:47 CET 2017


On 12/06/2017 04:04 PM, Fabian Grünbichler wrote:
> this one definitely needs to get a worker! we have a 30s timeout
> otherwise..
> 

Agreed, I'll change it for v3.

> On Mon, Dec 04, 2017 at 12:11:11PM +0100, Thomas Lamprecht wrote:
>> Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
>> ---
>>  data/PVE/API2/ClusterConfig.pm | 125 ++++++++++++++++++++++++++++++++++++++++-
>>  debian/control.in              |   2 +
>>  2 files changed, 126 insertions(+), 1 deletion(-)
>>
>> diff --git a/data/PVE/API2/ClusterConfig.pm b/data/PVE/API2/ClusterConfig.pm
>> index c38feb2..9a4d9f5 100644
>> --- a/data/PVE/API2/ClusterConfig.pm
>> +++ b/data/PVE/API2/ClusterConfig.pm
>> @@ -9,6 +9,7 @@ use PVE::RESTHandler;
>>  use PVE::RPCEnvironment;
>>  use PVE::JSONSchema qw(get_standard_option);
>>  use PVE::Cluster;
>> +use PVE::APIClient::LWP;
>>  use PVE::Corosync;
>>  
>>  use base qw(PVE::RESTHandler);
>> @@ -39,7 +40,8 @@ __PACKAGE__->register_method({
>>  	my $result = [
>>  	    { name => 'nodes' },
>>  	    { name => 'totem' },
>> -	    ];
>> +	    { name => 'join' },
>> +	];
>>  
>>  	return $result;
>>      }});
>> @@ -96,6 +98,127 @@ my $config_change_lock = sub {
>>  
>>  
>>  __PACKAGE__->register_method ({
>> +    name => 'join',
>> +    path => 'join',
>> +    method => 'POST',
>> +    description => "Joins this node to an existing cluster.",
>> +    parameters => {
>> +	additionalProperties => 0,
>> +	properties => {
>> +	    hostname => {
>> +		type => 'string',
>> +		description => "Hostname (or IP) of an existing cluster member."
>> +	    },
>> +	    nodeid => {
>> +		type => 'integer',
>> +		description => "Node id for this node.",
>> +		minimum => 1,
>> +		optional => 1,
>> +	    },
>> +	    votes => {
>> +		type => 'integer',
>> +		description => "Number of votes for this node",
>> +		minimum => 0,
>> +		optional => 1,
>> +	    },
>> +	    force => {
>> +		type => 'boolean',
>> +		description => "Do not throw error if node already exists.",
>> +		optional => 1,
>> +	    },
>> +	    ring0_addr => {
>> +		type => 'string', format => 'address',
>> +		description => "Hostname (or IP) of the corosync ring0 address of this node.".
>> +		    " Defaults to nodes hostname.",
>> +		optional => 1,
>> +	    },
>> +	    ring1_addr => {
>> +		type => 'string', format => 'address',
>> +		description => "Hostname (or IP) of the corosync ring1 address, this".
>> +		    " needs an valid configured ring 1 interface in the cluster.",
>> +		optional => 1,
>> +	    },
>> +	    fingerprint => {
>> +		description => "SSL certificate fingerprint. Optional in CLI environment.",
>> +		type => 'string',
>> +		pattern => '^(:?[A-Z0-9][A-Z0-9]:){31}[A-Z0-9][A-Z0-9]$',
>> +		optional => 1,
>> +	    },
>> +	    password => {
>> +		description => "Superuser (root) password of peer node.",
>> +		type => 'string',
>> +		maxLength => 128,
>> +	    },
>> +	},
>> +    },
>> +    returns => { type => 'null' },
>> +
>> +    code => sub {
>> +	my ($param) = @_;
>> +
>> +	my $nodename = PVE::INotify::nodename();
>> +	my $rpcenv = PVE::RPCEnvironment::get();
>> +
>> +	PVE::Cluster::setup_sshd_config();
>> +	PVE::Cluster::setup_rootsshconfig();
>> +	PVE::Cluster::setup_ssh_keys();
>> +
>> +	# check if we can join with the given parameters and current node state
>> +	PVE::Cluster::assert_joinable($param->{ring0_addr}, $param->{ring1_addr}, $param->{force});
>> +
>> +	# make sure known_hosts is on local filesystem
>> +	PVE::Cluster::ssh_unmerge_known_hosts();
>> +
>> +	my $host = $param->{hostname};
>> +
>> +	my $conn_args = {
>> +	    username => 'root at pam',
>> +	    password => $param->{password},
>> +	    cookie_name => 'PVEAuthCookie',
>> +	    protocol => 'https',
>> +	    host => $host,
>> +	    port => 8006,
>> +	};
>> +
>> +	if (my $fp = $param->{fingerprint}) {
>> +	    $conn_args->{cached_fingerprints} = { $fp => 1 };
>> +	} elsif ($rpcenv->{type} eq 'cli') {
>> +	    $conn_args->{manual_verification} = 1;
>> +	} else {
>> +	    raise_param_exc({
>> +		fingerprint => "Param 'fingerprint' only optional in interactive CLI environment."
>> +	    });
>> +	}
>> +
>> +	print "Etablishing API connection with host '$host'\n";
>> +
>> +	my $conn = PVE::APIClient::LWP->new(%$conn_args);
>> +	$conn->login();
>> +
>> +	print "Login succeeded.\n";
>> +
>> +	my $args = {
>> +	    node => $nodename,
>> +	};
>> +	$args->{force} = $param->{force} if defined($param->{force});
>> +	$args->{nodeid} = $param->{nodeid} if $param->{nodeid};
>> +	$args->{votes} = $param->{votes} if defined($param->{votes});
>> +	$args->{ring0_addr} = $param->{ring0_addr} if defined($param->{ring0_addr});
>> +	$args->{ring1_addr} = $param->{ring1_addr} if defined($param->{ring1_addr});
>> +
>> +	print "Request addition of this node\n";
>> +
>> +	my $res = $conn->post("/cluster/config/nodes", $args);
>> +
>> +	# added successfuly - now prepare local node
>> +
>> +	PVE::Cluster::finish_join($nodename, $res->{corosync_conf}, $res->{corosync_authkey});
>> +
>> +	return undef;
>> +    }});
>> +
>> +
>> +__PACKAGE__->register_method ({
>>      name => 'addnode',
>>      path => 'nodes',
>>      method => 'POST',
>> diff --git a/debian/control.in b/debian/control.in
>> index e6ccc90..2fce9f4 100644
>> --- a/debian/control.in
>> +++ b/debian/control.in
>> @@ -21,6 +21,7 @@ Build-Depends: debhelper (>= 7),
>>                 libdigest-hmac-perl,
>>                 dh-systemd,
>>                 pve-doc-generator,
>> +               libpve-apiclient-perl,
>>                 libuuid-perl
>>  Standards-Version: 3.7.3
>>  
>> @@ -47,6 +48,7 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}, @PERLAPI@,
>>           faketime,
>>           libcrypt-ssleay-perl,
>>           libuuid-perl,
>> +         libpve-apiclient-perl,
>>           lsb-base
>>  Breaks: pve-ha-manager (<<2.0-4)
>>  Description: Cluster Infrastructure for Proxmox Virtual Environment
>> -- 
>> 2.11.0
>>






More information about the pve-devel mailing list