2a0c3001c7
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@2018 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
1550 lines
47 KiB
Perl
1550 lines
47 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;
|
|
|
|
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",
|
|
}
|
|
}
|
|
|
|
#-------------------------------------------------------
|
|
=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
|
|
my $args=$req->{arg};
|
|
|
|
my @requests=();
|
|
|
|
|
|
if (($command eq "monstart") || ($command eq "monstop") || ($command eq "moncfg") || ($command eq "mondecfg") ) {
|
|
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);
|
|
} else {
|
|
@a_ret=preprocess_mondecfg($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};
|
|
#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);
|
|
}
|
|
|
|
my @mon_servers=keys(%$mon_hierachy);
|
|
my @hostinfo=xCAT::Utils->determinehostname();
|
|
#print "hostinfo=@hostinfo\n";
|
|
my $isSV=xCAT::Utils->isServiceNode();
|
|
my %iphash=();
|
|
foreach(@hostinfo) {$iphash{$_}=1;}
|
|
if (!$isSV) { $iphash{'noservicenode'}=1;}
|
|
|
|
foreach (@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(',', $_);
|
|
my $sv=$server_pair[0];
|
|
my $mon_nodes=$mon_hierachy->{$_};
|
|
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.
|
|
$reqcopy->{'_xcatdest'}=$sv;
|
|
my $rsp2={};
|
|
$rsp2->{data}->[0]="sending request to $sv...";
|
|
$callback->($rsp2);
|
|
}
|
|
|
|
push @{$reqcopy->{module}}, $a_ret[1];
|
|
push @{$reqcopy->{nodestatmon}}, $a_ret[2];
|
|
push @{$reqcopy->{scope}}, $a_ret[3];
|
|
push @{$reqcopy->{nodeinfo}}, join(',', @$mon_nodes);
|
|
push @requests, $reqcopy;
|
|
}
|
|
}
|
|
} 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);
|
|
} 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();
|
|
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 @nodes=split(',', $nodeinfo);
|
|
print "monstart get called: pname=$pname\nnodestatmon=$nodestatmon\nnodeinfo=$nodeinfo\nscope=$scope\n";
|
|
|
|
xCAT_monitoring::monitorctrl->startMonitoring([$pname], \@nodes, $scope, $callback);
|
|
|
|
if ($nodestatmon) {
|
|
xCAT_monitoring::monitorctrl->startNodeStatusMonitoring($pname, \@nodes, $scope, $callback);
|
|
}
|
|
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 stoped 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();
|
|
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 @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);
|
|
}
|
|
|
|
xCAT_monitoring::monitorctrl->stopMonitoring([$pname], \@nodes, $scope, $callback);
|
|
|
|
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();
|
|
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: [key1=value1],[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();
|
|
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"....
|
|
while ($settings =~ s/^\[([^\[\]\=]*)=([^\[\]]*)\](,)*//) {
|
|
$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();
|
|
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();
|
|
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];
|
|
|
|
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);
|
|
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();
|
|
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 @nodes=split(',', $nodeinfo);
|
|
print "mondecfg get called: pname=$pname\nnodestatmon=$nodestatmon\nnodeinfo=@nodes\nscope=$scope\n";
|
|
|
|
xCAT_monitoring::monitorctrl->deconfig([$pname], \@nodes, $scope, $callback);
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
|