#!/bin/bash
#######################################################################################
##                                                                                   ##
##          Script Name : db_inplace_upgrade.sh                                      ##
##          Purpose     : Script to upgrade CMS database from 2.5 to 3.1             ##
##          Created by  : Matthew Kruer & Suresh Neravati                            ##
##          Created on  : 05/10/2013                                                 ##
##                                                                                   ##
#######################################################################################
DBUPGRADE_DIR="/home/upgrade/db_upgrade"
YUM_REPO="/etc/yum.repos.d/upgrade.repo"
YUM_REPO_SOURCE=""
if [ `whoami` != "root" ]; then
   echo "************************************************************************************"
   echo " Only root user can run this script. Please log in as a root user and try again...!" 
   echo "************************************************************************************"
   exit 1
fi

# Backup Config Files
CONFIG_FILES=(
    "/etc/modprobe.d/bonding.conf"
    "/usr/local/platform/backup/bin/commonbackup_oracle_full_back.sh"
    "/usr/local/platform/backup/bin/commonbackup_oracle_inc_back.sh"
    "/usr/local/platform/backup/conf/commonbackup.cfg"
    "/var/spool/cron/root"
    "/etc/sysctl.conf"                                        
    "/etc/security/limits.conf"                               
    "/etc/oratab"                                             
    "/etc/init.d/oracle"                                      
    "/etc/oraInst.loc"                                        
    "/home/oracle/.bash_profile"                              
    "/opt/oracle/product/11.2.0/db_1/sqlplus/admin/glogin.sql"
    "/opt/oracle/backup/scripts/rman_backup.ksh"              
    "/opt/oracle/backup/scripts/rman_backup_arch.ksh"         
    "/opt/oracle/product/11.2.0/db_1/assistants/dbca/templates/ttv.ctl"
    "/opt/oracle/product/11.2.0/db_1/assistants/dbca/templates/ttv.dfb"
    "/opt/oracle/product/11.2.0/db_1/assistants/dbca/templates/ttv.dbc"
)

## Application Packages
APP_PACKAGES="  info-cms
                info-oracle
                oracle-admin
                oracleEE
                oracle-installcms        
                oracle-installdw           
                oracle-installepgmgr       
                oracle-installrcs          
                oracle-installrm 
                oracle-rdbms-install-scripts"

## Base OS Packages installed as part of the Kickstart
BASE_PACKAGES=" @Core
                bc
                cmsstaging
                commonbackup
                dmidecode
                dos2unix
                eject
                file
                jdk
                man
                mutt
                net-snmp
                net-snmp-utils
                nfs-utils
                ntp
                sysstat
                system-config-network-tui
                tcpdump
                zip
                pdksh
                warmstandby
                hpacucli"

# Settings
START=$(date +%s)
TIMESTAMP=`date --utc -d "@$(( $START ))" +%Y%m%d_%H%M%S`
FULL_LOG="${DBUPGRADE_DIR}/cms_direct_inplace_upgrade/$TIMESTAMP.update.log"
BACKUP_DIR="${DBUPGRADE_DIR}/cms_direct_inplace_upgrade/upgrade_pre_backup"
Color_Off='\e[0m'       # Text Reset
Black='\e[0;30m'        # Black
Red='\e[0;31m'          # Red
Green='\e[0;32m'        # Green
Yellow='\e[0;33m'       # Yellow
Blue='\e[0;34m'         # Blue
Purple='\e[0;35m'       # Purple
Cyan='\e[0;36m'         # Cyan
White='\e[0;37m'        # White

## Abort Loop
die() {
    printf -v f "\n\n%65s";printf "%s\n" "${f// /#}" 
    printf "Error: $1\n"
    printf "Please Review Log File $FULL_LOG\n"
    printf -v f "%65s";printf "%s\n" "${f// /#}" 
    printf "%-15s${Red}%-5s${Color_Off}\n\n\n" "Update Status: " "Failed!"
    exit 1
}

# Create log folder if it does exists
function create_log_folder
{
    if [[ ! -d "$LOGPATH" ]]; then
        mkdir $LOGPATH
        echo "Creating $LOGPATH"
        printf "${Green}%-5s${Color_Off}\n" "Done."    
    fi
}

function printline
{
   echo -e "********************************************************************************\n"
}

# Oracle Prep
function ora_prep
{    
    cp -f ${DBUPGRADE_DIR}/createbackup/change_db_archive.sh /home/oracle/scripts/dbca/change_db_archive.sh
    if [ $? -ne 0 ]; then
      echo "Error in copying the change_db_archive.sh file" 
      exit 1
    else
        chmod 755 /home/oracle/scripts/dbca/change_db_archive.sh
        chown oracle:oinstall /home/oracle/scripts/dbca/change_db_archive.sh
    fi

    su - oracle -c "/home/oracle/scripts/dbca/change_db_archive.sh"
    su - oracle -c "/opt/oracle/backup/scripts/rman_backup.ksh DISK"
    
    # unset Path
    unset PATH
    PATH=/opt/oracle/product/11.2.0/db_1/bin:/opt/oracle/product/11.2.0/db_1/OPatch:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:
    export PATH

    service oracle stop
    
    echo "Backing up files in case of rollback"
    cd /opt
    #tar -czvpf ${BACKUP_DIR}/oracle.tar.gz oracle
    cd ${DBUPGRADE_DIR}

    echo "Backingup crontabs ...."
    su - oracle -c "crontab -l > /home/oracle/oracle_cron.bak"
    cp /home/oracle/oracle_cron.bak ${BACKUP_DIR}/oracle_cron.bak
    crontab -l > ${BACKUP_DIR}/root_cron.bak    
    
}

# Backup configuration files
function backup_config_files 
{
    printf "%-7s\n" "Backing up config Files:"
    for c in "${CONFIG_FILES[@]}"
    do
        if [[ -e "$c" ]]; then 
            printf "%-9s%s\n" "  [ OK ]" "Backing up $c to $BACKUP_DIR/$c"
            DIRNAME=`dirname "${c}"`
            BASENAME=`basename "${c}"`
            if [ ! -d "$BACKUP_DIR"/"$DIRNAME" ] ; then
               mkdir -p "$BACKUP_DIR"/"$DIRNAME"
            fi
            cp -p "$c" "$BACKUP_DIR"/"$c"
        else 
            printf "%-9s%s\n" "  [WARN]" "Missing file $c"
        fi
    done
    printf "${Green}%-5s${Color_Off}\n" "Done."
}

# If rPath found remove it
function remove_rpath
{
    if [ -x /usr/bin/conary ] ; then
        printf "%-45s" "Removing Conary:"
        conary erase iconfig
        conary erase conary-cim-configuration
        conary erase conary-cim rpath-tools
        conary erase conary
        printf "${Green}%-5s${Color_Off}\n" "Done."
    else
        echo "Conary Not Installed"
    fi
}

# Create upgrade repository if it does not exists
function upg_repos
{
    # Create upgrade repository if it does not exists
    while [[ $CORRECT != "y" ]]
    do
        printf "Checking for Upgrade Repository\n"
        if [ ! -f ${YUM_REPO} ] ; then
            printf "%-50s\n" "Upgrade Repository not found, Please Enter Repository URL"
            printf "%-50s\n" "Examples:"
            printf "%-50s\n" "  http://www.my-repository.com/software/"
            printf "%-50s\n" "  ftp://www.my-repository.com/software/"
            printf "%-50s\n" "  file:///mnt/cdrom/"
            printf           "Enter Repository URL: "
        
            while [[ -z $YUM_REPO_SOURCE ]] ; do
                read YUM_REPO_SOURCE
                regex='(https?|ftp|file)://[-A-Za-z0-9\+&@#/%?=~_|!:,.;]*[-A-Za-z0-9\+&@#/%=~_|]'
                if [[ $YUM_REPO_SOURCE =~ $regex ]] ; then
                    YUM_REPO_SOURCE=$YUM_REPO_SOURCE
                else [[ $YUM_REPO_SOURCE == "" ]]
                    printf "Invalid Repository URL, Please enter again:"
                    YUM_REPO_SOURCE=""
                fi
            done
        else
            YUM_REPO_SOURCE=`cat /etc/yum.repos.d/upgrade.repo |grep "baseurl" | awk -F= '{print $2}'`
        fi
        printf "%-50s\n" "Repository URL is $YUM_REPO_SOURCE"
        printf "Is this correct? [y/n] "
        read CORRECT
        if [[ $CORRECT != "y" ]] ; then
            YUM_REPO_SOURCE=""
            if [[ -f $YUM_REPO ]] ; then
                rm  $YUM_REPO
            fi
        fi
    done

    printf "%-45s\n" "Creating Upgrade $YUM_REPO"
    echo "[Upgrade_Repository]"     >> ${YUM_REPO}
    echo "name=Upgrade Repository"  >> ${YUM_REPO}
    echo "baseurl=$YUM_REPO_SOURCE" >> ${YUM_REPO}
    echo "enabled=1"                >> ${YUM_REPO}
    echo "gpgcheck=0"               >> ${YUM_REPO}
}

function chk_repos
{
    yum clean all
    yum deplist ${BASE_PACKAGES} ${APP_PACKAGES}   
    if [ $? -ne 0 ]; then
       echo -e "\nInvalid repository: Missing Dependencies\n"
       exit 1
    else
       echo -e "\nValid Repository, please wait upgrade is continuing...\n"
    fi
}

# Updating Existing System Packages
function updt_existing_packs 
{
    printf "%-45s\n" "Updating Existing System Packages:"
    yum update --assumeyes                   2>&1 || die "Missing: System RPMs Not Found In Repository"
    printf "${Green}%-5s${Color_Off}\n" "Done."
}

# Installing New System and Appliance Packages
function install_appli_packs
{
    printf "%-45s\n" "Installing New System and Appliance Packages:"
    yum install --assumeyes ${BASE_PACKAGES} 2>&1 || die "Missing: System RPMs Not Found In Repository"
    yum install --assumeyes ${APP_PACKAGES}  2>&1 || die "Missing: Appliance RPMs Not Found In Repository"
    printf "${Green}%-5s${Color_Off}\n" "Done."
}

# Oracle Post Install Steps
function ora_post_steps
{
    mkdir -p /opt/oracle/product/11.2.0/db_1/dbs/dbs/arch
    chown oracle:oinstall /opt/oracle/product/11.2.0/db_1/dbs/arch
    mkdir -p /opt/oracle/backup/scripts
    chown -R oracle:oinstall /opt/oracle/
    mkdir -p /opt/oracle/oradata
    chown -R oracle:oinstall /opt/oracle/oradata
    mkdir -p /opt/oracle/admin
    chown -R oracle:oinstall /opt/oracle/admin

    cp -f ${BACKUP_DIR}/etc/oratab /etc/oratab
    TOTAL_MEMORY=$(echo "scale=0;$(cat /proc/meminfo | grep MemTotal | awk '{print $2}' ) /1024"|bc)
    ORA_MEMORY=$(printf %.0f $(echo "scale=0;${TOTAL_MEMORY}*2/3"|bc))
    sed -i "/vm.nr_hugepages =[.]*/d" /etc/sysctl.conf
    grep -q ^vm.nr_hugepages /etc/sysctl.conf
    if [ $? -ne 0 ]; then
      if [ ${ORA_MEMORY} -gt 42000 ]; then
         echo "vm.nr_hugepages = 21510" >> /etc/sysctl.conf
       elif [ ${ORA_MEMORY} -gt 15360 ]; then
         echo "vm.nr_hugepages = 7170" >> /etc/sysctl.conf
       else
         echo "#vm.nr_hugepages = 7170" >> /etc/sysctl.conf
       fi
    fi
    sysctl -p
    cp -f /home/oracle/scripts/dbca/oracle_profile        /home/oracle/.bash_profile
    cp -f /home/oracle/scripts/dbca/glogin.sql            /opt/oracle/product/11.2.0/db_1/sqlplus/admin/glogin.sql
    #cp -f /home/oracle/scripts/dbca/oraInst.loc          /etc/oraInst.loc
    cp -f /home/oracle/scripts/dbca/rman_backup.ksh       /opt/oracle/backup/scripts/rman_backup.ksh 
    cp -f /home/oracle/scripts/dbca/rman_backup_arch.ksh  /opt/oracle/backup/scripts/rman_backup_arch.ksh
    #chown root:root /etc/oraInst.loc
    chown oracle:oinstall /opt/oracle/product/11.2.0/db_1/sqlplus/admin/glogin.sql
    chown oracle:oinstall /opt/oracle/backup/scripts/rman_backup*.ksh
    chown oracle:oinstall /home/oracle/.bash_profile
    chmod 755 /opt/oracle/backup/scripts/rman_backup*.ksh
  
    cp -f /home/oracle/scripts/dbca/ttv.ctl /opt/oracle/product/11.2.0/db_1/assistants/dbca/templates/ttv.ctl
    cp -f /home/oracle/scripts/dbca/ttv.dfb /opt/oracle/product/11.2.0/db_1/assistants/dbca/templates/ttv.dfb
    cp -f /home/oracle/scripts/dbca/ttv.dbc /opt/oracle/product/11.2.0/db_1/assistants/dbca/templates/ttv.dbc
    cp -f /home/oracle/scripts/dbca/oracle_service /etc/init.d/oracle
    chown oracle:oinstall /opt/oracle/product/11.2.0/db_1/assistants/dbca/templates/ttv.*
    chown root:root /etc/init.d/oracle
    chmod 755 /etc/init.d/oracle
    ln -s /usr/bin /usr/local/bin

    # Start Oracle Service
    su - oracle -c "cd /home/oracle/scripts/db_restore; sh db_post_upgrade.sh"
 su - oracle -c "sqlplus -S /nolog<<BCD
    connect / as sysdba
    set pages 0
    set feedback off
    ALTER TABLESPACE WFS_DATA ADD DATAFILE size 1G AUTOEXTEND ON NEXT 200M MAXSIZE unlimited;
    ALTER TABLESPACE WFS_DATA ADD DATAFILE size 1G AUTOEXTEND ON NEXT 200M MAXSIZE unlimited;
    ALTER TABLESPACE UNDOTBS1 ADD DATAFILE size 100m AUTOEXTEND ON NEXT 100m MAXSIZE unlimited;
    ALTER TABLESPACE UNDOTBS1 ADD DATAFILE size 100m AUTOEXTEND ON NEXT 100m MAXSIZE unlimited;
    exit
BCD
"
    cd /home/oracle/scripts/dbca
    sh create_modify_instance.sh ttv 48G

}   
(
DB_ROLE=$(su - oracle -c "sqlplus -S /nolog<<PQR
  connect / as sysdba
  set pages 0
  set feedback off
  select trim(database_role) from v\\\$database;
  exit
PQR"
)
mkdir $BACKUP_DIR
if [ $? -ne 0 ]; then
    echo -e "\nYou can't run the upgrade script. This database server is already upgraded...!"
    printline
    exit 1
else
    if [ "${DB_ROLE}" = "PRIMARY" ]; then
        printline
        echo -e "Script started at $(date)"
        upg_repos
        chk_repos
        ora_prep
        backup_config_files
        remove_rpath
        yum erase ksh --assumeyes
        updt_existing_packs
        install_appli_packs
        ora_post_steps
        echo -e "\n Upgrade completed successfully.\n"
        echo -e "Script ended at $(date)"
        printline
     else 
        echo -e "\nThis is not a Primary Database. Upgrade script can run only on the Primary Database........\n"
        exit 1
    fi
fi
) 2>&1 | tee -a ${FULL_LOG}   

exit 0
