git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@15520 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
		
			
				
	
	
		
			693 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			693 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/env perl -w
 | |
| # IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
 | |
| #####################################################
 | |
| #
 | |
| #   xCAT post script for AIX nodes
 | |
| #
 | |
| #   This script is used to update software on AIX
 | |
| #		standalone systems.
 | |
| #		- it is executed by the updatenode command
 | |
| #
 | |
| #####################################################
 | |
| 
 | |
| use File::Basename;
 | |
| use Getopt::Long;
 | |
| 
 | |
| # MAIN
 | |
| #
 | |
| # Process the command line...
 | |
| #
 | |
| Getopt::Long::Configure("no_pass_through");
 | |
| Getopt::Long::Configure("bundling");
 | |
| $Getopt::Long::ignorecase = 0;
 | |
| if (
 | |
|     !GetOptions(
 | |
|               'f=s'      => \$::FILENAME,       # software list file name (full)
 | |
|               's=s'      => \$::SERVER,
 | |
|               'i=s'      => \$::INSTP_FLAGS,    # installp flags
 | |
|               'r=s'      => \$::RPM_FLAGS,      # RPM flags
 | |
|               'e=s'      => \$::EMGR_FLAGS,     # emgr flags
 | |
|               'n|nfsv4'  => \$::NFSV4,
 | |
|               'd|altsrc' => \$::ALTSRC,
 | |
|               'a|all'    => \$::ALLSW
 | |
|     )
 | |
|   )
 | |
| {                                         # Gather options
 | |
|     exit 1;
 | |
| }
 | |
| 
 | |
| #
 | |
| # set the name of this nodes server
 | |
| #
 | |
| my $servnode;
 | |
| if ($::SERVER)
 | |
| {
 | |
|     $servnode = $::SERVER;
 | |
| }
 | |
| elsif (-f "/etc/xcatinfo")
 | |
| {
 | |
|     my $cmd = "/bin/cat /etc/xcatinfo | /bin/grep 'XCATSERVER'";
 | |
|     &runcmd($cmd);
 | |
|     my $SNline = $::outref;
 | |
|     my $junk;
 | |
|     ($junk, $servnode) = split(/=/, $SNline);
 | |
|     chomp $servnode;
 | |
|     $servnode =~ s/^\s*//;
 | |
| }
 | |
| elsif ($ENV{'MASTER'})
 | |
| {
 | |
|     $servnode = $ENV{'MASTER'};
 | |
| }
 | |
| else
 | |
| {
 | |
| 
 | |
|     # error no server provided
 | |
|     print "aixswupdate: Could not determine the xCAT server for this node.\n";
 | |
|     exit 1;
 | |
| }
 | |
| 
 | |
| # pick a local mount point
 | |
| my $localsrc = "/xcatswmnt";
 | |
| 
 | |
| #ex. FILENAME -> /install/nim/lpp_source/71H_image_lpp_source/pkglist.$img
 | |
| #		mntdir -> /install/nim/lpp_source/71H_image_lpp_source
 | |
| my $mntdir   = dirname($::FILENAME);
 | |
| my $file     = basename($::FILENAME);
 | |
| my $listfile = "$localsrc/$file";
 | |
| 
 | |
| #
 | |
| #	mount the package source directory
 | |
| #
 | |
| my $mtcmd;
 | |
| if ($::NFSV4)
 | |
| {
 | |
|     $mtcmd =
 | |
|       qq~/bin/mkdir -m 644 -p $localsrc; /usr/sbin/mount -o vers=4 $servnode:$mntdir $localsrc~;
 | |
| }
 | |
| else
 | |
| {
 | |
|     $mtcmd =
 | |
|       qq~/bin/mkdir -m 644 -p $localsrc; /usr/sbin/mount $servnode:$mntdir $localsrc~;
 | |
| }
 | |
| 
 | |
| $rc = &runcmd($mtcmd);
 | |
| if ($rc != 0)
 | |
| {
 | |
|     print
 | |
|       "aixswupdate: Could not mount $mntdir source directory from $servnode.\n";
 | |
|     exit 1;
 | |
| }
 | |
| 
 | |
| # if the software list file exists then try to install the software
 | |
| if (-f $listfile)
 | |
| {
 | |
| 
 | |
|     # copy the file contents into a list
 | |
|     unless (open(LISTFILE, "<$listfile"))
 | |
|     {
 | |
| 
 | |
|         # error
 | |
|     }
 | |
|     my @pkglist = <LISTFILE>;
 | |
|     close(LISTFILE);
 | |
| 
 | |
|     if (scalar(@pkglist))
 | |
|     {
 | |
| 
 | |
|         # sort the list into diff packaging types
 | |
|         my ($instpfile, $emgrfile, $rpmstring) = &processpkglist(\@pkglist);
 | |
| 
 | |
|         #  installp
 | |
|         if (-f $instpfile)
 | |
|         {
 | |
|             my $rc = &do_installp($instpfile, $::INSTP_FLAGS, $localsrc);
 | |
|             if ($rc != 0)
 | |
|             {
 | |
|                 print "One or more errors from the installp command.\n";
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #  updtvpkg
 | |
|         my $upcmd = qq~/usr/sbin/updtvpkg~;
 | |
|         my $rc    = &runcmd($upcmd);
 | |
|         if ($rc != 0)
 | |
|         {
 | |
|             print "Could not run updtvpkg.\n";
 | |
|         }
 | |
| 
 | |
|         # rpm
 | |
|         if ($rpmstring)
 | |
|         {
 | |
|             my $rc = &do_rpms($rpmstring, $::RPM_FLAGS, $localsrc);
 | |
|             if ($rc != 0)
 | |
|             {
 | |
|                 print "One or more errors from the rpm command.\n";
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         # emgr
 | |
|         if (-f $emgrfile)
 | |
|         {
 | |
|             my $rc = &do_emgr($emgrfile, $::EMGR_FLAGS, $localsrc);
 | |
|             if ($rc != 0)
 | |
|             {
 | |
|                 print "One or more errors from the emgr command.\n";
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         # clean up tmp files
 | |
|         my $rmcmd = qq~/bin/rm -R $emgrfile $instpfile~;
 | |
| 		print "Running: \'$rmcmd\'\n";
 | |
| 		$rc = &runcmd($rmcmd);
 | |
|         if ($rc != 0)
 | |
|         {
 | |
| 			# "Could not remove  $emgrfile and $instpfile.\n";
 | |
| 		}
 | |
| 
 | |
|         # unmount source dir
 | |
|         my $umtcmd = qq~/usr/sbin/umount /xcatswmnt~;
 | |
| 		print "Running: \'$umtcmd\'\n";
 | |
|         $rc = &runcmd($umtcmd);
 | |
|         if ($rc != 0)
 | |
|         {
 | |
|             # "Could not unmount source directory.\n";
 | |
|         }
 | |
|     }
 | |
| 
 | |
| }
 | |
| else
 | |
| {
 | |
| 
 | |
|     # return error
 | |
|     print "aixswupdate: Cannot locate software list file: $::FILENAME\n";
 | |
|     exit 1;
 | |
| }
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   do_rpms
 | |
| 
 | |
|     This subroutine is used to install a list of rpm packages
 | |
| 
 | |
|     Arguments:
 | |
|     Returns:
 | |
|         0 - ok
 | |
|         1 - error
 | |
|     Example:
 | |
|         my $rc = &do_rpm($rpmstring, $rpmflags, $localsrc);
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| sub do_rpms
 | |
| {
 | |
|     my $rpmstring = shift;
 | |
|     my $rpmflag   = shift;
 | |
|     my $localsrc  = shift;
 | |
| 
 | |
|     # set flags
 | |
|     my $rflags;
 | |
|     if ($rpmflag)
 | |
|     {
 | |
|         $rflags = $rpmflag;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
| 
 | |
|         # default
 | |
|         $rflags = qq~ -Uvh --replacepkgs ~;
 | |
|     }
 | |
| 
 | |
|     # if a specific dir was provided then use it
 | |
|     # otherwise use the emgr dir in the lpp src
 | |
|     my $dir;
 | |
|     if ($::ALTSRC)
 | |
|     {
 | |
|         $dir = "$localsrc";
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         $dir = "$localsrc/RPMS/ppc";
 | |
|     }
 | |
| 
 | |
|     my $pkg_string = "";
 | |
|     if ($::ALLSW)
 | |
|     {
 | |
|         $pkg_string = " *.rpm   ";
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         $pkg_string = $rpmstring;
 | |
|     }
 | |
| 
 | |
|     # - need to test rpms to make sure all will install
 | |
|     #   - add test to rpm cmd if not included in rpm_flags
 | |
|     #
 | |
|     my @doinstall   = split /\s+/, $pkg_string;
 | |
|     my @dontinstall = ();
 | |
| 
 | |
|     if (   ($rflags =~ /\-i/)
 | |
|         || ($rflags =~ /install /)
 | |
|         || ($rflags =~ /U/)
 | |
|         || ($rflags =~ /update /))
 | |
|     {
 | |
| 
 | |
|         # if so then do test
 | |
|         @doinstall = ();
 | |
| 
 | |
|         my $flags;
 | |
| 
 | |
|         # if the flags don't include test then add it
 | |
|         if (!($rflags =~ /\-test/))
 | |
|         {
 | |
|             $flags = " $rflags  --test ";
 | |
|         }
 | |
| 
 | |
|         $rpmcmd = qq~cd $dir; /usr/bin/rpm $flags $pkg_string ~;
 | |
|         my $rc = &runcmd($rpmcmd);
 | |
|         my @outpt = split /\n/, $::outref;
 | |
|         my @badrpms;
 | |
| 
 | |
|         foreach my $line (@outpt)
 | |
|         {
 | |
|             chomp $line;
 | |
|             $line =~ s/^\s+//;    #remove leading spaces
 | |
|             my ($first, $second, $rest) = split /\s+/, $line;
 | |
|             chomp $first;
 | |
|             if ($first eq 'package')
 | |
|             {
 | |
|                 push @badrpms, $second;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         my @origrpms = split /\s+/, $pkg_string;
 | |
|         foreach my $sr (@origrpms)
 | |
|         {
 | |
|             if ($sr)
 | |
|             {
 | |
|                 my $r = $sr;
 | |
|                 $r =~ s/\*$//g;
 | |
|                 my $found = 0;
 | |
|                 foreach my $b (@badrpms)
 | |
|                 {
 | |
|                     if ($r =~ /$b/)
 | |
|                     {
 | |
|                         push @dontinstall, $r;
 | |
|                         $found++;
 | |
|                         last;
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 if (!$found)
 | |
|                 {
 | |
|                     push @doinstall, $sr;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if (scalar(@doinstall))
 | |
|         {
 | |
|             $pkg_string = join(' ', @doinstall);
 | |
| 
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             $pkg_string = "";
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if (scalar(@doinstall))
 | |
|     {
 | |
|         if ($pkg_string)
 | |
|         {
 | |
|             $rpmcmd = qq~cd $dir; /usr/bin/rpm $rflags $pkg_string ~;
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             $rpmcmd = qq~/usr/bin/rpm $rflags ~;
 | |
|         }
 | |
| 
 | |
| 		print "Running: \'$rpmcmd\'\n";
 | |
| 
 | |
|         my $rc = &runcmd($rpmcmd);
 | |
|         print "$::outref\n";
 | |
|         if ($rc != 0)
 | |
|         {
 | |
| 
 | |
|             # "error from rpm.\n";
 | |
|             return 1;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if (scalar(@dontinstall))
 | |
|     {
 | |
|         print
 | |
|           "The following RPM packages were already installed and were not reinstalled:\n";
 | |
|         my @rpms;
 | |
|         foreach my $rpm (@dontinstall)
 | |
|         {
 | |
|             print "$rpm\n";
 | |
|         }
 | |
|         print "\n\n";
 | |
|     }
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   do_emgr
 | |
| 
 | |
|     This subroutine is used to install a list of emgr packages
 | |
| 
 | |
|     Arguments:
 | |
|     Returns:
 | |
|         0 - ok
 | |
|         1 - error
 | |
|     Example:
 | |
|         my $rc = &do_emgr($emgrfile, $emgrflags, $localsrc);
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| sub do_emgr
 | |
| {
 | |
|     my $emgrfile = shift;
 | |
|     my $emgrflag = shift;
 | |
|     my $localsrc = shift;
 | |
| 
 | |
|     # set flags
 | |
|     my $eflags;
 | |
|     if ($emgrflag)
 | |
|     {
 | |
|         $eflags = $emgrflag;
 | |
|     }
 | |
| 
 | |
|     # if a specific dir was provided then use it
 | |
|     # otherwise use the emgr dir in the lpp src
 | |
|     my $dir;
 | |
|     if ($::ALTSRC)
 | |
|     {
 | |
|         $dir = "$localsrc";
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         $dir = "$localsrc/emgr/ppc";
 | |
|     }
 | |
| 
 | |
|     my $emgrcmd = qq~cd $dir; /usr/sbin/emgr~;
 | |
| 
 | |
|     if ($eflags)
 | |
|     {
 | |
|         $emgrcmd .= qq~ $eflags ~;
 | |
|     }
 | |
| 
 | |
|     if ($emgrfile)
 | |
|     {
 | |
|         $emgrcmd .= qq~ -f $emgrfile ~;
 | |
|     }
 | |
| 
 | |
| 	print "Running: \'$emgrcmd\'\n";
 | |
| 
 | |
|     my $rc = &runcmd($emgrcmd);
 | |
|     print "$::outref\n";
 | |
|     if ($rc != 0)
 | |
|     {
 | |
| 
 | |
|         # "error from emgr.\n";
 | |
|         return 1;
 | |
|     }
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   do_installp
 | |
| 
 | |
|     This subroutine is used to install a list of installp packages
 | |
| 
 | |
|     Arguments:
 | |
|     Returns:
 | |
| 		0 - ok
 | |
| 		1 - error
 | |
|     Example:
 | |
|         my $rc = &do_installp($instpfile, $instpflags, $localsrc);
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| sub do_installp
 | |
| {
 | |
|     my $instpfile = shift;
 | |
|     my $instpflag = shift;
 | |
|     my $localsrc  = shift;
 | |
| 
 | |
|     # set flags
 | |
|     my $iflags;
 | |
|     if ($instpflag)
 | |
|     {
 | |
|         $iflags = $instpflag;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
| 
 | |
|         # use default
 | |
|         $iflags = " -abgQXY ";
 | |
|     }
 | |
| 
 | |
|     # put together the installp command
 | |
|     my $inpcmd = qq~/usr/sbin/installp ~;
 | |
| 
 | |
|     # these installp flags can be used with -d
 | |
|     if ($iflags =~ /l|L|i|A|a/)
 | |
|     {
 | |
| 
 | |
|         # if a specific dir was provided then use it
 | |
|         # otherwise use the installp dir in the lpp src
 | |
|         if ($::ALTSRC)
 | |
|         {
 | |
|             $inpcmd .= qq~ -d $localsrc ~;
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             $inpcmd .= qq~ -d $localsrc/installp/ppc ~;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     $inpcmd .= qq~$iflags ~;
 | |
| 
 | |
|     # don't provide a list of filesets with these flags
 | |
|     if ($iflags !~ /C|L|l/)
 | |
|     {
 | |
|         if ($::ALLSW)
 | |
|         {
 | |
| 
 | |
|             # we want all sw installed
 | |
|             $inpcmd .= qq~ all ~;
 | |
|         }
 | |
|         else
 | |
|         {
 | |
| 
 | |
|             # install what is in the tmp file
 | |
|             $inpcmd .= qq~ -f $instpfile ~;
 | |
|         }
 | |
|     }
 | |
| 
 | |
| 	print "Running: \'$inpcmd\'\n";
 | |
| 
 | |
|     my $rc = &runcmd($inpcmd);
 | |
|     print "$::outref\n";
 | |
|     if ($rc != 0)
 | |
|     {
 | |
| 
 | |
|         # "error from installp.\n";
 | |
|         return 1;
 | |
|     }
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   processpkglist
 | |
| 
 | |
|     This subroutine is used to sort a list of software package names into
 | |
| 	separate lists for each software packaging tool.
 | |
| 
 | |
|     Arguments:
 | |
|     Returns:
 | |
| 		- name of installp list file
 | |
| 		- name of emgr list file
 | |
| 		- ptr to list of rpms
 | |
| 	Example:
 | |
| 		my ($instpfile, $emgrfile, $rpmstring) = &processpkglist(\@pkglist);
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| sub processpkglist
 | |
| {
 | |
|     my $pkg = shift;
 | |
| 
 | |
|     my @pkglist = @$pkg;
 | |
| 
 | |
|     # process the package list
 | |
|     #   - split into rpm, emgr, and installp
 | |
|     my @rpm_pkgs;
 | |
|     my @emgr_pkgs;
 | |
|     my @installp_pkgs;
 | |
| 
 | |
|     my $emgrfile;
 | |
|     my $instpfile;
 | |
|     my $rpmstring;
 | |
| 
 | |
|     # separate into lists for each type of software
 | |
|     if (scalar(@pkglist))
 | |
|     {
 | |
|         foreach my $p (@pkglist)
 | |
|         {
 | |
|             next if ($p =~ /^\s*$/ || $p =~ /^\s*#/);
 | |
|             chomp $p;
 | |
| 
 | |
|             if (($p =~ /\.rpm/) || ($p =~ /^R:/))
 | |
|             {
 | |
|                 my ($junk, $pname);
 | |
|                 if ($p =~ /:/)
 | |
|                 {
 | |
| 
 | |
|                     # remove leading prefix - if any
 | |
|                     ($junk, $pname) = split(/:/, $p);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     $pname = $p;
 | |
|                 }
 | |
|                 push @rpm_pkgs, $pname;
 | |
|             }
 | |
|             elsif (($p =~ /epkg\.Z/) || ($p =~ /^E:/))
 | |
|             {
 | |
|                 my ($junk, $pname);
 | |
|                 if ($p =~ /:/)
 | |
|                 {
 | |
|                     ($junk, $pname) = split(/:/, $p);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     $pname = $p;
 | |
|                 }
 | |
|                 push @emgr_pkgs, $pname;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 my ($junk, $pname);
 | |
|                 if ($p =~ /:/)
 | |
|                 {
 | |
|                     ($junk, $pname) = split(/:/, $p);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     $pname = $p;
 | |
|                 }
 | |
|                 push @installp_pkgs, $pname;
 | |
|             }
 | |
|         }
 | |
|     }    # end - separate into lists
 | |
| 
 | |
|     #
 | |
|     # create tmp file for containing a list of software for
 | |
|     #	installp and emgr
 | |
|     #
 | |
|     # tmp file for installp
 | |
|     #
 | |
| 
 | |
|     my $random_number      = int(rand(1000000));
 | |
|     my $installp_file_name = "installp_file-" . $random_number;
 | |
|     chomp $installp_file_name;
 | |
| 
 | |
|     if (scalar(@installp_pkgs))
 | |
|     {
 | |
|         if (!open(INSTPFILE, ">/tmp/$installp_file_name"))
 | |
|         {
 | |
| 
 | |
|             # error "Could not open $installp_file_name.\n";
 | |
|             $instpfile = "";
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             foreach (@installp_pkgs)
 | |
|             {
 | |
|                 print INSTPFILE $_ . "\n";
 | |
|             }
 | |
|             close(INSTPFILE);
 | |
|             $instpfile = qq~/tmp/$installp_file_name~;
 | |
|         }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         $instpfile = "";
 | |
|     }
 | |
| 
 | |
|     #
 | |
|     # create tmp file for interim fix packages
 | |
|     #
 | |
|     my $emgr_file_name = "emgr_file-" . $random_number;
 | |
|     chomp $emgr_file_name;
 | |
|     if (scalar(@emgr_pkgs))
 | |
|     {
 | |
|         if (!open(EMGRFILE, ">/tmp/$emgr_file_name"))
 | |
|         {
 | |
| 
 | |
|             # error "Could not open $emgr_file_name.\n";
 | |
|             $emgrfile = "";
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             foreach (@emgr_pkgs)
 | |
|             {
 | |
| 
 | |
|                 #    print EMGRFILE "./$_" . "\n";
 | |
|                 print EMGRFILE "$_" . "\n";
 | |
|             }
 | |
|             close(EMGRFILE);
 | |
|             $emgrfile = qq~/tmp/$emgr_file_name~;
 | |
|         }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         $emgrfile = "";
 | |
|     }
 | |
| 
 | |
|     # put rpm list in a string
 | |
|     if (scalar(@rpm_pkgs))
 | |
|     {
 | |
|         foreach my $pkg (@rpm_pkgs)
 | |
|         {
 | |
|             $rpmstring .= " $pkg";
 | |
|         }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         $rpmstring = "";
 | |
|     }
 | |
| 
 | |
|     return ($instpfile, $emgrfile, $rpmstring);
 | |
| }
 | |
| 
 | |
| #
 | |
| # run the command
 | |
| #
 | |
| sub runcmd
 | |
| {
 | |
|     my ($cmd) = @_;
 | |
|     my $rc = 0;
 | |
|     $cmd .= ' 2>&1';
 | |
|     $::outref = `$cmd`;
 | |
|     if ($?)
 | |
|     {
 | |
|         $rc = $? >> 8;
 | |
|         if ($rc > 0)
 | |
|         {
 | |
|             return 1;
 | |
|         }
 | |
|     }
 | |
|     return 0;
 | |
| }
 |