Signed-off-by: Thomas Lamprecht <[email protected]>
---
 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 79c699d..6afb866 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);
@@ -127,82 +126,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


_______________________________________________
pve-devel mailing list
[email protected]
https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to