#!/bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# bos720 src/bos/usr/lib/nim/methods/c_alt_disk_mig.sh 1.1 
#  
# Licensed Materials - Property of IBM 
#  
# Restricted Materials of IBM 
#  
# COPYRIGHT International Business Machines Corp. 2001 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# @(#)66	1.1  src/bos/usr/lib/nim/methods/c_alt_disk_mig.sh, cmdnim, bos720 6/8/01 10:04:39
#
#   COMPONENT_NAME: cmdnim
#
#   FUNCTIONS: mount_resources
#		unmount_resources
#		mnt_dir
#		ck_dir
#		set_flags
#		ck_SPOT
#
#   ORIGINS: 27
#
#
#   (C) COPYRIGHT International Business Machines Corp. 1997
#   All Rights Reserved
#   Licensed Materials - Property of IBM
#   US Government Users Restricted Rights - Use, duplication or
#   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
#

# include common NIM shell defines/functions
NIMPATH=${0%/*}
NIMPATH=${NIMPATH%/*}
[[ ${NIMPATH} = ${0} ]] && NIMPATH=/usr/lpp/bos.sysmgt/nim
NIM_METHODS="${NIMPATH}/methods"
. ${NIM_METHODS}/c_sh_lib

#---------------------------- local defines     --------------------------------

#---------------------------- module globals    --------------------------------
REQUIRED_ATTRS="client lpp_source spot disk"
OPTIONAL_ATTRS="boot_client bosinst_data debug exclude_files installp_bundle image_data mount_opts pre_mig post_mig set_bootlist show_details"

#
# Define variables for alt_disk_install files.  Such definitions would
# normally go in c_sh_lib, but this client method must work with older
# versions of c_sh_lib that would not have these variables defined.
#
ALT_DISK_MIG="/usr/lpp/bos.alt_disk_install/migration/alt_disk_mig"
ALT_DISK_INSTALL_LOG="/var/adm/ras/nim.alt_disk_install"

#
# Initialize global variables.
#
boot_client=""
bosinst_data=""
disk=""
exclude_files=""
installp_bundle=""
image_data=""
lpp_source=""
mount_opts=""
pre_mig=""
post_mig=""
set_bootlist=""
show_details=""
reboot=""
debug=""
show_debug=""
no_bootlist=""
verbose_output=""

adi_rc=""
mounted_res=""
#
# Define mount points for resources.
#
bosinst_data_access="/ALT_MIG_BOSINST_DATA"
exclude_files_access="/ALT_MIG_EXCLUDE_FILES"
installp_bundle_access="/ALT_MIG_INSTALLP_BUNDLE"
image_data_access="/ALT_MIG_IMAGE_DATA"
lpp_source_access="/ALT_MIG_LPP_SOURCE"
pre_mig_access="/ALT_MIG_PRE_MIG"
post_mig_access="/ALT_MIG_POST_MIG"
spot_access="/ALT_MIG_SPOT"

#---------------------------- ck_SPOT         --------------------------------
#
# NAME: ck_SPOT
#
# FUNCTION:
#		gets the level of bos.alt_disk_install.rte that is installed.
#
# EXECUTION ENVIRONMENT:
#
# NOTES:
#		calls error on failure
#
# RECOVERY OPERATION:
#
# DATA STRUCTURES:
#		parameters:
#		global:
#
# RETURNS: (int)
#		0							= success
#
# OUTPUT:
#-------------------------------------------------------------------------------
function ck_SPOT {

	# make sure source pathname ends with "/usr"
	if [[ "${spot##*/}" != usr ]]
	then
		spot=${spot}/usr
	fi

	# chop off the server name
	spotname=${spot##*:}

	# get product data from spots ODM database
	odm_fileset_level=`ODMDIR=${spotname}/lib/objrepos ${ODMGET} \
		-q "lpp_name=bos.alt_disk_install.rte" product\
		| ${AWK} '/state =|rel =|mod =|ver =|fix =|lpp_name =/ \
		  {
			if ($1 == "state")  c_state=$3
			if ($1 == "ver")    vrmf[1]=$3
			if ($1 == "rel")    vrmf[2]=$3
			if ($1 == "mod")    vrmf[3]=$3
			if ($1 == "fix") {
				vrmf[4]=$3
				if (c_state == 3 || c_state == 5) {
					bigger=0
					for ( ix=1; ix<=4; ix++ ) {
						if (vrmf[ix] < h_vrmf[ix]) break
						if (vrmf[ix] > h_vrmf[ix]) bigger++
					}
					if (bigger > 0)
					for ( ix=1; ix <= 4; ix++ )
						h_vrmf[ix] = vrmf[ix]
				}
				for ( ix=1; ix <= 4; ix++ ) vrmf[ix] = 9999;
			}
		  }
		  END {
			
			print h_vrmf[1] "." h_vrmf[2] "." h_vrmf[3] "." h_vrmf[4]
		  }'`

	
	# parse off the vrmf data into variables.
	vrmf=${odm_fileset_level}
	integer ver=`echo ${vrmf} | ${CUT} -d"." -f1`
	integer rel=`echo ${vrmf} | ${CUT} -d"." -f2`
	integer mod=`echo ${vrmf} | ${CUT} -d"." -f3`
	integer fix=`echo ${vrmf} | ${CUT} -d"." -f4`
	
if (( (ver < 5) || (ver == 5 && (rel == 0 || (rel < 2 && (fix < 1 && (mod < 1))))) ))
then
	error ${ERR_RELEASE_LEVEL} "${ver}" "${vrmf#*.}" "bos.alt_disk_install.rte" 
fi

} # end of ck_SPOT

#---------------------------- chk_dir 
#
# NAME: chk_dir
#
# FUNCTION:   Check to see if the directory exists, if not then 
#  make it.  It can be used for a mount point or the place we
#  want to copy the commands to.... 
#
# DATA STRUCTURES:
#     parameters:
#        1           = client name
#        2           = directory to check
#        
# RETURNS: (int)
#  Exits if an error occurs... 
#
#-------------------------------------------------------------------------------
function chk_dir
{
  client=$1
  client_dir=$2
  getrc="echo \$?"

  # Check to see if the directory already exists on the client.
  clientdir_exists=`${RSH} ${client} "test -d ${client_dir}; $getrc"`
  [ $clientdir_exists -ne 0 ] && {\
    clientdir_created=`${RSH} ${client} "${MKDIR} -p ${client_dir} >/dev/null; $getrc"`
        [ $clientdir_created -ne 0 ] && error ${ERR_MKDIR} ${client_dir} 
        }
}

#---------------------------- mnt_dir 
#
# NAME: mnt_dir
#
# FUNCTION:   Attempt to mount the support directory .... 
#
# DATA STRUCTURES:
#     parameters:
#        1           = client name
#        2           = directory to mount
#        3           = mount point on client
#        
# RETURNS: (int)
#  Exits if an error occurs... 
#
#-------------------------------------------------------------------------------
function mnt_dir
{
  client=$1
  mountdir=$2
  mountpnt=$3
  nfs_ok=""
  startnfs_ok=""
  nfsmount=""
  getrc="echo \$?"
  #
  # Make sure that the client mount point exists
  chk_dir ${client} ${mountpnt}

  # Check to see if client has nfs running; if not, then try to
  # start it.  If it can't be started, then error.  The machine
  # is required to be a configured NIM client for this operation,
  # so we should be able to start nfs on it.
  nfs_ok=`${RSH} ${client} "/usr/bin/ps -u root | /usr/bin/grep -q biod; $getrc"`
  if [ -z "$nfs_ok" ] || [ "$nfs_ok" != "0" ]
  then
    startnfs_ok=`${RSH} ${client} "/usr/bin/startsrc -g nfs; usr/bin/ps -u root | /usr/bin/grep -q biod; $getrc"`
    if [ -z "$startnfs_ok" ] || [ "$startnfs_ok" != "0" ]
    then
                error ${ERR_NFS_MNT} ${mountdir} ${mountpnt}
    fi
  fi

  nfsmount=`${RSH} ${client} "${MOUNT} -rohard,intr -vnfs ${mountdir} ${mountpnt}; $getrc"`
  if [ "${nfsmount}" != "0" ] || [ -z "${nfsmount}" ]
  then 
    error ${ERR_NFS_MNT} ${mountdir} ${mountpnt}
  fi

  # push onto mounted_res stack
  mounted_res="${mountpnt} ${mounted_res}"

  return 0
}

#---------------------------- unmount_resources 
#
# NAME: unmnt_dir
#
# FUNCTION:   Attempt to unmount the support directory .... 
#
# DATA STRUCTURES:
#     parameters:
#        1           = client name
#        
# RETURNS: (int)
#  Exits if an error occurs... 
#
#-------------------------------------------------------------------------------
function unmount_resources
{
  client=$1
  getrc="echo \$?"

  # find the specified <mountdir>
  for i in ${mounted_res}
  do
	unmount=`${RSH} ${client} "${UNMOUNT} ${i}; $getrc"`
	if [ "${unmount}" != "0" ] || [ -z "${unmount}" ]
	then
		warning_from_cmd ${UNMOUNT}
	fi
  done

  return 0
}

############################################################################
#
#  Name:        set_flags
#
#  Function:    Checks global variables and sets flags and variables for
#               the command to run.
#
#  Returns:     Nothing
#
#  Parameters:  None
#
############################################################################
function set_flags
{
  # Reboot the client?
  if [[ ${boot_client} = "yes" ]]
  then
    reboot="yes"
  fi

  # Run bootlist command to set bootlist?
  if [[ ${set_bootlist} = "no" ]]
  then
    no_bootlist="yes"
  fi

  # Show verbose output?
  if [[ ${show_details} = "yes" ]]
  then
    verbose_output="yes"
  fi

  # Show debug?
  if [[ ${debug} = "yes" ]]
  then
    show_debug="yes"
  fi

}

############################################################################
#
#  Name:        mount_resources
#
#  Function:    If resources were specified, then mount them
#               at specific mount points.
#
#  Returns:     Nothing
#
#  Parameters:  None
#
############################################################################
function mount_resources
{
  # mount the spot resource?
  if [[ -n "${spot}" ]]
  then
    mnt_dir ${client} ${spot} ${spot_access}
  fi

  # use a bosinst_data resource?
  if [[ -n "${bosinst_data}" ]]
  then
    mnt_dir ${client} ${bosinst_data} ${bosinst_data_access}
  fi

  # use an exclude_files resource?
  if [[ -n "${exclude_files}" ]]
  then
    mnt_dir ${client} ${exclude_files} ${exclude_files_access}
  fi

  # use an image_data resource?
  if [[ -n "${image_data}" ]]
  then
     mnt_dir ${client} ${image_data} ${image_data_access}
  fi

  # use a installp_bundle resource?
  #if [[ -n "${installp_bundle}" ]]
  #then
  #  mnt_dir ${client} ${installp_bundle} ${installp_bundle_access}
  #fi

  # use an lpp_source resource?
  #if [[ -n "${lpp_source}" ]]
  #then
  #  mnt_dir ${client} ${lpp_source} ${lpp_source_access}
  #fi

  # use a pre_mig resource?
  #if [[ -n "${pre_mig}" ]]
  #then
  #  mnt_dir ${client} ${pre_mig} ${pre_mig_access}
  #fi

  # use a post_mig resource?
  #if [[ -n "${post_mig}" ]]
  #then
  #  mnt_dir ${client} ${post_mig} ${post_mig_access}
  #fi

}

############################################################################
#
#  Name:        c_alt_disk_mig
#
#  Function:    Sets up access to remote resources, then calls
#               alt_disk_install
#
#  Returns:     Nothing
#
#  Parameters:  None
#
############################################################################

# signal processing
trap cleanup 0
trap err_signal 1 2 11 15

# NIM initialization
nim_init

# initialize local variables
typeset c=""

# set parameters from command line
while getopts :a:qvf c
do
  case ${c} in

    a)    # validate the attr ass
          parse_attr_ass "${OPTARG}"

	  # include the assignment for use in this environment
          eval ${variable}=\"${value}\"
          ;;

    f)    # passed to indicate that caller is not a 4.1 master
          # (Info is passed as a flag from m_maint and as a
          # variable if called from nim_script.)
          NIM_NON_41_MASTER=yes
          ;;

    q)    # show attr info
          cmd_what
          exit 0
          ;;

    v)    # verbose mode (for debugging)
          set -x
          for i in $(typeset +f)
          do
            typeset -ft $i
          done
          ;;

    \?)   # unknown option
          error ${ERR_BAD_OPT} ${OPTARG}
          ;;

  esac
done

# check for missing attrs
ck_attrs

# Get the version/release/mod of the bos.alt_disk_install.rte fileset in
# the SPOT
ck_SPOT

# set flags based on input attrs
set_flags

# mount resources to local access points.
mount_resources

# set the following variable so that errors are appended to err_info
# attribute on the client object.
UPDT_CL_ERR_INFO=yes

# Mark the beginning of execution with a timestamp in the log file.
${C_TIME_STAMP} >> ${ALT_DISK_INSTALL_LOG}

${ALT_DISK_MIG} \
 ${client:+-H $client} \
 ${image_data:+-i $image_data_access} \
 ${reboot:+-r} \
 ${mount_opts:+-m $mount_opts} \
 ${bosinst_data:+-o $bosinst_data_access} \
 ${show_debug:+-D} \
 ${no_bootlist:+-B} \
 ${installp_bundle:+-b ${installp_bundle##*:}} \
 ${lpp_source:+-l ${lpp_source##*:}} \
 ${exclude_files:+-e $exclude_files_access} \
 ${pre_mig:+-a ${pre_mig##*:}} \
 ${post_mig:+-c ${post_mig##*:}} \
 ${verbose_output:+-V} \
 ${disk:+-d $disk}

# Save the return code from the alt_disk_install command.
adi_rc=$?

# Mark the end of execution with a timestamp in the log file.
${C_TIME_STAMP} -e >> ${ALT_DISK_INSTALL_LOG}

# unmount resources from local access points.
unmount_resources ${client}

# success
exit 0
