#!/bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# bos72Q src/bos/usr/lib/nim/methods/c_alt_disk_install.sh 1.18.1.3 
#  
# Licensed Materials - Property of IBM 
#  
# Restricted Materials of IBM 
#  
# COPYRIGHT International Business Machines Corp. 1997,2019 
# 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 
# @(#)49	1.18.1.3  src/bos/usr/lib/nim/methods/c_alt_disk_install.sh, cmdnim, bos72Q, q2019_14A9 3/31/19 10:30:56
#
#   COMPONENT_NAME: cmdnim
#
#   FUNCTIONS: mount_resources
#		set_flags
#
#   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="source disk"
OPTIONAL_ATTRS="boot_client debug exclude_files filesets fix_bundle fixes installp_bundle installp_flags image_data lpp_source mksysb phase resolv_conf script set_bootlist no_nim_client show_details force"

#
# 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_INSTALL="/usr/sbin/alt_disk_install"
ALT_DISK_INSTALL_LOG="/var/adm/ras/nim.alt_disk_install"
C_ALT_DISK_INSTALL="/usr/lpp/bos.sysmgt/nim/methods/c_alt_disk_install"

#
# Initialize global variables.
#
boot_client=""
debug=""
disk=""
exclude_files=""
filesets=""
fix_bundle=""
force=""
installp_bundle=""
installp_flags=""
image_data=""
lpp_source=""
mksysb=""
no_bootlist=""
phase=""
platform=""
remain_client=""
resolv_conf=""
script=""
set_bootlist=""
show_debug=""
show_details=""
skip_boot_check=""
source=""
verbose_output=""

adi_rc=""

#
# Define mount points for resources.
#
exclude_files_access="${TMPDIR}/exclude_files"
fix_bundle_access="${TMPDIR}/fix_bundle"
installp_bundle_access="${TMPDIR}/installp_bundle"
image_data_access="${TMPDIR}/image_data"
lpp_source_access="${TMPDIR}/lpp_source"
mksysb_access="${TMPDIR}/mksysb"
resolv_conf_access="${TMPDIR}/resolv_conf"
script_access="${TMPDIR}/script"

############################################################################
#
#  Name:        set_flags
#
#  Function:    Checks global variables and sets flags and variables for
#               the command to run.
#
#  Returns:     Nothing
#
#  Parameters:  None
#
############################################################################
function set_flags
{
  # Determine if this will be a rootvg clone or a mksysb install.
  if [[ ${source} = "rootvg" ]]
  then
    source_device="-C"
  else
    source_device="-d $mksysb_access"

    # Determine the platform of this machine.
    # (bootinfo takes different flags for 4.1 and 4.2+)
    BOS_LEVEL=`${LSLPP} -Lcq bos.rte | ${AWK} 'BEGIN {FS=":"} {print $3}'`
    BOS_VERSION=`echo $BOS_LEVEL | ${AWK} 'BEGIN {FS="."} {print $1}'`
    BOS_RELEASE=`echo $BOS_LEVEL | ${AWK} 'BEGIN {FS="."} {print $2}'`
    if [[ ${BOS_VERSION}${BOS_RELEASE} -eq 41 ]]
    then
      platform=`${BOOTINFO} -T`
    else
      platform=`get_platform_value $(/usr/sbin/bootinfo -a)`
    fi
  fi

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

  # Remain NIM client after install?
  if [[ ${no_nim_client} = "no" ]]
  then
    remain_client="yes"
  fi

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

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

  # Force flag passed?  If so, certain flags are enforced -
  # for now, add the ability to skip bootability checks (-g)
  # maybe later, consider skipping space checks on target (-S)
  if [[ ${force} = "yes" ]]
  then
    skip_boot_check="yes"
  fi

  # Was the update_all keyword specified for fixes?  If so, pass it
  # on as a special bundle name to alt_disk_install.
  if [[ -n ${fixes} ]]
  then
    if [[ ${fixes} = "update_all" ]]
    then
      fixes=""
      installp_bundle="update_all"
      installp_bundle_access="update_all"
    fi
  fi
}

############################################################################
#
#  Name:        mount_resources
#
#  Function:    If resources were specified, then mount them
#               at specific mount points.
#
#  Returns:     Nothing
#
#  Parameters:  None
#
############################################################################
function mount_resources
{
  # use an exclude_files resource?
  if [[ -n "${exclude_files}" ]]
  then
    nim_mount ${exclude_files} ${exclude_files_access}
  fi

  # use a fix_bundle resource?
  if [[ -n "${fix_bundle}" ]]
  then
    nim_mount ${fix_bundle} ${fix_bundle_access}
  fi

  # use a installp_bundle resource?
  if [[ -n "${installp_bundle}" ]]
  then
    # installp_bundle_access would only have been set to "update_all"
    # if special processing was done to convert "fixes=update_all" to
    # the bundle keyword expected by alt_disk_install.  If that is the
    # case, we don't want to mount anything for the installp_bundle.
    if [[ ${installp_bundle_access} != "update_all" ]]
    then
      nim_mount ${installp_bundle} ${installp_bundle_access}
    fi
  fi

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

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

  # use a mksysb resource?
  if [[ -n "${mksysb}" ]]
  then
    nim_mount ${mksysb} ${mksysb_access}
  fi

  # use a resolv_conf resource?
  if [[ -n "${resolv_conf}" ]]
  then
    nim_mount ${resolv_conf} ${resolv_conf_access}
  fi

  # use a script resource?
  if [[ -n "${script}" ]]
  then
    nim_mount ${script} ${script_access}
  fi
}

############################################################################
#
#  Name:        c_alt_disk_install
#
#  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

# 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

# set flags based on input attrs
set_flags

# mount resources to local access points.
mount_resources

# update the state of the client object
${NIMCLIENT} -R success

# 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}

# Before we begin, let's make sure we have the
# latest version of alt_disk_install code for vios
# (IFF found in the mksysb)
if [[ "$NIM_CONFIGURATION" = "vios" ]] && \
   [[ -n $mksysb_access ]]; then

	get_fileset_level bos.alt_disk_install.rte

	if (( $version < 7 ))
	then
        	ios_version=`/usr/ios/cli/ioscli ioslevel | ${AWK} -F. '{print $1}'`
		if [[ $ios_version -lt 3 ]]; then
			
			INSTALL_IMAGE="./usr/sys/inst.images/installp/ppc/bos.alt_disk_install"
			
			cd ${TMPDIR} 2>${ERR}
			${RESTORE} -xqf ${mksysb_access} ${INSTALL_IMAGE} >/dev/null 2>${ERR}
			
			if [[ $? -eq 0 ]]; then
				${INUTOC} ${INSTALL_IMAGE%/*} 2>/dev/null
				${INSTALLP} -e $INSTALLP_LOG -agXbd ${INSTALL_IMAGE%/*} bos.alt_disk_install.rte \
					2>${ERR} || warning_from_cmd ${INSTALLP}
				${RM} -f ${INSTALL_IMAGE} 2>/dev/null
			else
				warning_from_cmd "${RESTORE} -xqf ${mksysb_access} ${INSTALL_IMAGE}"
			fi
		fi
        fi
	# mksysb to (alt)disk requires special support for VIOS -
	# due to clustering, name resolution must be intact.
	# If nim hasn't provided a resolv.conf, then add local
	# path and determine validity.
	if [[ -z $resolv_conf ]] && \
	   [[ -e "$RESOLV_CONF" ]]; then
		resolv_conf=local
		resolv_conf_access=$RESOLV_CONF
	fi
fi

${ALT_DISK_INSTALL} \
 -N \
 ${source_device} \
 ${image_data:+-i $image_data_access} \
 ${script:+-s $script_access} \
 ${resolv_conf:+-R $resolv_conf_access} \
 ${show_debug:+-D} \
 ${no_bootlist:+-B} \
 ${remain_client:+-n} \
 ${phase:+-P "$phase"} \
 ${platform:+-p $platform} \
 ${installp_bundle:+-b $installp_bundle_access} \
 ${installp_flags:+-I $installp_flags} \
 ${lpp_source:+-l $lpp_source_access} \
 ${fix_bundle:+-f $fix_bundle_access} \
 ${fixes:+-F "$fixes"} \
 ${exclude_files:+-e $exclude_files_access} \
 ${filesets:+-w "$filesets"} \
 ${skip_boot_check:+-g} \
 ${verbose_output:+-V} \
 ${disk} >> ${ALT_DISK_INSTALL_LOG} 2>&1

# 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}

# Update state on master.  Report errors if the operation failed.
if [[ ${adi_rc} -eq 0 ]]
then
  ${NIMCLIENT} -o change -aforce=yes -aignore_lock=yes \
              -ainfo=""

  ${NIMCLIENT} -R success

  # Reboot the client?
  if [[ ${boot_client} = "yes" ]]
  then
    ${SHUTDOWN} -Fr
  fi

else

  err_txt=`${C_ERRMSG} ${ERR_CMD} \
           ${C_ERRMSG_ERR} "${C_ALT_DISK_INSTALL}" \
           "${ALT_DISK_INSTALL}" "" "" 2>&1`
  ${NIMCLIENT} -o change -aforce=yes -aignore_lock=yes \
              -aerr_info="$( print ${err_txt} )"
  err_txt=`${C_ERRMSG} ${MSG_SEE_LOG_FILE} \
           ${C_ERRMSG_MSG} "${ALT_DISK_INSTALL_LOG}" \
           "" "" "" 2>&1`
  ${NIMCLIENT} -o change -aforce=yes -aignore_lock=yes \
              -aerr_info="$( print ${err_txt} )"

  ${NIMCLIENT} -R failure
fi

# success
exit 0
