#! /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 File::Basename; use Net::Ping; use Getopt::Long qw(:config no_ignore_case); use Data::Dumper; use warnings; my $program_name = basename("$0"); my $help; my $noderange = ""; my $test; my $osimage; my $osimagecmd = ""; my $output = "stdout"; my $verbose = 0; my $rst = 0; $::USAGE = "Usage: $program_name -h $program_name [-V|--verbose] Description: Use this command to check osimage defintions in xCAT DB. Options: -h : Get usage information of $program_name -V : To print additional debug information. --osimage=: Provide the osimage name to run the probe against "; #------------------------------------- # main process #------------------------------------- if ( !GetOptions("--help|h" => \$help, "T" => \$test, "osimage=s" => \$osimage, "V|verbose" => \$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", "Use this command to check osimage defintions in xCAT DB."); exit 0; } if (scalar(@ARGV) >= 1) { # After processing all the expected flags and arguments, # there is still left over stuff on the command line probe_utils->send_msg("$output", "f", "Invalid flag or parameter: @ARGV"); probe_utils->send_msg("$output", "d", "$::USAGE"); exit 1; } # Check for osimage definitions with duplicate values for rootimgdir sub check_for_duplicate_rootimgdir { probe_utils->send_msg("$output", "i", "==> Checking for duplicate usage of the rootimgdir in diskless images..."); my $na = "N/A"; my %rootimgdir_osimage_hash; my $any_dups = 0; my $all_osimages_rootimgdir = `lsdef -t osimage $osimagecmd -i rootimgdir -c 2> /dev/null`; chomp($all_osimages_rootimgdir); my @all_osimages_rootimgdir_lines = split("[\n\r]", $all_osimages_rootimgdir); if (scalar(@all_osimages_rootimgdir_lines) <= 0) { # There were no osimages found. Issue a warning and exit. probe_utils->send_msg("$output", "w", "No osimages were found."); return 1; } # Build a hash of key="rootimgdir" value="osimagename" foreach (@all_osimages_rootimgdir_lines) { probe_utils->send_msg("$output", "d", "Processing $_.") if ($VERBOSE); my ($osimage_name, $rootimgdir) = split ":", $_; if ($rootimgdir eq " rootimgdir=") { # Exclude entries that do not have rootimg set probe_utils->send_msg("$output", "d", "No rootimgdir for osimage $osimage_name") if ($VERBOSE); next; } # Check if hash already has the same key, indicating another osimage definition has the same rootimgdir if (exists($rootimgdir_osimage_hash{$rootimgdir})) { # Build a list of osimages that have the same rootimgdir $rootimgdir_osimage_hash{$rootimgdir} .= "," . $osimage_name; $any_dups = 1; } else { $rootimgdir_osimage_hash{$rootimgdir} = $osimage_name; } } #print Dumper(\%rootimgdir_osimage_hash) if ($VERBOSE); my $rc = 1; if ($any_dups) { # Loop through each entry in hash to print a list of osimgage objects that point to the same rootimgdir foreach $rootimgdirpath (keys %rootimgdir_osimage_hash) { my @list_of_osimages = split ",", $rootimgdir_osimage_hash{$rootimgdirpath}; if (scalar(@list_of_osimages) > 1) { # More than one entry in the hash value, means we # have more than one osimage point to the same rootimgdir my $print_list = join("\n ",@list_of_osimages); $rootimgdirpath=~s/^\s+//; #discard leading space probe_utils->send_msg("$output", "w", "Identical root image directory ($rootimgdirpath) is configured for the diskless osimages: \n $print_list"); } } } else { probe_utils->send_msg("$output", "o", "No diskless osimages with identical root image directories were found."); $rc = 0; } return $rc; } # Check attributes in osimage definitions for valid format sub check_for_valid_osimage_attributes { probe_utils->send_msg("$output", "i", "==> Checking for valid osimage template attribute ... "); my $na = "N/A"; my $rc = 0; my %rootimgdir_osimage_hash; my $any_dups = 0; # Check if any osimage object has "template" attribute set to service.tmpl or compute.tmpl my $all_osimages_template = `lsdef -t osimage $osimagecmd -i template -c 2> /dev/null`; chomp($all_osimages_template); my @all_osimages_template_lines = split("[\n\r]", $all_osimages_template); if (scalar(@all_osimages_template_lines) <= 0) { # There were no osimages found. Issue a warning and exit. probe_utils->send_msg("$output", "w", "No osimages were found."); return 1; } foreach (@all_osimages_template_lines) { probe_utils->send_msg("$output", "d", "Processing $_.") if ($VERBOSE); my ($osimage_name, $template) = split ":", $_; if ($template eq " template=") { # Exclude entries that do not have template attribute set probe_utils->send_msg("$output", "d", "No template for osimage $osimage_name") if ($VERBOSE); next; } my ($junk, $template_file) = split "=", $template; if (($template_file =~ /compute.tmpl/) || ($template_file =~ /service.tmpl/)) { if ($template_file !~ /ubuntu/) { # Skip Ubintu osimages, currently ok to have service.tmpl and compute.tmpl for them probe_utils->send_msg("$output", "w", "Default 'template' value is being used by $osimage_name \n". " If this image was generated by 'copycds -n ', make sure the specified\n". " follows xCAT naming convention (for example 'rhels7.2')"); } } } return $rc; } sub check_valid_files_defined { probe_utils->send_msg("$output", "i", "==> Checking that valid files are specified in osimage attributes ..."); my $rc = 0; my $osimage_list = `lsdef -t osimage $osimagecmd -s 2> /dev/null`; chomp($osimage_list); my @all_osimage_lists = split("[\n]", $osimage_list); foreach (@all_osimage_lists) { # loop over the osimage name my ($osimage_name, $junk) = split " ", $_; probe_utils->send_msg("$output", "d", "Inspecting osimage=$osimage_name") if ($VERBOSE); my @attributes = qw ( otherpkglist pkglist template ); foreach (@attributes) { # loop over the attributes to check probe_utils->send_msg("$output", "d", "Checking attribute=$_ ...") if ($VERBOSE); my $osimage_attribute = `lsdef -t osimage -o $osimage_name -i $_ -c 2> /dev/null`; chomp($osimage_attribute); my ($junk, $file) = split "=", $osimage_attribute; if ($file eq "") { # if no file is defined, skip next; } if ($file =~ /\,/) { my @files = split /,/, $file; foreach my $f (@files) { probe_utils->send_msg("$output", "d", "Defined in $_, checking for file: $f") if ($VERBOSE); if (! -e $f) { probe_utils->send_msg("$output", "f", "In $_, NON-EXISTANT FILE: $f"); $rc = 1; } } } } } if ($rc == 0) { probe_utils->send_msg("$output", "o", "Files specified in the osimage attributes seem to be valid."); } } # # MAIN # # Run all osimage probe checks one after another if ($osimage) { $osimagecmd = "-o $osimage"; probe_utils->send_msg("$output", "d", "[osimagecheck] osimage passed in: $osimage") if ($VERBOSE); # verify a valid osimage name was passed in my $osimage_output = `lsdef -t osimage $osimagecmd 2>&1`; if ($osimage_output =~ /Error: Could not find/) { probe_utils->send_msg("$output", "f", "Invalid osimage name passed in: $osimage"); exit 1; } } else { probe_utils->send_msg("$output", "d", "[osimagecheck] No osimage passed in, checking all osimages ...") if ($VERBOSE); } check_for_duplicate_rootimgdir(); check_for_valid_osimage_attributes(); check_valid_files_defined();