mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-31 03:12:30 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			2005 lines
		
	
	
		
			67 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			2005 lines
		
	
	
		
			67 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| #!/usr/bin/env perl
 | |
| # IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
 | |
| package xCAT_plugin::monctrlcmds;
 | |
| 
 | |
| BEGIN
 | |
| {
 | |
|     $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
 | |
| }
 | |
| use lib "$::XCATROOT/lib/perl";
 | |
| use strict;
 | |
| use xCAT::NodeRange;
 | |
| use xCAT::Table;
 | |
| use xCAT::MsgUtils;
 | |
| use xCAT_monitoring::monitorctrl;
 | |
| use xCAT::Utils;
 | |
| use Sys::Hostname;
 | |
| use Data::Dumper;
 | |
| 
 | |
| 
 | |
| 1;
 | |
| 
 | |
| 
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| =head1  xCAT_plugin:monctrlcmds
 | |
| =head2    Package Description
 | |
|   xCAT monitoring control commands plugini module. This modules handles
 | |
|   monitoring related commands.
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| 
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   handled_commands
 | |
|       It returns a list of commands handled by this plugin.
 | |
|     Arguments:
 | |
|         none
 | |
|     Returns:
 | |
|         a list of commands.
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub handled_commands {
 | |
|     return {
 | |
|         monstart => "monctrlcmds",
 | |
|         monstop  => "monctrlcmds",
 | |
|         monls    => "monctrlcmds",
 | |
|         monadd   => "monctrlcmds",
 | |
|         monrm    => "monctrlcmds",
 | |
|         moncfg   => "monctrlcmds",
 | |
|         mondecfg => "monctrlcmds",
 | |
|         monshow  => "monctrlcmds",
 | |
|       }
 | |
| }
 | |
| 
 | |
| #-------------------------------------------------------
 | |
| 
 | |
| =head3  preprocess_request
 | |
| 
 | |
|   Check and setup for hierarchy
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------
 | |
| sub preprocess_request
 | |
| {
 | |
|     my $req      = shift;
 | |
|     my $callback = shift;
 | |
|     my $command  = $req->{command}->[0];
 | |
| 
 | |
|     #  if ($req->{_xcatdest}) { return [$req]; }    #exit if preprocessed
 | |
|     if ($req->{_xcatpreprocessed}->[0] == 1) { return [$req]; }
 | |
| 
 | |
|     if ($req->{module}) { return [$req]; }
 | |
|     my $args = $req->{arg};
 | |
| 
 | |
|     my @requests = ();
 | |
| 
 | |
| 
 | |
|     if (($command eq "monstart") || ($command eq "monstop") || ($command eq "moncfg") || ($command eq "mondecfg") || ($command eq "monshow")) {
 | |
|         my @a_ret;    #(0, $modulename, $nodestatutmon, $scope, \@nodes)
 | |
|         if ($command eq "monstart") {
 | |
|             @a_ret = preprocess_monstart($args, $callback);
 | |
|         } elsif ($command eq "monstop") {
 | |
|             @a_ret = preprocess_monstop($args, $callback);
 | |
|         } elsif ($command eq "moncfg") {
 | |
|             @a_ret = preprocess_moncfg($args, $callback);
 | |
|         } elsif ($command eq "mondecfg") {
 | |
|             @a_ret = preprocess_mondecfg($args, $callback);
 | |
|         } elsif ($command eq "monshow") {
 | |
|             @a_ret = preprocess_monshow($args, $callback);
 | |
|         }
 | |
| 
 | |
|         if ($a_ret[0] != 0) {
 | |
|             $req = {};
 | |
|             return;
 | |
|         } else {
 | |
|             my $allnodes = $a_ret[4];
 | |
| 
 | |
|             #print "allnodes=@$allnodes\n";
 | |
|             my $pname       = $a_ret[1];
 | |
|             my $file_name   = "$::XCATROOT/lib/perl/xCAT_monitoring/$pname.pm";
 | |
|             my $module_name = "xCAT_monitoring::$pname";
 | |
|             undef $SIG{CHLD};
 | |
|             if (($command eq "monshow") && (@$allnodes == 0) && ($a_ret[2] & 0x2 != 0)) {
 | |
|                 my $reqcopy = {%$req};
 | |
|                 push @{ $reqcopy->{module} }, $a_ret[1];
 | |
|                 push @{ $reqcopy->{priv} },   $a_ret[2];
 | |
|                 push @{ $reqcopy->{priv} },   $a_ret[3];
 | |
|                 push @{ $reqcopy->{priv} },   $a_ret[5];
 | |
|                 push @{ $reqcopy->{priv} },   $a_ret[6];
 | |
|                 push @{ $reqcopy->{priv} },   $a_ret[7];
 | |
|                 push @requests, $reqcopy;
 | |
|                 return \@requests;
 | |
|             }
 | |
| 
 | |
|             #initialize and start monitoring
 | |
|             no strict "refs";
 | |
|             my $mon_hierachy;
 | |
|             if (defined(${ $module_name . "::" }{getNodesMonServers})) {
 | |
|                 $mon_hierachy = ${ $module_name . "::" }{getNodesMonServers}->($allnodes, $callback);
 | |
|             } else {
 | |
|                 $mon_hierachy = xCAT_monitoring::monitorctrl->getNodeMonServerPair($allnodes, 1);
 | |
|             }
 | |
| 
 | |
|             #print Dumper($mon_hierachy);
 | |
| 
 | |
|             if (ref($mon_hierachy) eq 'ARRAY') {
 | |
|                 my $rsp2 = {};
 | |
|                 $rsp2->{data}->[0] = $mon_hierachy->[1];
 | |
|                 $callback->($rsp2);
 | |
|                 $req = {};
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
| 
 | |
|             my @mon_servers = keys(%$mon_hierachy);
 | |
|             my @hostinfo    = xCAT::NetworkUtils->determinehostname();
 | |
| 
 | |
|             #print "hostinfo=@hostinfo\n";
 | |
|             my $isSV   = xCAT::Utils->isServiceNode();
 | |
|             my %iphash = ();
 | |
|             foreach (@hostinfo) { $iphash{$_} = 1; }
 | |
|             if (!$isSV) { $iphash{'noservicenode'} = 1; }
 | |
| 
 | |
|             #check if we should also pass nodes that are managed by the sn to mn.
 | |
|             my $handleGrands = 0;
 | |
|             if (!$isSV) {
 | |
|                 if (defined(${ $module_name . "::" }{handleGrandChildren})) {
 | |
|                     $handleGrands = ${ $module_name . "::" }{handleGrandChildren}->();
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             #print "handleGrands=$handleGrands\n";
 | |
| 
 | |
|             my $index          = 0;
 | |
|             my $reqcopy_grands = {%$req};
 | |
|             foreach my $sv_pair (@mon_servers) {
 | |
| 
 | |
|                 #service node come in pairs, the first one is the monserver adapter that facing the mn,
 | |
|                 # the second one is facing the cn. we use the first one here
 | |
|                 my @server_pair = split(':', $sv_pair);
 | |
|                 my $sv = $server_pair[0];
 | |
|                 my $sv1;
 | |
|                 if (@server_pair > 1) {
 | |
|                     $sv1 = $server_pair[1];
 | |
|                 }
 | |
|                 my $mon_nodes = $mon_hierachy->{$sv_pair};
 | |
|                 if ((!$mon_nodes) || (@$mon_nodes == 0)) { next; }
 | |
| 
 | |
|                 #print "sv=$sv, nodes=@$mon_nodes\n";
 | |
| 
 | |
|                 my $reqcopy = {%$req};
 | |
|                 if (!$iphash{$sv}) {
 | |
|                     if ($isSV) { next; } #if the command is issued on the monserver, only handle its children.
 | |
|                     else {
 | |
|                         if ($handleGrands) {
 | |
|                             $index++;
 | |
|                             $reqcopy_grands->{"grand_$index"} = "$sv,$sv1," . join(',', @$mon_nodes);
 | |
|                         }
 | |
|                     }
 | |
|                     $reqcopy->{'_xcatdest'} = $sv;
 | |
|                     $reqcopy->{_xcatpreprocessed}->[0] = 1;
 | |
|                     my $rsp2 = {};
 | |
|                     $rsp2->{data}->[0] = "sending request to $sv..., " . join(',', @$mon_nodes);
 | |
|                     $callback->($rsp2);
 | |
|                 }
 | |
| 
 | |
|                 push @{ $reqcopy->{module} }, $a_ret[1];
 | |
|                 if ($command eq "monshow") {
 | |
|                     push @{ $reqcopy->{priv} }, $a_ret[2];
 | |
|                     push @{ $reqcopy->{priv} }, $a_ret[3];
 | |
|                     push @{ $reqcopy->{priv} }, $a_ret[5];
 | |
|                     push @{ $reqcopy->{priv} }, $a_ret[6];
 | |
|                     push @{ $reqcopy->{priv} }, $a_ret[7];
 | |
|                 } else {
 | |
|                     push @{ $reqcopy->{nodestatmon} }, $a_ret[2];
 | |
|                     push @{ $reqcopy->{scope} },       $a_ret[3];
 | |
|                 }
 | |
|                 push @{ $reqcopy->{nodeinfo} }, join(',', @$mon_nodes);
 | |
|                 push @requests, $reqcopy;
 | |
|             }
 | |
| 
 | |
|             #add the a request for mn to handle all its grand children
 | |
|             if ($index > 0) {
 | |
|                 $reqcopy_grands->{grand_total} = $index;
 | |
|                 push @{ $reqcopy_grands->{module} }, $a_ret[1];
 | |
|                 if ($command eq "monshow") {
 | |
|                     push @{ $reqcopy_grands->{priv} }, $a_ret[2];
 | |
|                     push @{ $reqcopy_grands->{priv} }, $a_ret[3];
 | |
|                     push @{ $reqcopy_grands->{priv} }, $a_ret[5];
 | |
|                     push @{ $reqcopy_grands->{priv} }, $a_ret[6];
 | |
|                     push @{ $reqcopy_grands->{priv} }, $a_ret[7];
 | |
|                 } else {
 | |
|                     push @{ $reqcopy_grands->{nodestatmon} }, $a_ret[2];
 | |
|                     push @{ $reqcopy_grands->{scope} },       $a_ret[3];
 | |
|                 }
 | |
|                 push @requests, $reqcopy_grands;
 | |
|             }
 | |
|         }
 | |
|     } else {
 | |
|         my $reqcopy = {%$req};
 | |
|         push @requests, $reqcopy;
 | |
|     }
 | |
| 
 | |
|     return \@requests;
 | |
| }
 | |
| 
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   process_request
 | |
|       It processes the monitoring control commands.
 | |
|     Arguments:
 | |
|       request -- a hash table which contains the command name and the arguments.
 | |
|       callback -- a callback pointer to return the response to.
 | |
|     Returns:
 | |
|         0 for success. The output is returned through the callback pointer.
 | |
|         1. for unsuccess. The error messages are returns through the callback pointer.
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub process_request {
 | |
|     use Getopt::Long;
 | |
| 
 | |
|     # options can be bundled up like -vV
 | |
|     Getopt::Long::Configure("bundling");
 | |
|     $Getopt::Long::ignorecase = 0;
 | |
| 
 | |
|     #print "process_request get called\n";
 | |
|     my $request  = shift;
 | |
|     my $callback = shift;
 | |
|     my $command  = $request->{command}->[0];
 | |
|     my $args     = $request->{arg};
 | |
|     my $doreq    = shift;
 | |
| 
 | |
|     if ($command eq "monstart") {
 | |
|         return monstart($request, $callback, $doreq);
 | |
|     }
 | |
|     elsif ($command eq "monstop") {
 | |
|         return monstop($request, $callback, $doreq);
 | |
|     }
 | |
|     elsif ($command eq "monls") {
 | |
|         return monls($request, $callback, $doreq);
 | |
| 
 | |
|     }
 | |
|     elsif ($command eq "monadd") {
 | |
|         return monadd($request, $callback, $doreq);
 | |
|     }
 | |
|     elsif ($command eq "monrm") {
 | |
|         return monrm($request, $callback, $doreq);
 | |
|     }
 | |
|     elsif ($command eq "moncfg") {
 | |
|         return moncfg($request, $callback, $doreq);
 | |
|     }
 | |
|     elsif ($command eq "mondecfg") {
 | |
|         return mondecfg($request, $callback, $doreq);
 | |
|     }
 | |
|     elsif ($command eq "monshow") {
 | |
|         return monshow($request, $callback, $doreq);
 | |
|     } else {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "unsupported command: $command.";
 | |
|         $callback->($rsp);
 | |
|         return 1;
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3  preprocess_monstart
 | |
|         This function handles the syntax checking for monstart command,
 | |
|      turn on the given monitoring plug-in to the 'monitoring' table.
 | |
|     Arguments:
 | |
|       callback - the pointer to the callback function.
 | |
|       args - The format of the args is:
 | |
|         [-h|--help|-v|--version] or
 | |
|         name [noderange] [-r|--remote]
 | |
|         where
 | |
|           name is the monitoring plug-in name. For example: rmcmon.
 | |
|               The specified plug-in will be invoked for monitoring the xCAT cluster.
 | |
|           noderange a range of nodes to be monitored. Default is all.
 | |
|           -r|--remote indicates that both monservers and the nodes need to be called to start
 | |
|              the monitoring. The defaults is monservers only.
 | |
|     Returns:
 | |
|         (0, $modulename, $nodestatutmon, $scope, \@nodes) for success. scope is the scope of the
 | |
|             actions. 1 means monervers only, 2 means both nodes and monservers.
 | |
|         (1, "") for unsuccess. The error messages are returns through the callback pointer.
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub preprocess_monstart
 | |
| {
 | |
|     my $args     = shift;
 | |
|     my $callback = shift;
 | |
| 
 | |
|     if (xCAT::Utils->isServiceNode()) {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "This command is not supported on a service node.";
 | |
|         $callback->($rsp);
 | |
|         return (1, "");
 | |
|     }
 | |
| 
 | |
|     # subroutine to display the usage
 | |
|     sub monstart_usage
 | |
|     {
 | |
|         my $cb  = shift;
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "Usage:";
 | |
|         $rsp->{data}->[1] = "  monstart name [noderange] [-r|--remote]";
 | |
|         $rsp->{data}->[2] = "  monstart [-h|--help|-v|--version]";
 | |
|         $rsp->{data}->[3] = "     name is the name of the monitoring plug-in module to be invoked.";
 | |
|         $rsp->{data}->[4] = "       Use 'monls -a' command to list all the monitoring plug-in names.";
 | |
|         $rsp->{data}->[5] = "     noderange is a range of nodes to be monitored. The default is all nodes.";
 | |
|         $rsp->{data}->[6] = "      -r|--remote indicates that both monservers and the nodes need to be called\n       to start the monitoring. The default is monservers only.";
 | |
|         $cb->($rsp);
 | |
|     }
 | |
| 
 | |
|     @ARGV = ();
 | |
|     if ($args) { @ARGV = @{$args}; }
 | |
| 
 | |
|     my $settings;
 | |
| 
 | |
|     # parse the options
 | |
|     if (!GetOptions(
 | |
|             'h|help'    => \$::HELP,
 | |
|             'v|version' => \$::VERSION,
 | |
|             'r|remote'  => \$::REMOTE,))
 | |
|     {
 | |
|         &monstart_usage($callback);
 | |
|         return (1, "");
 | |
|     }
 | |
| 
 | |
|     # display the usage if -h or --help is specified
 | |
|     if ($::HELP) {
 | |
|         &monstart_usage($callback);
 | |
|         return 1;
 | |
|     }
 | |
| 
 | |
|     # display the version statement if -v or --verison is specified
 | |
|     if ($::VERSION)
 | |
|     {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = xCAT::Utils->Version();
 | |
|         $callback->($rsp);
 | |
|         return (1, "");
 | |
|     }
 | |
| 
 | |
|     my $pname = "";
 | |
|     my $scope = 0; #set it to 0 instead of 1 because it will be distributed to monservers.
 | |
|     my @nodes       = ();
 | |
|     my $nodestatmon = 0;
 | |
| 
 | |
|     if ($::REMOTE) { $scope = 2; }
 | |
| 
 | |
|     if (@ARGV < 1)
 | |
|     {
 | |
|         &monstart_usage($callback);
 | |
|         return (1, "");
 | |
|     }
 | |
|     else {
 | |
|         #@product_names=split(/,/, $ARGV[0]);
 | |
|         $pname = $ARGV[0];
 | |
|         if (@ARGV > 1) {
 | |
|             my $noderange = $ARGV[1];
 | |
|             @nodes = noderange($noderange);
 | |
|             if (nodesmissed) {
 | |
|                 my $rsp = {};
 | |
|                 $rsp->{data}->[0] = "Invalid nodes in noderange:" . join(',', nodesmissed);
 | |
|                 $callback->($rsp);
 | |
|                 return (1, "");
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         my $file_name = "$::XCATROOT/lib/perl/xCAT_monitoring/$pname.pm";
 | |
|         if (!-e $file_name) {
 | |
|             my $rsp = {};
 | |
|             $rsp->{data}->[0] = "File $file_name does not exist.";
 | |
|             $callback->($rsp);
 | |
|             return (1, "");
 | |
|         } else {
 | |
| 
 | |
|             #load the module in memory
 | |
|             eval { require($file_name) };
 | |
|             if ($@) {
 | |
|                 my $rsp = {};
 | |
|                 $rsp->{data}->[0] = "The file $file_name has compiling errors:\n$@\n";
 | |
|                 $callback->($rsp);
 | |
|                 return (1, "");
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     my $table = xCAT::Table->new("monitoring", -create => 1, -autocommit => 1);
 | |
|     if ($table) {
 | |
|         my $found = 0;
 | |
|         my $tmp1  = $table->getAllEntries("all");
 | |
|         if (defined($tmp1) && (@$tmp1 > 0)) {
 | |
|             foreach (@$tmp1) {
 | |
|                 if ($pname eq $_->{name}) {
 | |
|                     $found = 1;
 | |
|                     if ($_->{disable} !~ /0|NO|No|no|N|n/) {
 | |
|                         my %key_col = (name    => $pname);
 | |
|                         my %tb_cols = (disable => "0");
 | |
|                         $table->setAttribs(\%key_col, \%tb_cols);
 | |
|                     }
 | |
|                     if ($_->{nodestatmon} =~ /1|Yes|yes|YES|Y|y/) { $nodestatmon = 1; }
 | |
|                     last;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if (!$found) {
 | |
|             my $rsp = {};
 | |
|             $rsp->{data}->[0] = "$pname has not been added to the monitoring table. Please run 'monadd' command to add.";
 | |
|             $callback->($rsp);
 | |
|             $table->close();
 | |
|             return (1, "");
 | |
|         }
 | |
| 
 | |
|         $table->close();
 | |
|     } else {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "Failed to open the monitoring table.";
 | |
|         $callback->($rsp);
 | |
|         return (1, "");
 | |
|     }
 | |
| 
 | |
|     return (0, $pname, $nodestatmon, $scope, \@nodes);
 | |
| }
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   monstart
 | |
|         This function calls moniutoring control to start the monitoring and node
 | |
|     status monitoring for the given plug-in module.
 | |
|     Arguments:
 | |
|       request -- pointer to a hash with keys are command, module and nodestatmon.
 | |
|       callback - the pointer to the callback function.
 | |
|     Returns:
 | |
|         0 for success. The output is returned through the callback pointer.
 | |
|         1. for unsuccess. The error messages are returns through the callback pointer.
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub monstart {
 | |
|     my $request  = shift;
 | |
|     my $callback = shift;
 | |
| 
 | |
|     my $pname       = $request->{module}->[0];
 | |
|     my $nodestatmon = $request->{nodestatmon}->[0];
 | |
|     my $scope       = $request->{scope}->[0];
 | |
|     my $nodeinfo    = $request->{nodeinfo}->[0];
 | |
| 
 | |
|     my $grands = {};
 | |
|     my $total  = 0;
 | |
|     if (exists($request->{grand_total})) {
 | |
|         $total = $request->{grand_total};
 | |
|     }
 | |
|     for (my $i = 1 ; $i <= $total ; $i++) {
 | |
|         if (exists($request->{"grand_$i"})) {
 | |
|             my $temp = $request->{"grand_$i"};
 | |
|             my @tmpnodes = split(',', $temp);
 | |
|             if (@tmpnodes > 2) {
 | |
|                 my $sv  = shift(@tmpnodes);
 | |
|                 my $sv1 = shift(@tmpnodes);
 | |
|                 $grands->{"$sv,$sv1"} = \@tmpnodes;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     #print "-------grands" . Dumper($grands);
 | |
| 
 | |
| 
 | |
|     my @nodes = split(',', $nodeinfo);
 | |
| 
 | |
|     #print "monstart get called: pname=$pname\nnodestatmon=$nodestatmon\nnodeinfo=$nodeinfo\nscope=$scope\n";
 | |
| 
 | |
|     xCAT_monitoring::monitorctrl->startMonitoring([$pname], \@nodes, $scope, $callback, $grands);
 | |
| 
 | |
|     if ($nodestatmon) {
 | |
|         xCAT_monitoring::monitorctrl->startNodeStatusMonitoring($pname, \@nodes, $scope, $callback, $grands);
 | |
|     }
 | |
|     return;
 | |
| }
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   preprocess_monstop
 | |
|         This function unregisters the given monitoring plug-in from the 'monitoring' table.
 | |
|     Arguments:
 | |
|       callback - the pointer to the callback function.
 | |
|       args - The format of the args is:
 | |
|         [-h|--help|-v|--version] or
 | |
|         name [noderange] [-r|--remote]
 | |
|         name
 | |
|         where
 | |
|           name is the monitoring plug-in name. For example: rmcmon.
 | |
|               The specified plug-in will be stopped for monitoring the xCAT cluster.
 | |
|           noderange a range of nodes. Default is all.
 | |
|           -r|--remote indicates that both monservers and the nodes need to be called to stop
 | |
|              the monitoring. The defaults is monservers only.
 | |
|     Returns:
 | |
|         (0, $modulename, $nodestatutmon, $scope, \@nodes) for success. scope is the scope of the
 | |
|             actions. 1 means monervers only, 2 means both nodes and monservers.
 | |
|         (1, "") for unsuccess. The error messages are returns through the callback pointer.
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub preprocess_monstop
 | |
| {
 | |
|     my $args     = shift;
 | |
|     my $callback = shift;
 | |
| 
 | |
|     if (xCAT::Utils->isServiceNode()) {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "This command is not supported on a service node.";
 | |
|         $callback->($rsp);
 | |
|         return (1, "");
 | |
|     }
 | |
| 
 | |
|     # subroutine to display the usage
 | |
|     sub monstop_usage
 | |
|     {
 | |
|         my $cb  = shift;
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "Usage:";
 | |
|         $rsp->{data}->[1] = "  monstop name [noderange] [-r|--remote]";
 | |
|         $rsp->{data}->[2] = "  monstop [-h|--help|-v|--version]";
 | |
|         $rsp->{data}->[3] = "      name is the name of the monitoring plug-in module registered in the monitoring table.";
 | |
|         $cb->($rsp);
 | |
|     }
 | |
| 
 | |
|     @ARGV = ();
 | |
|     if ($args) { @ARGV = @{$args}; }
 | |
| 
 | |
|     # parse the options
 | |
|     if (!GetOptions(
 | |
|             'h|help'    => \$::HELP,
 | |
|             'r|remote'  => \$::REMOTE,
 | |
|             'v|version' => \$::VERSION,))
 | |
|     {
 | |
|         &monstop_usage($callback);
 | |
|         return (1, "");
 | |
|     }
 | |
| 
 | |
|     # display the usage if -h or --help is specified
 | |
|     if ($::HELP) {
 | |
|         &monstop_usage($callback);
 | |
|         return (1, "");
 | |
|     }
 | |
| 
 | |
|     # display the version statement if -v or --verison is specified
 | |
|     if ($::VERSION)
 | |
|     {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = xCAT::Utils->Version();
 | |
|         $callback->($rsp);
 | |
|         return (1, "");
 | |
|     }
 | |
| 
 | |
|     my $pname       = "";
 | |
|     my $scope       = 0;
 | |
|     my @nodes       = ();
 | |
|     my $nodestatmon = 0;
 | |
| 
 | |
|     if ($::REMOTE) { $scope = 2; }
 | |
| 
 | |
|     if (@ARGV < 1)
 | |
|     {
 | |
|         &monstop_usage($callback);
 | |
|         return (1, "");
 | |
|     }
 | |
|     else {
 | |
|         $pname = $ARGV[0];
 | |
|         if (@ARGV > 1) {
 | |
|             my $noderange = $ARGV[1];
 | |
|             @nodes = noderange($noderange);
 | |
|             if (nodesmissed) {
 | |
|                 my $rsp = {};
 | |
|                 $rsp->{data}->[0] = "Invalid nodes in noderange:" . join(',', nodesmissed);
 | |
|                 $callback->($rsp);
 | |
|                 return (1, "");
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         my $file_name = "$::XCATROOT/lib/perl/xCAT_monitoring/$pname.pm";
 | |
|         if (!-e $file_name) {
 | |
|             my $rsp = {};
 | |
|             $rsp->{data}->[0] = "File $file_name does not exist.";
 | |
|             $callback->($rsp);
 | |
|             return (1, "");
 | |
|         } else {
 | |
| 
 | |
|             #load the module in memory
 | |
|             eval { require($file_name) };
 | |
|             if ($@) {
 | |
|                 my $rsp = {};
 | |
|                 $rsp->{data}->[0] = "The file $file_name has compiling errors:\n$@\n";
 | |
|                 $callback->($rsp);
 | |
|                 return (1, "");
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     my $table = xCAT::Table->new("monitoring", -create => 1, -autocommit => 1);
 | |
|     if ($table) {
 | |
|         my $found = 0;
 | |
|         my $tmp1  = $table->getAllEntries("all");
 | |
|         if (defined($tmp1) && (@$tmp1 > 0)) {
 | |
|             foreach (@$tmp1) {
 | |
|                 if ($pname eq $_->{name}) {
 | |
|                     $found = 1;
 | |
|                     if ($_->{disable} =~ /0|NO|No|no|N|n/) {
 | |
|                         my %key_col = (name    => $pname);
 | |
|                         my %tb_cols = (disable => "1");
 | |
|                         $table->setAttribs(\%key_col, \%tb_cols);
 | |
|                     }
 | |
|                     if ($_->{nodestatmon} =~ /1|Yes|yes|YES|Y|y/) { $nodestatmon = 1; }
 | |
|                     last;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if (!$found) {
 | |
|             my $rsp = {};
 | |
|             $rsp->{data}->[0] = "$pname cannot be found in the monitoring table.";
 | |
|             $callback->($rsp);
 | |
|             $table->close();
 | |
|             return (1, "");
 | |
|         }
 | |
| 
 | |
|         $table->close();
 | |
|     } else {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "Failed to open the monitoring table.";
 | |
|         $callback->($rsp);
 | |
|         return (1, "");
 | |
|     }
 | |
| 
 | |
|     return (0, $pname, $nodestatmon, $scope, \@nodes);
 | |
| }
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   monstop
 | |
|         This function calls moniutoring control to stop the monitoring and node
 | |
|     status monitoring for the given plug-in module.
 | |
|     Arguments:
 | |
|       request -- pointer to a hash with keys are command, module and nodestatmon.
 | |
|       callback - the pointer to the callback function.
 | |
|     Returns:
 | |
|         0 for success. The output is returned through the callback pointer.
 | |
|         1. for unsuccess. The error messages are returns through the callback pointer.
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub monstop {
 | |
|     my $request  = shift;
 | |
|     my $callback = shift;
 | |
| 
 | |
|     my $pname       = $request->{module}->[0];
 | |
|     my $nodestatmon = $request->{nodestatmon}->[0];
 | |
|     my $scope       = $request->{scope}->[0];
 | |
|     my $nodeinfo    = $request->{nodeinfo}->[0];
 | |
| 
 | |
| 
 | |
|     my $grands = {};
 | |
|     my $total  = 0;
 | |
|     if (exists($request->{grand_total})) {
 | |
|         $total = $request->{grand_total};
 | |
|     }
 | |
|     for (my $i = 1 ; $i <= $total ; $i++) {
 | |
|         if (exists($request->{"grand_$i"})) {
 | |
|             my $temp = $request->{"grand_$i"};
 | |
|             my @tmpnodes = split(',', $temp);
 | |
|             if (@tmpnodes > 2) {
 | |
|                 my $sv  = shift(@tmpnodes);
 | |
|                 my $sv1 = shift(@tmpnodes);
 | |
|                 $grands->{"$sv,$sv1"} = \@tmpnodes;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     #print "-------grands" . Dumper($grands);
 | |
| 
 | |
| 
 | |
|     my @nodes = split(',', $nodeinfo);
 | |
| 
 | |
|     #print "monstop get called: pname=$pname\nnodestatmon=$nodestatmon\nnodeinfo=@nodes\nscope=$scope\n";
 | |
| 
 | |
|     if ($nodestatmon) {
 | |
|         xCAT_monitoring::monitorctrl->stopNodeStatusMonitoring($pname, \@nodes, $scope, $callback, $grands);
 | |
|     }
 | |
| 
 | |
|     xCAT_monitoring::monitorctrl->stopMonitoring([$pname], \@nodes, $scope, $callback, $grands);
 | |
| 
 | |
|     return;
 | |
| }
 | |
| 
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   monls
 | |
|         This function list the monitoring plug-in module names, status and description.
 | |
|     Arguments:
 | |
|       callback - the pointer to the callback function.
 | |
|       args - The format of the args is:
 | |
|         [-h|--help|-v|--version] or
 | |
|         [name] [-a|all] [-d|--description]
 | |
|     Returns:
 | |
|         0 for success. The output is returned through the callback pointer.
 | |
|         1. for unsuccess. The error messages are returns through the callback pointer.
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub monls {
 | |
|     my $request  = shift;
 | |
|     my $callback = shift;
 | |
|     my $args     = $request->{arg};
 | |
|     my $doreq    = shift;
 | |
| 
 | |
|     # subroutine to display the usage
 | |
|     sub monls_usage
 | |
|     {
 | |
|         my $cb  = shift;
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "Usage:";
 | |
|         $rsp->{data}->[1] = "  monls name [-d|--description]";
 | |
|         $rsp->{data}->[2] = "  monls [-a|--all] [-d|--description]";
 | |
|         $rsp->{data}->[3] = "  monls [-h|--help|-v|--version]";
 | |
|         $rsp->{data}->[4] = "     name is the name of the monitoring plug-in module.";
 | |
|         $cb->($rsp);
 | |
|     }
 | |
| 
 | |
|     @ARGV = ();
 | |
|     if ($args) {
 | |
|         @ARGV = @{$args};
 | |
|     }
 | |
| 
 | |
|     # parse the options
 | |
|     if (!GetOptions(
 | |
|             'h|help'        => \$::HELP,
 | |
|             'v|version'     => \$::VERSION,
 | |
|             'a|all'         => \$::ALL,
 | |
|             'd|discription' => \$::DESC))
 | |
|     {
 | |
|         &monls_usage($callback);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     # display the usage if -h or --help is specified
 | |
|     if ($::HELP) {
 | |
|         &monls_usage($callback);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     # display the version statement if -v or --verison is specified
 | |
|     if ($::VERSION)
 | |
|     {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = xCAT::Utils->Version();
 | |
|         $callback->($rsp);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     my $usetab     = 0;
 | |
|     my %names      = ();
 | |
|     my $plugin_dir = "$::XCATROOT/lib/perl/xCAT_monitoring";
 | |
|     if (@ARGV > 0)
 | |
|     {
 | |
|         $names{ $ARGV[0] } = 0;
 | |
|     }
 | |
|     else {
 | |
|         if ($::ALL) {
 | |
| 
 | |
|             #get all the module names from /opt/xcat/lib/perl/XCAT_monitoring directory
 | |
|             my @plugins = glob($plugin_dir . "/*.pm");
 | |
|             foreach (@plugins) {
 | |
|                 /.*\/([^\/]*).pm$/;
 | |
|                 $names{$1} = 0;
 | |
|             }
 | |
| 
 | |
|             # remove 2 files that are not plug-ins
 | |
|             delete($names{monitorctrl});
 | |
|             delete($names{montbhandler});
 | |
|         }
 | |
|         else {
 | |
|             $usetab = 1;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     #get the list from the table
 | |
|     my $table = xCAT::Table->new("monitoring", -create => 1);
 | |
|     if ($table) {
 | |
|         my $tmp1 = $table->getAllEntries("all");
 | |
|         if (defined($tmp1) && (@$tmp1 > 0)) {
 | |
|             foreach (@$tmp1) {
 | |
|                 my $pname = $_->{name};
 | |
|                 if (($usetab) || exists($names{$pname})) {
 | |
|                     $names{$pname} = 1;
 | |
| 
 | |
|                     #find out the monitoring plugin file and module name for the product
 | |
|                     my $rsp = {};
 | |
| 
 | |
|                     my $file_name = "$::XCATROOT/lib/perl/xCAT_monitoring/$pname.pm";
 | |
|                     my $module_name = "xCAT_monitoring::$pname";
 | |
| 
 | |
|                     #load the module in memory
 | |
|                     eval { require($file_name) };
 | |
|                     if ($@) {
 | |
|                         $rsp->{data}->[0] = "$pname: The file $file_name cannot be located or has compiling errors.";
 | |
|                         $callback->($rsp);
 | |
|                         next;
 | |
|                     } else {
 | |
|                         no strict "refs";
 | |
|                         if (!defined(${ $module_name . "::" }{start})) { next; }
 | |
|                     }
 | |
| 
 | |
|                     my $monnode = 0;
 | |
|                     my $disable = 1;
 | |
|                     if ($_->{nodestatmon} =~ /1|Yes|yes|YES|Y|y/) { $monnode = 1; }
 | |
|                     if ($_->{disable} =~ /0|NO|No|no|N|n/) { $disable = 0; }
 | |
|                     if ($disable) { $monnode = 0; }
 | |
|                     $rsp->{data}->[0] = "$pname\t\t" .
 | |
|                       ($disable ? "not-monitored"           : "monitored") .
 | |
|                       ($monnode ? "\tnode-status-monitored" : "");
 | |
|                     if ($::DESC) { getModuleDescription($rsp, $module_name); }
 | |
|                     $callback->($rsp);
 | |
|                 }
 | |
|             }    #foreach
 | |
|         }
 | |
|         $table->close();
 | |
|     }
 | |
| 
 | |
| 
 | |
|     #now handle the ones that are not in the table
 | |
|     foreach (keys(%names)) {
 | |
|         my $pname = $_;
 | |
|         if (!$names{$pname}) {
 | |
|             my $rsp = {};
 | |
| 
 | |
|             #find out the monitoring plugin file and module name for the product
 | |
|             my $file_name   = "$::XCATROOT/lib/perl/xCAT_monitoring/$pname.pm";
 | |
|             my $module_name = "xCAT_monitoring::$pname";
 | |
| 
 | |
|             #load the module in memory
 | |
|             eval { require($file_name) };
 | |
|             if ($@) {
 | |
|                 $rsp->{data}->[0] = "$pname: The file $file_name cannot be located or has compiling errors.";
 | |
|                 $callback->($rsp);
 | |
|                 next;
 | |
|             } else {
 | |
|                 no strict "refs";
 | |
|                 if (!defined(${ $module_name . "::" }{start})) { next; }
 | |
|             }
 | |
|             $rsp->{data}->[0] = "$pname\t\tnot-monitored";
 | |
| 
 | |
|             if ($::DESC) {
 | |
|                 getModuleDescription($rsp, $module_name);
 | |
|             }
 | |
|             $callback->($rsp);
 | |
|         }
 | |
|     }
 | |
|     return;
 | |
| }
 | |
| 
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   getModuleDescription
 | |
|         This function gets description, postscripts and other info from the
 | |
|      the given monitoring plug_in and stored it in the given hash.
 | |
|     Arguments:
 | |
|     Returns:
 | |
|         0 for success.
 | |
|         1. for unsuccess.
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub getModuleDescription {
 | |
|     my $rsp         = shift;
 | |
|     my $module_name = shift;
 | |
|     no strict "refs";
 | |
| 
 | |
|     #description
 | |
|     if (defined(${ $module_name . "::" }{getDescription})) {
 | |
|         $rsp->{data}->[1] = ${ $module_name . "::" }{getDescription}->();
 | |
|     } else {
 | |
|         $rsp->{data}->[1] = "    No description available.";
 | |
|     }
 | |
| 
 | |
|     #postscripts
 | |
|     $rsp->{data}->[2] = "  Postscripts:\n";
 | |
|     if (defined(${ $module_name . "::" }{getPostscripts})) {
 | |
|         my $desc = ${ $module_name . "::" }{getPostscripts}->();
 | |
|         my @pn   = keys(%$desc);
 | |
| 
 | |
|         if (@pn > 0) {
 | |
|             foreach my $group (@pn) {
 | |
|                 $rsp->{data}->[2] .= "    $group: " . $desc->{$group};
 | |
|             }
 | |
|         } else { $rsp->{data}->[2] .= "    None"; }
 | |
|     } else { $rsp->{data}->[2] .= "    None"; }
 | |
| 
 | |
|     #support node status monitoring
 | |
|     $rsp->{data}->[3] = "  Support node status monitoring:\n";
 | |
|     my $snodestatusmon = 0;
 | |
|     if (defined(${ $module_name . "::" }{supportNodeStatusMon})) {
 | |
|         $snodestatusmon = ${ $module_name . "::" }{supportNodeStatusMon}->();
 | |
|     }
 | |
|     if   ($snodestatusmon) { $rsp->{data}->[3] .= "    Yes\n"; }
 | |
|     else                   { $rsp->{data}->[3] .= "    No\n"; }
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   monadd
 | |
|         This function adds the given module name into the monitoring table and
 | |
|      sets the postsctipts in the postsctipts table. It also sets the given
 | |
|      settings into the monsetting table.
 | |
|     Arguments:
 | |
|       request -- a hash table which contains the command name and the arguments.
 | |
|       callback - the pointer to the callback function.
 | |
|       args - The format of the args is:
 | |
|         [-h|--help|-v|--version] or
 | |
|         name [-n|--nodestatmon] [-s|--settings ...]
 | |
|         where
 | |
|           name is the monitoring plug-in name. For example: rmcmon.
 | |
|               The specified plug-in will be registered and invoked
 | |
|               for monitoring the xCAT cluster.
 | |
|           -n|--nodestatmon  indicates that this plug-in will be used for feeding the node liveness
 | |
|               status to the xCAT nodelist table.  If not specified, the plug-in will not be used
 | |
|               for feeding node status to xCAT.
 | |
|           -s|--settings settings are used by the plug-in to customize it behavor.
 | |
|     Returns:
 | |
|         0 for success. The output is returned through the callback pointer.
 | |
|         1. for unsuccess. The error messages are returns through the callback pointer.
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub monadd {
 | |
|     my $request  = shift;
 | |
|     my $callback = shift;
 | |
|     my $args     = $request->{arg};
 | |
|     my $doreq    = shift;
 | |
| 
 | |
|     # subroutine to display the usage
 | |
|     sub monadd_usage
 | |
|     {
 | |
|         my $cb  = shift;
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "Usage:";
 | |
|         $rsp->{data}->[1] = "  monadd name [-n|--nodestatmon] [-s|--settings settings]";
 | |
|         $rsp->{data}->[2] = "  monadd [-h|--help|-v|--version]";
 | |
|         $rsp->{data}->[3] = "     name is the name of the monitoring plug-in module to be added.";
 | |
|         $rsp->{data}->[4] = "       Use 'monls -a' command to list all the monitoring plug-in names.";
 | |
|         $rsp->{data}->[5] = "     settings is used by the monitoring plug-in to customize its behavior.";
 | |
|         $rsp->{data}->[6] = "       Format: -s key1=value1 -s key2=value2 ... ";
 | |
|         $rsp->{data}->[7] = "       Please note that the square brackets are needed. ";
 | |
|         $rsp->{data}->[7] = "       Use 'monls name -d' command to look for the possible settings for a plug-in.";
 | |
|         $rsp->{data}->[8] = "  Example: monadd xcatmon -n -s ping-interval=10";
 | |
|         $cb->($rsp);
 | |
|     }
 | |
| 
 | |
|     @ARGV = ();
 | |
|     if ($args) { @ARGV = @{$args}; }
 | |
|     my $settings;
 | |
| 
 | |
|     # parse the options
 | |
|     if (!GetOptions(
 | |
|             'h|help'        => \$::HELP,
 | |
|             'v|version'     => \$::VERSION,
 | |
|             'n|nodestatmon' => \$::NODESTATMON,
 | |
|             's|settings=s@' => \$settings))
 | |
|     {
 | |
|         &monadd_usage($callback);
 | |
|         return 1;
 | |
|     }
 | |
| 
 | |
|     # display the usage if -h or --help is specified
 | |
|     if ($::HELP) {
 | |
|         &monadd_usage($callback);
 | |
|         return 1;
 | |
|     }
 | |
| 
 | |
|     # display the version statement if -v or --verison is specified
 | |
|     if ($::VERSION)
 | |
|     {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = xCAT::Utils->Version();
 | |
|         $callback->($rsp);
 | |
|         return 1;
 | |
|     }
 | |
| 
 | |
|     #my @product_names;
 | |
|     my $pname;
 | |
|     my $nodestatmon = 0;
 | |
|     if (@ARGV < 1)
 | |
|     {
 | |
|         &monadd_usage($callback);
 | |
|         return 1;
 | |
|     }
 | |
|     else {
 | |
|         #@product_names=split(/,/, $ARGV[0]);
 | |
|         $pname = $ARGV[0];
 | |
|         my $file_name = "$::XCATROOT/lib/perl/xCAT_monitoring/$pname.pm";
 | |
|         if (!-e $file_name) {
 | |
|             my $rsp = {};
 | |
|             $rsp->{data}->[0] = "File $file_name does not exist.";
 | |
|             $callback->($rsp);
 | |
|             return 1;
 | |
|         } else {
 | |
| 
 | |
|             #load the module in memory
 | |
|             eval { require($file_name) };
 | |
|             if ($@) {
 | |
|                 my $rsp = {};
 | |
|                 $rsp->{data}->[0] = "The file $file_name has compiling errors:\n$@\n";
 | |
|                 $callback->($rsp);
 | |
|                 return 1;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     my $table = xCAT::Table->new("monitoring", -create => 1);
 | |
|     if ($table) {
 | |
| 
 | |
|         #my $tmp1=$table->getAllEntries("all");
 | |
|         #if (defined($tmp1) && (@$tmp1 > 0)) {
 | |
|         #  foreach(@$tmp1) {
 | |
|         #    my $name=$_->{name};
 | |
|         #    if ($name eq $pname) {
 | |
|         #      my $rsp={};
 | |
|         #      $rsp->{data}->[0]="$pname has already been added in the monitoring table.";
 | |
|         #      $callback->($rsp);
 | |
|         #      $table->close();
 | |
|         #      return 1;
 | |
|         #    }
 | |
|         #  }
 | |
|         #}
 | |
| 
 | |
|         my $module_name = "xCAT_monitoring::$pname";
 | |
| 
 | |
|         #check if the module suppors node status monitoring or not.
 | |
|         if ($::NODESTATMON) {
 | |
|             no strict "refs";
 | |
|             my $snodestatusmon = 0;
 | |
|             if (defined(${ $module_name . "::" }{supportNodeStatusMon})) {
 | |
|                 $snodestatusmon = ${ $module_name . "::" }{supportNodeStatusMon}->();
 | |
|             }
 | |
|             if (!$snodestatusmon) {
 | |
|                 my $rsp = {};
 | |
|                 $rsp->{data}->[0] = "$pname does not support node status monitoring.";
 | |
|                 $callback->($rsp);
 | |
|                 $table->close();
 | |
|                 return 1;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #update the monsetting table
 | |
|         if ($settings) {
 | |
|             my $table1 = xCAT::Table->new("monsetting", -create => 1, -autocommit => 1);
 | |
|             my %key_col1 = (name => $pname);
 | |
| 
 | |
|             #parse the settings. Setting format: key="value",key="value"....
 | |
|             foreach (@$settings) {
 | |
|                 if (/^\[(.*)\]$/) {    #backward compatible
 | |
|                     while (s/^\[([^\[\]\=]*)=([^\[\]]*)\](,)*//) {
 | |
|                         $key_col1{key} = $1;
 | |
|                         my %setting_hash = ();
 | |
|                         $setting_hash{value} = $2;
 | |
|                         $table1->setAttribs(\%key_col1, \%setting_hash);
 | |
|                     }
 | |
|                 } else {
 | |
|                     /^([^\=]*)=(.*)/;
 | |
|                     $key_col1{key} = $1;
 | |
|                     my %setting_hash = ();
 | |
|                     $setting_hash{value} = $2;
 | |
|                     $table1->setAttribs(\%key_col1, \%setting_hash);
 | |
|                 }
 | |
|             }
 | |
|             $table1->close();
 | |
|         }
 | |
| 
 | |
|         #update the monitoring table
 | |
|         my %key_col = (name => $pname);
 | |
|         my $nstat = 'N';
 | |
|         if ($::NODESTATMON) {
 | |
|             $nstat       = 'Y';
 | |
|             $nodestatmon = 1;
 | |
|         }
 | |
|         my %tb_cols = (nodestatmon => $nstat, disable => "1");
 | |
|         $table->setAttribs(\%key_col, \%tb_cols);
 | |
|         $table->close();
 | |
| 
 | |
|         #updating the postscript table
 | |
|         no strict "refs";
 | |
|         my $postscripts_h = {};
 | |
|         if (defined(${ $module_name . "::" }{getPostscripts})) {
 | |
|             my $postscripts_h = ${ $module_name . "::" }{getPostscripts}->();
 | |
|             my @pn            = keys(%$postscripts_h);
 | |
|             if (@pn > 0) {
 | |
|                 my $table2 = xCAT::Table->new("postscripts", -create => 1);
 | |
|                 if (!$table2) {
 | |
|                     my $rsp = {};
 | |
|                     $rsp->{data}->[0] = "Cannot open the postscripts table.\nFailed to set the postscripts for $pname.";
 | |
|                     $callback->($rsp);
 | |
|                     return 1;
 | |
|                 }
 | |
|                 foreach my $group (@pn) {
 | |
|                     my $posts = $postscripts_h->{$group};
 | |
|                     if ($posts) {
 | |
|                         (my $ref) = $table2->getAttribs({ node => $group }, 'postscripts');
 | |
|                         if ($ref and $ref->{postscripts}) {
 | |
|                             my @old_a = split(',', $ref->{postscripts});
 | |
|                             my @new_a = split(',', $posts);
 | |
|                             my %new_h = ();
 | |
|                             foreach my $new_tmp (@new_a) {
 | |
|                                 my $found = 0;
 | |
|                                 foreach my $old_tmp (@old_a) {
 | |
|                                     if ($old_tmp eq $new_tmp) { $found = 1; last; }
 | |
|                                 }
 | |
|                                 if (!$found) { $new_h{$new_tmp} = 1; }
 | |
|                             }
 | |
| 
 | |
|                             if (keys(%new_h) > 0) {
 | |
|                                 foreach (keys(%new_h)) { push(@old_a, $_); }
 | |
|                                 my $new_post = join(',', @old_a);
 | |
|                                 my %key_col2 = (node        => $group);
 | |
|                                 my %tb_cols2 = (postscripts => $new_post);
 | |
|                                 $table2->setAttribs(\%key_col2, \%tb_cols2);
 | |
|                             }
 | |
|                         } else {
 | |
|                             my %key_col2 = (node        => $group);
 | |
|                             my %tb_cols2 = (postscripts => $posts);
 | |
|                             $table2->setAttribs(\%key_col2, \%tb_cols2);
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|                 $table2->close();
 | |
|             }
 | |
|         }
 | |
|     } else {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "Failed to open the monitoring table.";
 | |
|         $callback->($rsp);
 | |
|         return 1;
 | |
|     }
 | |
| 
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   monrm
 | |
|       This function removes the given monitoring plug-in from the 'monitoring' table.
 | |
|     It also removed the postscritps for the module from the 'postscritps' table.
 | |
|     Arguments:
 | |
|       request -- a hash table which contains the command name and the arguments.
 | |
|       callback - the pointer to the callback function.
 | |
|        args - The format of the args is:
 | |
|         [-h|--help|-v|--version] or
 | |
|         name
 | |
|         where
 | |
|           name is the monitoring plug-in name. For example: rmcmon.
 | |
|               The specified plug-in will be stopped for monitoring the xCAT
 | |
|               cluster if it is running and then removed from the monitoring table.
 | |
|     Returns:
 | |
|         0 for success.
 | |
|         1 for unsuccess. The error messages are returns through the callback pointer.
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub monrm {
 | |
|     my $request  = shift;
 | |
|     my $callback = shift;
 | |
|     my $args     = $request->{arg};
 | |
|     my $doreq    = shift;
 | |
| 
 | |
|     if (xCAT::Utils->isServiceNode()) {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "This command is not supported on a service node.";
 | |
|         $callback->($rsp);
 | |
|         return (1, "");
 | |
|     }
 | |
| 
 | |
|     # subroutine to display the usage
 | |
|     sub monrm_usage
 | |
|     {
 | |
|         my $cb  = shift;
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "Usage:";
 | |
|         $rsp->{data}->[1] = "  monrm name";
 | |
|         $rsp->{data}->[2] = "  monrm [-h|--help|-v|--version]";
 | |
|         $rsp->{data}->[3] = "      name is the name of the monitoring plug-in module registered in the monitoring table.";
 | |
|         $cb->($rsp);
 | |
|     }
 | |
| 
 | |
|     @ARGV = ();
 | |
|     if ($args) { @ARGV = @{$args}; }
 | |
| 
 | |
|     # parse the options
 | |
|     if (!GetOptions(
 | |
|             'h|help'    => \$::HELP,
 | |
|             'v|version' => \$::VERSION,))
 | |
|     {
 | |
|         &monrm_usage($callback);
 | |
|         return (1, "");
 | |
|     }
 | |
| 
 | |
|     # display the usage if -h or --help is specified
 | |
|     if ($::HELP) {
 | |
|         &monrm_usage($callback);
 | |
|         return (1, "");
 | |
|     }
 | |
| 
 | |
|     # display the version statement if -v or --verison is specified
 | |
|     if ($::VERSION)
 | |
|     {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = xCAT::Utils->Version();
 | |
|         $callback->($rsp);
 | |
|         return (1, "");
 | |
|     }
 | |
| 
 | |
|     my $pname;
 | |
|     if (@ARGV < 1)
 | |
|     {
 | |
|         &monrm_usage($callback);
 | |
|         return (1, "");
 | |
|     }
 | |
|     else {
 | |
|         $pname = $ARGV[0];
 | |
|     }
 | |
| 
 | |
|     my $disable = 1;
 | |
|     my $found   = 0;
 | |
|     my $table   = xCAT::Table->new("monitoring", -create => 1);
 | |
|     if ($table) {
 | |
|         my $tmp1 = $table->getAllEntries("all");
 | |
|         if (defined($tmp1) && (@$tmp1 > 0)) {
 | |
|             foreach (@$tmp1) {
 | |
|                 if ($pname eq $_->{name}) {
 | |
|                     if ($_->{disable} =~ /0|NO|No|no|N|n/) { $disable = 0; }
 | |
|                     $found = 1;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if (!$found) {
 | |
|             my $rsp = {};
 | |
|             $rsp->{data}->[0] = "$pname is not in the monitoring talble.";
 | |
|             $callback->($rsp);
 | |
|             $table->close();
 | |
|             return 0;
 | |
|         }
 | |
| 
 | |
|         if (!$disable) {
 | |
|             my $rsp = {};
 | |
|             $rsp->{data}->[0] = "Please run command 'monstop $pname' to stop monitoring before running this command.";
 | |
|             $callback->($rsp);
 | |
|             $table->close();
 | |
|             return 0;
 | |
|         }
 | |
| 
 | |
|         my %key_col = (name => $pname);
 | |
|         $table->delEntries(\%key_col);
 | |
|         $table->close();
 | |
| 
 | |
| 
 | |
|         #remove the postscripts for the module from the postscript table
 | |
|         no strict "refs";
 | |
|         my $file_name   = "$::XCATROOT/lib/perl/xCAT_monitoring/$pname.pm";
 | |
|         my $module_name = "xCAT_monitoring::$pname";
 | |
|         if (!-e $file_name) {
 | |
|             return 0;
 | |
|         } else {
 | |
| 
 | |
|             #load the module in memory
 | |
|             eval { require($file_name) };
 | |
|             if ($@) {
 | |
|                 return 0;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         my $postscripts_h = {};
 | |
|         if (defined(${ $module_name . "::" }{getPostscripts})) {
 | |
|             my $postscripts_h = ${ $module_name . "::" }{getPostscripts}->();
 | |
|             my @pn            = keys(%$postscripts_h);
 | |
|             if (@pn > 0) {
 | |
|                 my $table2 = xCAT::Table->new("postscripts", -create => 1);
 | |
|                 if (!$table2) {
 | |
|                     my $rsp = {};
 | |
|                     $rsp->{data}->[0] = "Cannot open the postscripts table.\nFailed to remove the postscripts for $pname.";
 | |
|                     $callback->($rsp);
 | |
|                     return 1;
 | |
|                 }
 | |
|                 foreach my $group (@pn) {
 | |
|                     my $posts = $postscripts_h->{$group};
 | |
|                     if ($posts) {
 | |
|                         (my $ref) = $table2->getAttribs({ node => $group }, 'postscripts');
 | |
|                         if ($ref and $ref->{postscripts}) {
 | |
|                             my @old_a = split(',', $ref->{postscripts});
 | |
|                             my @new_a = split(',', $posts);
 | |
|                             my %new_h = ();
 | |
|                             my @new_post_a = ();
 | |
|                             foreach my $old_tmp (@old_a) {
 | |
|                                 my $found = 0;
 | |
|                                 foreach my $new_tmp (@new_a) {
 | |
|                                     if ($old_tmp eq $new_tmp) { $found = 1; last; }
 | |
|                                 }
 | |
|                                 if (!$found) { push(@new_post_a, $old_tmp); }
 | |
|                             }
 | |
| 
 | |
|                             if (@new_post_a > 0) {
 | |
|                                 my $new_post = join(',', @new_post_a);
 | |
|                                 if ($new_post ne $ref->{postscripts}) {
 | |
|                                     my %key_col2 = (node        => $group);
 | |
|                                     my %tb_cols2 = (postscripts => $new_post);
 | |
|                                     $table2->setAttribs(\%key_col2, \%tb_cols2);
 | |
|                                 }
 | |
|                             } else {
 | |
|                                 my %key_col2 = (node => $group);
 | |
|                                 $table2->delEntries(\%key_col2);
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|                 $table2->close();
 | |
|             }
 | |
|         }
 | |
|     } else {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "Cannot open monitoring table.";
 | |
|         $callback->($rsp);
 | |
|         return 1;
 | |
|     }
 | |
| 
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3  preprocess_moncfg
 | |
|         This function handles the syntax checking for moncfg command.
 | |
|     Arguments:
 | |
|       callback - the pointer to the callback function.
 | |
|       args - The format of the args is:
 | |
|         [-h|--help|-v|--version] or
 | |
|         name [noderange] [-r|--remote]
 | |
|         where
 | |
|           name is the monitoring plug-in name. For example: rmcmon.
 | |
|               The specified plug-in will be invoked for configuring the cluster to monitor the nodes.
 | |
|           noderange a range of nodes to be configured for. Default is all.
 | |
|           -r|--remote indicates that both monservers and the nodes need to configured.
 | |
|              The defaults is monservers only.
 | |
|     Returns:
 | |
|         (0, $modulename, $nodestatutmon, $scope, \@nodes) for success. scope is the scope of the
 | |
|             actions. 1 means monervers only, 2 means both nodes and monservers.
 | |
|         (1, "") for unsuccess. The error messages are returns through the callback pointer.
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub preprocess_moncfg
 | |
| {
 | |
|     my $args     = shift;
 | |
|     my $callback = shift;
 | |
| 
 | |
|     # subroutine to display the usage
 | |
|     sub moncfg_usage
 | |
|     {
 | |
|         my $cb  = shift;
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "Usage:";
 | |
|         $rsp->{data}->[1] = "  moncfg name [noderange] [-r|--remote]";
 | |
|         $rsp->{data}->[2] = "  moncfg [-h|--help|-v|--version]";
 | |
|         $rsp->{data}->[3] = "     name is the name of the monitoring plug-in module to be invoked.";
 | |
|         $rsp->{data}->[4] = "        Use 'monls -a' command to list all the monitoring plug-in names.";
 | |
|         $rsp->{data}->[5] = "     noderange is a range of nodes to be configured for. The default is all nodes.";
 | |
|         $rsp->{data}->[6] = "      -r|--remote indicates that both monservers and the nodes need to be configured.\n       The default is monservers only.";
 | |
|         $rsp->{data}->[7] = "        The default is monservers only.";
 | |
|         $cb->($rsp);
 | |
|     }
 | |
| 
 | |
|     @ARGV = ();
 | |
|     if ($args) { @ARGV = @{$args}; }
 | |
| 
 | |
|     # parse the options
 | |
|     if (!GetOptions(
 | |
|             'h|help'    => \$::HELP,
 | |
|             'v|version' => \$::VERSION,
 | |
|             'r|remote'  => \$::REMOTE,))
 | |
|     {
 | |
|         &moncfg_usage($callback);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     # display the usage if -h or --help is specified
 | |
|     if ($::HELP) {
 | |
|         &moncfg_usage($callback);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     # display the version statement if -v or --verison is specified
 | |
|     if ($::VERSION)
 | |
|     {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = xCAT::Utils->Version();
 | |
|         $callback->($rsp);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
| 
 | |
|     my $pname       = "";
 | |
|     my $scope       = 0;
 | |
|     my @nodes       = ();
 | |
|     my $nodestatmon = 0;
 | |
| 
 | |
|     if ($::REMOTE) { $scope = 2; }
 | |
| 
 | |
|     if (@ARGV < 1)
 | |
|     {
 | |
|         &moncfg_usage($callback);
 | |
|         return (1, "");
 | |
|     }
 | |
|     else {
 | |
|         $pname = $ARGV[0];
 | |
|         if (@ARGV > 1) {
 | |
|             my $noderange = $ARGV[1];
 | |
|             @nodes = noderange($noderange);
 | |
|             if (nodesmissed) {
 | |
|                 my $rsp = {};
 | |
|                 $rsp->{data}->[0] = "Invalid nodes in noderange:" . join(',', nodesmissed);
 | |
|                 $callback->($rsp);
 | |
|                 return (1, "");
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         my $file_name = "$::XCATROOT/lib/perl/xCAT_monitoring/$pname.pm";
 | |
|         if (!-e $file_name) {
 | |
|             my $rsp = {};
 | |
|             $rsp->{data}->[0] = "File $file_name does not exist.";
 | |
|             $callback->($rsp);
 | |
|             return (1, "");
 | |
|         } else {
 | |
| 
 | |
|             #load the module in memory
 | |
|             eval { require($file_name) };
 | |
|             if ($@) {
 | |
|                 my $rsp = {};
 | |
|                 $rsp->{data}->[0] = "The file $file_name has compiling errors:\n$@\n";
 | |
|                 $callback->($rsp);
 | |
|                 return (1, "");
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     my $table = xCAT::Table->new("monitoring", -create => 1, -autocommit => 1);
 | |
|     if ($table) {
 | |
|         my $found = 0;
 | |
|         my $tmp1  = $table->getAllEntries("all");
 | |
|         if (defined($tmp1) && (@$tmp1 > 0)) {
 | |
|             foreach (@$tmp1) {
 | |
|                 if ($pname eq $_->{name}) {
 | |
|                     $found = 1;
 | |
|                     if ($_->{nodestatmon} =~ /1|Yes|yes|YES|Y|y/) { $nodestatmon = 1; }
 | |
|                     last;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if (!$found) {
 | |
|             my $rsp = {};
 | |
|             $rsp->{data}->[0] = "$pname cannot be found in the monitoring table.";
 | |
|             $callback->($rsp);
 | |
|             $table->close();
 | |
|             return (1, "");
 | |
|         }
 | |
| 
 | |
|         $table->close();
 | |
|     } else {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "Failed to open the monitoring table.";
 | |
|         $callback->($rsp);
 | |
|         return (1, "");
 | |
|     }
 | |
| 
 | |
|     return (0, $pname, $nodestatmon, $scope, \@nodes);
 | |
| }
 | |
| 
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   moncfg
 | |
|       This function configures the cluster for the given nodes. It includes configuring
 | |
|       and setting up the 3rd party monitoring software for monitoring the given nodes.
 | |
|     Arguments:
 | |
|       request -- a hash table which contains the command name and the arguments.
 | |
|        callback -- the callback pointer for error and status displaying. It can be null.
 | |
|     Returns:
 | |
|         0 for success. The output is returned through the callback pointer.
 | |
|         1. for unsuccess. The error messages are returns through the callback pointer.
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub moncfg
 | |
| {
 | |
|     my $request  = shift;
 | |
|     my $callback = shift;
 | |
| 
 | |
|     my $pname       = $request->{module}->[0];
 | |
|     my $nodestatmon = $request->{nodestatmon}->[0];
 | |
|     my $scope       = $request->{scope}->[0];
 | |
|     my $nodeinfo    = $request->{nodeinfo}->[0];
 | |
| 
 | |
|     #print "---------monctrlcmnd::moncfg request=" . Dumper($request);
 | |
| 
 | |
|     my $grands = {};
 | |
|     my $total  = 0;
 | |
|     if (exists($request->{grand_total})) {
 | |
|         $total = $request->{grand_total};
 | |
|     }
 | |
|     for (my $i = 1 ; $i <= $total ; $i++) {
 | |
|         if (exists($request->{"grand_$i"})) {
 | |
|             my $temp = $request->{"grand_$i"};
 | |
|             my @tmpnodes = split(',', $temp);
 | |
|             if (@tmpnodes > 2) {
 | |
|                 my $sv  = shift(@tmpnodes);
 | |
|                 my $sv1 = shift(@tmpnodes);
 | |
|                 $grands->{"$sv,$sv1"} = \@tmpnodes;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     #print "-------grands" . Dumper($grands);
 | |
| 
 | |
|     my @nodes = split(',', $nodeinfo);
 | |
| 
 | |
|     #print "moncfg get called: pname=$pname\nnodestatmon=$nodestatmon\nnodeinfo=@nodes\nscope=$scope\n";
 | |
| 
 | |
|     xCAT_monitoring::monitorctrl->config([$pname], \@nodes, $scope, $callback, $grands);
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3  preprocess_mondecfg
 | |
|         This function handles the syntax checking for mondecfg command.
 | |
|     Arguments:
 | |
|       callback - the pointer to the callback function.
 | |
|       args - The format of the args is:
 | |
|         [-h|--help|-v|--version] or
 | |
|         name [noderange] [-r|--remote]
 | |
|         where
 | |
|           name is the monitoring plug-in name. For example: rmcmon.
 | |
|               The specified plug-in will be invoked for deconfiguring the cluster to monitor the nodes.
 | |
|           noderange a range of nodes to be deconfigured for. Default is all.
 | |
|           -r|--remote indicates that both monservers and the nodes need to be deconfigured.
 | |
|              The defaults is monservers only.
 | |
|     Returns:
 | |
|         (0, $modulename, $nodestatutmon, $scope, \@nodes) for success. scope is the scope of the
 | |
|             actions. 1 means monervers only, 2 means both nodes and monservers.
 | |
|         (1, "") for unsuccess. The error messages are returns through the callback pointer.
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub preprocess_mondecfg
 | |
| {
 | |
|     my $args     = shift;
 | |
|     my $callback = shift;
 | |
| 
 | |
|     # subroutine to display the usage
 | |
|     sub mondecfg_usage
 | |
|     {
 | |
|         my $cb  = shift;
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "Usage:";
 | |
|         $rsp->{data}->[1] = "  mondecfg name [noderange] [-r|--remote]";
 | |
|         $rsp->{data}->[2] = "  mondecfg [-h|--help|-v|--version]";
 | |
|         $rsp->{data}->[3] = "     name is the name of the monitoring plug-in module to be invoked.";
 | |
|         $rsp->{data}->[4] = "        Use 'monls -a' command to list all the monitoring plug-in names.";
 | |
|         $rsp->{data}->[5] = "     noderange is a range of nodes to be deconfigured for.";
 | |
|         $rsp->{data}->[6] = "        The default is all nodes.";
 | |
|         $rsp->{data}->[7] = "      -r|--remote indicates that both monservers and the nodes need to be deconfigured.";
 | |
|         $rsp->{data}->[8] = "        The default is monservers only.";
 | |
|         $cb->($rsp);
 | |
|     }
 | |
| 
 | |
|     @ARGV = ();
 | |
|     if ($args) { @ARGV = @{$args}; }
 | |
| 
 | |
|     # parse the options
 | |
|     if (!GetOptions(
 | |
|             'h|help'    => \$::HELP,
 | |
|             'v|version' => \$::VERSION,
 | |
|             'r|remote'  => \$::REMOTE,))
 | |
|     {
 | |
|         &mondecfg_usage($callback);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     # display the usage if -h or --help is specified
 | |
|     if ($::HELP) {
 | |
|         &mondecfg_usage($callback);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     # display the version statement if -v or --verison is specified
 | |
|     if ($::VERSION)
 | |
|     {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = xCAT::Utils->Version();
 | |
|         $callback->($rsp);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
| 
 | |
|     my $pname       = "";
 | |
|     my $scope       = 0;
 | |
|     my @nodes       = ();
 | |
|     my $nodestatmon = 0;
 | |
| 
 | |
|     if ($::REMOTE) { $scope = 2; }
 | |
| 
 | |
|     if (@ARGV < 1)
 | |
|     {
 | |
|         &mondecfg_usage($callback);
 | |
|         return (1, "");
 | |
|     }
 | |
|     else {
 | |
|         $pname = $ARGV[0];
 | |
|         if (@ARGV > 1) {
 | |
|             my $noderange = $ARGV[1];
 | |
|             @nodes = noderange($noderange);
 | |
|             if (nodesmissed) {
 | |
|                 my $rsp = {};
 | |
|                 $rsp->{data}->[0] = "Invalid nodes in noderange:" . join(',', nodesmissed);
 | |
|                 $callback->($rsp);
 | |
|                 return (1, "");
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         my $file_name = "$::XCATROOT/lib/perl/xCAT_monitoring/$pname.pm";
 | |
|         if (!-e $file_name) {
 | |
|             my $rsp = {};
 | |
|             $rsp->{data}->[0] = "File $file_name does not exist.";
 | |
|             $callback->($rsp);
 | |
|             return (1, "");
 | |
|         } else {
 | |
| 
 | |
|             #load the module in memory
 | |
|             eval { require($file_name) };
 | |
|             if ($@) {
 | |
|                 my $rsp = {};
 | |
|                 $rsp->{data}->[0] = "The file $file_name has compiling errors:\n$@\n";
 | |
|                 $callback->($rsp);
 | |
|                 return (1, "");
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     my $table = xCAT::Table->new("monitoring", -create => 1, -autocommit => 1);
 | |
|     if ($table) {
 | |
|         my $found = 0;
 | |
|         my $tmp1  = $table->getAllEntries("all");
 | |
|         if (defined($tmp1) && (@$tmp1 > 0)) {
 | |
|             foreach (@$tmp1) {
 | |
|                 if ($pname eq $_->{name}) {
 | |
|                     $found = 1;
 | |
|                     if ($_->{nodestatmon} =~ /1|Yes|yes|YES|Y|y/) { $nodestatmon = 1; }
 | |
|                     last;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if (!$found) {
 | |
|             my $rsp = {};
 | |
|             $rsp->{data}->[0] = "$pname cannot be found in the monitoring table.";
 | |
|             $callback->($rsp);
 | |
|             $table->close();
 | |
|             return (1, "");
 | |
|         }
 | |
| 
 | |
|         $table->close();
 | |
|     } else {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "Failed to open the monitoring table.";
 | |
|         $callback->($rsp);
 | |
|         return (1, "");
 | |
|     }
 | |
| 
 | |
|     return (0, $pname, $nodestatmon, $scope, \@nodes);
 | |
| }
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   mondecfg
 | |
|       This function deconfigures the cluster for the given nodes. It includes deconfiguring
 | |
|       and clearning up the 3rd party monitoring software for monitoring the given nodes.
 | |
|     Arguments:
 | |
|        names -- a pointer to an  array of monitoring plug-in names. If non is specified,
 | |
|          all the plug-ins registered in the monitoring table will be notified.
 | |
|        p_nodes -- a pointer to an arrays of nodes to be removed from the monitoring domain.
 | |
|                   none means all.
 | |
|        scope -- the action scope, it indicates the node type the action will take place.
 | |
|                 0 means localhost only.
 | |
|                 1 means monserver only,
 | |
|                 2 means both monservers and nodes,
 | |
|        callback -- the callback pointer for error and status displaying. It can be null.
 | |
|     Returns:
 | |
|         0 for success. The output is returned through the callback pointer.
 | |
|         1. for unsuccess. The error messages are returns through the callback pointer.
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub mondecfg
 | |
| {
 | |
|     my $request  = shift;
 | |
|     my $callback = shift;
 | |
| 
 | |
|     my $pname       = $request->{module}->[0];
 | |
|     my $nodestatmon = $request->{nodestatmon}->[0];
 | |
|     my $scope       = $request->{scope}->[0];
 | |
|     my $nodeinfo    = $request->{nodeinfo}->[0];
 | |
| 
 | |
|     my $grands = {};
 | |
|     my $total  = 0;
 | |
|     if (exists($request->{grand_total})) {
 | |
|         $total = $request->{grand_total};
 | |
|     }
 | |
|     for (my $i = 1 ; $i <= $total ; $i++) {
 | |
|         if (exists($request->{"grand_$i"})) {
 | |
|             my $temp = $request->{"grand_$i"};
 | |
|             my @tmpnodes = split(',', $temp);
 | |
|             if (@tmpnodes > 2) {
 | |
|                 my $sv  = shift(@tmpnodes);
 | |
|                 my $sv1 = shift(@tmpnodes);
 | |
|                 $grands->{"$sv,$sv1"} = \@tmpnodes;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     #print "-------grands" . Dumper($grands);
 | |
| 
 | |
|     my @nodes = split(',', $nodeinfo);
 | |
| 
 | |
|     #print "mondecfg get called: pname=$pname\nnodestatmon=$nodestatmon\nnodeinfo=@nodes\nscope=$scope\n";
 | |
| 
 | |
|     xCAT_monitoring::monitorctrl->deconfig([$pname], \@nodes, $scope, $callback, $grands);
 | |
| 
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3  preprocess_monshow
 | |
|         This function handles the syntax checking for monshow command.
 | |
|     Arguments:
 | |
|       callback - the pointer to the callback function.
 | |
|       args - The format of the args is:
 | |
|         [-h|--help|-v|--version] or
 | |
|         name [noderange] [-s] [-t time] [-a attributes] [-w attr<operator>val [-w attr<operator>val] ...] [-o pe]
 | |
|         where
 | |
|           name is the monitoring plug-in name. For example: rmcmon. Only for rmcmon currently.
 | |
|           noderange a range of nodes to be showed for. If omitted, the data for all the nodes will be displayed.
 | |
|           -s shows the summary data only
 | |
|           -t specify a range of time for the data, default is last 60 minutes
 | |
| 	  -a specifies a comma-separated list of attributes or metrics names. The default is all.
 | |
|     Returns:
 | |
|         (0, $modulename, $sum, $time, \@nodes, $attrs, $pe, $where) for success.
 | |
|         (1, "") for unsuccess. The error messages are returns through the callback pointer.
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub preprocess_monshow
 | |
| {
 | |
|     my $args     = shift;
 | |
|     my $callback = shift;
 | |
| 
 | |
|     # subroutine to display the usage
 | |
|     sub monshow_usage
 | |
|     {
 | |
|         my $cb    = shift;
 | |
|         my $error = shift;
 | |
|         my $rsp   = {};
 | |
|         $rsp->{data}->[0] = "Usage:";
 | |
|         $rsp->{data}->[1] = "  monshow name noderange [-s] [-t time] [-a attributes] [-w attr<operator>val[-w attr<operator>val ...]][-o pe]";
 | |
|         $rsp->{data}->[2] = "  monshow [-h|--help|-v|--version]";
 | |
|         $rsp->{data}->[3] = "     name is the name of the monitoring plug-in module to be invoked.";
 | |
|         $rsp->{data}->[4] = "     noderange is a list of nodes to be showed for. If omitted,";
 | |
|         $rsp->{data}->[5] = "        the data for all the nodes will be displayed.";
 | |
|         $rsp->{data}->[6] = "     -s shows the summary data.";
 | |
|         $rsp->{data}->[7] = "     -t specifies a range of time for the data, The default is last 60 minutes";
 | |
|         $rsp->{data}->[8] = "     -a specifies a comma-separated list of attributes or metrics names. The default is all.";
 | |
|         $rsp->{data}->[9] = "     -w specifies one or multiple selection string that can be used to select events.";
 | |
|         $rsp->{data}->[10] = "     -o specifies montype, it can be p, e or pe.";
 | |
|         $rsp->{data}->[11] = "        p means performance, e means events, default is e";
 | |
| 
 | |
|         #    $cb->($rsp);
 | |
|         xCAT::MsgUtils->message("D", $rsp, $callback, $error);
 | |
|     }
 | |
| 
 | |
|     @ARGV = ();
 | |
|     if ($args) { @ARGV = @{$args}; }
 | |
| 
 | |
|     # parse the options
 | |
|     if (!GetOptions(
 | |
|             'h|help'    => \$::HELP,
 | |
|             'v|version' => \$::VERSION,
 | |
|             's'         => \$::SUMMARY,
 | |
|             't=s'       => \$::TIME,
 | |
|             'a=s'       => \$::ATTRS,
 | |
|             'o=s'       => \$::PE,
 | |
|             'w=s@'      => \$::OPT_W))
 | |
|     {
 | |
|         &monshow_usage($callback, 1);
 | |
|         return (1, "");
 | |
|     }
 | |
| 
 | |
|     # display the usage if -h or --help is specified
 | |
|     if ($::HELP) {
 | |
|         &monshow_usage($callback, 0);
 | |
|         return (1, "");
 | |
|     }
 | |
| 
 | |
|     # display the version statement if -v or --verison is specified
 | |
|     if ($::VERSION)
 | |
|     {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = xCAT::Utils->Version();
 | |
|         $callback->($rsp);
 | |
|         return (1, "");
 | |
|     }
 | |
| 
 | |
|     my $pname = "";
 | |
|     my $sum   = 0;
 | |
|     my $time  = 60;
 | |
|     my @nodes = ();
 | |
|     my $attrs = undef;
 | |
|     my $pe    = 'e';
 | |
|     my $where = [];
 | |
| 
 | |
|     if (@ARGV < 1) {
 | |
|         &monshow_usage($callback, 1);
 | |
|         return (1, "");
 | |
|     }
 | |
| 
 | |
|     if ($::SUMMARY) { $sum  = 1; }
 | |
|     if ($::TIME)    { $time = $::TIME; }
 | |
|     if ($::ATTRS) {
 | |
|         $attrs = $::ATTRS;
 | |
|     } else {
 | |
|         my $conftable = xCAT::Table->new('monsetting');
 | |
|         my @metrixconf = $conftable->getAttribs({ 'name' => 'rmcmon' }, ('key', 'value'));
 | |
|         foreach (@metrixconf) {
 | |
|             my $key   = $_->{key};
 | |
|             my $value = $_->{value};
 | |
|             my $temp  = undef;
 | |
|             if ($key =~ /^rmetrics/) {
 | |
|                 if ($value =~ /\]/) {
 | |
|                     ($temp, $value) = split /\]/, $value;
 | |
|                 }
 | |
|                 ($value, $temp) = split /:/, $value;
 | |
|                 if ($attrs) {
 | |
|                     $attrs = "$attrs,$value";
 | |
|                 } else {
 | |
|                     $attrs = $value;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     if ($::PE) { $pe = $::PE; }
 | |
|     if ($::OPT_W) {
 | |
|         $where = $::OPT_W;
 | |
|     }
 | |
| 
 | |
|     $pname = $ARGV[0];
 | |
| 
 | |
|     my $noderange = '';
 | |
|     if (@ARGV == 1) {
 | |
|         if ($sum) {
 | |
|             $sum |= 0x2;
 | |
|         }
 | |
|     } else {
 | |
|         $noderange = $ARGV[1];
 | |
|     }
 | |
| 
 | |
|     @nodes = noderange($noderange);
 | |
| 
 | |
|     if (xCAT::Utils->isMN() && nodesmissed) {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "Invalid nodes in noderange:" . join(',', nodesmissed);
 | |
|         xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|         return (1, "");
 | |
|     }
 | |
| 
 | |
|     my $file_name = "$::XCATROOT/lib/perl/xCAT_monitoring/$pname.pm";
 | |
|     if (!-e $file_name) {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "File $file_name does not exist.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|         return (1, "");
 | |
|     } else {
 | |
| 
 | |
|         #load the module in memory
 | |
|         eval { require($file_name) };
 | |
|         if ($@) {
 | |
|             my $rsp = {};
 | |
|             $rsp->{data}->[0] = "The file $file_name has compiling errors:\n$@\n";
 | |
|             xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|             return (1, "");
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     my $table = xCAT::Table->new("monitoring", -create => 1, -autocommit => 1);
 | |
|     if ($table) {
 | |
|         my $found = 0;
 | |
|         my $tmp1  = $table->getAllEntries();
 | |
|         if (defined($tmp1) && (@$tmp1 > 0)) {
 | |
|             foreach (@$tmp1) {
 | |
|                 if ($pname eq $_->{name}) {
 | |
|                     $found = 1;
 | |
|                     last;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if (!$found) {
 | |
|             my $rsp = {};
 | |
|             $rsp->{data}->[0] = "$pname cannot be found in the monitoring table.";
 | |
|             xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|             $table->close();
 | |
|             return (1, "");
 | |
|         }
 | |
| 
 | |
|         $table->close();
 | |
|     } else {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "Failed to open the monitoring table.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|         return (1, "");
 | |
|     }
 | |
| 
 | |
|     return (0, $pname, $sum, $time, \@nodes, $attrs, $pe, $where);
 | |
| }
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   monshow
 | |
|       This function configures the cluster performance for the given nodes.
 | |
|     Arguments:
 | |
|       request -- a hash table which contains the command name and the arguments.
 | |
|       callback -- the callback pointer for error and status displaying. It can be null.
 | |
|     Returns:
 | |
|         0 for success. The output is returned through the callback pointer.
 | |
|         1. for unsuccess. The error messages are returns through the callback pointer.
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub monshow
 | |
| {
 | |
|     my $request  = shift;
 | |
|     my $callback = shift;
 | |
| 
 | |
|     my $pname    = $request->{module}->[0];
 | |
|     my $nodeinfo = $request->{nodeinfo}->[0];
 | |
|     my $sum      = $request->{priv}->[0];
 | |
|     my $time     = $request->{priv}->[1];
 | |
|     my $attrs    = $request->{priv}->[2];
 | |
|     my $pe       = $request->{priv}->[3];
 | |
|     my $where    = $request->{priv}->[4];
 | |
| 
 | |
|     my @nodes = split(',', $nodeinfo);
 | |
| 
 | |
|     xCAT_monitoring::monitorctrl->show([$pname], \@nodes, $sum, $time, $attrs, $pe, $where, $callback);
 | |
|     return 0;
 | |
| }
 | |
| 
 |