mirror of
https://github.com/xcat2/xcat-core.git
synced 2025-05-22 11:42:05 +00:00
239 lines
8.6 KiB
Perl
Executable File
239 lines
8.6 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
# IBM(c) 2016 EPL license http://www.eclipse.org/legal/epl-v10.html
|
|
|
|
#--------------------------------------------------------
|
|
#This is a template for developing a new probe sub_command. Especially in hierarchical environment.
|
|
#This template mainly implement the sub_comamd dispatch in hierarchical structure and basic framework of a new sub_comamd.
|
|
#Developer only need to focus on main probe job (by implement do_main_job function) and friendly output (by implement summary_all_jobs_output function) for user.
|
|
#This template can also be used in flat structure. but if developer think it's too heavy in flat, it's fine to develop sub command directly.
|
|
#But in hierarchical structure, we strongly recommand using this template.
|
|
#
|
|
#The main dispatch policy are:
|
|
#1. if there isn't noderange input from commmand line and there are service nodes defined in current MN,
|
|
# dispatch exact same command input from STDIN to all SNs and current MN. if there isn't service nodes defined,
|
|
# just hanld command input from STDIN in current MN
|
|
#2. If there is noderange input from command line by opion "-n", we will dispatch the command input from STDIN to SN which can hanle these ndoes
|
|
# For example, if we got command from STDIN like "probecommand -n test[1-15] -V" and test[1-5] 's SN is SN1, test[6-10]'s SN is SN2
|
|
# The dispatch result will be:
|
|
# For MN run: probecommand -n test[11-15] -V
|
|
# For SN1 run: probecommand -n test[1-5] -V
|
|
# For SN2 run: probecommand -n test[6-10] -V
|
|
#3. All the return message from SNs and MN will be saved in hash %summaryoutput, develper can use it when implement summary_all_jobs_output function
|
|
#--------------------------------------------------------
|
|
|
|
BEGIN { $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr'; }
|
|
|
|
use lib "$::XCATROOT/probe/lib/perl";
|
|
use probe_utils;
|
|
use hierarchy;
|
|
use File::Basename;
|
|
use Data::Dumper;
|
|
use Getopt::Long qw(:config no_ignore_case);
|
|
|
|
|
|
my $help = 0; #command line attribute '-h', get usage information
|
|
my $test = 0; #command line attribute '-T'
|
|
my $hierarchy = 0;
|
|
my $verbose = 0; #command line attribute '-V'
|
|
my $noderange; #command line attribute '-n'
|
|
my $output = "stdout"; #used by probe_utils->send_msg("$output", "o", "xxxxxxxxxx"); print output to STDOUT
|
|
my $is_sn = 0; #flag current server is SN
|
|
my $rst = 0; #the exit code of current command
|
|
my $terminal = 0; #means get INT signal from STDIN
|
|
|
|
#save all output from commands running on SNs and MN
|
|
# one example:
|
|
# $summaryoutput{mn} = @mn_output_history
|
|
# $summaryoutput{SN1} = @SN1_output_history
|
|
my %summaryoutput;
|
|
|
|
my $is_sn;
|
|
$is_sn = 1 if (-e "/etc/xCATSN");
|
|
|
|
#-------------------------------------
|
|
# Usage
|
|
#-------------------------------------
|
|
# below are some options rules used by default
|
|
# -h : Get usage information of current sub command
|
|
# -V : Output more information for debug
|
|
# -T : To verify if $program_name can work, reserve option for probe framework, dosen't use by customer
|
|
# -n : In xCAT probe, -n is uesd to specify node range uniformly
|
|
#-------------------------------------
|
|
my $program_name = basename("$0"); #current sub_command name
|
|
$::USAGE = "Usage:
|
|
$program_name -h
|
|
$program_name [-V]
|
|
|
|
Description:
|
|
This is a template for developing a probe sub_command.
|
|
<# ADD DESCRIPTION FOR YOUR COMMAND #>
|
|
|
|
Options:
|
|
-h : Get usage information of $program_name
|
|
-V : Output more information for debug
|
|
";
|
|
|
|
#------------------------------------
|
|
# Please implement the main job of current command in do_main_job function
|
|
# Recommand to use probe_utils->send_msg() to handle message you plan to print out to STDOUT
|
|
# A simple example has been written in funciton.
|
|
#------------------------------------
|
|
sub do_main_job {
|
|
my $rst = 0;
|
|
|
|
probe_utils->send_msg("$output", "o", "Received node range: $noderange");
|
|
|
|
#<#DO YOUR OWN JOB1#>
|
|
probe_utils->send_msg("$output", "o", "Do the first job");
|
|
|
|
#<#DO YOUR OWN JOB2#>
|
|
probe_utils->send_msg("$output", "f", "Do the second job");
|
|
|
|
return $rst;
|
|
}
|
|
|
|
#-------------------------------------
|
|
# When this command return from all SNs and MN, you need to generate a summary
|
|
# All history outpout from SNs and MN are saved in globle hash %summaryoutput.
|
|
# $summaryoutput{mn} = @mnhistory
|
|
# $summaryoutput{snname1} = @snname1history;
|
|
# The entry in each histroy array isn't categorized, the message coming early is arranged before the one coming later.
|
|
# A simple example of how to dump %summaryoutput has been written in function
|
|
#-------------------------------------
|
|
sub summary_all_jobs_output {
|
|
my $rst = 0;
|
|
|
|
#DO SUMMARY DEPENDING ON YOUR SUB_COMMAND NEED
|
|
probe_utils->send_msg("$output", "d", "======================do summary=====================");
|
|
|
|
#print "summaryoutput:\n";
|
|
#print Dumper \%summaryoutput;
|
|
|
|
foreach my $sn (keys %summaryoutput) {
|
|
probe_utils->send_msg("$output", "d", "[$sn]");
|
|
foreach my $log (@{ $summaryoutput{$sn} }) {
|
|
probe_utils->send_msg("$output", "d", "\t$log");
|
|
}
|
|
}
|
|
return $rst;
|
|
}
|
|
|
|
#-------------------------------------
|
|
# main process
|
|
#-------------------------------------
|
|
my @tmpargv = @ARGV;
|
|
if (
|
|
!GetOptions("--help|h" => \$help,
|
|
"T" => \$test,
|
|
"H" => \$hierarchy,
|
|
"n=s" => \$noderange,
|
|
"V" => \$verbose))
|
|
{
|
|
probe_utils->send_msg("$output", "f", "Invalid parameter for $program_name");
|
|
probe_utils->send_msg("$output", "d", "$::USAGE");
|
|
exit 1;
|
|
}
|
|
|
|
if ($help) {
|
|
if ($output ne "stdout") {
|
|
probe_utils->send_msg("$output", "d", "$::USAGE");
|
|
} else {
|
|
print "$::USAGE";
|
|
}
|
|
exit 0;
|
|
}
|
|
|
|
if ($test) {
|
|
probe_utils->send_msg("$output", "o", "This isn't a probe tool, this is just a template for sub command coding. Using it to develop sub command which need to cover hierarchical cluster");
|
|
exit 0;
|
|
}
|
|
|
|
#Handle the interrupt signal from STDIN
|
|
$SIG{TERM} = $SIG{INT} = sub {
|
|
$terminal = 1;
|
|
};
|
|
|
|
#if it is called by hierarchy template, just run job, not to do dispatch
|
|
if ($hierarchy || $is_sn) {
|
|
$rst = do_main_job();
|
|
exit $rst;
|
|
}
|
|
|
|
my $hierarchy_instance = hierarchy->new();
|
|
|
|
#-------starting to dispatch_cmd--------
|
|
my @error;
|
|
$rst = $hierarchy_instance->dispatch_cmd($noderange, \@tmpargv, \@error);
|
|
if ($rst) {
|
|
probe_utils->send_msg("$output", "f", "Calculate dispatch command failed");
|
|
foreach (@error) {
|
|
probe_utils->send_msg("$output", "", "$_");
|
|
}
|
|
if ($hierarchy_instance->destory(\@error)) {
|
|
probe_utils->send_msg("$output", "", "$_") foreach (@error);
|
|
}
|
|
exit $rst;
|
|
}
|
|
|
|
#----------start to read reply-------
|
|
my %reply_cache;
|
|
while ($hierarchy_instance->read_reply(\%reply_cache)) {
|
|
foreach my $servers (keys %reply_cache) { #Dispatch_cmd may use SN range to dispatch cms to SNs at one time
|
|
my @server_array = split(",", $servers);
|
|
foreach my $server (@server_array) {
|
|
foreach (@{ $reply_cache{$servers} }) {
|
|
my $msg = "";
|
|
my $logmsg = "";
|
|
|
|
#For cases like below:
|
|
#c910f02c04p04: [ok] :All xCAT deamons are running
|
|
if ($reply_cache{$servers}->[$_] =~ /^(\w+)\s*:\s*(\[\w+\]\s*):\s*(.*)/) {
|
|
if ("$1" eq "$server") {
|
|
$logmsg = "$2: $3";
|
|
$msg = "$2:<$server>: $3";
|
|
}
|
|
|
|
#For cases like below:
|
|
#c910f02c04p05: IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
|
|
} elsif ($reply_cache{$servers}->[$_] =~ /^(\w+)\s*:\s*(.*)/) {
|
|
if ("$1" eq "$server") {
|
|
$logmsg = "$2";
|
|
$msg = "<$server>: $2";
|
|
}
|
|
|
|
#For cases like below:
|
|
#Unable to open socket connection to xcatd daemon on localhost:3001.
|
|
} else {
|
|
if (length($reply_cache{$servers}->[$_])) {
|
|
$logmsg = $reply_cache{$servers}->[$_];
|
|
$msg = "[failed] :[$server]: $reply_cache{$servers}->[$_]";
|
|
}
|
|
}
|
|
probe_utils->send_msg("$output", "", "$msg") if (length($msg));
|
|
push @{ $summaryoutput{$server} }, $logmsg if (length($logmsg));
|
|
}
|
|
}
|
|
}
|
|
if ($terminal) {
|
|
last;
|
|
}
|
|
}
|
|
|
|
#----------hierarchy_instance->destory-----------
|
|
if ($hierarchy_instance->destory(\@error)) {
|
|
probe_utils->send_msg("$output", "", "$_") foreach (@error);
|
|
}
|
|
|
|
#-------------------------------------
|
|
# summary all jobs output to display
|
|
#-------------------------------------
|
|
$rst = summary_all_jobs_output();
|
|
|
|
exit $rst;
|
|
|
|
|
|
|
|
|
|
|
|
|