mirror of
https://github.com/xcat2/xcat-core.git
synced 2025-05-30 09:36:41 +00:00
1072 lines
35 KiB
Perl
Executable File
1072 lines
35 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
# IBM(c) 2016 EPL license http://www.eclipse.org/legal/epl-v10.html
|
|
|
|
BEGIN { $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr'; }
|
|
|
|
use lib "$::XCATROOT/probe/lib/perl";
|
|
use probe_utils;
|
|
use hierarchy;
|
|
use xCAT::ServiceNodeUtils;
|
|
use xCAT::NetworkUtils;
|
|
use File::Basename;
|
|
use File::Copy;
|
|
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 $rst = 0; #the exit code of current command
|
|
my $terminal = 0; #means get INT signal from STDIN
|
|
my $installnic;
|
|
|
|
#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
|
|
#-------------------------------------
|
|
my $program_name = basename("$0"); #current sub_command name
|
|
$::USAGE = "Usage:
|
|
$program_name -h
|
|
$program_name -i <install_nic> [-V]
|
|
|
|
Description:
|
|
After xCAT installation, use this command to check if xCAT has been installed correctly and is ready for use.
|
|
For hierarchical cluster, only the provision network on the same network as the management node is supported. If in the different network, ignore the results.
|
|
|
|
Options:
|
|
-h : Get usage information of $program_name
|
|
-V : Output more information for debug
|
|
-i : Required. Specify the network interface name of provision network on management node
|
|
";
|
|
|
|
sub do_main_job {
|
|
my $rst = 0;
|
|
my @error = ();
|
|
my $checkpoint;
|
|
my $rc = 0;
|
|
my $installnicip;
|
|
|
|
#check if all xcat deamons are running
|
|
$rst = check_all_xcat_deamons(\$checkpoint, \@error);
|
|
print_check_result($checkpoint, "f", $rst, \@error);
|
|
return $rst if ($rst);
|
|
|
|
#check if xcatd can receive request
|
|
$rst = check_xcatd_receive_request(\$checkpoint, \@error);
|
|
print_check_result($checkpoint, "f", $rst, \@error);
|
|
return $rst if ($rst);
|
|
|
|
#check 'site' table configuratiions
|
|
my %sitetable;
|
|
$rst = check_site_table(\%sitetable, \$checkpoint, \@error);
|
|
print_check_result($checkpoint, "f", $rst, \@error);
|
|
return $rst if ($rst);
|
|
|
|
#check network configuratiions
|
|
$rst = check_network(\%sitetable, \$installnicip, \$checkpoint, \@error);
|
|
print_check_result($checkpoint, "f", $rst, \@error);
|
|
return $rst if ($rst);
|
|
|
|
#check 'passwd' table configuratiions
|
|
$rst = check_passwd_table(\$checkpoint, \@error);
|
|
print_check_result($checkpoint, "f", $rst, \@error);
|
|
$rc |= $rst;
|
|
|
|
#check important directory
|
|
$rst = check_directory(\%sitetable, \$checkpoint, \@error);
|
|
print_check_result($checkpoint, "f", $rst, \@error);
|
|
$rc |= $rst;
|
|
|
|
#check if SElinux is disabled
|
|
$rst = check_selinux(\$checkpoint, \@error);
|
|
print_check_result($checkpoint, "f", $rst, \@error);
|
|
$rc |= $rst;
|
|
|
|
#check http service
|
|
$rst = check_http_service($installnicip, \$checkpoint, \@error);
|
|
print_check_result($checkpoint, "f", $rst, \@error);
|
|
$rc |= $rst;
|
|
|
|
#check tftp service
|
|
$rst = check_tftp_service($installnicip, \$checkpoint, \@error);
|
|
print_check_result($checkpoint, "f", $rst, \@error);
|
|
$rc |= $rst;
|
|
|
|
#check DNS service
|
|
$rst = check_dns_service(\%sitetable, $installnicip, \$checkpoint, \@error);
|
|
print_check_result($checkpoint, "f", $rst, \@error);
|
|
$rc |= $rst;
|
|
|
|
#check DHCP service
|
|
$rst = check_dhcp_service($installnicip, \$checkpoint, \@error);
|
|
print_check_result($checkpoint, "f", $rst, \@error);
|
|
$rc |= $rst;
|
|
|
|
#check NTP service
|
|
$rst = check_ntp_service(\$checkpoint, \@error);
|
|
print_check_result($checkpoint, "f", $rst, \@error);
|
|
$rc |= $rst;
|
|
|
|
#Below are the 'warning` level check points
|
|
|
|
#check if firewall is close
|
|
$rst = check_firewall(\$checkpoint, \@error);
|
|
print_check_result($checkpoint, "w", $rst, \@error);
|
|
$rc |= $rst;
|
|
|
|
#check disk space
|
|
$rst = check_disk(\$checkpoint, \@error);
|
|
print_check_result($checkpoint, "w", $rst, \@error);
|
|
$rc |= $rst;
|
|
|
|
|
|
#some sepecific check points in MN
|
|
if (!$is_sn) {
|
|
|
|
#check if server ip is a static ip in MN
|
|
$rst = check_server_ip_static($installnicip,\$checkpoint, \@error);
|
|
print_check_result($checkpoint, "w", $rst, \@error);
|
|
$rc |= $rst;
|
|
|
|
#check if dhcpd.leases is less than 100M
|
|
$rst = check_dhcp_leases(\$checkpoint, \@error);
|
|
print_check_result($checkpoint, "w", $rst, \@error);
|
|
$rc |= $rst;
|
|
}
|
|
|
|
cleanup();
|
|
return $rc;
|
|
}
|
|
|
|
sub summary_all_jobs_output {
|
|
my $rst = 0;
|
|
|
|
if ($terminal) {
|
|
return 0;
|
|
}
|
|
|
|
#DO SUMMARY DEPENDING ON YOUR SUB_COMMAND NEED
|
|
probe_utils->send_msg("$output", "d", "=================================== SUMMARY ====================================");
|
|
|
|
#print "summaryoutput:\n";
|
|
#print Dumper \%summaryoutput;
|
|
|
|
my @summary;
|
|
push @summary, "[ok]:[MN]: Checking on MN...";
|
|
my $ok_section = 0;
|
|
foreach my $line (@{ $summaryoutput{mn} }) {
|
|
if ($line =~ /(\[failed\]\s*):\s*(.*)/) {
|
|
push @summary, "$1: $2";
|
|
$summary[0] = "[failed]:[MN]: Checking on MN...";
|
|
$ok_section = 0;
|
|
} elsif ($line =~ /(\[warning\]\s*):\s*(.*)/) {
|
|
push @summary, "$1: $2";
|
|
$ok_section = 0;
|
|
} elsif ($line =~ /(\[debug\]\s*):\s*(.*)/ && !$ok_section) {
|
|
push @summary, "$1: $2";
|
|
} elsif ($line =~ /(\[ok\]\s*):\s*(.*)/) {
|
|
$ok_section = 1;
|
|
}
|
|
|
|
}
|
|
|
|
my %summary_sn = ();
|
|
foreach my $node (keys %summaryoutput) {
|
|
next if ($node eq "mn");
|
|
${ $summary_sn{$node}{"rst"} } = 1;
|
|
push @{ $summary_sn{$node}{"details"} }, "[ok]:[SN:$node]: Checking on SN $node...";
|
|
$ok_section = 0;
|
|
foreach my $log (@{ $summaryoutput{$node} }) {
|
|
if ($log =~ /(\[failed\]\s*):\s*(.*)/) {
|
|
push @{ $summary_sn{$node}{"details"} }, "$1: $2";
|
|
${ $summary_sn{$node}{"rst"} } = 0;
|
|
$summary_sn{$node}{"details"}[0] = "[failed]:[SN:$node]: Checking on SN $node...";
|
|
$ok_section = 0;
|
|
} elsif ($log =~ /(\[warning\]\s*):\s*(.*)/) {
|
|
push @{ $summary_sn{$node}{"details"} }, "$1: $2";
|
|
$ok_section = 0;
|
|
} elsif ($log =~ /(\[debug\]\s*):\s*(.*)/ && !$ok_section) {
|
|
push @{ $summary_sn{$node}{"details"} }, "$1: $2";
|
|
} elsif ($log =~ /(\[ok\]\s*):\s*(.*)/) {
|
|
$ok_section = 1;
|
|
} elsif ($log !~ /^(\[\w+\]\s*):\s*(.*)/) {
|
|
push @{ $summary_sn{$node}{"details"} }, "[failed]: $log";
|
|
${ $summary_sn{$node}{"rst"} } = 0;
|
|
$summary_sn{$node}{"details"}[0] = "[failed]:[SN:$node]: Checking on SN $node...";
|
|
$ok_section = 0;
|
|
}
|
|
}
|
|
}
|
|
if ($summary[0] =~ /^\[ok\]:/) {
|
|
foreach (@summary) {
|
|
print "$_\n";
|
|
}
|
|
}
|
|
|
|
foreach my $node (keys %summary_sn) {
|
|
if (${ $summary_sn{$node}{"rst"} }) {
|
|
foreach (@{ $summary_sn{$node}{"details"} }) {
|
|
print "$_\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($summary[0] =~ /^\[failed\]:/) {
|
|
foreach (@summary) {
|
|
print "$_\n";
|
|
}
|
|
}
|
|
|
|
foreach my $node (keys %summary_sn) {
|
|
if (!${ $summary_sn{$node}{"rst"} }) {
|
|
foreach (@{ $summary_sn{$node}{"details"} }) {
|
|
print "$_\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
return $rst;
|
|
}
|
|
|
|
sub print_check_result {
|
|
my $msg = shift;
|
|
my $error_level = shift;
|
|
my $check_return_code = shift;
|
|
my $error_msg_ref = shift;
|
|
|
|
if ($check_return_code == 1) {
|
|
probe_utils->send_msg("$output", "$error_level", $msg);
|
|
probe_utils->send_msg("$output", "d", "$_") foreach (@$error_msg_ref);
|
|
} elsif ($check_return_code == 2) {
|
|
return;
|
|
} else {
|
|
probe_utils->send_msg("$output", "o", $msg);
|
|
}
|
|
|
|
}
|
|
|
|
sub check_all_xcat_deamons {
|
|
my $checkpoint_ref = shift;
|
|
my $error_ref = shift;
|
|
my $rst = 0;
|
|
|
|
$$checkpoint_ref = "Checking all xCAT deamons are running...";
|
|
@$error_ref = ();
|
|
|
|
my @deamon_list = ("SSL listener",
|
|
"DB Access",
|
|
"UDP listener",
|
|
"install monitor",
|
|
"Discovery worker",
|
|
"Command log writer");
|
|
|
|
my $output = `ps aux 2>&1|grep -v grep|grep xcatd`;
|
|
foreach my $deamon (@deamon_list) {
|
|
if ($output !~ /$deamon/) {
|
|
push @$error_ref, "Deamon '$deamon' isn't running";
|
|
$rst = 1;
|
|
}
|
|
}
|
|
|
|
return $rst;
|
|
}
|
|
|
|
sub check_xcatd_receive_request {
|
|
my $checkpoint_ref = shift;
|
|
my $error_ref = shift;
|
|
my $rst = 0;
|
|
|
|
$$checkpoint_ref = "Checking xcatd can receive command request...";
|
|
@$error_ref = ();
|
|
|
|
#send one command to test if xcatd can receive request
|
|
my $cmdoutput = `lsxcatd -a 2>&1`;
|
|
my $tmprst = $?;
|
|
chomp($cmdoutput);
|
|
if ($tmprst) {
|
|
my @lines = split("[\n\r]", $cmdoutput);
|
|
push @$error_ref, $_ foreach (@lines);
|
|
$rst = 1;
|
|
}elsif($cmdoutput =~ /Permission denied for request/){
|
|
push @$error_ref, "Permission denied for request, please checking xcatd";
|
|
$rst = 1;
|
|
}
|
|
return $rst if ($rst);
|
|
|
|
#check important port
|
|
my @port_list = ("xcatdport", "xcatiport");
|
|
foreach my $port_attr (@port_list) {
|
|
my $port = `lsdef -t site -i $port_attr -c 2>&1| awk -F'=' '{print \$2}'`;
|
|
chomp($port);
|
|
if ($port) {
|
|
my $cmdoutput = `netstat -ant 2>&1|grep LISTEN|grep $port`;
|
|
if ($?) {
|
|
push @$error_ref, "Attribute '$port_attr' in site table is set to $port, but xcatd isn't listening on $port";
|
|
$rst = 1;
|
|
}
|
|
} else {
|
|
push @$error_ref, "Attribute '$port_attr' isn't set in 'site' table";
|
|
$rst = 1;
|
|
}
|
|
}
|
|
|
|
return $rst;
|
|
}
|
|
|
|
sub check_site_table {
|
|
my $sitetable_ref = shift;
|
|
my $checkpoint_ref = shift;
|
|
my $error_ref = shift;
|
|
my $rst = 0;
|
|
|
|
$$checkpoint_ref = "Checking 'site' table is configured...";
|
|
@$error_ref = ();
|
|
|
|
my @attr_list = ("master", "domain", "installdir", "tftpdir");
|
|
foreach my $attr (@attr_list) {
|
|
my $value;
|
|
$value = `lsdef -t site -i $attr -c 2>&1 | awk -F'=' '{print \$2}'`;
|
|
chomp($value);
|
|
if ($value eq "") {
|
|
push @$error_ref, "There isn't '$attr' definition in 'site' table";
|
|
$rst = 1;
|
|
} else {
|
|
if (($attr eq "master") and (!probe_utils->is_ip_addr("$value"))) {
|
|
push @$error_ref, "The value of 'master' in 'site' table isn't an IP addres";
|
|
$rst = 1;
|
|
}
|
|
$sitetable_ref->{$attr} = $value;
|
|
}
|
|
}
|
|
|
|
return $rst;
|
|
}
|
|
|
|
sub check_passwd_table {
|
|
my $checkpoint_ref = shift;
|
|
my $error_ref = shift;
|
|
my $rst = 0;
|
|
|
|
@$error_ref = ();
|
|
$$checkpoint_ref = "Checking 'passwd' table is configured...";
|
|
|
|
my $passwd = `tabdump passwd 2>&1|awk -F',' '/system/ { gsub(/"/, "", \$2); gsub(/"/, "", \$3); print \$2,\$3 }'`;
|
|
chomp($passwd);
|
|
my ($username, $pw) = split(" ", $passwd);
|
|
if ($username eq "" || $pw eq "") {
|
|
push @$error_ref, "There isn't username or password for 'system' in 'passwd' table";
|
|
$rst = 1;
|
|
}
|
|
|
|
return $rst;
|
|
}
|
|
|
|
sub check_network {
|
|
my $sitetable_ref = shift;
|
|
my $serverip_ref = shift; #output arguments
|
|
my $checkpoint_ref = shift; #output arguments
|
|
my $error_ref = shift; #output arguments
|
|
my $rst = 0;
|
|
|
|
@$error_ref = ();
|
|
$$checkpoint_ref = "Checking provision network is configured...";
|
|
|
|
if ($is_sn) {
|
|
|
|
# on SN, get ip address by compare 'master' attribute in 'site' table
|
|
# choose the one in the same network with 'master'
|
|
my @ipoutput = `ip -4 a show 2>&1| grep inet`;
|
|
foreach (@ipoutput) {
|
|
if ($_ =~ /inet\s+(.+)\/(.+)\s+brd\s+(.+)\s+scope global/i) {
|
|
if (xCAT::NetworkUtils::isInSameSubnet($sitetable_ref->{master}, $1, $2, 1)) {
|
|
$$serverip_ref = $1;
|
|
}
|
|
}
|
|
}
|
|
if (!defined($$serverip_ref) || ($$serverip_ref eq "")) {
|
|
push @$error_ref, "There isn't IP in current server has the same network as master '$sitetable_ref->{master}'";
|
|
$rst = 1;
|
|
}
|
|
} else { # on MN
|
|
my $nics = `ip addr show $installnic >/dev/null 2>&1`;
|
|
if ($?) {
|
|
push @$error_ref, "There isn't NIC '$installnic' in current server";
|
|
$rst = 1;
|
|
} else {
|
|
$$serverip_ref = `ip addr show $installnic 2>&1| awk -F" " '/inet / {print \$2}'|awk -F"/" '{print \$1}'`;
|
|
chomp($$serverip_ref);
|
|
if (!defined($$serverip_ref) || ($$serverip_ref eq "")) {
|
|
push @$error_ref, "There isn't IP address assigned to NIC $installnic";
|
|
$rst = 1;
|
|
} else {
|
|
if ($$serverip_ref ne $sitetable_ref->{master}) {
|
|
push @$error_ref, "The IP $$serverip_ref of $installnic doesn't equal the value of 'master' in 'site' table";
|
|
$rst = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
my $networks = `tabdump networks 2>&1|grep -v "^#"`;
|
|
$networks =~ s/\"//g;
|
|
my $netcnt = `echo "$networks"|wc -l`;
|
|
my $hit = 0;
|
|
for (my $i = 1 ; $i < $netcnt + 1 ; $i++) {
|
|
my $line = `echo "$networks" |sed -n ${i}p |awk -F"," '{print \$2,\$3,\$4}'`;
|
|
chomp($line);
|
|
if ($line =~ /(.+) (.+) (.+)/) {
|
|
if ($is_sn) {
|
|
$hit = 1 if (probe_utils->is_ip_belong_to_net("$1", "$2", $$serverip_ref));
|
|
} else {
|
|
$hit = 1 if (probe_utils->is_ip_belong_to_net("$1", "$2", $$serverip_ref) && ("$3" eq "$installnic"));
|
|
}
|
|
}
|
|
}
|
|
if (!$hit) {
|
|
push @$error_ref, "IP $$serverip_ref of $installnic doesn't belong to any network defined in 'networks' table";
|
|
$rst = 1;
|
|
}
|
|
return $rst;
|
|
}
|
|
|
|
sub check_server_ip_static {
|
|
my $serverip = shift;
|
|
my $checkpoint_ref = shift;
|
|
my $error_ref = shift;
|
|
my $rst = 0;
|
|
|
|
$$checkpoint_ref = "Checking xCAT management node IP: <$serverip> is configured to static...";
|
|
@$error_ref = ();
|
|
|
|
if (!probe_utils->is_static_ip("$serverip", "$installnic")) {
|
|
push @$error_ref, "The value '$serverip' of 'master' in 'site' table isn't a static ip";
|
|
$rst = 1;
|
|
}
|
|
return $rst;
|
|
}
|
|
|
|
|
|
sub check_directory {
|
|
my $sitetable_ref = shift;
|
|
my $checkpoint_ref = shift;
|
|
my $error_ref = shift;
|
|
my $rst = 0;
|
|
|
|
my @dir_list = ("installdir", "tftpdir");
|
|
my $dir_list_str = join(",",@dir_list);
|
|
$$checkpoint_ref = "Checking important directories($dir_list_str) are configured...";
|
|
@$error_ref = ();
|
|
|
|
foreach my $dir (@dir_list) {
|
|
if ($sitetable_ref->{$dir} eq "") {
|
|
push @$error_ref, "There isn't '$dir' definition in 'site' table";
|
|
$rst = 1;
|
|
} else {
|
|
if (!-e "$sitetable_ref->{$dir}") {
|
|
push @$error_ref, "There isn't '$sitetable_ref->{$dir}' directory on current server, there is something wrong during xCAT installation";
|
|
$rst = 1;
|
|
} else {
|
|
if ($is_sn) {
|
|
my $mountoutput = `mount 2>&1| grep '$sitetable_ref->{$dir}'`;
|
|
chomp($mountoutput);
|
|
|
|
my $mountip;
|
|
if ($mountoutput =~ /(.+):$sitetable_ref->{$dir} on $sitetable_ref->{$dir} /) {
|
|
my $mountsource = $1;
|
|
if (xCAT::NetworkUtils->isIpaddr($mountsource)) {
|
|
$mountip = $mountsource;
|
|
} else {
|
|
$mountip = xCAT::NetworkUtils->getipaddr($mountsource);
|
|
}
|
|
}
|
|
|
|
if ($mountip ne $sitetable_ref->{master}) {
|
|
push @$error_ref, "$dir '$sitetable_ref->{$dir}' isn't mounted from the management node,please check SN's configuration";
|
|
$rst = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return $rst;
|
|
}
|
|
|
|
|
|
sub check_disk {
|
|
my $checkpoint_ref = shift;
|
|
my $error_ref = shift;
|
|
my $rst = 0;
|
|
@$error_ref = ();
|
|
|
|
my $installdir = `lsdef -t site -i installdir -c 2>&1| awk -F'=' '{print \$2}'`;
|
|
chomp($installdir);
|
|
my %dir_expectedspace_list = ("/var" => 1, "/tmp" => 1, "$installdir" => 10);
|
|
my $disk_str="[";
|
|
foreach (keys %dir_expectedspace_list){
|
|
$disk_str.="'$_' needs $dir_expectedspace_list{$_}GB;";
|
|
}
|
|
$disk_str=~s/;$/]/g;
|
|
$$checkpoint_ref = "Checking minimum disk space for xCAT $disk_str...";
|
|
|
|
my $msg = "";
|
|
my %mountpointinfo;
|
|
foreach my $dir (keys %dir_expectedspace_list) {
|
|
if(! -d "$dir"){
|
|
$msg.="There isn't '$dir' in current server.";
|
|
$rst = 1;
|
|
}else{
|
|
my $output = `df --block-size=1G $dir|tail -n 1`;
|
|
chomp($output);
|
|
my @splitoutput = split(" ", $output);
|
|
$mountpointinfo{ $splitoutput[5] }{available} = $splitoutput[3];
|
|
$mountpointinfo{ $splitoutput[5] }{need} += $dir_expectedspace_list{$dir};
|
|
push @{ $mountpointinfo{ $splitoutput[5] }{mount} }, $dir;
|
|
}
|
|
}
|
|
|
|
unless($rst){
|
|
foreach $mountpoint (keys %mountpointinfo) {
|
|
if ($mountpointinfo{$mountpoint}{need} > $mountpointinfo{$mountpoint}{available}) {
|
|
foreach (@{ $mountpointinfo{$mountpoint}{mount} }) {
|
|
$msg .= "'$_',";
|
|
}
|
|
my $mountmun = $#{$mountpointinfo{$mountpoint}{mount}} +1 ;
|
|
if($mountmun >1){
|
|
$msg .= "these directories are parts of file system '$mountpoint'. The free space available in directory '$mountpoint' is $mountpointinfo{$mountpoint}{available} GiB, it is not enough.";
|
|
}else{
|
|
$msg .= "this directory is a part of file system '$mountpoint'. The free space available in directory '$mountpoint' is $mountpointinfo{$mountpoint}{available} GiB, it is not enough.";
|
|
}
|
|
$rst = 1;
|
|
}
|
|
}
|
|
}
|
|
if ($rst) {
|
|
push @$error_ref, "$msg";
|
|
}
|
|
|
|
return $rst;
|
|
}
|
|
|
|
sub check_selinux {
|
|
my $checkpoint_ref = shift;
|
|
my $error_ref = shift;
|
|
my $rst = 0;
|
|
|
|
$$checkpoint_ref = "Checking SELinux is disabled...";
|
|
@$error_ref = ();
|
|
|
|
if (probe_utils->is_selinux_enable()) {
|
|
push @$error_ref, "SELinux is enabled on current server";
|
|
$rst = 1;
|
|
}
|
|
|
|
return $rst;
|
|
}
|
|
|
|
sub check_firewall {
|
|
my $checkpoint_ref = shift;
|
|
my $error_ref = shift;
|
|
my $rst = 0;
|
|
|
|
$$checkpoint_ref = "Checking firewall is disabled...";
|
|
@$error_ref = ();
|
|
|
|
if (probe_utils->is_firewall_open()) {
|
|
push @$error_ref, "Firewall is configured on current server";
|
|
$rst = 1;
|
|
}
|
|
|
|
return $rst;
|
|
}
|
|
|
|
sub check_http_service {
|
|
my $serverip = shift;
|
|
my $checkpoint_ref = shift;
|
|
my $error_ref = shift;
|
|
my $rst = 1;
|
|
|
|
$$checkpoint_ref = "Checking HTTP service is configured...";
|
|
@$error_ref = ();
|
|
|
|
`which wget > /dev/null 2>&1`;
|
|
if ($?) {
|
|
push @$error_ref, "HTTP check need 'wget' tool, please install 'wget' tool and try again";
|
|
} else {
|
|
{
|
|
my $installdir = `lsdef -t site -i installdir -c 2>&1 | awk -F'=' '{print \$2}'`;
|
|
chomp($installdir);
|
|
unless($installdir){
|
|
push @$error_ref, "HTTP work path(installdir) isn't configured in 'sit' table";
|
|
last;
|
|
}
|
|
|
|
unless(-d "$installdir"){
|
|
push @$error_ref, "There isn't '$installdir' directory on current server";
|
|
last;
|
|
}
|
|
|
|
my $errormsg;
|
|
unless(probe_utils->is_http_ready("$serverip", $installdir, \$errormsg)) {
|
|
push @$error_ref, "$errormsg";
|
|
last;
|
|
}
|
|
|
|
$rst = 0;
|
|
}
|
|
}
|
|
|
|
return $rst;
|
|
}
|
|
|
|
|
|
sub check_tftp_service {
|
|
my $serverip = shift;
|
|
my $checkpoint_ref = shift;
|
|
my $error_ref = shift;
|
|
my $rst = 1;
|
|
|
|
$$checkpoint_ref = "Checking TFTP service is configured...";
|
|
@$error_ref = ();
|
|
|
|
my $nodename = `hostname -s 2>&1`;
|
|
chomp($nodename);
|
|
|
|
# For sn, 'setuptftp' attribute could be set to '0' or '1'.
|
|
# if '0', sn does not need to provie TFTP service, will not check it
|
|
my $checktftp = 1;
|
|
if ($is_sn) {
|
|
$checktftp = `lsdef $nodename -i setuptftp -c 2>&1 | awk -F'=' '{print \$2}' `;
|
|
chomp($checktftp);
|
|
}
|
|
if ($checktftp) {
|
|
`which tftp > /dev/null 2>&1`;
|
|
if ($?) {
|
|
push @$error_ref, "TFTP check need 'tftp' tool, please install 'tftp' tool and try again";
|
|
} else {
|
|
{
|
|
my $tftpdir = `lsdef -t site -i tftpdir -c 2>&1| awk -F'=' '{print \$2}'`;
|
|
chomp($tftpdir);
|
|
unless($tftpdir){
|
|
push @$error_ref, "TFTP work path isn't configured in 'sit' table";
|
|
last;
|
|
}
|
|
unless(-d "$tftpdir"){
|
|
push @$error_ref, "There isn't '$tftpdir' directory on current server";
|
|
last;
|
|
}
|
|
unless(probe_utils->is_tftp_ready("$serverip", $tftpdir)) {
|
|
push @$error_ref, "TFTP service isn't ready on $serverip";
|
|
last;
|
|
}
|
|
$rst = 0;
|
|
}
|
|
}
|
|
} else {
|
|
$rst = 2;
|
|
}
|
|
|
|
return $rst;
|
|
}
|
|
|
|
sub check_ntp_service{
|
|
my $checkpoint_ref = shift;
|
|
my $error_ref = shift;
|
|
my $rst = 0;
|
|
|
|
$$checkpoint_ref = "Checking NTP service is configured...";
|
|
@$error_ref = ();
|
|
|
|
`which ntpq > /dev/null 2>&1`;
|
|
if($?){
|
|
push @$error_ref, "ntp service check need 'ntpq' tool, please install 'ntpq' toll and try again";
|
|
$rst = 1;
|
|
}else{
|
|
my $error;
|
|
if(!probe_utils->is_ntp_ready(\$error)){
|
|
push @$error_ref, "$error";
|
|
$rst = 1;
|
|
}
|
|
}
|
|
|
|
return $rst;
|
|
}
|
|
|
|
sub check_dns_service {
|
|
my $sitetable_ref = shift;
|
|
my $serverip = shift;
|
|
my $checkpoint_ref = shift;
|
|
my $error_ref = shift;
|
|
my $rst = 0;
|
|
|
|
$$checkpoint_ref = "Checking DNS service is configured...";
|
|
@$error_ref = ();
|
|
|
|
my $nodename = `hostname -s 2>&1`;
|
|
chomp($nodename);
|
|
|
|
# For sn, 'setupdns' attribute could be set to '0' or '1'.
|
|
# if '0', sn does not need to provie DNS service, will not check it
|
|
my $checkdns = 1;
|
|
if ($is_sn) {
|
|
$checkdns = `lsdef $nodename -i setupnameserver -c 2>&1| awk -F'=' '{print \$2}'`;
|
|
chomp($checkdns);
|
|
}
|
|
|
|
if ($checkdns) {
|
|
`which nslookup > /dev/null 2>&1`;
|
|
if ($?) {
|
|
push @$error_ref, "DNS check need 'nslookup' tool, please install 'nslookup' tool and try again";
|
|
$rst = 1;
|
|
} else {
|
|
if ($is_sn) {
|
|
|
|
# on sn, nslookup it's ip to check DNS service
|
|
if (!probe_utils->is_dns_ready("$serverip", "$sitetable_ref->{master}", "$nodename", "$sitetable_ref->{domain}")) {
|
|
push @$error_ref, "DNS service isn't ready on $serverip";
|
|
$rst = 1;
|
|
}
|
|
} else {
|
|
my $rc = 0;
|
|
|
|
# if this is a hierarchical cluster, nslookup one of sn to check DNS service
|
|
my @snlist = xCAT::ServiceNodeUtils->getAllSN();
|
|
my $sntmp = shift(@snlist);
|
|
if ($sntmp) {
|
|
my $sninfo = `cat /etc/hosts 2>&1| grep $sntmp`;
|
|
if ($sninfo =~ /(\d+).(\d+).(\d+).(\d+)/) {
|
|
my $snip = "$1.$2.$3.$4";
|
|
if (!probe_utils->is_dns_ready("$snip", "$serverip", "$sntmp", "$sitetable_ref->{domain}")) {
|
|
$rc = 1;
|
|
}
|
|
}
|
|
} else {
|
|
|
|
# if there is no sn, nslookup mnip
|
|
my $nslkp = `nslookup $serverip $serverip 2>&1`;
|
|
chomp($nslkp);
|
|
my $tmp = grep { $_ =~ "Server:[\t\s]*$serverip" } split(/\n/, $nslkp);
|
|
if (!$tmp) {
|
|
$rc = 1;
|
|
}
|
|
}
|
|
if ($rc) {
|
|
push @$error_ref, "DNS service isn't ready on $serverip";
|
|
$rst = 1;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
$rst = 2;
|
|
}
|
|
|
|
return $rst;
|
|
}
|
|
|
|
|
|
sub check_dhcp_service {
|
|
my $serverip = shift;
|
|
my $checkpoint_ref = shift;
|
|
my $error_ref = shift;
|
|
my $rst = 0;
|
|
|
|
$$checkpoint_ref = "Checking DHCP service is configured...";
|
|
@$error_ref = ();
|
|
|
|
|
|
# For sn, 'setupdhcp' attribute could be set to '0' or '1'.
|
|
# if '0', sn does not need to provie DHCP service, will not check it
|
|
if ($is_sn) {
|
|
my $nodename = `hostname -s 2>&1`;
|
|
chomp($nodename);
|
|
my $checkdhcp = `lsdef $nodename -i setupdhcp -c 2>&1| awk -F'=' '{print \$2}'`;
|
|
chomp($checkdhcp);
|
|
if ($checkdhcp) {
|
|
|
|
# on sn, just check dhcpd service whether running
|
|
my $dhcpoutput = `ps aux 2>&1| grep dhcpd |grep -v grep`;
|
|
if (!$dhcpoutput) {
|
|
push @$error_ref, "There isn't 'dhcpd' deamon in current server";
|
|
$rst = 1;
|
|
}
|
|
} else {
|
|
$rst = 2;
|
|
}
|
|
} else {
|
|
my $rc = 0;
|
|
{ #very important brace to create a block
|
|
my @snlist = xCAT::ServiceNodeUtils->getAllSN();
|
|
my $sntmp = shift(@snlist);
|
|
if ($sntmp) {
|
|
my $tmp = `makedhcp -q $sntmp 2>&1`;
|
|
if ($?) {
|
|
push @$error_ref, "makedhcp -q $sntmp failed";
|
|
returncmdoutput($tmp, $error_ref) if ($verbose);
|
|
$rc = 1;
|
|
last;
|
|
}
|
|
chomp($tmp);
|
|
my $snip = xCAT::NetworkUtils->getipaddr($sntmp);
|
|
my $snmac = `lsdef $sntmp -i mac -c 2>&1| awk -F'=' '{print \$2}'`;
|
|
chomp($snmac);
|
|
my $tmpmac;
|
|
if ($tmp =~ /$sntmp: ip-address = $snip, hardware-address = (.+)/) {
|
|
$tmpmac = $1;
|
|
if ($tmpmac !~ $snmac) {
|
|
push @$error_ref, "DHCP server reply is wrong";
|
|
returncmdoutput($tmp, $error_ref) if ($verbose);
|
|
$rc = 1;
|
|
}
|
|
} else {
|
|
push @$error_ref, "DHCP server reply is wrong";
|
|
returncmdoutput($tmp, $error_ref) if ($verbose);
|
|
$rc = 1;
|
|
}
|
|
} else {
|
|
|
|
my $tmp = `chdef xcatmntest groups=all ip=$serverip mac=aa:aa:aa:aa:aa:aa 2>&1`;
|
|
if ($?) {
|
|
push @$error_ref, "Node simulation by 'chdef' has failed";
|
|
returncmdoutput($tmp, $error_ref) if ($verbose);
|
|
$rc = 1;
|
|
last;
|
|
} else {
|
|
push @$error_ref, "Simulate a node xcatmntest<ip=$serverip mac=aa:aa:aa:aa:aa:aa> to do dhcp test" if ($verbose);
|
|
}
|
|
|
|
`cp /etc/hosts /etc/hosts.bak.probe > /dev/null 2>&1`;
|
|
|
|
open HOSTFILE, ">> /etc/hosts";
|
|
print HOSTFILE "$serverip xcatmntest xcatmntest.$domain";
|
|
close HOSTFILE;
|
|
|
|
probe_utils->send_msg($outputtarget, "d", "To do 'makedhcp xcatmntest'") if ($verbose);
|
|
$tmp = `makedhcp xcatmntest 2>&1`;
|
|
if ($?) {
|
|
push @$error_ref, "makedhcp xcatmntest failed";
|
|
returncmdoutput($tmp, $error_ref) if ($verbose);
|
|
$rc = 1;
|
|
`rmdef xcatmntest 2>&1`;
|
|
last;
|
|
}
|
|
|
|
$tmp = `makedhcp -q xcatmntest 2>&1`;
|
|
if ($?) {
|
|
push @$error_ref, "makedhcp -q xcatmntest failed";
|
|
returncmdoutput($tmp, $error_ref) if ($verbose);
|
|
$rc = 1;
|
|
`makedhcp -d xcatmntest 2>&1 && rmdef xcatmntest 2>&1`;
|
|
last;
|
|
}
|
|
chomp($tmp);
|
|
if ($tmp !~ /xcatmntest: ip-address = $serverip, hardware-address = aa:aa:aa:aa:aa:aa/) {
|
|
push @$error_ref, "DHCP server reply is wrong";
|
|
returncmdoutput($tmp, $error_ref) if ($verbose);
|
|
$rc = 1;
|
|
`makedhcp -d xcatmntest 2>&1 && rmdef xcatmntest 2>&1`;
|
|
last;
|
|
}
|
|
|
|
push @$error_ref, "Start clearing simulation information for dhcp test" if ($verbose);
|
|
$tmp = `makedhcp -d xcatmntest 2>&1 && rmdef xcatmntest 2>&1`;
|
|
returncmdoutput($tmp, $error_ref) if ($verbose);
|
|
|
|
unlink "/etc/hosts";
|
|
move("/etc/hosts.bak.probe", "/etc/hosts");
|
|
}
|
|
}
|
|
if ($rc) {
|
|
push @$error_ref, "Run 'makedhcp -n' if it has not been ran before.";
|
|
$rst = 1;
|
|
}
|
|
}
|
|
|
|
return $rst;
|
|
}
|
|
|
|
sub check_dhcp_leases {
|
|
my $checkpoint_ref = shift;
|
|
my $error_ref = shift;
|
|
my $rst = 0;
|
|
|
|
$$checkpoint_ref = "Checking dhcpd.leases file is less than 100M...";
|
|
@$error_ref = ();
|
|
|
|
my $leasefile = "";
|
|
if (-e "/var/lib/dhcpd/dhcpd.leases") {
|
|
$leasefile = "/var/lib/dhcpd/dhcpd.leases";
|
|
} elsif (-e "/var/lib/dhcp/db/dhcpd.leases") {
|
|
$leasefile = "/var/lib/dhcp/db/dhcpd.leases";
|
|
} elsif (-e "/var/lib/dhcp/dhcpd.leases") {
|
|
$leasefile = "/var/lib/dhcp/dhcpd.leases";
|
|
}
|
|
|
|
my @fileinfo = stat("$leasefile");
|
|
if ($fileinfo[7] > 104857600) {
|
|
my $size_m = $fileinfo[7] / 1048576;
|
|
push @$error_ref, "The size of $leasefile is $size_m M, more than 100M";
|
|
$rst = 1;
|
|
}
|
|
|
|
return $rst;
|
|
}
|
|
|
|
sub returncmdoutput {
|
|
my $rst = shift;
|
|
my $error_ref = shift;
|
|
|
|
chomp($rst);
|
|
my @lines = split("[\n\r]", $rst);
|
|
foreach my $line (@lines) {
|
|
push @$error_ref, $line;
|
|
}
|
|
}
|
|
|
|
#-------------------------------------
|
|
# Clean up test environment
|
|
# -------------------------------------
|
|
sub cleanup {
|
|
my $tmptest = `nodels xcatmntest 2>&1`;
|
|
if ($tmptest !~ /Error: Invalid nodes and\/or groups in noderange: xcatmntest/) {
|
|
`makedhcp -d xcatmntest && rmdef xcatmntest > /dev/null 2>&1`;
|
|
}
|
|
if (-e "/etc/hosts.bak.probe") {
|
|
unlink "/etc/hosts";
|
|
move("/etc/hosts.bak.probe", "/etc/hosts");
|
|
}
|
|
}
|
|
|
|
#-------------------------------------
|
|
# main process
|
|
#-------------------------------------
|
|
my @tmpargv = @ARGV;
|
|
if (
|
|
!GetOptions("--help|h" => \$help,
|
|
"T" => \$test,
|
|
"H" => \$hierarchy,
|
|
"V" => \$verbose,
|
|
"i=s" => \$installnic))
|
|
{
|
|
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", "After xcat installation, use this command to check if xcat has been installed correctly and is ready for use. Before using this command, install 'tftp', 'nslookup' and 'wget' commands. Supported platforms are RedHat, SLES and Ubuntu.");
|
|
exit 0;
|
|
}
|
|
|
|
if (!$installnic){
|
|
probe_utils->send_msg("$output", "f", "Option '-i' is required");
|
|
probe_utils->send_msg("$output", "d", "$::USAGE");
|
|
exit 1;
|
|
}
|
|
|
|
#Handle the interrupt signal from STDIN
|
|
$SIG{TERM} = $SIG{INT} = sub {
|
|
$terminal = 1;
|
|
cleanup();
|
|
};
|
|
|
|
#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 @error;
|
|
my $hierarchy_instance = hierarchy->new();
|
|
$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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
|
|
|