[pve-devel] [PATCH RFC 19/21] use https API call for addnode
Dietmar Maurer
dietmar at proxmox.com
Mon Nov 28 08:09:11 CET 2016
And remove 'addnode' from pvecm command line tool. It has too
many parameters now, and confuses the user anyways ('add' is
the correct command for the user).
Signed-off-by: Dietmar Maurer <dietmar at proxmox.com>
---
data/PVE/API2/ClusterConfig.pm | 51 +++++++++++++++--
data/PVE/CLI/pvecm.pm | 123 ++++++++++++++++++++---------------------
2 files changed, 106 insertions(+), 68 deletions(-)
diff --git a/data/PVE/API2/ClusterConfig.pm b/data/PVE/API2/ClusterConfig.pm
index 6ac2378..7398621 100644
--- a/data/PVE/API2/ClusterConfig.pm
+++ b/data/PVE/API2/ClusterConfig.pm
@@ -99,19 +99,41 @@ __PACKAGE__->register_method ({
},
ring0_addr => {
type => 'string', format => 'address',
- description => "Hostname (or IP) of the corosync ring0 address of this node.".
- " Defaults to nodes hostname.",
+ 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 bindnet1_addr.",
+ description => "Hostname (or IP) of the corosync ring1 address, this needs an valid bindnet1_addr.",
optional => 1,
},
+ ssh_host_pubkey => {
+ type => 'string',
+ description => "Contents of /etc/ssh/ssh_host_rsa_key.pub from joining node.",
+ },
+ ssh_root_pubkey => {
+ type => 'string',
+ description => "Contents of /root/.ssh/id_rsa.pub from joining node.",
+ },
+ },
+ },
+ returns => {
+ type => "object",
+ properties => {
+ ssh_host_cert => {
+ type => 'string',
+ },
+ ssh_root_cert => {
+ type => 'string',
+ },
+ corosync_authkey => {
+ type => 'string',
+ },
+ corosync_conf => {
+ type => 'string',
+ }
},
},
- returns => { type => 'null' },
code => sub {
my ($param) = @_;
@@ -180,7 +202,24 @@ __PACKAGE__->register_method ({
PVE::Cluster::corosync_update_nodelist($conf, $nodelist);
- return undef;
+ my $res = {};
+
+ $res->{ssh_host_cert} = PVE::Cluster::gen_pve_ssh_cert(
+ $param->{ssh_host_pubkey}, $name, "PVE-HOST-$name", 1);
+ $res->{ssh_root_cert} = PVE::Cluster::gen_pve_ssh_cert(
+ $param->{ssh_root_pubkey}, 'root', "PVE-ROOT-$name");
+
+ my $basedir = "/etc/pve";
+ my $clusterconf = "$basedir/corosync.conf";
+ my $authfile = "/etc/corosync/authkey";
+
+ $res->{corosync_authkey} =
+ PVE::Tools::file_get_contents($authfile);
+
+ $res->{corosync_conf} =
+ PVE::Tools::file_get_contents($clusterconf);
+
+ return $res;
}});
diff --git a/data/PVE/CLI/pvecm.pm b/data/PVE/CLI/pvecm.pm
index 5063b4e..4bc406a 100755
--- a/data/PVE/CLI/pvecm.pm
+++ b/data/PVE/CLI/pvecm.pm
@@ -29,10 +29,15 @@ $ENV{HOME} = '/root'; # for ssh-copy-id
my $basedir = "/etc/pve";
my $clusterconf = "$basedir/corosync.conf";
+my $localclusterconf = "/etc/corosync/corosync.conf";
my $libdir = "/var/lib/pve-cluster";
my $backupdir = "/var/lib/pve-cluster/backup";
my $dbfile = "$libdir/config.db";
my $authfile = "/etc/corosync/authkey";
+my $ssh_rsa_id = "/root/.ssh/id_rsa.pub";
+my $ssh_rsa_cert = "/root/.ssh/id_rsa-cert.pub";
+my $ssh_host_rsa_id = "/etc/ssh/ssh_host_rsa_key.pub";
+my $ssh_host_rsa_cert = "/etc/ssh/ssh_host_rsa_key-cert.pub";
sub read_password {
my $term = new Term::ReadLine ('pvecm');
@@ -499,92 +504,87 @@ __PACKAGE__->register_method ({
# make sure known_hosts is on local filesystem
PVE::Cluster::ssh_unmerge_known_hosts();
- my $cmd = ['ssh-copy-id', '-i', '/root/.ssh/id_rsa', "root\@$host"];
- PVE::Tools::run_command($cmd, 'outfunc' => sub {}, 'errfunc' => sub {},
- 'errmsg' => "unable to copy ssh ID");
+ # call addnode on remote cluster
- $cmd = ['ssh', $host, '-o', 'BatchMode=yes',
- 'pvecm', 'addnode', $nodename, '--force', 1];
+ my $password = read_password();
- push @$cmd, '--nodeid', $param->{nodeid} if $param->{nodeid};
-
- push @$cmd, '--votes', $param->{votes} if defined($param->{votes});
+ # load certs for all existing nodes
+ my $nodelist = PVE::Cluster::get_nodelist();
+ foreach my $n (@$nodelist) {
+ PVE::Cluster::initialize_cert_cache($n);
+ }
- push @$cmd, '--ring0_addr', $param->{ring0_addr} if defined($param->{ring0_addr});
+ my $agent = api2_connect($host, $password);
- push @$cmd, '--ring1_addr', $param->{ring1_addr} if defined($param->{ring1_addr});
+ my $ssh_root_pubkey = PVE::Tools::file_get_contents($ssh_rsa_id);
+ my $ssh_host_pubkey = PVE::Tools::file_get_contents($ssh_host_rsa_id);
- if (system (@$cmd) != 0) {
- my $cmdtxt = join (' ', @$cmd);
- die "unable to add node: command failed ($cmdtxt)\n";
- }
+ my $args = {
+ node => $nodename,
+ force => 1, # fixme: why?
+ ssh_root_pubkey => $ssh_root_pubkey,
+ ssh_host_pubkey => $ssh_host_pubkey,
+ };
- my $tmpdir = "$libdir/.pvecm_add.tmp.$$";
- mkdir $tmpdir;
+ $args->{nodeid} = $param->{nodeid} if $param->{nodeid};
- eval {
- print "copy corosync auth key\n";
- $cmd = ['rsync', '--rsh=ssh -l root -o BatchMode=yes', '-lpgoq',
- "[$host]:$authfile $clusterconf", $tmpdir];
+ $args->{votes} = $param->{votes} if defined($param->{votes});
- system(@$cmd) == 0 || die "can't rsync data from host '$host'\n";
+ $args->{ring0_addr} = $param->{ring0_addr} if defined($param->{ring0_addr});
- mkdir "/etc/corosync";
- my $confbase = basename($clusterconf);
+ $args->{ring1_addr} = $param->{ring1_addr} if defined($param->{ring1_addr});
- $cmd = "cp '$tmpdir/$confbase' '/etc/corosync/$confbase'";
- system($cmd) == 0 || die "can't copy cluster configuration\n";
+ my $data = api2_post($agent, $host, 'cluster/addnode', $args);
- my $keybase = basename($authfile);
- system ("cp '$tmpdir/$keybase' '$authfile'") == 0 ||
- die "can't copy '$tmpdir/$keybase' to '$authfile'\n";
+ # added successfuly - now prepare local node
- print "stopping pve-cluster service\n";
+ PVE::Tools::file_set_contents($ssh_host_rsa_cert, $data->{ssh_host_cert});
+ PVE::Tools::file_set_contents($ssh_rsa_cert, $data->{ssh_root_cert});
- system("umount $basedir -f >/dev/null 2>&1");
- system("systemctl stop pve-cluster") == 0 ||
- die "can't stop pve-cluster service\n";
+ mkdir "/etc/corosync";
+ PVE::Tools::file_set_contents($localclusterconf, $data->{corosync_conf});
+ PVE::Tools::file_set_contents($authfile, $data->{corosync_authkey});
- backup_database();
+ print "stopping pve-cluster service\n";
- unlink $dbfile;
+ system("umount $basedir -f >/dev/null 2>&1");
+ system("systemctl stop pve-cluster") == 0 ||
+ die "can't stop pve-cluster service\n";
- system("systemctl start pve-cluster") == 0 ||
- die "starting pve-cluster failed\n";
+ backup_database();
- system("systemctl start corosync");
+ unlink $dbfile;
- # wait for quorum
- my $printqmsg = 1;
- while (!PVE::Cluster::check_cfs_quorum(1)) {
- if ($printqmsg) {
- print "waiting for quorum...";
- STDOUT->flush();
- $printqmsg = 0;
- }
- sleep(1);
- }
- print "OK\n" if !$printqmsg;
+ system("systemctl start pve-cluster") == 0 ||
+ die "starting pve-cluster failed\n";
- # system("systemctl start clvm");
+ system("systemctl start corosync");
- my $local_ip_address = PVE::Cluster::remote_node_ip($nodename);
+ # wait for quorum
+ my $printqmsg = 1;
+ while (!PVE::Cluster::check_cfs_quorum(1)) {
+ if ($printqmsg) {
+ print "waiting for quorum...";
+ STDOUT->flush();
+ $printqmsg = 0;
+ }
+ sleep(1);
+ }
+ print "OK\n" if !$printqmsg;
- $update_cluster_files->(1, $nodename, $local_ip_address, 1);
+ # system("systemctl start clvm");
- print "restart services\n";
- # restart pvedaemon (changed certs)
- system("systemctl restart pvedaemon");
- # restart pveproxy (changed certs)
- system("systemctl restart pveproxy");
+ my $local_ip_address = PVE::Cluster::remote_node_ip($nodename);
- print "successfully added node '$nodename' to cluster.\n";
- };
- my $err = $@;
+ $update_cluster_files->(1, $nodename, $local_ip_address, 1);
- rmtree $tmpdir;
+ print "restart services\n";
+ # restart pvedaemon (changed certs)
+ system("systemctl restart pvedaemon");
+ # restart pveproxy (changed certs)
+ system("systemctl restart pveproxy");
- die $err if $err;
+ print "successfully added node '$nodename' to cluster.\n";
return undef;
}});
@@ -763,7 +763,6 @@ our $cmddef = {
keygen => [ __PACKAGE__, 'keygen', ['filename']],
create => [ __PACKAGE__, 'create', ['clustername']],
add => [ __PACKAGE__, 'add', ['hostname']],
- addnode => [ 'PVE::API2::ClusterConfig', 'addnode', ['node']],
delnode => [ 'PVE::API2::ClusterConfig', 'delnode', ['node']],
status => [ __PACKAGE__, 'status' ],
nodes => [ __PACKAGE__, 'nodes' ],
--
2.1.4
More information about the pve-devel
mailing list