[pve-devel] [PATCH RFC 15/21] PVE::API2::ClusterConfig: add API class for cluster configuration

Dietmar Maurer dietmar at proxmox.com
Mon Nov 28 08:09:07 CET 2016


Signed-off-by: Dietmar Maurer <dietmar at proxmox.com>
---
 data/PVE/API2/ClusterConfig.pm |  72 ++++++++++++++++++++++++++
 data/PVE/CLI/pvecm.pm          | 112 +++--------------------------------------
 data/PVE/Cluster.pm            |  99 ++++++++++++++++++++++++++++++++++++
 data/PVE/Makefile.am           |   3 ++
 4 files changed, 181 insertions(+), 105 deletions(-)
 create mode 100644 data/PVE/API2/ClusterConfig.pm

diff --git a/data/PVE/API2/ClusterConfig.pm b/data/PVE/API2/ClusterConfig.pm
new file mode 100644
index 0000000..5e6b09e
--- /dev/null
+++ b/data/PVE/API2/ClusterConfig.pm
@@ -0,0 +1,72 @@
+package PVE::API2::ClusterConfig;
+
+use strict;
+use warnings;
+use PVE::Tools;
+use PVE::SafeSyslog;
+use PVE::RESTHandler;
+use PVE::RPCEnvironment;
+use PVE::JSONSchema qw(get_standard_option);
+use PVE::AccessControl;
+use PVE::Cluster;
+use Data::Dumper;
+
+use base qw(PVE::RESTHandler);
+
+__PACKAGE__->register_method({
+    name => 'index',
+    path => '', 
+    method => 'GET',
+    description => "Directory index.",
+    parameters => {
+	additionalProperties => 0,
+	properties => {},
+    },
+    returns => {
+	type => 'array',
+	items => {
+	    type => "object",
+	    properties => {},
+	},
+	links => [ { rel => 'child', href => "{name}" } ],
+    },
+    code => sub {
+	my ($param) = @_;
+
+	my $result = [
+	    { name => 'nodes' },
+	    ];
+
+	return $result;
+    }});
+
+__PACKAGE__->register_method({
+    name => 'nodes',
+    path => 'nodes',
+    method => 'GET',
+    description => "Corosync node list.",
+    parameters => {
+    	additionalProperties => 0,
+	properties => {},
+    },
+    returns => {
+	type => 'array',
+	items => {
+	    type => "object",
+	    properties => {
+		node => { type => 'string' },
+	    },
+	},
+	links => [ { rel => 'child', href => "{node}" } ],
+    },
+    code => sub {
+	my ($param) = @_;
+
+
+	my $conf = PVE::Cluster::cfs_read_file('corosync.conf');
+	my $nodelist = PVE::Cluster::corosync_nodelist($conf);
+	
+	return PVE::RESTHandler::hash_to_array($nodelist, 'node');
+    }});
+
+1;
diff --git a/data/PVE/CLI/pvecm.pm b/data/PVE/CLI/pvecm.pm
index 9f6c479..b5b5311 100755
--- a/data/PVE/CLI/pvecm.pm
+++ b/data/PVE/CLI/pvecm.pm
@@ -11,10 +11,12 @@ use File::Basename;
 use Data::Dumper; # fixme: remove 
 use PVE::Tools;
 use PVE::Cluster;
+use PVE::API2::ClusterConfig;
 use PVE::INotify;
 use PVE::JSONSchema;
 use PVE::CLIHandler;
 
+
 use base qw(PVE::CLIHandler);
 
 $ENV{HOME} = '/root'; # for ssh-copy-id
@@ -327,9 +329,9 @@ __PACKAGE__->register_method ({
 
 	my $conf = PVE::Cluster::cfs_read_file("corosync.conf");
 
-	my $nodelist = corosync_nodelist($conf);
+	my $nodelist = PVE::Cluster::corosync_nodelist($conf);
 
-	my $totem_cfg = corosync_totem_config($conf);
+	my $totem_cfg = PVE::Cluster::corosync_totem_config($conf);
 
 	my $name = $param->{node};
 
@@ -386,7 +388,7 @@ __PACKAGE__->register_method ({
 	$nodelist->{$name}->{ring1_addr} = $param->{ring1_addr} if $param->{ring1_addr};
 	$nodelist->{$name}->{quorum_votes} = $param->{votes} if $param->{votes};
 	
-	corosync_update_nodelist($conf, $nodelist);
+	PVE::Cluster::corosync_update_nodelist($conf, $nodelist);
 	
 	exit (0);
     }});
@@ -415,7 +417,7 @@ __PACKAGE__->register_method ({
 
 	my $conf = PVE::Cluster::cfs_read_file("corosync.conf");
 
-	my $nodelist = corosync_nodelist($conf);
+	my $nodelist = PVE::Cluster::corosync_nodelist($conf);
 
 	my $node;
 	my $nodeid;
@@ -438,7 +440,7 @@ __PACKAGE__->register_method ({
 
 	delete $nodelist->{$node};
 
-	corosync_update_nodelist($conf, $nodelist);
+	PVE::Cluster::corosync_update_nodelist($conf, $nodelist);
 
 	PVE::Tools::run_command(['corosync-cfgtool','-k', $nodeid])
 	    if defined($nodeid);
@@ -687,106 +689,6 @@ __PACKAGE__->register_method ({
 
     }});
 
-sub corosync_update_nodelist {
-    my ($conf, $nodelist) = @_;
-
-    delete $conf->{digest};
-    
-    my $version = PVE::Cluster::corosync_conf_version($conf);
-    PVE::Cluster::corosync_conf_version($conf, undef, $version + 1);
-
-    my $children = [];
-    foreach my $v (values %$nodelist) {
-	next if !($v->{ring0_addr} || $v->{name});
-	my $kv = [];
-	foreach my $k (keys %$v) {
-	    push @$kv, { key => $k, value => $v->{$k} };
-	} 
-	my $ns = { section => 'node', children => $kv };
-	push @$children, $ns;
-    }
-    
-    foreach my $main (@{$conf->{children}}) {
-	next if !defined($main->{section});
-	if ($main->{section} eq 'nodelist') {
-	    $main->{children} = $children;
-	    last;
-	}
-    }
-
-    
-    PVE::Cluster::cfs_write_file("corosync.conf.new", $conf);
-    
-    rename("/etc/pve/corosync.conf.new", "/etc/pve/corosync.conf")
-	|| die "activate  corosync.conf.new failed - $!\n";
-}
-
-sub corosync_nodelist {
-    my ($conf) = @_;
-
-    my $nodelist = {};
-
-    foreach my $main (@{$conf->{children}}) {
-	next if !defined($main->{section});
-	if ($main->{section} eq 'nodelist') {
-	    foreach my $ne (@{$main->{children}}) {
-		next if !defined($ne->{section}) || ($ne->{section} ne 'node');
-		my $node = { quorum_votes => 1 };
-		my $name;
-		foreach my $child (@{$ne->{children}}) {
-		    next if !defined($child->{key});
-		    $node->{$child->{key}} = $child->{value};
-		    # use 'name' over 'ring0_addr' if set
-		    if ($child->{key} eq 'name') {
-			delete $nodelist->{$name} if $name;
-			$name = $child->{value};
-			$nodelist->{$name} = $node;
-		    } elsif(!$name && $child->{key} eq 'ring0_addr') {
-			$name = $child->{value};
-			$nodelist->{$name} = $node;
-		    }
-		}
-	    }
-	}
-    }   
-
-    return $nodelist;
-}
-
-# get a hash representation of the corosync config totem section
-sub corosync_totem_config {
-    my ($conf) = @_;
-
-    my $res = {};
-
-    foreach my $main (@{$conf->{children}}) {
-	next if !defined($main->{section}) ||
-	    $main->{section} ne 'totem';
-
-	foreach my $e (@{$main->{children}}) {
-
-	    if ($e->{section} && $e->{section} eq 'interface') {
-		my $entry = {};
-
-		$res->{interface} = {};
-
-		foreach my $child (@{$e->{children}}) {
-		    next if !defined($child->{key});
-		    $entry->{$child->{key}} = $child->{value};
-		    if($child->{key} eq 'ringnumber') {
-			$res->{interface}->{$child->{value}} = $entry;
-		    }
-		}
-
-	    } elsif  ($e->{key}) {
-		$res->{$e->{key}} = $e->{value};
-	    }
-	}
-    }
-
-    return $res;
-}
-
 __PACKAGE__->register_method ({
     name => 'updatecerts', 
     path => 'updatecerts',
diff --git a/data/PVE/Cluster.pm b/data/PVE/Cluster.pm
index 5223eb1..c1bfd6c 100644
--- a/data/PVE/Cluster.pm
+++ b/data/PVE/Cluster.pm
@@ -1714,6 +1714,105 @@ sub check_corosync_conf_exists {
     return $exists;
 }
 
+sub corosync_nodelist {
+    my ($conf) = @_;
+
+    my $nodelist = {};
+
+    foreach my $main (@{$conf->{children}}) {
+	next if !defined($main->{section});
+	if ($main->{section} eq 'nodelist') {
+	    foreach my $ne (@{$main->{children}}) {
+		next if !defined($ne->{section}) || ($ne->{section} ne 'node');
+		my $node = { quorum_votes => 1 };
+		my $name;
+		foreach my $child (@{$ne->{children}}) {
+		    next if !defined($child->{key});
+		    $node->{$child->{key}} = $child->{value};
+		    # use 'name' over 'ring0_addr' if set
+		    if ($child->{key} eq 'name') {
+			delete $nodelist->{$name} if $name;
+			$name = $child->{value};
+			$nodelist->{$name} = $node;
+		    } elsif(!$name && $child->{key} eq 'ring0_addr') {
+			$name = $child->{value};
+			$nodelist->{$name} = $node;
+		    }
+		}
+	    }
+	}
+    }
+
+    return $nodelist;
+}
+
+sub corosync_update_nodelist {
+    my ($conf, $nodelist) = @_;
+
+    delete $conf->{digest};
+
+    my $version = corosync_conf_version($conf);
+    corosync_conf_version($conf, undef, $version + 1);
+
+    my $children = [];
+    foreach my $v (values %$nodelist) {
+	next if !($v->{ring0_addr} || $v->{name});
+	my $kv = [];
+	foreach my $k (keys %$v) {
+	    push @$kv, { key => $k, value => $v->{$k} };
+	}
+	my $ns = { section => 'node', children => $kv };
+	push @$children, $ns;
+    }
+
+    foreach my $main (@{$conf->{children}}) {
+	next if !defined($main->{section});
+	if ($main->{section} eq 'nodelist') {
+	    $main->{children} = $children;
+	    last;
+	}
+    }
+
+    cfs_write_file("corosync.conf.new", $conf);
+
+    rename("/etc/pve/corosync.conf.new", "/etc/pve/corosync.conf")
+	|| die "activate  corosync.conf.new failed - $!\n";
+}
+
+# get a hash representation of the corosync config totem section
+sub corosync_totem_config {
+    my ($conf) = @_;
+
+    my $res = {};
+
+    foreach my $main (@{$conf->{children}}) {
+	next if !defined($main->{section}) ||
+	    $main->{section} ne 'totem';
+
+	foreach my $e (@{$main->{children}}) {
+
+	    if ($e->{section} && $e->{section} eq 'interface') {
+		my $entry = {};
+
+		$res->{interface} = {};
+
+		foreach my $child (@{$e->{children}}) {
+		    next if !defined($child->{key});
+		    $entry->{$child->{key}} = $child->{value};
+		    if($child->{key} eq 'ringnumber') {
+			$res->{interface}->{$child->{value}} = $entry;
+		    }
+		}
+
+	    } elsif  ($e->{key}) {
+		$res->{$e->{key}} = $e->{value};
+	    }
+	}
+    }
+
+    return $res;
+}
+
 # X509 Certificate cache helper
 
 my $cert_cache_nodes = {};
diff --git a/data/PVE/Makefile.am b/data/PVE/Makefile.am
index b284e7f..0d89e63 100644
--- a/data/PVE/Makefile.am
+++ b/data/PVE/Makefile.am
@@ -33,6 +33,9 @@ noinst_DATA = pvecm.bash-completion
 cliclass_DATA = CLI/pvecm.pm
 cliclassdir = $(PERL_VENDORLIB)/PVE/CLI
 
+apiclass_DATA = API2/ClusterConfig.pm
+apiclassdir = $(PERL_VENDORLIB)/PVE/API2
+
 install-exec-hook: pvecm.bash-completion
 	perl -I.. -T -e "use PVE::CLI::pvecm; PVE::CLI::pvecm->verify_api();"
 	install -m 0644 -D pvecm.bash-completion ${DESTDIR}/usr/share/bash-completion/completions/pvecm
-- 
2.1.4




More information about the pve-devel mailing list