Fully unintended CPU Patch Download for Oracle WebLogic Server

Posted by Dirk Nachbar on Tuesday, May 09, 2017
In case you are owning different versions of Oracle WebLogic Server, e.g. 10.3.6, 12.1.3, 12.2.1.2 and so on and you are regularly applying the Oracle Critical Patch Updates, you will have to download various different Patches.

Mainly you will have to click through different Websites and My Oracle Support Notes until you can download the required patches.

For this purpose I have developed a handy script, with which you can perform a fully unintended download of the latest Oracle WebLogic Server CPU Patches.

All what you need is:

Instructions

At first generate the required folder structure on your Linux Server:

root@server> cd /
root@server> mkdir -p CPU_TOOL/em_catalog
root@server> mkdir -p CPU_TOOL/archive
root@server> mkdir CPU_PATCHES

Create in the directory CPU_TOOL the following 2 files:
patch_download.ksh (afterwards make it executable chmod +x patch_download.ksh

#!/bin/ksh
# Author: Dirk Nachbar, http://dirknachbar.blogspot.com
#
# Purpose:    Wrapper Script for automated Critical Patch Update
#             download from My Oracle Suppurt (MOS)
#             
# Requirements: getMOSPatch, Author: Maris Elsins
#               Source: https://github.com/MarisElsins/getMOSPatch
#
#
# Parameters: -i <PropertiesFile> 
#       e.g.: -i mos.properties
#
#
# Exit Codes:
#             - 1 = Exit Code of Usage Function
#             - 2 = Missing Property or Value in configfile
#
#---------------------------------------------------------------------


#---------------------------------------------------------------------
# CONSTANTS
#---------------------------------------------------------------------

MyName="$(basename $0)"
StartDate="$(date '+%Y-%m-%d_%H:%M:%S')"
LogDir=/work/logs
WorkDir=`pwd`

#---------------------------------------------------------------------
Usage()
#
# PURPOSE: Displays the Usage of the script
#---------------------------------------------------------------------
{
cat << EOF
Usage: patch_download.ksh -i <ConfigFile>
       Wrapper Script for automated Critical Patch Update
       download from My Oracle Support (MOS)
       for Oracle WebLogic Server Release 10.3.6, 12.1.x, 12.2.x

Parameters:
   -i: config file with required parameters

EOF
exit 1
}

#---------------------------------------------------------------------
DoMsg()
#
# PURPOSE: Displays the TimeStamp in front of each status line
#---------------------------------------------------------------------
{
    if [ "${DoAppend}" = "TRUE" ]; then
        echo "`date +%Y-%m-%d_%H:%M:%S` `printf "%05d" $$` ${1}" | tee -a ${LogFile}
    else
        echo "`date +%Y-%m-%d_%H:%M:%S` `printf "%05d" $$` ${1}"
    fi

    shift

    while [ "${1}" != "" ]; do

        if [ "${DoAppend}" = "TRUE" ]; then
            echo "                     ${1}" | tee -a ${LogFile}
        else
            echo "                     ${1}"
        fi

        shift
    done
}


#---------------------------------------------------------------------
CheckParams()
#
# PURPOSE: Checks the input Parmeter -i
#---------------------------------------------------------------------
{
    if [ "${ConfigFile}" = "" ] ; then
        DoMsg "  ERR: Missing parameter(s), the flags -i must be used."
        Usage
    fi
}


#---------------------------------------------------------------------
ReadParams()
#
# PURPOSE: Reads the Parmeters of the Configfile and validate them
#---------------------------------------------------------------------
{
DoMsg "Reading provided Configuration File"
DoMsg "..."

TheMOSUser="$(cat ${ConfigFile} | grep -i "^MOSUser=" | head -n 1 | cut -d= -f2-)"
TheMOSPassword="$(cat ${ConfigFile} | grep -i "^MOSPassword=" | head -n 1 | cut -d= -f2-)"
TheUploadDir="$(cat ${ConfigFile} | grep -i "^UploadDir=" | head -n 1 | cut -d= -f2-)"

    if [ "${TheMOSUser}" = "" ] ; then
        echo "  ERR: Missing value MOSUser in the provided Config File."
        exit 2
    fi

    if [ "${TheMOSPassword}" = "" ] ; then
        echo "  ERR: Missing value MOSPassword in the provided Config File."
        exit 2
    fi

    if [ "${TheUploadDir}" = "" ] ; then
        echo "  ERR: Missing value UploadDir in the provided Config File."
        exit 2
    fi
}


#---------------------------------------------------------------------
DownloadEMCatalog()
#
# PURPOSE: Download of actual Patch List from MOS
#---------------------------------------------------------------------
{

DoMsg "Starting to download latest Version of em_catalog.zip from My Oracle Support"

# Cleanup the em_catalog directory from previous executions
rm -f ${WorkDir}/em_catalog/*.*

TheCookieFile=/tmp/$$.cookies
TheEM_CatalogLogFile=${LogDir}/wget_em_catalog_download_${StartDate}.log

# Contact updates site so that we can get SSO Params for logging in
SSO_Response=`wget https://updates.oracle.com/Orion/Services/download 2>&1|grep Location`

# Extract request parameters for SSO
SSO_Token=`echo $SSO_Response| cut -d '=' -f 2|cut -d ' ' -f 1`
SSO_Server=`echo $SSO_Response| cut -d ' ' -f 2|cut -d 'p' -f 1,2`
SSO_Auth_URL=sso/auth
Auth_Data="ssousername=${TheMOSUser}&password=${TheMOSPassword}&site2pstoretoken=$SSO_Token"

wget --post-data $Auth_Data --save-cookies=${TheCookieFile} --keep-session-cookies $SSO_Server$SSO_Auth_URL >> ${TheEM_CatalogLogFile} 2>&1
wget  --load-cookies=${TheCookieFile} --save-cookies=${TheCookieFile} --keep-session-cookies "https://updates.oracle.com/download/em_catalog.zip" -O em_catalog.zip >> ${TheEM_CatalogLogFile} 2>&1

# Cleanup the Cookie File
rm -f ${TheCookieFile}
rm -f auth

# Extract the em_catalog.zip
unzip ${WorkDir}/em_catalog.zip -d ${WorkDir}/em_catalog/

mv ${WorkDir}/em_catalog.zip ${WorkDir}/archive/em_catalog_${StartDate}.zip

DoMsg "Done to download latest Version of em_catalog.zip from My Oracle Support"

}

#---------------------------------------------------------------------
#
DownloadPatches()
# PURPOSE: Download the actual Patches for Oracle WLS
#---------------------------------------------------------------------
{

# Calculate actual Quarter Year
TheQYear=`echo $(date +%Y)_Q$(( ($(date +%-m)-1)/3+1 ))`
TheDownloadLogFile=${LogDir}/download_patches_${StartDate}.log
DoMsg "Starting to download Oracle WLS CPU's" | tee -a ${TheDownloadLogFile}


# Patch Download for WLS 10.3.6
PatchNumber=`grep -B 2 "<psu_bundle>WLS 10.3" em_catalog/patch_recommendations.xml | grep "<name>" | sed -e 's,.*<name>\([^<]*\)</name>.*,\1,g'`

ThePatchDir=${TheUploadDir}/WLS10.3.6.0/${TheQYear}/${PatchNumber}
mkdir -p ${ThePatchDir}
cd ${ThePatchDir}

DoMsg "Downloading CPU Patch ${PatchNumber} for WLS 10.3.6" | tee ${TheDownloadLogFile}

java -jar ${WorkDir}/getMOSPatch/getMOSPatch.jar MOSUser=${TheMOSUser} MOSPass=${TheMOSPassword} patch=${PatchNumber} regexp=.*Generic.* download=all platform=1234P >> ${TheDownloadLogFile}

cd ${TheUploadDir}/WLS10.3.6.0
rm -f actual
ln -s ${ThePatchDir} actual
cd ${WorkDir}

# Patch Download for WLS 12.1.2
PatchNumber=`grep -B 2 "<psu_bundle>WLS 12.1.2" em_catalog/patch_recommendations.xml | grep "<name>" | sed -e 's,.*<name>\([^<]*\)</name>.*,\1,g'`

ThePatchDir=${TheUploadDir}/WLS12.1.2.0.0/${TheQYear}/${PatchNumber}
mkdir -p ${ThePatchDir}
cd ${ThePatchDir}

DoMsg "Downloading CPU Patch ${PatchNumber} for WLS 12.1.2" | tee -a ${TheDownloadLogFile}

java -jar ${WorkDir}/getMOSPatch/getMOSPatch.jar MOSUser=${TheMOSUser} MOSPass=${TheMOSPassword} patch=${PatchNumber} regexp=.*Generic.* download=all platform=1234P >> ${TheDownloadLogFile}

cd ${TheUploadDir}/WLS12.1.2.0.0
rm -f actual
ln -s ${ThePatchDir} actual
cd ${WorkDir}

# Patch Download for WLS 12.1.3
PatchNumber=`grep -B 2 "<psu_bundle>Oracle WebLogic Server 12.1.3" em_catalog/patch_recommendations.xml | grep "<name>" | sed -e 's,.*<name>\([^<]*\)</name>.*,\1,g'`

ThePatchDir=${TheUploadDir}/WLS12.1.3.0.0/${TheQYear}/${PatchNumber}
mkdir -p ${ThePatchDir}
cd ${ThePatchDir}

DoMsg "Downloading CPU Patch ${PatchNumber} for WLS 12.1.3" | tee -a ${TheDownloadLogFile}

java -jar ${WorkDir}/getMOSPatch/getMOSPatch.jar MOSUser=${TheMOSUser} MOSPass=${TheMOSPassword} patch=${PatchNumber} regexp=.*Generic.* download=all platform=1234P >> ${TheDownloadLogFile}

cd ${TheUploadDir}/WLS12.1.3.0.0
rm -f actual
ln -s ${ThePatchDir} actual
cd ${WorkDir}

# Patch Download for WLS 12.2.1.0
PatchNumber=`grep -B 2 "<psu_bundle>Oracle WebLogic Server 12.2.1.0" em_catalog/patch_recommendations.xml | grep "<name>" | sed -e 's,.*<name>\([^<]*\)</name>.*,\1,g'`

ThePatchDir=${TheUploadDir}/WLS12.2.1.0.0/${TheQYear}/${PatchNumber}
mkdir -p ${ThePatchDir}
cd ${ThePatchDir}

DoMsg "Downloading CPU Patch ${PatchNumber} for WLS 12.2.1.0" | tee -a ${TheDownloadLogFile}

java -jar ${WorkDir}/getMOSPatch/getMOSPatch.jar MOSUser=${TheMOSUser} MOSPass=${TheMOSPassword} patch=${PatchNumber} regexp=.*Generic.* download=all platform=1234P >> ${TheDownloadLogFile}

cd ${TheUploadDir}/WLS12.2.1.0.0
rm -f actual
ln -s ${ThePatchDir} actual
cd ${WorkDir}

# Patch Download for WLS 12.2.1.1
PatchNumber=`grep -B 2 "<psu_bundle>Oracle WebLogic Server 12.2.1.1" em_catalog/patch_recommendations.xml | grep "<name>" | sed -e 's,.*<name>\([^<]*\)</name>.*,\1,g'`

ThePatchDir=${TheUploadDir}/WLS12.2.1.1.0/${TheQYear}/${PatchNumber}
mkdir -p ${ThePatchDir}
cd ${ThePatchDir}

DoMsg "Downloading CPU Patch ${PatchNumber} for WLS 12.2.1.1" | tee -a ${TheDownloadLogFile}

java -jar ${WorkDir}/getMOSPatch/getMOSPatch.jar MOSUser=${TheMOSUser} MOSPass=${TheMOSPassword} patch=${PatchNumber} regexp=.*Generic.* download=all platform=1234P >> ${TheDownloadLogFile}

cd ${TheUploadDir}/WLS12.2.1.1.0
rm -f actual
ln -s ${ThePatchDir} actual
cd ${WorkDir}

# Patch Download for WLS 12.2.1.2
PatchNumber=`grep -B 2 "<psu_bundle>Oracle WebLogic Server 12.2.1.2" em_catalog/patch_recommendations.xml | grep "<name>" | sed -e 's,.*<name>\([^<]*\)</name>.*,\1,g'`

ThePatchDir=${TheUploadDir}/WLS12.2.1.2.0/${TheQYear}/${PatchNumber}
mkdir -p ${ThePatchDir}
cd ${ThePatchDir}

DoMsg "Downloading CPU Patch ${PatchNumber} for WLS 12.2.1.2" | tee -a ${TheDownloadLogFile}

java -jar ${WorkDir}/getMOSPatch/getMOSPatch.jar MOSUser=${TheMOSUser} MOSPass=${TheMOSPassword} patch=${PatchNumber} regexp=.*Generic.* download=all platform=1234P >> ${TheDownloadLogFile}

cd ${TheUploadDir}/WLS12.2.1.2.0
rm -f actual
ln -s ${ThePatchDir} actual
cd ${WorkDir}

DoMsg "Done to download Oracle WLS CPU's" | tee -a ${TheDownloadLogFile}

}

#---------------------------------------------------------------------
# MAIN
#---------------------------------------------------------------------

ConfigFile=""

# All required ConfigParameters are initially set to empty
TheMOSUser=
TheMOSPassword=

while getopts i: CurOpt; do
    case ${CurOpt} in
        i) ConfigFile="${OPTARG}" ;;
        ?) Usage
           exit 1 ;;
    esac
done

shift $((${OPTIND}-1))

if [ $# -ne 0 ]; then
    Usage
fi

# Check Input Params
CheckParams

# Read the Params from the Config File
ReadParams
# Downloading EM Catalog zip file
DownloadEMCatalog
# Downloading the latest available Patches
DownloadPatches


mos.properties
# Configuration File for Automated Critical Patch Download
#
# Author: Dirk Nachbar, http://dirknachbar.blogspot.com
#

# My Oracle Support Credentials

MOSUser=<your_email>
MOSPassword=<your_mos_password>

# Upload Directory for CPU Patches

UploadDir=/CPU_PATCHES

Download the getMOSPatch.jar from https://github.com/MarisElsins/getMOSPatch and place it under /CPU_TOOL/getMOSPatch

root@server> mkdir -p /CPU_TOOL/getMOSPatch
root@server> cp /tmp/getMOSPatch.jar /CPU_TOOL/getMOSPatch

Make sure that you have a java 1.6 or higher in your PATH
root@server> which java
/bin/java
root@server> java -version
openjdk version "1.8.0_102"
OpenJDK Runtime Environment (build 1.8.0_102-b14)
OpenJDK 64-Bit Server VM (build 25.102-b14, mixed mode)

How does it work?

The trick behind the unintended CPU download is really simple, I am using the em_catalog.zip provided by My Oracle Support, which is used by Oracle Cloud Control for the so called Offline Patching (see MOS Note https://support.oracle.com/epmos/faces/DocContentDisplay?id=1931891.1)
In the patch_download.ksh script within the function DownloadEMCatalog() I am downloading the latest version of the em_catalog.zip, place it in the subdirectory /CPU_TOOL/em_catalog, unzip the file.
In the function DownloadPatches() I am using grep to identify the latest available CPU Patches for various WebLogic Server Releases within the file /CPU_TOOL/em_catalog/patch_recommendations.xml and through Maris Elsins' getMOSPatch I am downloading unintended the identified Patches, place them in the directory /CPU_PATCHES/WLS/<VersionNumber>/YYYY_Q[1|2|3|4] and creating a symlink on the latest CPU Patch to actual.

Get your Patches

To download the latest available patches, simply execute following commands:

root@server> cd /CPU_TOOL
root@server> ./patch_download.ksh -i mos.properties

2017-05-09_11:46:19 08102 Reading provided Configuration File
2017-05-09_11:46:19 08102 ...
2017-05-09_11:46:19 08102 Starting to download latest Version of em_catalog.zip from My Oracle Support
Archive:  /CPU_TOOL/em_catalog.zip
  inflating: /CPU_TOOL/em_catalog/aru_products.xml  
  inflating: /CPU_TOOL/em_catalog/aru_releases.xml  
  inflating: /CPU_TOOL/em_catalog/aru_platforms.xml  
  inflating: /CPU_TOOL/em_catalog/aru_languages.xml  
  inflating: /CPU_TOOL/em_catalog/aru_product_groups.xml  
  inflating: /CPU_TOOL/em_catalog/aru_product_releases.xml  
  inflating: /CPU_TOOL/em_catalog/aru_component_releases.xml  
  inflating: /CPU_TOOL/em_catalog/aru_targets.xml  
  inflating: /CPU_TOOL/em_catalog/components.xml  
  inflating: /CPU_TOOL/em_catalog/certifications.xml  
  inflating: /CPU_TOOL/em_catalog/patch_recommendations.xml  
 extracting: /CPU_TOOL/em_catalog/README.txt  
2017-05-09_11:46:56 08102 Done to download latest Version of em_catalog.zip from My Oracle Support
2017-05-09_11:46:56 08102 Starting to download Oracle WLS CPU's
2017-05-09_11:46:57 08102 Downloading CPU Patch 25388747 for WLS 10.3.6
2017-05-09_11:47:39 08102 Downloading CPU Patch 22505331 for WLS 12.1.2
2017-05-09_11:48:07 08102 Downloading CPU Patch 25388793 for WLS 12.1.3
2017-05-09_11:48:34 08102 Downloading CPU Patch 25388847 for WLS 12.2.1.0
2017-05-09_11:48:54 08102 Downloading CPU Patch 25388843 for WLS 12.2.1.1
2017-05-09_11:49:18 08102 Downloading CPU Patch 25388866 for WLS 12.2.1.2
2017-05-09_11:49:41 08102 Done to download Oracle WLS CPU's


Now you will find under the directory /CPU_PATCHES/WLS<VersionNumber>/YYYY_Q[1|2|3|4] the latest available CPU Patch for your Oracle WebLogic Server.
You can easily change in the mos.properties configuration file the target location for the CPU Patches to e.g. a mounted NAS drive, which you can attach to your WebLogic hosts, so that the patches are immediately available on your hosts for WebLogic Server.