#!/bin/ksh # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # bos72L src/bos/usr/lib/nim/methods/c_instspot.sh 1.72.5.4 # # Licensed Materials - Property of IBM # # COPYRIGHT International Business Machines Corp. 1993,2018 # 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 # @(#)13 1.72.5.4 src/bos/usr/lib/nim/methods/c_instspot.sh, cmdnim, bos72L, l2018_27A2 6/27/18 17:51:46 # # COMPONENT_NAME: CMDNIM # # FUNCTIONS: ./usr/lib/nim/methods/c_instspot.sh # # ORIGINS: 27 # # # (C) COPYRIGHT International Business Machines Corp. 1993, 1995, 1996 # 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 -------------------------------- SPOT_INSTALLP_FLAGS="-agqQb" #---------------------------- module globals -------------------------------- REQUIRED_ATTRS="location name" OPTIONAL_ATTRS="lpp_source installp_bundle installp_flags filesets auto_expand fixes fix_bundle show_progress mount_opts force" location="" lpp_source="" src_access="" ext_access="" name="" installp_bundle="" bundle_access="" installp_flags="" filesets="" spot_fs="" auto_expand="" installp_env_variable="" fileset_list="" non_41_master="" check_hooks="" default_spot_options_set="" tape_source="" geninstall_cmd="" updts="" force="" #---------------------------- undo -------------------------------- # # NAME: undo # # FUNCTION: # backs out changes made by c_instspot # # EXECUTION ENVIRONMENT: # # NOTES: # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # 1-> = error message stuff # global: # # RETURNS: (int) # # OUTPUT: #------------------------------------------------------------------------------- function undo { nim_unmount # umount anything which has been mounted by nim_mount [[ $# = 1 ]] && err_from_cmd $1 || error $@ } # end of undo #---------------------------- prep_tape -------------------------------- # # NAME: prep_tape # # FUNCTION: # prepares the specified tape device for use # # EXECUTION ENVIRONMENT: # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # 0 = success # # OUTPUT: #------------------------------------------------------------------------------- function prep_tape { typeset bs="" # tape needs a "no-rewind-on-close" extension # remove whatever extension was given and use ".1" src_access="${lpp_source%.*}.1" # cache the logical device name of the tape drive tape_device_name=${lpp_source##*/} tape_device_name=${tape_device_name%.*} # get current block_size bs=$( ${LSATTR} -El ${tape_device_name} 2>${ERR} | \ ${AWK} '$1=="block_size"{print $2}' ) [[ -z "${bs}" ]] && err_from_cmd ${LSATTR} # block_size needs to be 512: should we change it? if [[ ${bs} != 512 ]] then ${CHDEV} -l ${tape_device_name} -a block_size=512 1>/dev/null 2>${ERR} ||\ err_from_cmd ${CHDEV} # by setting the global "tape_block_size" var, the cleanup function will # reset the block_size to the original value tape_block_size=${bs} fi # rewind the tape ${TCTL} -f ${src_access} rewind 2>${ERR} || err_from_cmd tctl # set a flag to indicate that the image source is a tape tape_source="yes" } # end of prep_tape #---------------------------- prep_cd -------------------------------- # # NAME: prep_cd # # FUNCTION: # prepares a CDROM device as the source for a SPOT # # EXECUTION ENVIRONMENT: # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # 0 = success # # OUTPUT: #------------------------------------------------------------------------------- function prep_cd { ${CDCHECK} -aq $lpp_source 2>/dev/null 1>&2 if [[ $? -eq 0 ]]; then export AUTOMOUNT_DISABLE_FLAG="true" ${CDCHECK} -mq $lpp_source 2>/dev/null 1>&2 if [[ $? -eq 0 ]]; then lpp_source=`${CDCHECK} -mq $lpp_source 2>/dev/null` fi fi # mount the CDROM at a specific offset nim_mount ${lpp_source} ${new_root}${IMAGES} # images are actually at another offset [[ ! -d "${new_root}${IMAGES}${OFFSET_FOR_CDROM}" ]] && \ OFFSET_FOR_CDROM=${OFFSET_FOR_CDROM_OLD} src_access=${IMAGES}${OFFSET_FOR_CDROM} ext_access=${new_root}${src_access} } # end of prep_cd #---------------------------- prep_dir -------------------------------- # # NAME: prep_dir # # FUNCTION: # prepares environment to use a directory as the source for installp images # # EXECUTION ENVIRONMENT: # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # 0 = success # # OUTPUT: #------------------------------------------------------------------------------- function prep_dir { # need to mount lpp_source if it's remote or this is non-/usr SPOT if [[ ${lpp_source} = ?*:?* ]] || [[ -n "${new_root}" ]] then # mount images at a specific offset nim_mount ${lpp_source} ${new_root}${IMAGES} src_access=${IMAGES} ext_access=${new_root}${src_access} else # use the local directory src_access=${lpp_source} fi } # end of prep_dir #---------------------------- prep_source -------------------------------- # # NAME: prep_source # # FUNCTION: # prepares the specified source device for use # # EXECUTION ENVIRONMENT: # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # 0 = success # # OUTPUT: #------------------------------------------------------------------------------- function prep_source { typeset objrepos=${new_root}/etc/objrepos typeset i="" # what kind of source? if [[ "${lpp_source}" = /dev/* ]] || [[ -f "${lpp_source}" ]]; then # non-/usr SPOT? if [[ ${location} != /usr ]] then # we need to use the server's device database in order to # access the specified device once we chroot into the SPOT # to do this, we'll copy the server's Cu* database into the # SPOT, then create an undo_on_exit script to clean out # the SPOT's database # Save the original CuDvDr in the spot, since it contains # default entries that are needed in the network boot image. ${CP} ${objrepos}/CuDvDr ${objrepos}/CuDvDr.spot 2>${ERR} || err_from_cmd ${CP} for i in /etc/objrepos/Cu* do # copy the object class into the SPOT ${CP} ${i} ${objrepos} 2>${ERR} || err_from_cmd ${CP} # cleanup the SPOT's database when we're done [[ ${i} != ?*.vc ]] && \ print "ODMDIR=${objrepos} ${ODMDELETE} -o ${i} > /dev/null 2>&1" >> \ ${TMPDIR}/undo_on_exit done # Move the original CuDvDr back. print "${MV} ${objrepos}/CuDvDr.spot ${objrepos}/CuDvDr > /dev/null 2>&1" >> ${TMPDIR}/undo_on_exit fi # tape or CDROM? if [[ ${lpp_source} = /dev/rmt[0-9]* ]] then prep_tape elif [[ ${lpp_source} = /dev/cd[0-9]* ]] ||[[ ${lpp_source} = /dev/usbms[0-9]* ]] || [[ -f "${lpp_source}" ]] then prep_cd else error ${ERR_SYS} "invalid lpp_source device \"${lpp_source}\"" fi elif [[ -d "${lpp_source}" ]] || [[ "${lpp_source}" = */* ]]; then # source is a directory prep_dir else # unknown type error ${ERR_SYS} "unknown lpp_source type - \"${lpp_source}\"" fi } # end of prep_source #--------------------------- ck_mand_updts_in_instp_output --------------------- # # NAME: ck_mand_updts_in_instp_output # # FUNCTION: # greps installp preview output for the existence of # specific keywords to indicate that the installp # command is about to be updated. This functionality # acts as a 2ndary check to the ${NIM_INSTP_UPDT_LIST} # file which will not be set by installp when older # SPOTs are being updated. # This routine populates the NIM_INSTP_UPDT_LIST file # with bos.rte.install fileset names if found in the # grepped output. # # # EXECUTION ENVIRONMENT: # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # ${TMPDIR}/installp.preview = output file from installp # preview operation as set # in ck_required_space # # RETURNS: (int) # 0 = installp updates found in the preview operation # AND # installation of other filesets have been deferred # 1 = installp updates not found in the preview operation # # OUTPUT: #------------------------------------------------------------------------------- function ck_mand_updts_in_instp_output { INSTP_PREV_OUT=${TMPDIR}/installp.preview # Look for all output between the two substrings indicated ${AWK} '/SUCCESSES/,/End of Success Section/ {print}' \ ${INSTP_PREV_OUT} | \ # grep the resultant paragraph which should include # the installp fileset names ${GREP} -p "Mandatory Fileset Updates" 2>/dev/null | \ # grep the installp updates themselves and save in # a file that will ultimately be used by the caller ${GREP} bos.rte.install | ${AWK} -F"#" '{print $1}' | \ ${GREP} bos.rte.install \ > ${NIM_INSTP_UPDT_LIST} 2>/dev/null if [ $? -ne 0 ] then ${RM} ${NIM_INSTP_UPDT_LIST} return 1 fi # Ensure that there are other filesets to install after the # installp updates are installed by grepping the installp # pre-installation summary to see if any were deferred. ${GREP} -p "FILESET STATISTICS" ${INSTP_PREV_OUT} 2>/dev/null | \ ${GREP} -q "Deferred" if [ $? -ne 0 ] then ${RM} ${NIM_INSTP_UPDT_LIST} return 1 fi return 0 } #---------------------------- ck_required_space -------------------------------- # # NAME: ck_required_space # # FUNCTION: # uses the preview option on installp to determine how much space is # required for the operation # # EXECUTION ENVIRONMENT: # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # 1 = installp flags to use # 2 = non-NULL if auto expand used # 3 = d_flag # 4 = f_flag # 5 = filesets # global: # location # spot_fs # # RETURNS: (int) # 0 = enough room for operation # # OUTPUT: #------------------------------------------------------------------------------- function ck_required_space { typeset installp_flags=${1} typeset auto_expand=${2} typeset d_flag=${3} typeset f_flag=${4} typeset filesets=${5} typeset filesystem="" typeset -i required=0 typeset -i available=0 typeset -i additional=0 # check the available space in the SPOT and auto expand if necessary. # use the preview option with installp to get the space it needs # NOTE that we set the appropriate installp environment variable in order # to make it behave correctly in the NIM environment ${installp_env_variable} # Temporarily set the language variable since we may be grepping # installp output for translatable keywords OLD_LANG=${LANG} export LANG=C ${chroot} ${geninstall_cmd:-$INSTALLP -pk $installp_flags} \ ${geninstall_cmd:+-p -I "-k $installp_flags"} \ ${d_flag} ${f_flag} ${filesets} \ ${TMPDIR}/installp.preview 2>&1 export LANG=${OLD_LANG} # if installp doesn't return anything, might as well continue [[ ! -s ${TMPDIR}/installp.preview ]] && return 0 # get the size info out of the file # NOTE that we have to jump through some hoops here because of the way in # which installp prints this information root=$( echo ${location} | ${AWK} -F "/" '{print $2}' ) # For /usr SPOTs, we need to remember the "/" size requirements to # check against free space in /usr before doing sync_root on # /usr/lpp/bos/inst_root. Save this information in a file in /tmp. [[ ${location} = "/usr" ]] && print 0 > ${INSTROOT_CUST_SZ} ${CAT} ${TMPDIR}/installp.preview | \ while read line do # ASSUMING installp preview info matches the following pattern: # field 1 = "_SIZE_" # field 2 = name of filesystem # field 3 = free space required to install into the filesystem # field 4 = currently available free space in the filesystem # does this line match our pattern? [[ "${line}" != _SIZE_?* ]] && continue set -- ${line} # ignore info if this is the "TOTAL" [[ "${2}" = TOTAL ]] && continue filesystem=${2} let "required=${3}" let "available=${4}" # add in a fudge factor of 10% let "required+=(required/10)+1" # Save "/" requirement for /usr SPOTs. [[ ${location} = "/usr" ]] \ && [[ ${filesystem} = "/" ]] \ && print ${required} > ${INSTROOT_CUST_SZ} # is there enough free space? if (( required > available )) then # auto expand? [[ "${auto_expand}" = "no" ]] && error ${ERR_SPACE} ${filesystem} ${required} ${available} # calculate additional space needed let "additional=required-available" # try to expand the filesystem ${CHFS} -a size=+${additional} ${filesystem} 2>${ERR} 1>&2 || \ err_from_cmd "${CHFS} ${filesystem}" fi done # If the preview op above detected an installp update on the media, # whether or not it was requested for installation, the preview # output only shows us size information for the update of the # installp fileset. Installp will tell us about this condition. # If it does we will apply all installp updates on the media before # calculating the space needed to install the rest of the filesets # that were requested. if [[ -s "${NIM_INSTP_UPDT_LIST}" ]] || ck_mand_updts_in_instp_output then # get the list of filesets printed by the installp command # then remove the file we used to communicate this info. instp_list=`${CAT} ${NIM_INSTP_UPDT_LIST}` ${RM} ${NIM_INSTP_UPDT_LIST} # expand the fs to help prevent the unarchive failures due to bos.rte ${CHFS} -a size=+65536 ${filesystem} 2>${ERR} 1>&2 # install the installp updates ${chroot} ${geninstall_cmd:-$INSTALLP -e $INSTALLP_LOG $installp_flags} \ ${geninstall_cmd:+-I "-e $INSTALLP_LOG $installp_flags"} \ ${d_flag} ${instp_list} \ ${ERR} 1>&2 || err_from_cmd ${INSTALLP} # Now see if there's enough space for the original # list of filesets. # NOTE THE RECURSION HERE! ck_required_space "${installp_flags}" \ "${auto_expand}" "${d_flag}" \ "${f_flag}" "${filesets}" fi } # end of ck_required_space #---------------------------- inst_spot -------------------------------- # # NAME: inst_spot # # FUNCTION: # installs the specified SPOT with the specified software # # EXECUTION ENVIRONMENT: # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # spot_fs = filesystem where SPOT resides # chroot = command to execute in order to be in correct env # for installp # new_root = pathname of new root dir # # RETURNS: (int) # 0 = success # # OUTPUT: #------------------------------------------------------------------------------- function inst_spot { typeset d_flag="" typeset f_flag="" typeset i="" typeset auto_expand="" typeset MKSPOT_PRE_I="_SPOT._.pre_i.usr.1.0.0.0" typeset MKSPOT_POST_I="_SPOT._.post_i.usr.1.0.0.0" # prevent savebase from writing to the system's boot disk (d1058970) export AIX_NO_SAVEBASE=1 # which filesystem is SPOT in? spot_fs=$( ${DF} -Pk ${location} 2>/dev/null | ${AWK} 'NR==2{print $6}' ) # setup the chroot environment # NOTE that we do this before the preparing the source device because local # access to the source needs to be mounted over the chroot environment chroot="" setup_chroot_env # Now ensure that the server's libraries mounted into the SPOT # will be used. ${SET_CHROOT_LIBPATH} # New versions ( > 4.x.x.x ) of bos.sysmgt use the GENINSTALL # command as opposed to INSTALLP # Get the version of the bos.rte.install fileset in # the SPOT lslpp_fileset=`${chroot} ${LSLPP} -lqcOu bos.rte.install` || \ err_from_cmd "${LSLPP} -lqcOu bos.rte.install" # only update TCB_STATE for non-/usr spots. if [[ -n "${new_root}" ]] && [[ $force != "yes" ]]; then # force TCB_STATE=tcb_enabled for spot installs with TCB=yes # this will make installp update the sysck.cfg from /usr/lib/instl/instal cat << END |${chroot} /usr/bin/odmchange -o PdAt -q "attribute like TCB_STATE" PdAt: uniquetype = "" attribute = "TCB_STATE" deflt = "tcb_enabled" values = "" width = "" type = "" generic = "" rep = "" nls_index = 0 END fi # end of TCB enable vrmf=`echo $lslpp_fileset | ${CUT} -d":" -f3` version=`echo ${vrmf} | ${CUT} -d"." -f1` # set geninstall_cmd (if needed) # version is obtained from SPOT, set_geninst checks flags [[ ${version} > 4 ]] && set_geninst ${installp_flags} # if a source was specified, then prepare it for use if [[ -n "${lpp_source}" ]] then prep_source # use the "-d" installp option d_flag="-d ${src_access}" fi # Skip all this processing if the installp_flag is "-s" for # listing APPLIED software only. if [[ ${installp_flags} != "-s" ]] then # use a bundle file? if [[ -n "${installp_bundle}" ]] then prep_bundle # use the "-f" installp option f_flag="-f ${bundle_access}" filesets="" #fix_bundle specified? elif [[ -n "${fix_bundle}" ]] then # setup local access (use installp's bundle prep routine) installp_bundle=${fix_bundle} prep_bundle # convert list of fix keywords to list of filesets prep_instfix_lst "spot" "bun" "${bundle_access}" "${d_flag}" filesets="-f ${fileset_list}" # fixes specified? elif [[ -n "${fixes}" ]] then # "update_all" keyword specified? if [ "${fixes}" = "update_all" ] then # get list of fileset updates needing installation. prep_updt_all_lst "spot" "${d_flag}" if [ ! -s "${fileset_list}" ] then # print sm_inst error for "nothing to update" ${INUUMSG} 177 > ${ERR} 2>&1 err_from_cmd "c_instspot" fi filesets="-f ${fileset_list}" else # convert list of fix keywords to list of filesets prep_instfix_lst "spot" "fixes" "${fixes}" "${d_flag}" filesets="-f ${fileset_list}" fi elif [[ ${installp_flags} = *u* ]] || [[ ${installp_flags} = *r* ]] then # this is a deinstall operation: filesets must be specified [[ -z "${filesets}" ]] && error ${ERR_MISSING_ATTR} filesets elif [[ ${installp_flags} != *C* ]] then # this is an install operation: use default if filesets not specified if [ -z "${filesets}" ] then # Set the "lvl_type" and "lvl_source" variables # so they can be used later by the "set_option_lists" # routine. We need the lpp_source for this. # Use access_pnt, set up by nim_mount, if the # lpp_source is remote or is a cdrom; else use # the values appropriate for a tape source or a # local directory. # NOTE: don't use src_access because this is the # value that's used in the chroot'd env. if [[ ${lpp_source} = ?*:?* ]] then lvl_type="rte" [[ -e "${access_pnt}/installp/ppc/bos" ]] && \ lvl_source="${access_pnt}/installp/ppc/bos" || \ lvl_source="${access_pnt}/bos" elif [[ ${lpp_source} = /dev/cd[0-9]* ]] then lvl_type="rte" [[ ! -e "${access_pnt}${OFFSET_FOR_CDROM}/bos" ]] && \ OFFSET_FOR_CDROM=${OFFSET_FOR_CDROM_OLD} lvl_source="${access_pnt}${OFFSET_FOR_CDROM}/bos" elif [[ ${lpp_source} = /dev/rmt[0-9]* ]] then lvl_type="device" lvl_source="${lpp_source}" else lvl_type="rte" [[ -e "${lpp_source}/installp/ppc/bos" ]] && \ lvl_source="${lpp_source}/installp/ppc/bos" || \ lvl_source="${lpp_source}/bos" fi # call set_option_lists to set "DEFAULT_SPOT_OPTIONS" to # contain the list appropriate for the level of source. set_option_lists ${lvl_type} ${lvl_source} filesets="${DEFAULT_SPOT_OPTIONS}" default_spot_options_set=1 fi fi fi if [[ -n "${fixes}" ]] || [[ -n "${fix_bundle}" ]] then # if not doing an update_all, add B flag for safety # (so that base levels are not accidently instld via requisites) if [[ "${fixes}" != "update_all" ]] && \ [[ "${installp_flags}" != *B* ]] then installp_flags=${installp_flags}B fi fi # If the lpp_source is a tape, then do not prompt the user # to prepare the device. Add the q option if it is not # already there. if [[ -n "${tape_source}" ]] then if [[ "${installp_flags}" != *q* ]] then installp_flags="${installp_flags}q" fi fi # installp cannot expand in a chroot'd env. We need to do our own # checks and expansion if necessary. This is really only required # for non-/usr SPOT's, since installp can expand when installing into # /usr SPOTs. However, a sync_root takes place for the # /usr/lpp/bos/inst_root directory for /usr SPOTs. Therefore, we'll # call the space checking routine for either type of SPOT. if [[ ${installp_flags} = *X* ]] then # intercept the installp "X" flag for non-/usr SPOTs since # it won't work correctly and may expand the wrong filesystem. # # NOTE: installp seems to handle non-/usr SPOTs correctly now # so we will let the -X flag go through. There seems to # be a difference in the way NIM did space calculations and # the way installp does them. So, we should allow installp # the option of expanding also. # # if [[ ${location} != /usr ]] # then # installp_flags=$( echo ${installp_flags} | \ # ${AWK} '{gsub(/X/,"");print}' ) # fi auto_expand="yes" fi # check the available space in the SPOT and auto expand if # necessary (only when not doing installp preview) [[ "${installp_flags}" != *p* ]] && \ ck_required_space "${installp_flags}" "${auto_expand}" "${d_flag}" \ "${f_flag}" "${filesets}" # # Check to see if a previous installp flag file exists... # [[ -f ${MK_NETBOOT} ]] && ${RM} ${MK_NETBOOT} # install into the SPOT # NOTE that this may just be maintenance operation where no source or # bundle file is used (ie, this script can be invoked from m_instspot # or m_maintspot) # NOTE also that we set the appropriate installp environment variable in # order to make it behave correctly in the NIM environment ${installp_env_variable} # Disable the loader control controlling loader # handling of unresolved system calls export NOFORCE_KIMP_RES=1 # If there is a pre-installation hook provided in the lpp_source, # invoke it and error off if return code is non-zero if [[ -n ${check_hooks} ]] then if [[ ${lpp_source} != /dev/rmt[0-9]* ]] then if [[ -f ${ext_access}/${MKSPOT_PRE_I} ]] then ${ext_access}/${MKSPOT_PRE_I} ${location} ${ext_access} >${ERR} 2>&1 if [ $? -eq 0 ] then ${CAT} ${ERR} 2>&1 # display the output >${ERR} # wipe out all traces of error else err_from_cmd ${MKSPOT_PRE_I} fi fi fi fi # if using the default set of filesets to install into the # SPOT, then add bos.rte to the list if there is a bos.rte # fileset or update found on the install source. # (Not all media will contain something called bos.rte.) if [[ -n ${default_spot_options_set} ]] then ${chroot} ${geninstall_cmd:-$INSTALLP} ${tape_source:+-q} -L ${d_flag} | \ ${AWK} 'BEGIN {FS=":"} {print $2}' | \ ${GREP} "^bos.rte" > /dev/null 2>&1 if [[ $? -eq 0 ]] then updts="yes" fi # prepend I: to default_spot_options list -- for geninstall call if [[ -n ${geninstall_cmd} ]] then geninstall_list="" for i in `${ECHO} ${filesets}` do geninstall_list="${geninstall_list} I:${i} " done filesets="${geninstall_list}" fi fi # call the installp command differently depending upon the level of # master if [[ -z ${non_41_master} ]] then # Called from a 4.1 master... # if doing an installp preview, capture the output in ERR. # Cat the file to stdout if there were no errors, otherwise # do normal error handling. if [[ "${installp_flags}" = *p* ]] then ${chroot} ${INSTALLP} ${installp_flags} ${d_flag} \ ${f_flag} ${filesets} ${ERR} 2>&1 if [ $? -eq 0 ] then ${CAT} ${ERR} 2>&1 # display the output >${ERR} # wipe out all traces of error else err_from_cmd ${INSTALLP} fi else ${chroot} ${INSTALLP} ${E_FLAG} \ ${installp_flags} \ ${d_flag} ${f_flag} \ ${filesets} ${ERR} 1>&2 fi else if [[ ${show_progress} = "no" ]] then ${chroot} ${geninstall_cmd:-$INSTALLP $installp_flags $E_FLAG} \ ${geninstall_cmd:+-I "$installp_flags $E_FLAG"} \ ${d_flag} ${f_flag} ${filesets} ${ERR} 1>&2 else ${chroot} ${geninstall_cmd:-$INSTALLP $installp_flags $E_FLAG} \ ${geninstall_cmd:+-I "$installp_flags $E_FLAG"} \ ${d_flag} ${f_flag} ${filesets} 2>&1 fi fi # any updates to pull in? if [[ ${updts} = "yes" ]] then # get list of fileset updates needing installation. prep_updt_all_lst "spot" "${d_flag}" "${updts}" if [ -s "${fileset_list}" ] then filesets="-f ${fileset_list}" # check the available space in the SPOT and auto expand if # necessary (only when not doing installp preview) [[ "${installp_flags}" != *p* ]] && \ ck_required_space "${installp_flags}" "${auto_expand}" "${d_flag}" \ "${f_flag}" "${filesets}" # install the updates ${chroot} ${geninstall_cmd:-$INSTALLP $installp_flags $E_FLAG} \ ${geninstall_cmd:+-I "$installp_flags $E_FLAG"} \ ${d_flag} ${f_flag} ${filesets} 2>&1 fi fi # # Save installp return code for later.. # rc=$? # # If installp says make boot images, communicate this with mk_netboot # attr to the caller (different depending upon level of caller) # if [[ -n ${non_41_master} ]] then # save attr assignment in a status file for later processing. [[ -f ${MK_NETBOOT} ]] && echo "mk_netboot=yes" > ${NIM_STATUS} else # print attr assignment to stdout to be read by caller [[ -f ${MK_NETBOOT} ]] && echo "mk_netboot=yes" fi # If there is a post-installation hook provided in the lpp_source, # invoke it and error off if return code is non-zero if [[ -n ${check_hooks} ]] then if [[ ${lpp_source} != /dev/rmt[0-9]* ]] then if [[ -f ${ext_access}/${MKSPOT_POST_I} ]] then ${ext_access}/${MKSPOT_POST_I} ${location} ${ext_access} >${ERR} 2>&1 if [ $? -eq 0 ] then ${CAT} ${ERR} 2>&1 # display the output >${ERR} # wipe out all traces of error else # Make sure that any installp failures gets # reported, so only exit from here if installp # was clean... if [[ ${rc} != 0 ]] then warning_from_cmd ${MKSPOT_POST_I} >${ERR} else err_from_cmd ${MKSPOT_POST_I} fi fi fi fi fi # # Its later.. Now check the return code from installp. # if [[ ${rc} != 0 ]] then # Set variables used by error function to print out extra msg # about viewing the log. # (Only do this if called from a non-41 master) if [[ -n ${non_41_master} ]] then if [[ ${location} = /usr ]] then instp_err_log=${INSTALLP_LOG} else instp_err_log="${location}/lpp/bos/inst_root${INSTALLP_LOG}" fi export NIM_SHOW_PROGRESS=yes fi err_from_cmd ${INSTALLP} fi } # end of inst_spot #---------------------------- c_instspot -------------------------------- # # NAME: c_instspot # # FUNCTION: # installs the specified software into a SPOT # # EXECUTION ENVIRONMENT: # # NOTES: # this method does NOT create a SPOT - that work is done by c_mkspot # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # 0 = SPOT installed # 1 = error encountered - message on stderr # # OUTPUT: #------------------------------------------------------------------------------- # 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:qvfH 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}\" ;; 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 ;; f) # called from non-41 master non_41_master=1 ;; H) # check for the existence of SPOT creation hooks check_hooks=1 ;; \?) # unknown option error ${ERR_BAD_OPT} ${OPTARG} ;; esac done # check for missing attrs ck_attrs # call undo() on interrupt undo_on_interrupt="undo" # set defaults installp_flags=${installp_flags:-${SPOT_INSTALLP_FLAGS}} installp_flags=$( ck_installp_flags "${installp_flags}" ) # The -e flag (for specifying an alternate log file) will hide output for # listing operations. Therefore, we do not want to use the -e flag if we # are only performing installp listing operations. We will figure that # the operation is a listing operation if it isn't an apply (a), commit (c), # reject (r), or deinstall (u) operation. # Use sed to remove any "Ou" or "Or" combinations before grepping for # the action flags (acru). echo ${installp_flags} | ${SED} 's/Ou//' | ${SED} 's/Or//' | ${GREP} "[acru]" \ > /dev/null 2>&1 if [[ $? -eq 0 ]] then E_FLAG="-e ${INSTALLP_LOG}" fi # if auto_expand specified, make sure there's an "X" in the flags [[ "${auto_expand}" = "yes" ]] && [[ ${installp_flags} != *X* ]] && \ installp_flags="${installp_flags}X" # which installp environment variable should be used? # INUSERVERS = set for /usr SPOTs so that installp bypasses looking in the # /etc/niminfo file for the NIM_USR_SPOT variable # INUCLIENTS = set for non-/usr SPOTs so that installp doesn't create a # boot image and to prevent any install scripts from # mucking with device configuration ont the server if [[ ${location} = /usr ]] then installp_env_variable="export INUSERVERS=yes" # make sure "b" not passed installp_flags=$( echo ${installp_flags} | \ ${AWK} '{gsub(/b/,"");print}' ) else installp_env_variable="export INUCLIENTS=yes" fi # check for errors if [[ -n "${installp_bundle}" ]] && [[ -n "${filesets}" ]] then error ${ERR_ATTR_CONFLICT} installp_bundle filesets elif [[ -n "${fix_bundle}" ]] && [[ -n "${filesets}" ]] then error ${ERR_ATTR_CONFLICT} fix_bundle filesets elif [[ -n "${fixes}" ]] && [[ -n "${filesets}" ]] then error ${ERR_ATTR_CONFLICT} fixes filesets elif [[ -n "${fix_bundle}" ]] && [[ -n "${installp_bundle}" ]] then error ${ERR_ATTR_CONFLICT} fix_bundle installp_bundle elif [[ -n "${fix_bundle}" ]] && [[ -n "${fixes}" ]] then error ${ERR_ATTR_CONFLICT} fix_bundle fixes elif [[ ${installp_flags} = *a* ]] && [[ -z "${lpp_source}" ]] then error ${ERR_MISSING_ATTR} lpp_source fi # perform the install inst_spot # all done exit 0