# $Header: ecmPatchEMD.pl 31-jan-2005.05:29:53 shgangul Exp $ # # Copyright (c) 2001, 2005, Oracle. All rights reserved. # # DESCRIPTION # ECM script to patch Oracle Enterprise Manager with One-off/Patchset patches # # USAGE # ecmPatchEMD.pl # [ ( | )] # # NOTES # # # MODIFIED (MM/DD/YY) # shgangul 01/31/05 - bug 3845819: MAC OS port # mbhoopat 03/10/04 - linux port # nsharma 01/19/04 - Correct path of find, id, nawk and unzip on linux # xxu 06/25/02 - remove /usr/local/bin/perl # mgoodric 12/21/01 - Add script steps to patch job # mgoodric 12/07/01 - Add echodo function to display system cmd # mgoodric 12/06/01 - Fix PatchDatabase job for Patchset # mgoodric 12/04/01 - Fixes for PatchDatabase job # mgoodric 11/29/01 - Add PatchEMD job type # # # --- Set up necessary variables for proper running of this environment --- use strict; use FileHandle; use File::Basename; use File::Path; my $scriptDir = dirname($0); require "$scriptDir/ecmCommon.pl"; # ------ Initialize global variables ------------------------------------- my $action = ''; # [0] = checkTarget | installPatch | showResults my $depot_path = ''; # [1] = ecmdepot/patches my $patch_type = ''; # [2] = Patch | Patchset my $patch_id = ''; # [3] = 1234567 my $patch_size = '0'; # [4] = 463162 | 142144398 my $patch_file = ''; # [4] = p1234567.zip my $patch_index = '1'; # [5] = 1..n my $patch_count = '1'; # [6] = n my $db_name = ''; my $patch_lock = 'PATCH.lck'; my $EMDROOT = ''; my $JAVA_HOME = ''; my $OUILOC = ''; my $debug = 1; # true if debugging # --------------------- OS platform-specific ---------------------------- my $chmod = '/bin/chmod'; my $df = '/bin/df'; my $echo = '/bin/echo'; my $egrep = '/bin/egrep'; my $emctl = 'emctl'; my $find = '/bin/find'; my $id = '/bin/id'; my $jar = 'jar'; my $ls = '/bin/ls'; my $nawk = '/bin/nawk'; my $null = '/dev/null'; my $ps = '/bin/ps'; my $rm = '/bin/rm -f'; my $tar = '/bin/tar'; my $unzip = '/bin/unzip'; my $tempfile = "/tmp/sqlplus_$$.sql"; my $DEF_PATH = '/bin:/sbin:/usr/bin:/usr/sbin:/etc:/usr/etc:/usr/ccs/bin:/usr/ucb'; my $DEF_LD_LIBRARY_PATH = '/usr/lib'; my $DEF_JAVA_HOME = '/usr/local/packages/jdk1.3.1'; if ($^O eq 'linux') { $find = '/usr/bin/find'; $id = '/usr/bin/id'; $nawk = '/bin/awk'; $unzip = '/usr/bin/unzip'; } elsif ($^O eq 'darwin') { $egrep = '/usr/bin/egrep'; $find = '/usr/bin/find'; $id = '/usr/bin/id'; $nawk = '/usr/bin/awk'; $tar = '/usr/bin/tar'; $unzip = '/usr/bin/unzip'; } # --------------------- Subroutines ------------------------------------- # # err(,) # # Display a formatted error message # sub err($$) { my ($error_number,$error_text) = @_; printf "---------- Error Message ----------\n"; printf "Error: %03d\n",$error_number; printf "%s\n",$error_text; printf "----------- End Message -----------\n"; } # # warn(,) # # Display a formatted warning message # sub warn($$) { my ($warning_number,$warning_text) = @_; printf "--------- Warning Message ---------\n"; printf "Warning: %03d\n",$warning_number; printf "%s\n",$warning_text; printf "----------- End Message -----------\n"; } # # echodo() # # Display the command and execute it # Return status # sub echodo($) { my ($cmd) = @_; printf "\n%s\n", $cmd; return system($cmd); } # # createLock(,) # # Place a marker in the depot to indicate patching state # sub createLock($$) { my ($lock_file,$lock_id) = @_; my $lock_path = dirname($lock_file); mkpath($lock_path,0,0775) if (! -d $lock_path); open(OUTPUT,'>',$lock_file); print OUTPUT "$lock_id\n"; close(OUTPUT); } # # isLocked() # # Test a marker in the depot to indicate patching state # sub isLocked($) { my ($lock_file) = @_; return (-f $lock_file); } # # clearLocks() # # Reset all patching state markers # sub clearLocks { unlink($patch_lock); } # # checkTarget() # # - Verify EMDROOT # - Create depot directory to store patch # - Check disk space for available free space # sub checkTarget { my $patch_path = "$depot_path/$patch_id"; my $undo_patch = ''; my $tempfile = "_test_$$"; my $freeKB = 0; my $needKB = 0; my $status = 0; $! = 0; chdir($EMDROOT) or abort($action,$? >>8,"Could not cd to >$EMDROOT<: $!"); if (! -d $patch_path) { mkpath($patch_path,0,0775) > 0 or abort($action,$? >>8,"Could not mkpath >$patch_path<: $!"); } chdir($patch_path) or abort($action,$? >>8,"Could not cd to >$patch_path<: $!"); if ($patch_type eq 'Patch') { chomp($undo_patch = `$find $patch_path -name 'undo_pre[0-9]*.sh'`); $undo_patch eq '' or abort($action,1,"$patch_id already applied"); } open(OUTPUT,'>',$tempfile) or abort($action,$? >>8,"Could not open file $tempfile to write: $!"); close(OUTPUT); unlink($tempfile); chomp($freeKB = `$df -b $patch_path | $nawk '/dev/{print \$2}'`); $needKB = int(($needKB + (3 * $patch_size)) / 1024); $freeKB > $needKB or abort($action,7,"Not enough free disk space: ${freeKB}KB < ${needKB}KB"); } # # installPatch() # # - Unjar the patch # - Untar the tar (if Patchset) # - create the patch script and run in background # sub installPatch { my $patch_path = "$depot_path/$patch_id"; my $orapatch = ''; my $patch_args = ''; my $patch_log = "$patch_path/../EMD_${patch_id}.log"; my $patch_sh = "$patch_path/../EMD_${patch_id}.sh"; my $patch_home = $patch_path; my $patchset_rsp = ''; my $products_jar = ''; my $patch_tar = ''; my $failed = 'skipped'; my $status = 1; $! = 0; chdir($patch_path) or abort($action,$? >>8,"Could not cd to >$patch_path<: $!"); unlink($patch_lock) if ($patch_index == 1); if (!isLocked($patch_lock)) { createLock($patch_lock,$patch_id) if ($patch_count > 1); printf "Unpacking patch file $patch_file...\n"; echodo("$jar -xf $patch_file") == 0 or abort($action,$? >>8,"Could not unjar $patch_file"); open(OUTPUT,'>',$patch_sh); print OUTPUT "#!/bin/sh -x\n"; if ($patch_type eq 'Patch') { chomp($orapatch = `$find $patch_path -name 'orapatch'`); if ($orapatch eq '') { chomp($orapatch = `$find $patch_path -name 'patch.sh'`); } $orapatch ne '' or abort($action,3,"Could not find patch.sh"); $patch_home = dirname($orapatch); $patch_args = "install $EMDROOT" if (basename($orapatch) eq 'orapatch'); if ($patch_args eq '') { print OUTPUT "cd $patch_home || exit 1\n"; print OUTPUT "$chmod 777 $orapatch; $echo Y | $orapatch\n"; } else { print OUTPUT "cd $patch_home || exit 1\n"; print OUTPUT "$chmod 777 $orapatch; $orapatch $patch_args >8,"Could not untar $patch_tar"); chomp($patchset_rsp = `$find $patch_path/response -name '*.rsp'`); $patchset_rsp ne '' or abort($action,3,"Could not find response file"); chomp($products_jar = `$find $patch_path/stage -name 'products.jar'`); $products_jar ne '' or abort($action,3,"Could not find products.jar"); $patch_args = "-silent -responseFile $patchset_rsp session_FROM_LOCATION=\"$products_jar\" session_ORACLE_HOME=\"$EMDROOT\""; $orapatch = "$OUILOC/oui/install/runInstaller.sh"; print OUTPUT "DISPLAY=:0.0; export DISPLAY\n"; print OUTPUT "cd $EMDROOT\n"; print OUTPUT "$orapatch $patch_args >8,"Could not chmod >$patch_sh<: $!"); } chdir($EMDROOT) or abort($action,$? >>8,"Could not cd to >$EMDROOT<: $!"); $failed = 'failed'; printf "\nApplying Patch $patch_id...\n"; $status = echodo("(sleep 1; $emctl stop; $patch_sh; $emctl start) <$null >$patch_log 2>&1 &"); unlink($patch_lock) if ($patch_count > 1 && $status == 0); } if ($patch_index == $patch_count) { unlink($patch_lock); } $status == 0 or abort($action,$status >>8,"Patch $failed"); if (!$debug) { unlink($patch_file); unlink($patch_tar) if ($patch_tar ne ''); } } # # showResults() # # - Show the log of the actual EMD patch # sub showResults { my $patch_path = "$depot_path/$patch_id"; my $patch_log = "$patch_path/../EMD_$patch_id.log"; my $status = 1; $! = 0; chdir($EMDROOT) or abort($action,$? >>8,"Could not cd to >$EMDROOT<: $!"); printf "\nPatch results for $patch_id...\n"; if (-f $patch_log) { open(INPUT,'<',$patch_log); while() { print $_; } close(INPUT); } if (!$debug) { unlink($patch_log); rmtree($patch_path,0,1); } } # # emdenv() # # Set EMD environment # sub emdenv { $EMDROOT = $ENV{'EMDROOT'}; if (! defined $EMDROOT || $EMDROOT eq '') { ($EMDROOT = $scriptDir) =~ s~/sysman/admin/scripts/osm~~; } $emctl = "$EMDROOT/bin/$emctl"; $JAVA_HOME = $ENV{'JAVA_HOME'}; if (! defined $JAVA_HOME || $JAVA_HOME eq '') { $JAVA_HOME = $DEF_JAVA_HOME; } $jar = "$JAVA_HOME/bin/$jar"; $OUILOC = $ENV{'OUILOC'}; } # --------------------- Main program ------------------------------------- setOutputAutoflush(); printHeader($0,$#ARGV); emdenv(); # # Check for minimum number of args # $action = $ARGV[0]; # checkTarget | installPatch | showResults $#ARGV >= 2 or abort($action,3,"Missing args: $#ARGV < 2"); $depot_path = "$EMDROOT/$ARGV[1]"; # ecmdepot/patches $db_name = 'EMD'; $patch_lock = "$depot_path/${db_name}-$patch_lock"; $patch_type = $ARGV[2]; # Patch # # Execute the action requested # if ($action eq 'checkTarget') { $#ARGV >= 3 or abort($action,3,"Missing args: $#ARGV < 3"); $patch_id = $ARGV[3]; # 1234567 $patch_size = $ARGV[4] if ($#ARGV >= 4); # 463162 checkTarget(); } elsif ($action eq 'installPatch') { $#ARGV >= 4 or abort($action,3,"Missing args: $#ARGV < 4"); $patch_id = $ARGV[3]; # 1234567 $patch_file = $ARGV[4]; # p1234567_9010_SOLARIS.zip $patch_index = $ARGV[5] if ($#ARGV >= 5); # 1..n $patch_count = $ARGV[6] if ($#ARGV >= 6); # n installPatch(); } elsif ($action eq 'showResults') { $#ARGV >= 3 or abort($action,3,"Missing args: $#ARGV < 3"); $patch_id = $ARGV[3]; # 1234567 showResults(); } else { abort($action,3,"Unrecognized action: $action"); } # # Indicate a successful action; exit with success status # printf "\n$action successful\n"; exit 0;