#!/bin/bash
#/usr/bin/env bash
# (c) Copyright 2015-2017 Hewlett-Packard Enterprise Development LP.
# (C) Copyright 2007-2014 Hewlett-Packard Development Company, L.P.
# Version A.12.10.00
###############################################################################
# Package Easy deployment Script for oracle toolkit on Linux
###############################################################################
# This script configures the Oracle toolkit package configuration file
# with the minimum default values wherever applicable and values would be
# queried from the running application wherever it is feasible.
# This script is a deployment script for oracle toolkit which supports the
# deployment of the Oracle toolkit package in following configurations
# 1. Oracle Single instance toolkit
# 2. Oracle ASM instance package in ASM configuration
# 3. Oracle ASM DB package in ASM configuration.
###############################################################################
# This script needs arguments based on different types of Oracle 
# application configuration.
# Arguments required for single instance database package:
# 1. Oracle home location
# 2. Oracle SID name.
# Arguments required for ASM instance package:
# 1. ASM home location
# Arguments required for ASM DB package:
# 2. ASM home location 
# 3. ASM SID is required if the database is 11gR1.
###############################################################################
. /etc/cmcluster.conf
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/lbin
export PATH=$PATH
CMD="su"
TKITDIR=`pwd`
cmexec=${SGSBIN}/cmexec
BASEDIR="${SGROOT}"
MNTTAB="/etc/mtab"
LISTENERNAME=""
SGDEPLOYVOLUMES="${SGROOT}/sgeasy/sgdeployvolumes"
SGDEPLOYMC="/opt/drenabler/utils/deploymc"
exit_error=0
current_node=`hostname`
localnode=`hostname | cut -d "." -f 1`
DB_SERVICE_NAME=" "
DB_SERVICE_LISTENER_NAME=" "
DB_SERVICE_HANG_NAME=" "
DB_PDB_SERVICE_NAME=" "
ASM_SERVICE_NAME=" "
DG_SERVICE_NAME=" "
typeset -a SGNODES
typeset -a ASMDGS
typeset -a VGARRAY
typeset -a DGARRAY
typeset -a FSARRAY
typeset -a DEPEND
typeset -a NODENAMES
typeset -a PVS
typeset -a ASM_VGARRAY
typeset DG_PRIMARY
typeset dataguard_input
typeset REAL_TIME_APPLY
typeset MOUNTED_NODE
typeset tmpfile="/tmp/DGvars"
typeset workload_flag=0
typeset DB_PKGNAME

###############################################################################
# Function: cleanitup
# Description: This function cleans up tkit directory after every exit caused
# by error
# Arguments : NONE
################################################################################
function cleanitup
{
confile=$1
     if [[ -f ${confile} ]] ; then
        rm -rf ${confile}
     fi
}

##################################################
# Function: check_mounted_on_vg
# Description: This function determines whether
# Oracle home is mounted on a VG or it is 
# placed on a local file system
# Returns: 0 if placed in local FS.
#          1 if placed in FS mounted on a vg
################################################## 

function check_mounted_on_vg
{
 if [[ -n "${SGNODES[*]}" ]]; then
   for node in ${SGNODES[*]} ; do
      var=`${SGSBIN}/cmexec -n $node df -P ${ORACLE_HOME} | tail -1 | awk '{print $NF}'`
      if [[ "$var" != "/" ]]; then
          MOUNTED_NODE="$node"
          return 1
      fi
   done
fi
return 0
}

##################################################
# Function: check_binary_presence
# Description: This function executes the check
# for the presence of Oracle/ASM application
# binaries.
# Returns: 0 if binary is present.
#          1 if binary is not present.
##################################################

function check_binary_presence
{
node_name=$1
#Check for the presence of Oracle application binaries on all packaged nodes
if [[ -n "${ORACLE_HOME}" ]]; then
  ${SGSBIN}/cmexec -n $node_name ls ${ORACLE_HOME}/dbs > /dev/null 2>&1
  if [ $? -ne 0 ]; then
     echo "ERROR: Oracle Application is not installed in the Oracle Home ${ORACLE_HOME} of the node $node_name."
     exit  1
  fi
fi

#If its a asm package then check if GRID infrastructure is installed all specified nodes.
if [[ $asm_pkg = "true" ]]; then
    ${SGSBIN}/cmexec -n $node_name ls ${ASM_HOME}/dbs > /dev/null 2>&1
    if [ $? -ne 0 ]; then
       echo "ERROR: Oracle ASM Application is not installed in the location ASM Home ${ASM_HOME} of the node $node_name."
       exit 1
    fi
fi
return 0
}
#########################################################
# Function: check_nodes
# Description: This function checks whether node is up and
# checks whether oracle/asm binaries are available in the 
# nodes provided in the argument list for easy deployment 
# script.
#######################################################

function check_nodes
{
#Verify nodes for the status and presence of application binaries on the specified nodes.
if [[ -n "${SGNODES[*]}" ]]; then
   # Check if the app binary is on VG then
   check_mounted_on_vg
   if [[ $? -eq 0 ]]; then
      for node in ${SGNODES[*]} ; do
         check_binary_presence $node
      done
   elif [[ $? -eq 1 ]]; then
         check_binary_presence ${MOUNTED_NODE}
         return $?
   fi
elif [[ -z "${SGNODES[*]}" ]]; then
   exit 1
fi
return 0
}

###############################################################################
# Function: application_check
# Description: This function checks whether database or ASM instances are 
# up and running. If its not running, it will halt the script.
# Arguments : Takes SID name as argument
################################################################################

function application_check
{
typeset sid_name=$1
typeset type=$2
typeset oracle_node_found=0
typeset integer run_count=0
for node in ${SGNODES[*]} ; do
  app_count=`$SGSBIN/cmexec -n $node ps -ef | grep "$sid_name$" | grep pmon | wc -l`
  if [[ $type = "oracle" ]]; then
     if [[ $app_count -ge 1 ]]; then
        echo "oracle_status_up=$node"
        oracle_node_found=1
        oracle_node="$node"
        
     fi
  fi
  if [[ $type = "asm" ]]; then
     app_count=`$SGSBIN/cmexec -n $node ps -ef | grep "$sid_name$" | grep pmon | wc -l`
     if [[ $app_count -ge 1 ]]; then
       run_count=`expr ${run_count} + 1`
     else
       echo "ERROR: ASM instance is not running on the node $node."
       return 1
     fi
   fi
done

if [[ $type = "oracle" && $oracle_node_found -ne 1 ]]; then
    return 1 
fi


}

#######################################################
# Function: check_app_status
# Description: This function performs the check to verify
# if ASM/ORACLE application is running or not.
#######################################################
function check_app_status
{
#
typeset asm_ret=0
typeset ora_ret=0
#Check for the status of ASM instance and ASM DB instances
if [[ -n ${ASM_SID} ]]; then
   application_check ${ASM_SID} asm
   asm_ret=$?
   application_check ${ORACLE_SID} oracle
   ora_ret=$?
   if [[ $asm_ret -ne 0 || $ora_ret -ne 0 ]]; then
      return 1
   else
      return 0
   fi
fi

#Check for the status of Single instance DB
if [[ -n ${ORACLE_HOME} && -n ${ORACLE_SID} && -z ${ASM_HOME} ]]; then
   application_check ${ORACLE_SID} oracle
   return $?
fi


}

###############################################################################
# Function: verify_nodes 
# Description: This function verifies whether the particular node specified is
# running or not. 
# Arguments: Packaged nodenames.
###############################################################################

function verify_nodes
{
node=$1
typeset node1
typeset status
typeset state
  var=`${SGSBIN}/cmviewcl -n $node -f line | grep -e "state" -e "status" 2>> /dev/null`
  if [[ $? -eq 0 ]]; then
    status=`echo "$var" | grep "status" | cut -d "=" -f 2`
    state=`echo "$var" | grep "state" | cut -d "=" -f 2`
    if [[ "${status}" != "up" && "${state}" != "running" ]] ; then
       echo "ERROR: Specified Serviceguard node ${node1} must be up and running."
       exit 1
    fi
  else
     echo "ERROR: Specified Serviceguard node $node is not configured in the cluster."
     exit 1
  fi
return 0
}

###############################################################################
# Function: discover_all_oracle_asm_values
# Description: This function executes SQL queries and spools the required data
# for Oracle and ASM DB instances. 
# Arguments: None 
###############################################################################

function discover_all_oracle_asm_values
{

#Set of Oracle queries that needs to be executed for single instance.
$CMD $ORACLE_ADMIN -c "/bin/bash"<<EOF
export ORACLE_HOME=${ORACLE_HOME}
export ORACLE_SID=${SID_NAME}
${ORACLE_HOME}/bin/sqlplus '/ as sysdba' <<EOF1
spool ${ORACLE_HOME}/output.csv.$$
select concat('DBHOSTNAME:',HOST_NAME) A from V\\\$instance;
select concat('DB_SERVER_IP:',UTL_INADDR.GET_HOST_ADDRESS) from dual;
select concat('DATAFILENAME:',NAME) A from v\\\$datafile where file#=1;
select concat('CNTFILENAME:',NAME) A from v\\\$CONTROLFILE;
select concat('TFILENAME:',file_name) A from dba_temp_files;
select concat('RFILENAME:',member) A from v\\\$logfile;
select concat('FRA:',NAME) A from V\\\$RECOVERY_FILE_DEST;
archive log list;
select concat('ASMSTATUS:',status) A from v\\\$asm_client;
spool off;
exit;
EOF1
exit;
EOF

}

###############################################################################
# Function: discover_oracle_or_asm_admin
# Description: This function identifies the oracle and ASM admin user for the 
# specified oracle home and ASM home directories.
# Arguments: None
###############################################################################

function discover_oracle_or_asm_admin
{
        #Get oracle admin only for oracle db package or asm db package
		if [[ $ora_pkg == "true" || $asm_db_pkg -eq 1 ]]; then
          	ORACLE_ADMIN=`ls -ld ${ORACLE_HOME}/OPatch/opatch | awk '{print $3}'`
			if [[ -z "${ORACLE_ADMIN}" ]]; then
			   return 1
			fi
        fi
		
		#Get the user name for asm admin for asm instance package
        if [[ $asm_pkg = "true" ]]; then
			ASM_USER=`ls -ld ${ASM_HOME}/OPatch/opatch | awk {'print $3'}` 
			if [[ -z "${ASM_USER}" ]]; then
			   return 1
			fi
        fi 
		return 0
}

###############################################################################
# Function: discover_service_name
# Description: This function identifies the oracle/ASM service name,Oracle listener
# service name and Oracle hang service name.
# Arguments: None
###############################################################################
function discover_service_name
{
    service_prefix_for_DB_pkg=`echo "$SINGINST_DB_PKG_NAME" | cut -c 1-34`
    service_prefix_for_ASM_DB_pkg=`echo "$ASM_DB_PKG_NAME" | cut -c 1-34`
    service_prefix_for_ASM_INST_pkg=`echo "$ASM_INST_PKG_NAME" | cut -c 1-34`
    
     if [[ $ora_pkg = "true" ]]; then
        DB_SERVICE_NAME="${service_prefix_for_DB_pkg}_oras"
        DB_SERVICE_LISTENER_NAME="${service_prefix_for_DB_pkg}_list"
        DB_SERVICE_HANG_NAME="${service_prefix_for_DB_pkg}_hang"
        DB_PDB_SERVICE_NAME="${service_prefix_for_DB_pkg}_pdbm"
     fi

     if [[ $asm_db_pkg -eq 1 ]]; then
        DB_SERVICE_NAME="${service_prefix_for_ASM_DB_pkg}_oras"
        DB_SERVICE_LISTENER_NAME="${service_prefix_for_ASM_DB_pkg}_list"
        DB_SERVICE_HANG_NAME="${service_prefix_for_ASM_DB_pkg}_hang"
        DB_PDB_SERVICE_NAME="${service_prefix_for_ASM_DB_pkg}_pdbm"
     fi

     if [[ $asm_inst_pkg -eq 1 ]]; then
       ASM_SERVICE_NAME="${service_prefix_for_ASM_INST_pkg}_serv"
     fi

     if [[ -n ${dataguard_input} ]]; then
        if [[ -n "${ASM_DB_PKG_NAME}" ]]; then
            DG_SERVICE_NAME="${service_prefix_for_ASM_DB_pkg}_dgms"
        else
            DG_SERVICE_NAME="${service_prefix_for_DB_pkg}_dgms"
        fi
     fi
}

###############################################################################
# Function: discover_oracle_version
# Description: This function determines the version of the oracle installed.
# Arguments : None
# Variables initialized: oracle_version
###############################################################################

function discover_oracle_version
{
if [[ -f $ORACLE_HOME/inventory/ContentsXML/comps.xml ]]; then
   oracle_version=`/bin/sed -e '/^<COMP NAME="oracle.server" VER="/p;D' $ORACLE_HOME/inventory/ContentsXML/comps.xml | awk -F \" 'END {print $4}' | cut -d "." -f 1-2`
else
   echo "ERROR: Unable to determine the Oracle version."
   echo "Unable to deploy the Oracle toolkit Package. Exiting !"
   exit 1
fi
}


###############################################################################
# Function: get_asm_sid
# Description: This function determines the SID for ASM instance.
# Arguments : None
###############################################################################

function get_asm_sid
{
discover_oracle_version
#Identify ASM SID
if [[ -n ${ASM_HOME} ]]; then
      asm_process_name=`ps -ef | grep asm_pmon | grep -v grep | awk {'print $NF'}`
      if [[ -n $asm_process_name ]]; then
         ASM_SID_RUNNING=`echo ${asm_process_name:9}`
      else
         echo "ERROR: Oracle ASM instances are not running on the current node."
         echo "Oracle ASM instaces needs to be up and running on all the specified nodes"
         exit 1
      fi

      if [[ -n "${ASMSID}" ]]; then
         if [[ $oracle_version = "11.1" ]]; then
            ASM_SID="${ASMSID}"
         elif [[ $oracle_version > "11.2" || $oracle_version = "11.2" ]]; then
            if [[ "${ASMSID}" = "${ASM_SID_RUNNING}" ]]; then
               ASM_SID="${ASMSID}"
            else
               echo "ERROR: ASM SID provided is not matching the ASM instance currently running in specified nodes."
               exit 1
            fi
         else
            echo "ERROR: Unsupported Version of Oracle is installed on the system."
            exit 1
         fi
      else
          if [[ $oracle_version = "11.1" ]]; then
            echo "ERROR: Oracle version is 11.1. ASM SID needs to be specified."
            exit 1
          elif [[ $oracle_version > "11.2" || $oracle_version = "11.2" ]]; then
             ASM_SID="${ASM_SID_RUNNING}"
          fi
      fi
fi

}


###############################################################################
# Function: get_nodes
# Description: This function provides format to update the package configuration
# file with node name values.
# Arguments : None
###############################################################################
function get_nodes
{
    typeset node
    for node in ${SGNODES[*]} ; do
            echo "node_name ${node}\\"
    done
}

###############################################################################
# Function: get_lvm_vg
# Description: This function provides format to update the package configuration
# file with lvm vg values.
# Arguments : None
###############################################################################
function get_lvm_vg
{
    typeset dg
    VGARRAY=($(printf "%s\n" "${VGARRAY[@]}" | sort -u));
    for dg in ${VGARRAY[*]} ; do
            echo "vg ${dg}\\"
    done
}


###############################################################################
# Function: get_asm_vg
# Description: This function provides format to update the package configuration
# file with ASM_VOLUMEGROUP values.
# Arguments : None
###############################################################################
function get_asm_vg
{
    typeset asmvg 
    ASM_VGARRAY=($(printf "%s\n" "${ASM_VGARRAY[@]}" | sort -u));
    for asmvg in ${ASM_VGARRAY[*]} ; do
            echo "tkit/oracle/oracle/ASM_VOLUME_GROUP ${asmvg}\\"
    done
}

###############################################################################
# Function: get_vxvm_dg
# Description: This function provides format to update the package configuration
# file with vxvm dg values
# Arguments : None
###############################################################################
function get_vxvm_dg
{
    typeset dg
    DGARRAY=($(printf "%s\n" "${DGARRAY[@]}" | sort -u));
    for dg in ${DGARRAY[*]} ; do
             echo "vxvm_dg ${dg}\\"
    done
}

###############################################################################
# Function: get_fs
# Description: This function provides format to update the package configuration
# file with fs values like mount point, logical volume and type of fs and default
# mount point option.
# Arguments : None
###############################################################################

function get_fs
{
 typeset i=0
 typeset fs
 typeset fserv
 typeset dir
 typeset path
 typeset fstype
 typeset mopt
 typeset mopt1
 FSARRAY=($(printf "%s\n" "${FSARRAY[@]}" | sort -u));
 for fs in ${FSARRAY[*]} ; do
    path=`echo ${fs} | cut -d ":" -f 1`
    dir=`echo ${fs} | cut -d ":" -f 2`
    fstype=`echo ${fs} | cut -d ":" -f 3`
    mopt=`echo ${fs} | cut -d ":" -f 4`
    mopt1=`echo ${fs} | cut -d ":" -f 5`
    fserv=`echo ${fs} | cut -d ":" -f 6`
         cat <<EOF
fs_name           ${path}\\
fs_server        \"${fserv}\"\\
fs_directory     ${dir}\\
fs_type          \"${fstype}\"\\
fs_mount_opt     \"${mopt} ${mopt1}\"\\
fs_umount_opt    \"\"\\
fs_fsck_opt      \"\"\\
EOF
let i+=1
done
}



###############################################################################
# Function: get_asm_pv
# Description: This function provides the format to update the package
# configuration file with PV's used for ASM DG. 
# Arguments: None
###############################################################################
function get_asm_pv
{
  typeset asmpv
  PVS=($(printf "%s\n" "${PVS[@]}" | sort -u));
  for asmpv in ${PVS[*]} ; do
      echo "tkit/oracle/oracle/ASM_PV ${asmpv}\\"
  done
}

###############################################################################
# Function: get_pv_name
# Description: This function provides the format to update the package
# configuration file with PV's used for ASM DG whichto add in "pv" section
# in package configuration file in case if PR is enabled.
# Arguments: None
###############################################################################
function get_pv_name
{
  typeset pv_name
  PVS=($(printf "%s\n" "${PVS[@]}" | sort -u));
  for pv_name in ${PVS[*]} ; do
      echo "pv ${pv_name}\\"
  done
}


###############################################################################
# Function: get_asm_dg
# Description: This function provides the format to update the package
# configuration file with ASM disk group values
# Arguments: None
###############################################################################
function get_asm_dg
{
  typeset asmdg
  ASMDGS=($(printf "%s\n" "${ASMDGS[@]}" | sort -u));
  for asmdg in ${ASMDGS[*]} ; do
      echo "tkit/oracle/oracle/ASM_DISKGROUP ${asmdg}\\"
  done
}

###############################################################################
# Function: get_depend
# Description: This function provides format to update the package configuration
# file with dependency values 
# Arguments : None
###############################################################################
function get_depend
{
    typeset pack cond loc
    typeset i=0
    DEPEND=($(printf "%s\n" "${DEPEND[@]}" | sort -u));
    while [[ ${i} -lt ${#DEPEND[*]} ]] ; do
          pack=`echo "${DEPEND[i]}" | cut -d ":" -f 1`
         cond=`echo "${DEPEND[i]}" | cut -d ":" -f 2`
         loc=`echo "${DEPEND[i]}" | cut -d ":" -f 3`
            if [[ -n $pack && -n $cond && -n $loc ]]; then
               echo "dependency_name ${pack}\\"
               echo "dependency_condition  ${pack} = ${cond}\\"
               echo "dependency_location ${loc}\\"
               echo "\\"
            fi
        let i+=1
     done

}

#######################################################################
# Function: cleanup_sqlquery_files
# Description: This function cleans up the file generated by sql query 
# which captures all the values required for Oracle and ASM values
#######################################################################
function cleanup_sqlquery_files
{
  if [[ -f ${ORACLE_HOME}/output.csv.$$ ]]; then
   rm ${ORACLE_HOME}/output.csv.$$
 fi
}

###############################################################
# Function: discover_storage
# Arguments:  Takes application directory path as argument
# Return: NONE
###############################################################
function discover_storage
{
  FS_MNT_OPT="-o"
  FS_MNT_OPT1="rw"
  
  #$1 here is directory name where application binaries and other application files reside.
  MNTPOINT=`df -P $1 | tail -1 | awk '{print $NF}'`
  if [[ "$MNTPOINT" = "/"  ]]; then
	st_local="true"
  else
	st_local="false"
  fi

   if [[ "$st_local" = "false" ]]; then
      # read the fsname for the mount point ( something like /dev/vg00/lvol1 )
      # This is required to determine if its vxvm

      STG_NAME=`df -P $MNTPOINT 2>> /dev/null | tail -1 | cut -d " " -f 1`
      FS_TYPE=`mount -v | grep "$STG_NAME" | cut -d " " -f 5`
      if [[ ${STG_NAME} != " " ]]; then
          if echo "${STG_NAME} " | grep "^/dev/vx/dsk" >> /dev/null
          then
            vxfs_found=1
          else
            vxfs_found=0
          fi
       fi

       #If file system used is vxfs, then get details about vxvm_dg and fs attribute values.
       if [[ $vxfs_found -eq 1 ]]; then
       
         VX_MPOINT=`df -P $MNTPOINT | tail -1 | cut -d " " -f 1` 
         VX_DGNAME=`dirname $VX_MPOINT | cut -d "/" -f 5` 
         VX_MPNAME=$MNTPOINT        
         FS_TYPE="vxfs"
   
         #Add element to DGARRAY and FSARRAY
           DGARRAY[${#DGARRAY[*]}]="$VX_DGNAME"
           FSARRAY[${#FSARRAY[*]}]="${VX_MPOINT}:${VX_MPNAME}:${FS_TYPE}:${FS_MNT_OPT}:${FS_MNT_OPT1}"
    
       fi #end of if vxfs_found eq 1


       if [[ $vxfs_found -eq 0 ]]; then
         if [[ $FS_TYPE != "nfs" ]]; then
             VGNAME=`lvs --noheadings --separator : $STG_NAME | cut -d ":" -f 2`
	     if [[ $? -eq 0 ]]; then
                LV_NAME=`lvdisplay -c $STG_NAME | cut -d ":" -f 1 | sed 's/ //g'`
	        if [[ $? -eq 0 ]]; then
                  VGARRAY[${#VGARRAY[*]}]="$VGNAME"
                  FSARRAY[${#FSARRAY[*]}]="${LV_NAME}:${MNTPOINT}:${FS_TYPE}:${FS_MNT_OPT}:${FS_MNT_OPT1}"
                fi
             fi
         elif [[ ${FS_TYPE} = "nfs" ]]; then
           echo "WARNING: Oracle toolkit - Oracle Application does not recommends NFS file system for storing Oracle files !"
           FS_NAME=`echo $STG_NAME | cut -d ":" -f 2`
           FS_SERVER=`echo $STG_NAME | cut -d ":" -f 1`
           FS_DIR=`mount -t nfs | grep ${STG_NAME} | cut -d " " -f 3`
           FS_MNT_OPT="-o"
           FS_MNT_OPT1="local_lock=all"
           FSARRAY[${#FSARRAY[*]}]="${FS_NAME}:${FS_DIR}:${FS_TYPE}:${FS_MNT_OPT}:${FS_MNT_OPT1}:${FS_SERVER}"
         fi
       fi
   fi 
}

########################################################
# Function: discover_oracle_db_file_locations
# Description: Identifies the location of the Database files
#              in oracle package. Identifies ASM binary location
#              in ASM instance package and appropriately adds the
#              values to VG and FS.
# Arguments: None
########################################################
function discover_oracle_db_file_locations
{
if [[ $ora_pkg = "true" ]]; then
 if [[ -f ${ORACLE_HOME}/output.csv.$$ ]]; then
  #temp=`cat ${ORACLE_HOME}/output.csv.$$`
  DFPATH=`grep "^DATAFILENAME:" ${ORACLE_HOME}/output.csv.$$ | cut -d : -f 2`
  CNTPATH=`grep "^CNTFILENAME:" ${ORACLE_HOME}/output.csv.$$ | head -1 | cut -d ":" -f 2`
  FRPATH=`grep "^FRA:" ${ORACLE_HOME}/output.csv.$$ | cut -d : -f 2`
  TPATH=`grep "^TFILENAME:" ${ORACLE_HOME}/output.csv.$$ | cut -d : -f 2`
  RFDEST=`grep "^RFILENAME:" ${ORACLE_HOME}/output.csv.$$ | head -1 | cut -d ":" -f 2` 
  DBFILES=( "$ORACLE_HOME" "$DFPATH" "$CNTPATH" "$FRPATH" "$TPATH" "$RFDEST" )
  typeset -i i=0 
  for file in ${DBFILES[*]}; 
  do
    discover_storage "$file"
  done         
 else
    echo "ERROR:${ORACLE_HOME}/output.csv.$$ is not found."
	exit 1
 fi
fi

if [[ $asm_pkg = "true" && $asm_inst_pkg -eq 1 ]]; then
   discover_storage "$ASM_HOME" 
fi
} 

#########################################################
# Function: discover_asm_dgs
# Description: Discovers the asm dg's that are used
# by the particular database instance which is getting
# easy deployed by this script
# #######################################################

function discover_asm_dgs
{
if [[ $asm_pkg = "true" ]]; then
  if [[ -f ${ORACLE_HOME}/output.csv.$$ ]]; then
     DFDGNAME=`grep "^DATAFILENAME:" ${ORACLE_HOME}/output.csv.$$ | cut -d : -f 2 | cut -d "/" -f 1 | sed 's/+//'`
     CNTDGNAME=`grep "^CNTFILENAME:" ${ORACLE_HOME}/output.csv.$$ | head -1 | cut -d ":" -f 2 | cut -d "/" -f 1 | sed 's/+//'`
     FRDGNAME=`grep "^FRA:" ${ORACLE_HOME}/output.csv.$$ | cut -d : -f 2 | cut -d "/" -f 1 | sed 's/+//' | tr -d '[:space:]'`
     TDGNAME=`grep "^TFILENAME:" ${ORACLE_HOME}/output.csv.$$ | cut -d : -f 2 | cut -d "/" -f 1 | sed 's/+//'`
     RFDESTDGNAME=`grep "^RFILENAME:" ${ORACLE_HOME}/output.csv.$$ | head -1 | cut -d ":" -f 2 | cut -d "/" -f 1 | sed 's/+//'`
     ASMDGS=( "$DFDGNAME" "$CNTDGNAME" "$FRDGNAME" "$TDGNAME" "$RFDESTDGNAME" )
 else
     echo "ERROR:${ORACLE_HOME}/output.csv.$$ is not found."
     cleanitup ${ASM_DB_PKGCONF}  
     exit 1
 fi

 #For each DG, find the device path
 for dg in ${ASMDGS[*]}
 do
   device_path=`${ASM_HOME}/bin/asmcmd lsdsk -G $dg 2>> /dev/null`
   if [[ $? -eq 0 ]]; then
      device_path=`echo $device_path | cut -d " " -f 2`
      vgname=`lvs --noheadings --separator : $device_path 2>> /dev/null`
      if [[ $? -eq 0 ]]; then #logical volume is used.
         vgname=`echo "$vgname" | cut -d ":" -f 2`
         ASM_VGARRAY[${#ASM_VGARRAY[*]}]="${vgname}"
      else
         #Check if raw device is used or character special device is used
         ls -ld $device_path | cut -d " " -f 1 | grep "^c" >> /dev/null
         if [[ $? -ne 0 ]]; then
            #Raw device has been used hence add the disk alias in the pv section of
            #package configuration file.
            PVS[${#PVS[*]}]="${device_path}"
         fi
      fi
   else
     echo "WARNING: Oracle toolkit - Failed to obtain the device path for ASM DG $dg."
   fi 
 done
fi
}

########################################################
# Function: discover_floating_ip
# Description: This function gets floating IP configured
# for database server. 
# Arguments: None
########################################################
function discover_floating_ip
{
if [[ -f ${ORACLE_HOME}/output.csv.$$ ]]; then
  
  DBHOSTNAME=`grep "^DBHOSTNAME:" ${ORACLE_HOME}/output.csv.$$ | cut -d ":" -f 2`
  DBHOSTNAME=`echo $DBHOSTNAME`
  #If DB hostname is same as local nodename then floating ip for the package is not used.
  if [[ "${DBHOSTNAME}" != "${current_node}" ]]; then
    FLOATING_IP=`grep "^DB_SERVER_IP" ${ORACLE_HOME}/output.csv.$$ | cut -d ":" -f 2`
    discover_ip_subnet_address ${FLOATING_IP} 
    return $? 
  else  
    return 2 
  fi 
fi
}

#########################################################
# Function: discover_ip_subnet_address
# Arguments: ip address
# returns : NONE
########################################################
function discover_ip_subnet_address
{

IP_ADDRESS=$1
NET_MASK=`ifconfig -a  | grep "$IP_ADDRESS" | cut -d ":" -f 4` 
#Determine the subnet IP using ip address and netmask available
var=`awk -vip="$IP_ADDRESS" -vmask="$NET_MASK" 'BEGIN{
split(ip,a, ".");
split(mask,b,".");
for(i=1;i<=4;i++)a[i]=b[i]==255?a[i]:b[i];
for(i=1;i<=3;i++)printf a[i]".";printf a[4]}'`
SUBNET_IP=`echo $var`

}

##############################################################
# Function: update_array_attributes
# Description: This function updates the package configuration
# file with the attributes which can take multiple values
# Arguments: Takes Package configuration file name as arguments
###############################################################
function update_array_attributes
{
PKGCONF=$1
if [[ -n ${SGNODES[*]} ]] ; then
cat $PKGCONF |
sed "/^node_name[[:space:]]*\*[[:space:]]*/{
s/.*/# &/
a\\
`get_nodes`

} " > $PKGCONF.tmp1
mv $PKGCONF.tmp1 $PKGCONF
fi

#Configure VG's
if [[ -n ${VGARRAY[*]} ]] ; then
cat $PKGCONF |
sed "/#vg[[:space:]]*$/a\\
`get_lvm_vg` " > $PKGCONF.tmp1
mv $PKGCONF.tmp1 $PKGCONF
fi

#Configure FS
if [[ -n ${FSARRAY[*]} ]] ; then
cat $PKGCONF |
sed "/#fs_fsck_opt[[:space:]]*$/a\\
`get_fs` " > $PKGCONF.tmp1
mv $PKGCONF.tmp1 $PKGCONF
fi

#Configure VXVM DG's
if [[ -n ${DGARRAY[*]} ]] ; then
cat $PKGCONF |
sed "/#vxvm_dg[[:space:]]*$/a\\
`get_vxvm_dg` " > $PKGCONF.tmp1
mv $PKGCONF.tmp1 $PKGCONF
fi

#Configure DEPENDENCY
if [[ -n ${DEPEND[*]} ]] ; then
cat $PKGCONF |
sed "/#dependency_location[[:space:]]*$/a\\
`get_depend` " > $PKGCONF.tmp1
mv $PKGCONF.tmp1 $PKGCONF
fi

#ADD DISKGROUPS
if [[ -n ${ASMDGS[*]} ]] ; then
cat ${PKGCONF} |
sed "/#tkit\/oracle\/oracle\/ASM_DISKGROUP[[:space:]]*$/a\\
`get_asm_dg` " > ${PKGCONF}.tmp
mv ${PKGCONF}.tmp ${PKGCONF}
fi

#ADD  ASM_PV and pv attribute values.
if [[ -n ${PVS[*]} ]]; then
cat ${PKGCONF} | 
sed "/#tkit\/oracle\/oracle\/ASM_PV[[:space:]]*$/a\\
`get_asm_pv` " > ${PKGCONF}.tmp
mv ${PKGCONF}.tmp ${PKGCONF}

cat ${PKGCONF} |
sed "/#pv[[:space:]]*$/a\\
`get_pv_name` " > ${PKGCONF}.tmp
mv ${PKGCONF}.tmp ${PKGCONF}
fi

#Add ASM_VOLUMEGROUP
if [[ -n ${ASM_VGARRAY[*]} ]] ; then
cat $PKGCONF |
sed "/#tkit\/oracle\/oracle\/ASM_VOLUME_GROUP[[:space:]]*$/a\\
`get_asm_vg` " > $PKGCONF.tmp1
mv $PKGCONF.tmp1 $PKGCONF
fi

}

###############################################################################
# Function: generatePkgNames
# Description: Generate the package Names
###############################################################################
function generatePkgNames
{
    typeset serial
    typeset prefix
    typeset VCLVIEW
    
    VCLVIEW=`${SGSBIN}/cmviewcl -f line -s config 2>&1`
    
    serial=`echo "$VCLVIEW" | awk -F "[:|=]" '(($1 == "package") \
        && ($3 == "name")) {print $4}'`
    for i in {1..999}; do
        prefix=ORA"$i"
        echo "$serial" | grep "^$prefix" > /dev/null 2>&1
        if [[ $? -ne 0 ]]; then
            break
        else
            continue
        fi
    done
    
    DB_PKGNAME=`echo "$prefix"_"$SID_NAME" | cut -c 1-34`
    
    # Make sure the packages do not exist already
    PKG_NAME=`echo "$VCLVIEW" | awk -F "[:|=]" '(($1 == "package") && ($3 == "name") && ($4 == "'$DB_PKGNAME'")){print $4}' > /dev/null 2>&1`
    if [[ -n $PKG_NAME ]]; then
      echo "Error: Package $DB_PKGNAME already exists"
      exit 1
    fi
}

###############################################################################
# Function: update_asm_package_with_workloadname
# Description: Function to update workload name in the existing ASM package
###############################################################################
function update_asm_package_with_workloadname
{
    WORKLOAD_TYPE="oracle_asm_db"
    if [[ -n ${dataguard_input} ]]; then
        WORKLOAD_TYPE="oracle_dataguard_asm_db"
    fi
  
    if [[ -n $asm_package_name ]]; then
    
        $SGSBIN/cmgetconf -p $asm_package_name $TKITDIR/asm_inst.ascii
        
        if [[ $? -eq 0 ]]; then
            ASM_INST_PKGCONF="${TKITDIR}/asm_inst.ascii"
            
            #Check if already workload name is configured. If present append the new name else configure the workload parameter.
            ${SGSBIN}/cmviewcl -f line -v -p "$asm_package_name" | grep "standard_workload_name" >> /dev/null
            if [[ $? -eq 0 ]]; then
                cat ${ASM_INST_PKGCONF} |
                sed -e "$ a STANDARD_WORKLOAD_NAME ${WORKLOAD_NAME}" > ${ASM_INST_PKGCONF}.tmp1
                mv $ASM_INST_PKGCONF.tmp1 $ASM_INST_PKGCONF
                cat ${ASM_INST_PKGCONF} |
                sed -e "$ a STANDARD_WORKLOAD_TYPE ${WORKLOAD_TYPE}" > ${ASM_INST_PKGCONF}.tmp1
            else
                cat ${ASM_INST_PKGCONF} |
                sed -e "s%^#standard_workload_name.*$%standard_workload_name ${WORKLOAD_NAME}%
                s%^#standard_workload_type.*$%standard_workload_type ${WORKLOAD_TYPE}%" > ${ASM_INST_PKGCONF}.tmp1
            fi
            
            if [[ $? -eq 0 ]]; then
                mv $ASM_INST_PKGCONF.tmp1 $ASM_INST_PKGCONF
                echo "Updating $asm_package_name with workload name............................."
                ${SGSBIN}/cmapplyconf -f -P "${ASM_INST_PKGCONF}"
                if [[ $? -ne 0 ]]; then
                    echo "ERROR: cmapplyconf failed for the package ${ASM_INST_PKGCONF}."
                    cleanitup ${ASM_INST_PKGCONF}	
                    exit 1 
                fi
                while [ 1 ]
                do
                    state=`${SGSBIN}/cmviewcl -f line -v -p "$asm_package_name" | awk -F "[=]" '($1 == "state") {print $2}'`
                    if [[ "${state}" == "running" ]]; then
                        break
                    fi
                    sleep 5
                done
                echo "Updating $asm_package_name with workload name....................[SUCCESS]"
                cleanitup ${ASM_INST_PKGCONF}
            fi
        fi
    fi
}

###############################################################################
# Function: check_asm_insatnce_package_exists
# Description: Function to find existing ASM package and set flags
###############################################################################
function check_asm_insatnce_package_exists
{
    typeset node
    typeset PKG
    typeset -a ASM_PKGS
    typeset -i flag
    asm_db_pkg=1
    asm_inst_pkg=1
    asm_package_name=""
    typeset VCLVIEW
    
    VCLVIEW=`${SGSBIN}/cmviewcl -v -f line -s config 2>&1`
    if [[ $? -eq 0 ]]; then
         ASM_PKGS=`echo "$VCLVIEW" | awk -F "[:|=]" '(($1 == "package") && ($3 == "tkit/oracle/oracle/INSTANCE_TYPE") && ($4 == "ASM")){print $2}'`
        #For non dataguard input if ASM Instance package present set the flag 
        if [[ -z "$dataguard_input" ]]; then
            asm_package_name=$ASM_PKGS
            if [[ -n "$asm_package_name" ]]; then
                asm_inst_pkg=0
            fi
        else
            #For dataguard find ASM Instance using the node list provided package present set the flag 
            for PKG in ${ASM_PKGS[*]} ; do
                flag=0
                for node in ${SGNODES[*]} ; do
                    NODE_NAME=`echo "$VCLVIEW" | awk -F "[:|=]" '( ($1 == "package") && ($2 == "'$PKG'") && ($3 == "node") && ($6 =="'$node'")){print $6}'`
                    if [[ -n "$NODE_NAME" ]]; then
                            flag=1
                            break;
                    fi
                done
                if [[ $flag -eq 1 ]]; then
                    asm_package_name=${PKG}
                    asm_inst_pkg=0
                    break;
                fi
            done
        fi
    fi
}

######################################################
# Function: update_config_file_for_asm_db
# Description: This function updates the package configuration
# file for ASM DB package 
# Argument: ASM DB package configuration file
#######################################################
function update_config_file_for_asm_db
{
ASM_DB_PKGCONF="$1"
ASM_value="yes"
if [[ -n ${dataguard_input} ]]; then
        WORKLOAD_TYPE="oracle_dataguard_asm_db"
    else
        WORKLOAD_TYPE="oracle_asm_db"
fi
cat ${ASM_DB_PKGCONF} |
sed -e "s%^package_name.*$%package_name ${ASM_DB_PKG_NAME}%
s%^tkit/oracle/oracle/ORACLE_HOME[[:space:]]*$%tkit/oracle/oracle/ORACLE_HOME ${ORACLE_HOME}%
s%^tkit\/oracle\/oracle\/ORACLE_ADMIN[[:space:]]*oracle$%tkit\/oracle\/oracle\/ORACLE_ADMIN ${ORACLE_ADMIN}%
s%^tkit\/oracle\/oracle\/SID_NAME[[:space:]]*$%tkit\/oracle\/oracle\/SID_NAME ${SID_NAME}%
s%^#tkit\/oracle\/oracle\/ASM_HOME[[:space:]]*$%tkit/oracle/oracle/ASM_HOME ${ASM_HOME}%
s%^tkit\/oracle\/oracle\/ASM_USER[[:space:]]*oracle$%tkit/oracle/oracle/ASM_USER ${ASM_USER}%
s%^#tkit\/oracle\/oracle\/ASM_SID[[:space:]]*$%tkit\/oracle\/oracle\/ASM_SID ${ASM_SID}%
s%^tkit\/oracle\/oracle\/ASM[[:space:]]*no$%tkit\/oracle\/oracle\/ASM ${ASM_value}%
s/^service_name[[:space:]]*oracle_service/service_name ${DB_SERVICE_NAME}/
s/^service_name[[:space:]]*oracle_listener_service/service_name ${DB_SERVICE_LISTENER_NAME}/
s/^service_name[[:space:]]*oracle_pdb_monitor_service/service_name ${DB_PDB_SERVICE_NAME}/
s/^service_name[[:space:]]*oracle_hang_service/service_name ${DB_SERVICE_HANG_NAME}/" > ${ASM_DB_PKGCONF}.tmp
if [[ $?  -eq 0 ]]; then
  mv ${ASM_DB_PKGCONF}.tmp ${ASM_DB_PKGCONF}
fi

if [[ $workload_flag -eq 1 ]]; then
    cat ${ASM_DB_PKGCONF} |
     sed -e "s%^#standard_workload_name.*$%standard_workload_name ${WORKLOAD_NAME}%
            s%^#standard_workload_type.*$%standard_workload_type ${WORKLOAD_TYPE}%"> ${ASM_DB_PKGCONF}.tmp
    if [[ $? -eq 0 ]]; then
        mv ${ASM_DB_PKGCONF}.tmp ${ASM_DB_PKGCONF}
    fi
fi

if [[ -n "${FLOATING_IP}" && -n "${SUBNET_IP}" ]]; then
  cat ${ASM_DB_PKGCONF} |
  sed -e "s%^#ip_subnet[[:space:]]*$%ip_subnet ${SUBNET_IP}%
s%^#ip_address[[:space:]]*$%ip_address ${FLOATING_IP}%" > ${ASM_DB_PKGCONF}.tmp
  if [[ $?  -eq 0 ]]; then
     mv ${ASM_DB_PKGCONF}.tmp ${ASM_DB_PKGCONF}
  fi
fi

if [[ -n ${dataguard_input} ]]; then
  cat $ASM_DB_PKGCONF |
  sed "s%^tkit\/oracle\/oracle\/START_MODE[[:space:]]*[[:alnum:]]*$%tkit\/oracle\/oracle\/START_MODE mount%
  s/^service_name[[:space:]]*dataguard_monitor/service_name ${DG_SERVICE_NAME}/     
  s%^tkit\/dataguard\/dataguard\/DC1_NODE_LIST[[:space:]]*$%tkit\/dataguard\/dataguard\/DC1_NODE_LIST ${PRIMARY_NODELIST}%
  s%^tkit\/dataguard\/dataguard\/DC2_NODE_LIST[[:space:]]*$%tkit\/dataguard\/dataguard\/DC2_NODE_LIST ${STANDBY_NODELIST}%
  s%^tkit\/dataguard\/dataguard\/ACTIVE_STANDBY[[:space:]]*no$%tkit\/dataguard\/dataguard\/ACTIVE_STANDBY $ACTIVE_STANDBY%
  s%^tkit\/dataguard\/dataguard\/REAL_TIME_APPLY[[:space:]]*no$%tkit\/dataguard\/dataguard\/REAL_TIME_APPLY $REAL_TIME_APPLY%     
  s%^#tkit/dataguard/dataguard/RPO_LIMIT[[:space:]]*$%tkit/dataguard/dataguard/RPO_LIMIT $RPO%     
  s%^tkit\/dataguard\/dataguard\/DC1_ODG_PKG_NAME[[:space:]]*$%tkit\/dataguard\/dataguard\/DC1_ODG_PKG_NAME ${DC1_ODG_PKG_NAME}%
  s%^tkit\/dataguard\/dataguard\/DC2_ODG_PKG_NAME[[:space:]]*$%tkit\/dataguard\/dataguard\/DC2_ODG_PKG_NAME ${DC2_ODG_PKG_NAME}% 
  s%^#generic_resource_name[[:space:]]*$%generic_resource_name ${RM_PKG_NAME}_RES% 
  s%^#generic_resource_evaluation_type[[:space:]]*$%generic_resource_evaluation_type during_package_start% 
  s%^#generic_resource_up_criteria[[:space:]]*$%generic_resource_up_criteria <=3 % " > $PKGCONF.tmp1
  if [[ $? -eq 0 ]]; then 
     mv $PKGCONF.tmp1 $ASM_DB_PKGCONF
  fi 
  if [[ -n "${PKGDESC}" ]]; then
     DESC="\"$PKGDESC\""
     cat $ASM_DB_PKGCONF |
     sed "s%^package_description[[:space:]]*\"Serviceguard Package\"$%package_description  $DESC % " > $PKGCONF.tmp1
     if [[ $? -eq 0 ]]; then 
        mv $ASM_DB_PKGCONF.tmp1 $ASM_DB_PKGCONF
     fi 
      
  fi
fi

if [[ -n "$asm_package_name" ]]; then
	#Identify Dependency package name
        DEPEND[${#DEPEND[*]}]="${asm_package_name}:up:same_node"
fi
#Function to discover the asm dg's.
discover_asm_dgs
if [[ -n $ORACLE_HOME ]]; then 
  discover_storage "$ORACLE_HOME"
fi
}

##################################################################
# Function: update_config_file_for_asm_instance
# Description: This function updates the package configuration file
#              for ASM instance package.
# Arguments: Takes ASM instance configuration file as argument.
##################################################################

function update_config_file_for_asm_instance
{

ASM_INST_PKGCONF="$1"
INSTANCE_TYPE="ASM"
ASM_PFILE_LOCATION="${ASM_HOME}/dbs/init${ASM_SID}.ora"

WORKLOAD_TYPE="oracle_asm_db"
if [[ -n ${dataguard_input} ]]; then
    WORKLOAD_TYPE="oracle_dataguard_asm_db"
fi

cat ${ASM_INST_PKGCONF} |
sed -e "s%^package_name.*$%package_name ${ASM_INST_PKG_NAME}%
s%^tkit/oracle/oracle/ORACLE_HOME[[:space:]]*$%tkit/oracle/oracle/ORACLE_HOME ${ORACLE_HOME}%
s%^tkit\/oracle\/oracle\/ORACLE_ADMIN[[:space:]]*oracle$%tkit\/oracle\/oracle\/ORACLE_ADMIN ${ORACLE_ADMIN}%
s%^tkit\/oracle\/oracle\/SID_NAME[[:space:]]*$%tkit\/oracle\/oracle\/SID_NAME ${SID_NAME}%
s%^tkit\/oracle\/oracle\/PFILE[[:space:]]*\${ORACLE_ORACLE_HOME}/dbs/init\${ORACLE_SID_NAME}.ora$%tkit\/oracle\/oracle\/PFILE ${ASM_PFILE_LOCATION}%
s%^tkit\/oracle\/oracle\/INSTANCE_TYPE[[:space:]]*database$%tkit\/oracle\/oracle\/INSTANCE_TYPE ${INSTANCE_TYPE}%
s%^tkit\/oracle\/oracle\/LISTENER[[:space:]]*yes$%tkit\/oracle\/oracle\/LISTENER no%
s%^#tkit\/oracle\/oracle\/ASM_HOME[[:space:]]*$%tkit/oracle/oracle/ASM_HOME ${ASM_HOME}%
s%^tkit\/oracle\/oracle\/ASM_USER[[:space:]]*oracle$%tkit/oracle/oracle/ASM_USER ${ASM_USER}%
s%^#tkit\/oracle\/oracle\/ASM_SID[[:space:]]*$%tkit\/oracle\/oracle\/ASM_SID ${ASM_SID}%
s%^service_name[[:space:]]*oracle_service%service_name ${ASM_SERVICE_NAME}%
s%^tkit\/oracle\/oracle\/MONITOR_PROCESSES[[:space:]]*ora_pmon_\${ORACLE_SID_NAME}$%tkit\/oracle\/oracle\/MONITOR_PROCESSES asm_pmon_\${ORACLE_ASM_SID}%
s%^tkit\/oracle\/oracle\/MONITOR_PROCESSES[[:space:]]*ora_dbw0_\${ORACLE_SID_NAME}$%tkit\/oracle\/oracle\/MONITOR_PROCESSES asm_dbw0_\${ORACLE_ASM_SID}%
s%^tkit\/oracle\/oracle\/MONITOR_PROCESSES[[:space:]]*ora_ckpt_\${ORACLE_SID_NAME}$%tkit\/oracle\/oracle\/MONITOR_PROCESSES asm_ckpt_\${ORACLE_ASM_SID}%
s%^tkit\/oracle\/oracle\/MONITOR_PROCESSES[[:space:]]*ora_smon_\${ORACLE_SID_NAME}$%tkit\/oracle\/oracle\/MONITOR_PROCESSES asm_smon_\${ORACLE_ASM_SID}%
s%^tkit\/oracle\/oracle\/MONITOR_PROCESSES[[:space:]]*ora_lgwr_\${ORACLE_SID_NAME}$%tkit\/oracle\/oracle\/MONITOR_PROCESSES asm_lgwr_\${ORACLE_ASM_SID}%
s%^tkit\/oracle\/oracle\/MONITOR_PROCESSES[[:space:]]*ora_reco_\${ORACLE_SID_NAME}$%tkit\/oracle\/oracle\/MONITOR_PROCESSES asm_gmon_\${ORACLE_ASM_SID}%" -e \
/'^service_name[[:space:]]*oracle_listener_service$/,+17 s/^/#/' -e \
"/^tkit\/oracle\/oracle\/MONITOR_PROCESSES[[:space:]]*asm_gmon_${ORACLE_ASM_SID}/ a\tkit\/oracle\/oracle\/MONITOR_PROCESSES asm_rbal_\${ORACLE_ASM_SID}" > ${ASM_INST_PKGCONF}.tmp1
if [[ $? -eq 0 ]]; then
  mv ${ASM_INST_PKGCONF}.tmp1 ${ASM_INST_PKGCONF}
fi

if [[ $workload_flag -eq 1 ]]; then
    cat ${ASM_INST_PKGCONF} |
    sed -e "s%^#standard_workload_name.*$%standard_workload_name ${WORKLOAD_NAME}%
            s%^#standard_workload_type.*$%standard_workload_type ${WORKLOAD_TYPE}%"> ${ASM_INST_PKGCONF}.tmp1
    if [[ $? -eq 0 ]]; then
        mv ${ASM_INST_PKGCONF}.tmp1 ${ASM_INST_PKGCONF}
    fi
fi

}

##################################################################
# Function: update_config_file_for_single_inst_db
# Description: This function updates the package configuration file
#              for Oracle single instance package.
# Arguments: Takes Package configuration template as argument.
##################################################################
function update_config_file_for_single_inst_db
{
  PKGCONF="$1"
    if [[ -n ${dataguard_input} ]]; then
        WORKLOAD_TYPE="oracle_dataguard_si_db"
    else
        WORKLOAD_TYPE="oracle_si_db"
    fi
  cat $PKGCONF |
  sed "s%^package_name.*$%package_name ${SINGINST_DB_PKG_NAME}%
  s%^tkit/oracle/oracle/ORACLE_HOME[[:space:]]*$%tkit/oracle/oracle/ORACLE_HOME ${ORACLE_HOME}%
  s/^tkit\/oracle\/oracle\/SID_NAME[[:space:]]*$/tkit\/oracle\/oracle\/SID_NAME ${SID_NAME}/
  s/^service_name[[:space:]]*oracle_service/service_name ${DB_SERVICE_NAME}/
  s/^service_name[[:space:]]*oracle_listener_service/service_name ${DB_SERVICE_LISTENER_NAME}/
  s/^service_name[[:space:]]*oracle_hang_service/service_name ${DB_SERVICE_HANG_NAME}/
  s/^service_name[[:space:]]*oracle_pdb_monitor_service/service_name ${DB_PDB_SERVICE_NAME}/
  s/^tkit\/oracle\/oracle\/LISTENER_NAME[[:space:]]*$/tkit\/oracle\/oracle\/LISTENER_NAME ${LISTENERNAME}/
  s/^tkit\/oracle\/oracle\/ORACLE_ADMIN[[:space:]]*oracle$/tkit\/oracle\/oracle\/ORACLE_ADMIN ${ORACLE_ADMIN}/ " > $PKGCONF.tmp1
  if [[ $? -eq 0 ]]; then 
    mv $PKGCONF.tmp1 $PKGCONF
  fi 
  
  if [[ $workload_flag -eq 1 ]]; then
    cat $PKGCONF |
    sed -e "s%^#standard_workload_name.*$%standard_workload_name ${WORKLOAD_NAME}%
            s%^#standard_workload_type.*$%standard_workload_type ${WORKLOAD_TYPE}%"> ${PKGCONF}.tmp1
    if [[ $? -eq 0 ]]; then
        mv $PKGCONF.tmp1 $PKGCONF
    fi
  fi

  if [[ -n "${FLOATING_IP}" && -n "${SUBNET_IP}" ]]; then
     cat ${PKGCONF} |
     sed -e "s%^#ip_subnet[[:space:]]*$%ip_subnet ${SUBNET_IP}%
     s%^#ip_address[[:space:]]*$%ip_address ${FLOATING_IP}%" > ${PKGCONF}.tmp
     if [[ $?  -eq 0 ]]; then
         mv ${PKGCONF}.tmp ${PKGCONF}
     fi
  fi 
  
  if [[ -n ${dataguard_input} ]]; then
     cat $PKGCONF |
     sed "s%^tkit\/oracle\/oracle\/START_MODE[[:space:]]*[[:alnum:]]*$%tkit\/oracle\/oracle\/START_MODE mount%
     s/^service_name[[:space:]]*dataguard_monitor/service_name ${DG_SERVICE_NAME}/     
     s%^tkit\/dataguard\/dataguard\/DC1_NODE_LIST[[:space:]]*$%tkit\/dataguard\/dataguard\/DC1_NODE_LIST ${PRIMARY_NODELIST}%
     s%^tkit\/dataguard\/dataguard\/DC2_NODE_LIST[[:space:]]*$%tkit\/dataguard\/dataguard\/DC2_NODE_LIST ${STANDBY_NODELIST}%
     s%^tkit\/dataguard\/dataguard\/ACTIVE_STANDBY[[:space:]]*no$%tkit\/dataguard\/dataguard\/ACTIVE_STANDBY $ACTIVE_STANDBY%
     s%^tkit\/dataguard\/dataguard\/REAL_TIME_APPLY[[:space:]]*no$%tkit\/dataguard\/dataguard\/REAL_TIME_APPLY $REAL_TIME_APPLY%     
     s%^#tkit/dataguard/dataguard/RPO_LIMIT[[:space:]]*$%tkit/dataguard/dataguard/RPO_LIMIT $RPO%     
     s%^tkit\/dataguard\/dataguard\/DC1_ODG_PKG_NAME[[:space:]]*$%tkit\/dataguard\/dataguard\/DC1_ODG_PKG_NAME ${DC1_ODG_PKG_NAME}%
     s%^tkit\/dataguard\/dataguard\/DC2_ODG_PKG_NAME[[:space:]]*$%tkit\/dataguard\/dataguard\/DC2_ODG_PKG_NAME ${DC2_ODG_PKG_NAME}% 
     s%^#generic_resource_name[[:space:]]*$%generic_resource_name ${RM_PKG_NAME}_RES% 
     s%^#generic_resource_evaluation_type[[:space:]]*$%generic_resource_evaluation_type during_package_start% 
     s%^#generic_resource_up_criteria[[:space:]]*$%generic_resource_up_criteria <=3 % " > $PKGCONF.tmp1
     if [[ $? -eq 0 ]]; then 
        mv $PKGCONF.tmp1 $PKGCONF
     fi 
     if [[ -n "${PKGDESC}" ]]; then
        DESC="\"$PKGDESC\""
        cat $PKGCONF |
        sed "s%^package_description[[:space:]]*\"Serviceguard Package\"$%package_description  $DESC % " > $PKGCONF.tmp1
        if [[ $? -eq 0 ]]; then 
            mv $PKGCONF.tmp1 $PKGCONF
        fi 
     fi
  fi

  CONFILE="$PKGCONF"
}

############################################################
# Function: apply_configuration
# Description: This function verifies the configuration file, 
# If verification is successful, then it applies the configuration
# file to all packaged nodes. If applying configuration is
# successful, then cmrunpkg will be executed.
# Arguments: Package configuration file.
# Returns: 0 On Success
#          1 on Normal exit
#          Different exit code for cmrunpkg.
#############################################################

function apply_configuration
{
CONFILE="$1"
PKG_NAME="$2"
MULTI_NODE_PKG="$3"

#Using cmcheckconf to verify the package configuration file
${SGSBIN}/cmcheckconf -P "${CONFILE}"
if [[ $? -ne 0 ]]; then
  echo "ERROR: cmcheckconf failed for the package ${CONFILE}."
  cleanitup ${CONFILE}	
  exit 1
else
  ${SGSBIN}/cmapplyconf -f -P "${CONFILE}"
  if [[ $? -ne 0 ]]; then
     echo "ERROR: cmapplyconf failed for the package ${CONFILE}."
     cleanitup ${CONFILE}	
     exit 1 
  else 
    if [[ $MULTI_NODE_PKG == "false" ]]; then
        ${SGSBIN}/cmmodpkg -e -n $oracle_node "${PKG_NAME}"
    else
        ${SGSBIN}/cmmodpkg -e "${PKG_NAME}"
    fi
    if [[ -z "$dataguard_input" ]]; then
        ${SGSBIN}/cmrunpkg "${PKG_NAME}"
        if [[ $? -ne 0 ]]; then
           echo "ERROR: cmrunpkg failed for package ${PKG_NAME}. Please check package log for more details."
           cleanitup ${CONFILE}	
           exit 1
        fi
    fi
  fi
fi 
#As we do not require to store the configuration file. Removing it
if [[ -f ${CONFILE} ]]; then
  rm -rf ${CONFILE}
fi
}

###########################################################
# Function: check_package_already_exists
# Description: This function checks if there is any package
# currently formed for the Oracle DB instance provided.
##########################################################
function check_package_already_exists
{
sidname=$1
db_package_name=`${SGSBIN}/cmviewcl -f line -v | grep "INSTANCE_TYPE=database" | cut -d "|" -f 1 | cut -d ":" -f 2`
if [[ $? -eq 0 ]]; then
 if [[ -n $db_package_name ]]; then
    for pkg in ${db_package_name}
    do 
        ${SGSBIN}/cmgetpkgenv $pkg | grep "ORACLE_SID_NAME=\"$sidname\"" >> /dev/null
        if [[ $? -eq 0 ]]; then
            if [[ -n $DG_PRIMARY ]]; then
                if [[ $pkg == $DC2_ODG_PKG_NAME ]]; then
                    return
                else
                    echo "ERROR: Oracle Package for Oracle SID $sidname already exists."
                fi
            else
                echo "ERROR: Oracle Package for Oracle SID $sidname already exists."
            fi
            exit 1
        fi
    done
 fi
fi
}

#####################MAIN starts from here###############################
# Receive Command line arguments and parse the same to get oracle home
# ASM home, Oracle SID, nodenames and replication value

while getopts ":p:o:i:a:s:n:r:c:q:g:w:" option; do
case "$option" in
p)  DB_PKGNAME="$OPTARG"
    ;;
w)  WORKLOAD_NAME="$OPTARG"
	workload_flag=1
	;;
o)  ORACLE_HOME="$OPTARG"
    if [[ ! -d ${ORACLE_HOME} ]]; then
      	echo "ERROR: Oracle Home specified by user does not exists."
        exit 1
    fi	
    ;;
i)  ORACLE_SID="$OPTARG" 
    ;;
a)  ASM_HOME="$OPTARG" 
    if [[ ! -d ${ASM_HOME} ]]; then
      	echo "ERROR: ASM Home specified by user does not exists."
	    exit 1
    fi
    ;;
s) ASMSID="$OPTARG"
   ;;
n)  NODENAMES="${NODENAMES} $OPTARG" 
    if [[ -n "${NODENAMES[*]}" ]]; then
       for node in ${NODENAMES[*]}; do
          verify_nodes $node
          if [[ $? -eq 0 ]]; then
             echo "${SGNODES[*]}" | grep -e "$node" >> /dev/null
             if [[ $? -ne 0 ]]; then
              SGNODES[${#SGNODES[*]}]=${node}
            fi
          fi
       done
    else
       exit 1
    fi
    ;;
r)  repl_flag="$OPTARG";;
c)  check_app_binary="$OPTARG"
    if [[ $check_app_binary = "check" ]]; then
       check_nodes
       exit $?
    fi
    ;;
q)  check_status="$OPTARG"
    get_asm_sid
    if [[ $check_status = "check" ]]; then
      check_app_status
      exit $?
    fi
    ;;
g)  dataguard_input="$OPTARG"
    if [[ $dataguard_input = "primary" ]]; then
        DG_PRIMARY=1
    fi
    if [[ -e $tmpfile ]]; then
        . $tmpfile
        if (( $? != 0 ))
        then
            echo "ERROR: Unable to source Dataguard information file: ${tmpfile}"
            exit 1
        fi
    else
        echo "ERROR: The required Dataguard Parameter file $tmpfile is not available"
        exit 1
    fi
    ;;
*)  echo "Usage:"
    echo "For Binary check for Oracle DB package: deployOraclePkg -o <oraclehome> -i <oraclesid> -n <node1> -n <node2> -c check"
    echo "For Binary check for ASM packages: deployOraclePkg -o <oraclehome> -i <oraclesid> -a <asmhome> -n <node1> -n <node2> -c check"
    echo "For Application Run check: deployOraclePkg -o <oraclehome> -i <oraclesid> -a <asmhome> -n <node1> -n <node2> -q check"
    echo "For enabling replication: deployOraclePkg -o <oraclehome> -i <oraclesid> -n <node1> -n <node2> -r <yes>"
    echo "For Oracle 11gR1, 11gR2 or later: deployOraclePkg -p <package_name> -o <oraclehome> -i <oraclesid> -n <node1> -n <node2>"
    echo "For Oracle 11gR1 with ASM: deployOraclePkg -p <package_name> -o <oraclehome> -i <oraclesid> -a <asmhome> -s <asmsid> -n <node1> -n <node2>"
    echo "For Oracle 11gR2 or later with ASM: deployOraclePkg -p <package_name> -o <oraclehome> -i <oraclesid> -a <asmhome> -n <node1> -n <node2>"
    echo "For configuring standard workload: deployOraclePkg -o <oraclehome> -i <oraclesid> -n <node1> -n <node2> -w <standard_workload>" 
    echo "For configuring standard workload with ASM: deployOraclePkg -o <oraclehome> -i <oraclesid> -a <asmhome> -n <node1> -n <node2> -w <standard_workload>"   
 exit 1 ;;
esac
done
shift $(( OPTIND - 1))

ora_pkg="false"
asm_pkg="false"

if [[ -n ${ORACLE_SID} ]]; then
   check_package_already_exists ${ORACLE_SID}
fi

if [[ -z "${ORACLE_HOME}" ]];then
   echo "ERROR: Oracle Home argument is missing."
   exit 1
elif [[ -z "${ORACLE_SID}" ]]; then
  echo "ERROR: Oracle SID argument is missing."
  exit 1
fi


#Set the flags based on what package you are trying to configure.
if [[ -z "${ASM_HOME}" && -n "${ORACLE_HOME}" && -n "${ORACLE_SID}" ]]; then
   ora_pkg="true"
elif [[ -n ${ASM_HOME} ]]; then
   asm_pkg="true"
fi

if [[ -n $dataguard_input ]]; then
    if [[ -z $PRIMARY_NODELIST || -z $STANDBY_NODELIST ]]; then
        echo "Could not find the Primary/Standby Nodelist."
        exit 1    
    fi
    if [[ -z $DC1_ODG_PKG_NAME || -z $DC2_ODG_PKG_NAME ]]; then
        echo "Could not find the DC1/DC2 Package Names."
        exit 1    
    fi
fi

#Check if asm instance package already exists. If it exists then get asm instance package name and create only ASM db package
#If asm instance package does not exists, then create both asm instance and asm db package.
#In case of Dataguard, if the ASM instance package exists but belongs to the standby, then we must create the 
# primary ASM instance package
if [[ $asm_pkg = "true" ]]; then
    check_asm_insatnce_package_exists
fi

#Get the oracle sid name for Oracle Single instance DB package or ASM DB package
if [[ $ora_pkg = "true" || $asm_db_pkg -eq 1 ]]; then
		SID_NAME="${ORACLE_SID}"
fi

#Get the SID name for ASM
get_asm_sid

#Generate Package Name if it is not supplied
if [[ -z "$DB_PKGNAME" ]]; then
    generatePkgNames
fi

#Get the Package Name for single instance db, ASM db, ASM instance packages
if [[ -n "$dataguard_input" ]]; then
    if [[ $ora_pkg = "true" ]]; then
       SINGINST_DB_PKG_NAME="${DB_PKGNAME}"
    elif [[ $asm_inst_pkg -eq 1 && $asm_db_pkg -eq 1 ]]; then
       ASM_INST_PKG_NAME="${DB_PKGNAME}_ASM"
       ASM_INST_PKG_NAME=`echo ${ASM_INST_PKG_NAME} | sed 's/+//'`
       ASM_DB_PKG_NAME="${DB_PKGNAME}"
    elif [[ $asm_inst_pkg -eq 0 && $asm_db_pkg -eq 1 ]]; then
       ASM_DB_PKG_NAME="${DB_PKGNAME}"
    fi
else
    if [[ $ora_pkg = "true" ]]; then
       SINGINST_DB_PKG_NAME="${DB_PKGNAME}"
    elif [[ $asm_inst_pkg -eq 1 && $asm_db_pkg -eq 1 ]]; then
       ASM_INST_PKG_NAME="asm_${ASM_SID}_inst_pkg"
       ASM_INST_PKG_NAME=`echo ${ASM_INST_PKG_NAME} | sed 's/+//'`
       ASM_DB_PKG_NAME="${DB_PKGNAME}"
    elif [[ $asm_inst_pkg -eq 0 && $asm_db_pkg -eq 1 ]]; then
       ASM_DB_PKG_NAME="${DB_PKGNAME}"
    fi
fi

#Get Oracle application running node
application_check ${ORACLE_SID} oracle
if [[ $? -ne 0 ]]; then
  echo "ERROR: Failed to find the node in cluster where Oracle application is up and running."
  exit 1
fi

#Get the oracle home and sid name
echo "Discovering Oracle/ASM Home and Oracle/ASM SID................................................"
if [[ $ora_pkg = "true" || $asm_db_pkg -eq 1 ]]; then
   echo "ORACLE_HOME is $ORACLE_HOME"
   echo "SID_NAME is $SID_NAME"
fi
if [[ $asm_pkg = "true" ]]; then
   echo "ASM HOME is $ASM_HOME"
   echo "ASM_SID is $ASM_SID"
fi
 echo "Discovering Oracle/ASM Home and SID.......................................[SUCCESS]"

#Get the oracle admin
echo "Discovering Oracle/ASM Admin user.................................................."
discover_oracle_or_asm_admin
if [[ $? -eq 0 ]] ; then
   if [[ $ora_pkg = "true"  || $asm_db_pkg -eq 1 ]]; then
     echo "ORACLE_ADMIN is $ORACLE_ADMIN"
   elif [[ $asm_pkg = "true" ]]; then
     echo "ASM_ADMIN is $ASM_ADMIN"
   fi
   echo "Discovering Oracle/ASM Admin user.........................................[SUCCESS]"
else
   echo "ERROR: Discovering Oracle/ASM Admin user....................................[FAILED]"
   exit 1
fi

# Get all oracle and ASM values from queries
discover_all_oracle_asm_values >> /dev/null


#Get the service name
echo "Discovering service name................................................"
discover_service_name

#Get all file locations for DB files
discover_oracle_db_file_locations
if [[ $? -eq 0 ]]; then
  echo "Discovering Oracle/ASM files location..................................[SUCCESS]"
else
  echo "Discovering Oracle/ASM files location..................................[FAILURE]"
fi

#Get DB server IP address if Oracle DB package is configured in a floating
#IP configuration
if [[ $ora_pkg = "true" || $asm_db_pkg -eq 1 ]]; then
  discover_floating_ip
  if [[ $? -eq 0 ]]; then
    echo "Discovering Oracle DB Server floating IP..................................[SUCCESS]"
  elif [[ $? -eq 2 ]]; then
    echo "Discovering Oracle DB Server floating IP.................................[NOT DEFINED]"
  fi
fi

#create configuration file for single instance DB package or ASM DB package
if [[ $ora_pkg = "true" || $asm_db_pkg -eq 1 ]]; then
  if [[ -z "$dataguard_input" ]]; then
      #Create package configuration file and update the values for package attributes.
      $SGSBIN/cmmakepkg -m tkit/oracle/oracle $TKITDIR/${ORACLE_SID}.ascii 
      ret=$?
  elif [[ -n "$dataguard_input" ]]; then
      #Create package configuration file and update the values for package attributes.
      echo "Creating the Package with Dataguard"
      $SGSBIN/cmmakepkg -m tkit/oracle/oracle -m tkit/dataguard/dataguard $TKITDIR/${ORACLE_SID}.ascii 
      ret=$?
  fi
  if [[ $ret -eq 0 ]] ; then
    echo "Creating template package configuration file..........................[SUCCESS]"
    DB_PKGCONF="$TKITDIR/${ORACLE_SID}.ascii"
  else
    echo "Creation of template package configuration file failed.\n"
    cleanup_sqlquery_files
    exit 1
  fi
fi

#Update configuration file for oracle single instance DB package
if [[ $ora_pkg = "true" ]]; then
  update_config_file_for_single_inst_db $DB_PKGCONF
  update_array_attributes $DB_PKGCONF


  # if this is replication enabled Metro cluster configuration then only following part
  # of code will be called.
  # Metro cluster currently supports only single instance oracle toolkit. Hence below condition is
  # applicable for single instance oracle toolkit without ASM.
  if [[ $repl_flag == "yes" ]]; then
        #Call sgdeploylvm and sgdeployvxvm
        if [[ -n ${VGARRAY[*]} ]] ; then
                vgstr=`echo ${VGARRAY[*]} | tr ' ' '|'`
                if [[ -f ${SGDEPLOYVOLUMES} && -f ${SGDEPLOYMC} ]] ; then
                        ${SGDEPLOYVOLUMES} -i ${DB_PKGCONF} -o "lvm_vgs=$vgstr"
                        if [[ $? -eq 0 ]] ; then
                                echo "Metrocluster Configuration is Successful"
                        else
                                echo "ERROR: Metrocluster Configuration Failed."
                        fi
                fi
        fi


        if [[ -n ${DGARRAY[*]} ]] ; then
                dgstr=`echo ${DGARRAY[*]} | tr ' ' '|'`
                if [[ -f ${SGDEPLOYVOLUMES} && -f ${SGDEPLOYMC} ]] ; then
                        ${SGDEPLOYVOLUMES} -i ${DB_PKGCONF} -o "vxvm_dgs=$dgstr"
                        if [[ $? -eq 0 ]] ; then
                                echo "Metrocluster Configuration is Successful"
                        else
                                echo "ERROR: Metrocluster Configuration is Failed."
                        fi
                fi
        fi
  fi
fi

#For creating ASM instance package 
if [[ $asm_pkg = "true" ]]; then
		if [[ $asm_inst_pkg -eq 1 ]]; then
		   ${SGSBIN}/cmmakepkg -m sg/multi_node -m tkit/oracle/oracle ${TKITDIR}/asm_inst.ascii
                   if [[ $? -eq 0 ]]; then
                      echo "Creating template package configuration file..........................[SUCCESS]"
		      ASM_INST_PKGCONF="${TKITDIR}/asm_inst.ascii"
                   else 
                      echo "Creating template package configuration file failed.\n"
                      cleanup_sqlquery_files 
                      exit 1
                   fi    
			update_config_file_for_asm_instance $ASM_INST_PKGCONF
			update_array_attributes $ASM_INST_PKGCONF
			VGARRAY=( )
			FSARRAY=( )
			DGARRAY=( )
                        DEPEND=( )
                       asm_package_name="${ASM_INST_PKG_NAME}"
		fi
    #For creating ASM DB package
	if [[ $asm_db_pkg -eq 1 ]]; then 
		ASM_DB_PKGCONF="$DB_PKGCONF"
		update_config_file_for_asm_db $ASM_DB_PKGCONF 
		update_array_attributes $ASM_DB_PKGCONF
	fi
fi

echo "Configuring Application Package configuration file....................[SUCCESS]"

#Update Workload name for existing Oracle ASM package 
if [[ $asm_pkg = "true" ]]; then
    if [[ $asm_inst_pkg -eq 0 && $workload_flag -eq 1 ]]; then
        update_asm_package_with_workloadname
    fi
fi


# Function cleans up output.csv file in the oracle home directory
cleanup_sqlquery_files

# This function applies the package configuration and runs the package for all the three configuration of
# Oracle toolkit (i.e single instance oracle, ASM instance and ASM db packages)
if [[ $ora_pkg = "true" ]]; then
        apply_configuration $DB_PKGCONF $SINGINST_DB_PKG_NAME "false"
elif [[ $asm_pkg = "true" ]]; then
    if [[ $asm_inst_pkg -eq 1 ]]; then
            apply_configuration $ASM_INST_PKGCONF $ASM_INST_PKG_NAME "true"            
    fi
    apply_configuration $ASM_DB_PKGCONF $ASM_DB_PKG_NAME "false"
fi
