[pve-devel] [RFC cluster v2 07/10] cluster create: factor out initial corosync config assembly

Thomas Lamprecht t.lamprecht at proxmox.com
Mon Dec 4 12:11:14 CET 2017


Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
---
 data/PVE/CLI/pvecm.pm | 77 ++++-----------------------------------------------
 data/PVE/Corosync.pm  | 73 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+), 71 deletions(-)

diff --git a/data/PVE/CLI/pvecm.pm b/data/PVE/CLI/pvecm.pm
index 07ae0af..553dbee 100755
--- a/data/PVE/CLI/pvecm.pm
+++ b/data/PVE/CLI/pvecm.pm
@@ -3,7 +3,6 @@ package PVE::CLI::pvecm;
 use strict;
 use warnings;
 
-use Net::IP;
 use File::Path;
 use File::Basename;
 use PVE::Tools qw(run_command);
@@ -129,82 +128,18 @@ __PACKAGE__->register_method ({
 	PVE::Cluster::setup_ssh_keys();
 
 	-f $authfile || __PACKAGE__->keygen({filename => $authfile});
-
 	-f $authfile || die "no authentication key available\n";
 
-	my $clustername = $param->{clustername};
-
-	$param->{nodeid} = 1 if !$param->{nodeid};
-
-	$param->{votes} = 1 if !defined($param->{votes});
-
 	my $nodename = PVE::INotify::nodename();
 
+	# get the corosync basis config for the new cluster
+	my $config = PVE::Corosync::create_conf($nodename, %$param);
+
+	print "Writing corosync config to /etc/corosync/corosync.conf\n";
+	PVE::Corosync::atomic_write_conf($config);
+
 	my $local_ip_address = PVE::Cluster::remote_node_ip($nodename);
 
-	$param->{bindnet0_addr} = $local_ip_address
-	    if !defined($param->{bindnet0_addr});
-
-	$param->{ring0_addr} = $nodename if !defined($param->{ring0_addr});
-
-	die "Param bindnet1_addr and ring1_addr are dependend, use both or none!\n"
-	    if (defined($param->{bindnet1_addr}) != defined($param->{ring1_addr}));
-
-	my $bind_is_ipv6 = Net::IP::ip_is_ipv6($param->{bindnet0_addr});
-
-	# use string as here-doc format distracts more
-	my $interfaces = "interface {\n    ringnumber: 0\n" .
-	    "    bindnetaddr: $param->{bindnet0_addr}\n  }";
-
-	my $ring_addresses = "ring0_addr: $param->{ring0_addr}" ;
-
-	# allow use of multiple rings (rrp) at cluster creation time
-	if ($param->{bindnet1_addr}) {
-	    die "IPv6 and IPv4 cannot be mixed, use one or the other!\n"
-		if Net::IP::ip_is_ipv6($param->{bindnet1_addr}) != $bind_is_ipv6;
-
-	    $interfaces .= "\n  interface {\n    ringnumber: 1\n" .
-		"    bindnetaddr: $param->{bindnet1_addr}\n  }\n";
-
-	    $interfaces .= "rrp_mode: passive\n"; # only passive is stable and tested
-
-	    $ring_addresses .= "\n    ring1_addr: $param->{ring1_addr}";
-	}
-
-	# No, corosync cannot deduce this on its own
-	my $ipversion = $bind_is_ipv6 ? 'ipv6' : 'ipv4';
-
-	my $config = <<_EOD;
-totem {
-  version: 2
-  secauth: on
-  cluster_name: $clustername
-  config_version: 1
-  ip_version: $ipversion
-  $interfaces
-}
-
-nodelist {
-  node {
-    $ring_addresses
-    name: $nodename
-    nodeid: $param->{nodeid}
-    quorum_votes: $param->{votes}
-  }
-}
-
-quorum {
-  provider: corosync_votequorum
-}
-
-logging {
-  to_syslog: yes
-  debug: off
-}
-_EOD
-;
-	PVE::Tools::file_set_contents($clusterconf, $config);
-
 	PVE::Cluster::ssh_merge_keys();
 
 	PVE::Cluster::gen_pve_node_files($nodename, $local_ip_address);
diff --git a/data/PVE/Corosync.pm b/data/PVE/Corosync.pm
index cf88022..35af087 100644
--- a/data/PVE/Corosync.pm
+++ b/data/PVE/Corosync.pm
@@ -5,6 +5,7 @@ use warnings;
 
 use Digest::SHA;
 use Clone 'clone';
+use Net::IP qw(ip_is_ipv6);
 
 use PVE::Cluster;
 
@@ -181,4 +182,76 @@ sub atomic_write_conf {
 	|| die "activating corosync.conf.new failed - $!\n";
 }
 
+# for creating a new cluster with the current node
+# params are those from the API/CLI cluster create call
+sub create_conf {
+    my ($nodename, %param) = @_;
+
+    my $clustername = $param{clustername};
+    my $nodeid = $param{nodeid} || 1;
+    my $votes = $param{votes} || 1;
+
+    my $local_ip_address = PVE::Cluster::remote_node_ip($nodename);
+    my $ring0_addr = $param{ring0_addr} // $local_ip_address;
+    my $bindnet0_addr = $param{bindnet0_addr} // $local_ip_address;
+
+    my $use_ipv6 = ip_is_ipv6($ring0_addr);
+    die "ring 0 addresses must be from same IP family!\n"
+	if $use_ipv6 != ip_is_ipv6($bindnet0_addr);
+
+    my $conf = {
+	totem => {
+	    version => 2, # protocol version
+	    secauth => 'on',
+	    cluster_name => $clustername,
+	    config_version => 0,
+	    ip_version => $use_ipv6 ? 'ipv6' : 'ipv4',
+	    interface => {
+		0 => {
+		    bindnetaddr => $bindnet0_addr,
+		    ringnumber => 0,
+		},
+	    },
+	},
+	nodelist => {
+	    node => {
+		$nodename => {
+		    name => $nodename,
+		    nodeid => $nodeid,
+		    quorum_votes => $votes,
+		    ring0_addr => $ring0_addr,
+		},
+	    },
+	},
+	quorum => {
+	    provider => 'corosync_votequorum',
+	},
+	logging => {
+	    to_syslog => 'yes',
+	    debug => 'off',
+	},
+    };
+
+    die "Param bindnet1_addr set but ring1_addr not specified!\n"
+	if (defined($param{bindnet1_addr}) && !defined($param{ring1_addr}));
+
+    my $ring1_addr = $param{ring1_addr};
+    my $bindnet1_addr = $param{bindnet1_addr} // $param{ring1_addr};
+
+    if ($bindnet1_addr) {
+	die "ring 1 addresses must be from same IP family as ring 0!\n"
+	    if $use_ipv6 != ip_is_ipv6($bindnet1_addr) ||
+	       $use_ipv6 != ip_is_ipv6($ring1_addr);
+
+	$conf->{totem}->{interface}->{1} = {
+	    bindnetaddr => $bindnet1_addr,
+	    ringnumber => 1,
+	};
+	$conf->{totem}->{rrp_mode} = 'passive';
+	$conf->{nodelist}->{node}->{$nodename}->{ring1_addr} = $ring1_addr;
+    }
+
+    return { main => $conf };
+}
+
 1;
-- 
2.11.0





More information about the pve-devel mailing list