2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2025-08-24 20:20:33 +00:00
Files
xcat-core/xCAT-probe/xcatprobe
2016-05-26 05:45:20 -04:00

259 lines
6.1 KiB
Perl
Executable File

#!/usr/bin/env perl
use File::Basename;
use Data::Dumper;
use File::Path;
use POSIX qw(WNOHANG setsid :errno_h);
use Term::ANSIColor qw(:constants);
$Term::ANSIColor::AUTORESET=1;
my $pro_name=basename($0);
my $pro_dir=dirname($0);
#my $plugin_dir="$pro_dir/subcmds";
my $plugin_dir="/opt/xcat/probe/subcmds";
my %cmds=();
my $verbose=0;
my $nocolor=0;
my $help=0;
my $list=0;
$::USAGE = "Usage:
xcatprobe -h
xcatprobe -l
xcatprobe -v
xcatprobe [-n] <subcommand> <attrbute_to_subcommand>
Options:
-h : get usage information of $pro_name
-l : list all valid sub commands
-v : print verbose information of $pro_name
-n : print output without colors
";
#-----------------------------------
=head3
Description:
Load sub commands from ~/subcmds directory
Using -t option of command to judge if it is valid.
If command in ~/subcmds has syntax error, or doesn't follow interface specification, this command will be skipped
=cut
#-----------------------------------
sub loadsubcmds{
my @candidate=glob("$plugin_dir/*");
my @subcmds=();
my @validflag=("debug", "warning", "failed", "ok");
my $output;
print "Starting to load sub command form ~/subcmds.............\n" if($verbose);
foreach (@candidate) {
my $cmdname = basename("$_");
$output = `$_ -t 2>&1`;
chomp($output);
print "\n-->$_\n[OUTPUT]:\n$output\n" if($verbose);
if($output !~ /\[(\w+)\]\s*:\s*(.+)/){
print "skip $_ for doing '$_ -t' failed, bad format\n" if($verbose);
next;
}else{
my $desc =$2;
unless(@validflag ~~ /$1/){
print "skip $_ for doing '$_ -t' failed, invalid flag\n" if($verbose);
next;
}
$cmds{$cmdname} = $desc;
print "load $_ \n" if($verbose);
}
}
print "\nLoad sub command.........[done]\n" if($verbose);
}
#-----------------------------------
=head3
Description:
Format the output of sub command, make them colorfully.
=cut
#----------------------------------
sub format_cmd_output{
my $line=shift;
my $nocolor=shift;
if($line =~ /\[(\w+)\]\s*:\s*(.+)/){
my $flag = $1;
my $msg = $2;
if($flag =~ /failed/i){
if($nocolor){
print "[FAIL] ";
}else{
print BOLD RED "[FAIL] ";
}
}elsif($flag =~ /warning/i){
if($nocolor){
print "[WARN] ";
}else{
print BOLD BLUE "[WARN] ";
}
}elsif($flag =~ /ok/i){
if($nocolor){
print "[ OK ] ";
}else{
print BOLD GREEN "[ OK ] ";
}
}elsif($flag =~ /debug/i){
print " ";
}
print "$msg\n";
}else{
print "$line\n";
}
return 0;
}
#-----------------------------------
=head3
Description:
List all valid sub command in ~/subcmds directory
=cut
#----------------------------------
sub listvalidsubcmd{
my $maxlen=0;
foreach my $key (keys %cmds) {
$maxlen=length($key) if(length($key)>$maxlen);
}
$maxlen+=4;
print "Supported sub commands are:\n";
foreach my $key (keys %cmds){
my @desc=split(" ", $cmds{$key});
my $str="";
my @formatdesc=();
foreach my $word (@desc){
$str.=$word." ";
if(length($str)>100){
push @formatdesc, $str;
$str="";
}
}
push @formatdesc, $str;
if($nocolor){
print "$key";
}else{
print BOLD GREEN "$key";
}
my $space=" " x ($maxlen-length($key));
print "$space $formatdesc[0]\n";
delete $formatdesc[0];
$space=" " x $maxlen;
foreach my $line (@formatdesc){
print "$space $line\n" if(length($line));
}
}
}
#######################################
# main
#######################################
my @tmpargv=@ARGV;
my @supportopt=("-v","-h","-l","-n");
my $pluginname;
my $optnum=0;
foreach my $attr (@tmpargv){
if($attr =~ /^-/){
unless(@supportopt ~~ /$attr/){
print "Unsupported attribute: $attr\n";
print $::USAGE;
exit 1;
}
$optnum++;
$help=1 if($attr eq "-h");
$verbose=1 if($attr eq "-v");
$list=1 if($attr eq "-l");
$nocolor=1 if($attr eq "-n");
}else{
$pluginname=$attr;
last;
}
}
&loadsubcmds;
if(defined ($pluginname)){
my $hit=0;
foreach my $key (keys %cmds){
$hit=1 if($pluginname eq $key);
}
unless($hit){
print "Unsupported sub command: $pluginname\n";
&listvalidsubcmd;
exit 1;
}
}
if($help){
print $::USAGE;
exit 0;
}
if($ARGV[0] eq "-l"){
&listvalidsubcmd;
exit 0;
}
if(!defined ($pluginname)){
print "There isn't sub command input from command line\n";
exit 0;
}
for(my $i =0; $i<$optnum+1; $i++){
shift @tmpargv;
}
my $pluginattrs = join(" ", @tmpargv);
my $date = `date +"%Y%m%d%H%M%S"`;
chomp($date);
my $cmmpath="/tmp/probe";
my $cmmfile="$cmmpath/$pluginname.$date";
mkpath("$cmmpath") unless(-d "$cmmpath");
`touch $cmmfile`;
my $subcmd="$plugin_dir/$pluginname -f $cmmfile $pluginattrs";
print "\n[main] subcmd = $subcmd\n" if($verbose);
my $subproc = fork();
my $subrst=0;
if(!defined($subproc)){
print "Unable to fork new process to run subcommand\n";
exit 1;
}elsif($subproc==0){
$SIG{INT} = sub {
print "Sub proc $$ recrive INT signal to exit";
exit 0;
};
print "[sub $$] run $subcmd\n----------------------\n" if($verbose);
`$subcmd`;
exit $? ;
}
if(!open (CMMFILE, "$cmmfile") ) {
print "[main] Failed to open $cmmfile\n";
exit 1;
}
my $offset = 0;
my $prst=0;
if($subproc){
do{
seek(CMMFILE,$offset,0);
while(my $line = <CMMFILE>){
chomp($line);
format_cmd_output($line, $nocolor);
}
$offset=tell;
}while(waitpid($subproc, WNOHANG)==0)
}
close(CMMFILE);
unlink($cmmfile);
exit 0;