mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-11-03 21:02:34 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			308 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			308 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env perl
 | 
						|
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
 | 
						|
 | 
						|
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;
 | 
						|
 | 
						|
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
 | 
						|
 | 
						|
my $program_name = basename($0);
 | 
						|
 | 
						|
my $pro_dir    = "$::XCATROOT/probe/";
 | 
						|
my $plugin_dir = "$pro_dir/subcmds";
 | 
						|
my %cmds       = ();
 | 
						|
 | 
						|
my $verbose = 0;
 | 
						|
my $color   = (-t *STDOUT);
 | 
						|
my $fullmsg = 0;
 | 
						|
my $help    = 0;
 | 
						|
my $list    = 0;
 | 
						|
 | 
						|
$::USAGE = "Usage:
 | 
						|
xcatprobe -h
 | 
						|
xcatprobe -l
 | 
						|
xcatprobe [-V] <subcommand>  <attrbute_to_subcommand>
 | 
						|
 | 
						|
Options:
 | 
						|
    -h : get usage information of $program_name 
 | 
						|
    -l : list all valid sub commands
 | 
						|
    -V : print verbose information of $program_name
 | 
						|
    -w : show each line completely. By default long lines are truncated. 
 | 
						|
";
 | 
						|
 | 
						|
#-----------------------------------
 | 
						|
 | 
						|
=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 $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 ($1 =~ /^ok$/) {
 | 
						|
                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 $color   = shift;
 | 
						|
    my $fullmsg = shift;
 | 
						|
 | 
						|
    my $msg;
 | 
						|
    my $flag;
 | 
						|
 | 
						|
    if ($line =~ /\[(\w+)\]\s*:(.+)/) {
 | 
						|
        $flag = $1;
 | 
						|
        $msg  = $2;
 | 
						|
    } else {
 | 
						|
        $msg = $line;
 | 
						|
    }
 | 
						|
 | 
						|
    $msg =~ s/\t/        /g;
 | 
						|
    my $flaglen      = 6;
 | 
						|
    my $desiredwidth = 120;
 | 
						|
    my $screenwidth  = (`tput cols` + 0);
 | 
						|
    my $maxlen = ($screenwidth > $desiredwidth ? $desiredwidth : $screenwidth);
 | 
						|
 | 
						|
    my @finalmsg = ();
 | 
						|
    my $msglen   = length($msg);
 | 
						|
    if ($msglen <= $maxlen) {
 | 
						|
        if (!$fullmsg && $flag) {
 | 
						|
            my $leftspace = $maxlen - length($msg);
 | 
						|
            if ($leftspace < $flaglen) {
 | 
						|
                $msg = substr($msg, 0, $maxlen - $flaglen);
 | 
						|
                $msg =~ s/(.*).../$1\.\.\./g;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        push @finalmsg, $msg;
 | 
						|
    } else {
 | 
						|
        my @tmpmsg = split("", $msg);
 | 
						|
        my $head   = 0;
 | 
						|
        my $tail   = $maxlen;
 | 
						|
        while ($head < $msglen) {
 | 
						|
            push @finalmsg, substr($msg, $head, ($tail - $head));
 | 
						|
            if (!$fullmsg) {
 | 
						|
                if ($flag) {
 | 
						|
                    $finalmsg[0] =~ s/(.*).........$/$1\.\.\./g;
 | 
						|
                } else {
 | 
						|
                    $finalmsg[0] =~ s/(.*)...$/$1\.\.\./g;
 | 
						|
                }
 | 
						|
                last;
 | 
						|
            }
 | 
						|
            $head = $tail;
 | 
						|
            $tail = $head + ($maxlen <= ($msglen - $tail) ? $maxlen : ($msglen - $tail));
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    for (my $i = 0 ; $i < $#finalmsg + 1 ; ++$i) {
 | 
						|
        if ($i ne $#finalmsg) {
 | 
						|
            print "$finalmsg[$i]\n";
 | 
						|
            next;
 | 
						|
        }
 | 
						|
 | 
						|
        if ($flag) {
 | 
						|
            my $leftspace = $maxlen - length($finalmsg[$i]);
 | 
						|
            my $spacenum = 0;
 | 
						|
            if($flag !~ /debug/i) {
 | 
						|
                $spacenum = (($leftspace >= $flaglen) ? ($leftspace - $flaglen) : ($screenwidth - length($finalmsg[$i]) + $maxlen - $flaglen));
 | 
						|
            }
 | 
						|
            my $spacestr = " " x $spacenum;
 | 
						|
            print "$finalmsg[$i]$spacestr";
 | 
						|
 | 
						|
            if ($flag =~ /failed/i) {
 | 
						|
                if ($color) {
 | 
						|
                    print BOLD RED "[FAIL]\n";
 | 
						|
                } else {
 | 
						|
                    print "[FAIL]\n";
 | 
						|
                }
 | 
						|
            } elsif ($flag =~ /warning/i) {
 | 
						|
                if ($color) {
 | 
						|
                    print BOLD BLUE "[WARN]\n";
 | 
						|
                } else {
 | 
						|
                    print "[WARN]\n";
 | 
						|
                }
 | 
						|
            } elsif ($flag =~ /ok/i) {
 | 
						|
                if ($color) {
 | 
						|
                    print BOLD GREEN "[ OK ]\n";
 | 
						|
                } else {
 | 
						|
                    print "[ OK ]\n";
 | 
						|
                }
 | 
						|
            } elsif ($flag =~ /debug/i) {
 | 
						|
                print "\n";
 | 
						|
            } elsif ($flag =~ /info/i) {
 | 
						|
                print "[INFO]\n";
 | 
						|
            }
 | 
						|
        } else {
 | 
						|
            print "$finalmsg[$i]\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;
 | 
						|
 | 
						|
    my $desiredwidth = 120;
 | 
						|
    my $screenwidth  = (`tput cols` + 0);
 | 
						|
    my $finallen = ($screenwidth > $desiredwidth ? $desiredwidth : $screenwidth);
 | 
						|
 | 
						|
    print "Supported sub commands are:\n";
 | 
						|
    foreach my $key (keys %cmds) {
 | 
						|
        my @desc       = split(" ", $cmds{$key});
 | 
						|
        my $str        = "";
 | 
						|
        my @formatdesc = ();
 | 
						|
        foreach my $word (@desc) {
 | 
						|
            if (length($str) + length($word) > $finallen - $maxlen) {
 | 
						|
                $str =~ s/([^\s]+)\s$/$1/g;
 | 
						|
                push @formatdesc, $str;
 | 
						|
                $str = "";
 | 
						|
            }
 | 
						|
            $str .= $word . " ";
 | 
						|
        }
 | 
						|
        $str =~ s/([^\s]+)\s$/$1/g;
 | 
						|
        push @formatdesc, $str;
 | 
						|
 | 
						|
        if ($color) {
 | 
						|
            print BOLD GREEN "$key";
 | 
						|
        } else {
 | 
						|
            print "$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", "-w");
 | 
						|
my $pluginname;
 | 
						|
my $optnum = 0;
 | 
						|
foreach my $attr (@tmpargv) {
 | 
						|
    if ($attr =~ /^-/) {
 | 
						|
        unless (grep(/^$attr$/, @supportopt)) {
 | 
						|
            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");
 | 
						|
        $fullmsg = 1 if ($attr eq "-w");
 | 
						|
    } 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, use '-l' to list all valid subcommand\n";
 | 
						|
    exit 0;
 | 
						|
}
 | 
						|
 | 
						|
splice(@tmpargv, 0, $optnum + 1);
 | 
						|
my $pluginattrs = join(" ", @tmpargv);
 | 
						|
my $subcmd = "$plugin_dir/$pluginname $pluginattrs";
 | 
						|
print "\nsubcmd = $subcmd\n" if ($verbose);
 | 
						|
 | 
						|
my $subcmdpid = 0;
 | 
						|
$SIG{TERM} = $SIG{INT} = sub {
 | 
						|
    $subcmdpid or exit 0;
 | 
						|
    kill 'INT', $subcmdpid;
 | 
						|
};
 | 
						|
 | 
						|
$subcmdpid = open(PIPE, "$subcmd |") or die("Something went wrong while fork()ing to handle subcommand $subcmd: $!");
 | 
						|
 | 
						|
while (<PIPE>) {
 | 
						|
    chomp;
 | 
						|
    format_cmd_output($_, $color, $fullmsg);
 | 
						|
}
 | 
						|
close(PIPE);    # This will set the $? properly
 | 
						|
 | 
						|
my $ret = $? >> 8;
 | 
						|
 | 
						|
exit $ret;
 | 
						|
 |