#!/bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# bos720 src/bos/usr/lib/nim/methods/mkts.sh 1.14 
#  
# Licensed Materials - Property of IBM 
#  
# COPYRIGHT International Business Machines Corp. 2006,2009 
# 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 
# @(#)89    1.14  src/bos/usr/lib/nim/methods/mkts.sh, cmdnim, bos720  4/29/09  08:46:40
#
#   COMPONENT_NAME: CMDNIM
#
#   FUNCTIONS: ./usr/lib/nim/methods/mkts.sh
#
#   ORIGINS: 27
#


NIMPATH=/usr/lpp/bos.sysmgt/nim
NIM_METHODS="${NIMPATH}/methods"
export NIMPATH NIM_METHODS
. ${NIM_METHODS}/c_sh_lib
. ${NIM_METHODS}/libcosi

# --------------------------- module globals
devicetype=""
level=""
local=""
ARGUMENT=""
FILESYSTEM=""

# --------------------------------------------------------------------------- #
# NAME:         usage
#
# FUNCTION:     Print usage message
#
# PARAMETERS:   None.
#
# RETURNS:      0 - successful function execution
# --------------------------------------------------------------------------- #
function usage {

	/usr/bin/dspmsg -s ${MSG_SET} cmdnim.cat ${MSG_MKTS_USAGE} \
		'%1$s -i IPAddress -m SubnetMask -g Gateway -c COSI\n\
[-s Speed] [-d Duplex] [-p Size] [-H | -h] [-t] [-l] [-v] [-D] \ThinServer\n' "${PROGNAME}"

	return 0
}

# --------------------------------------------------------------------------- #
# NAME:         ck_attr
#
# FUNCTION:     Check for valid attribute.
#
# PARAMETERS:   None.
#
# RETURNS:      0 - valid attribute
#               1 - invalid attribute
# --------------------------------------------------------------------------- #
function ck_attr {

	# Check the following global flag:
	# ARGUMENT
	# ipaddr
	# mask
	# gatway
	# cosi
	# psize

	ck_user || return 1

	if [[ -z $ARGUMENT || -z $ipaddr || -z $gateway || -z $mask ]] ||
           [[ -n $shared_home && -n $home ]] ||
	   [[ $(echo $ARGUMENT | wc -w) -gt 1 ]]; then
		usage
		return 1
	fi

	if [[ $(obj_exist "master" $ARGUMENT; echo $?) -eq 0 ]]; then
		/usr/bin/dspmsg -s ${MSG_SET} cmdnim.cat ${MSG_CMD_EXISTS} \
                        '%1$s: \"%2$s\" already exists.\n' "${PROGNAME}" "${ARGUMENT}"
		return 1
	fi

	if [[ -z $cosi ]] || [[ $(obj_exist "master" $cosi; echo $?) -ne 0 ]]; then 
		/usr/bin/dspmsg -s ${MSG_SET} cmdnim.cat ${MSG_CMD_NOT_EXIST} \
                        '%1$s: \"%2$s\" does not exist.\n' "${PROGNAME}" "${cosi}"
                /usr/bin/dspmsg -s ${MSG_SET} cmdnim.cat ${MSG_COSI_REQUIRED} \
                        '%1$s: A common image is required.\n' "${PROGNAME}"
		usage 
		return 1
	else
		if [[ `get_attr_value "master" "$cosi" "type"` != "spot" ]]; then
			/usr/bin/dspmsg -s ${MSG_SET} cmdnim.cat ${MSG_NOT_COSI} \
				'%1$s: \"%2$s\" is not a common OS image.\n' "${PROGNAME}" "${cosi}"
			return 1
		fi
	fi

        if [[ -s /var/adm/ras/eznim.cfg ]]; then
                . /var/adm/ras/eznim.cfg
                location=${EZNIM_FS}
	elif [[ $(/usr/sbin/lsfs /export/nim >/dev/null 2>&1; echo $?) -eq 0 ]]; then
		location=/export/nim
        else
                res_loc=`get_attr_value "master" $cosi "location"`
		location=`LANG=C /usr/bin/df -m $res_loc | /usr/bin/awk '(NR==2) {print $7}'`
        fi

        ck_ipaddr "client"  $ipaddr  || return 1
        ck_ipaddr "gateway" $gateway || return 1
        ck_ipaddr " mask"   $mask    || return 1

	if [[ -n $psize ]]; then
		if [[ $psize != +([0-9]) ]]; then
			/usr/bin/dspmsg -s ${MSG_SET} cmdnim.cat ${MSG_BAD_ARG} \
				'Bad argument assignment : %s\n' "${psize}"
			return 1
		fi
		[[ $psize -lt 64 ]] && psize="512"
	else
		# 512mb is the new default paging size (#654603)
		psize="512"
	fi	


	[[ -z $server ]] && server="master"
	[[ -z $speed  ]] && speed=100      || ck_speed  $speed  || return 1
	[[ -z $duplex ]] && duplex=full    || ck_duplex $duplex || return 1

        return 0
}

# --------------------------------------------------------------------------- #
# NAME:         define_ts
#
# FUNCTION:     Define the dataless client.
#
# PARAMETERS:   None.
#
# RETURNS:      0 - nim environment exist
#               1 - unable to determine environment
# --------------------------------------------------------------------------- #
function define_ts {

	typeset name=$1
	typeset type=$2
	typeset ipaddr=$3
	typeset mask=$4
	typeset gateway=$5
	typeset cosi=$6
	typeset speed=$7
	typeset duplex=$8
	typeset psize=$9
	typeset rc=0

	res_loc=`get_attr_value "master" $cosi "location"`
	inst_root_sz=`LANG=C /usr/bin/du -sm "${res_loc}/lpp/bos/inst_root" | /usr/bin/awk '{print $1}'`
	if [[ $type = "diskless" ]]; then
                if [[ -n $psize ]]; then
                        let inst_root_sz=inst_root_sz+$psize
                else
                        let inst_root_sz=inst_root_sz+512
                fi
        fi

	root_loc=`get_attr_value "master" "root" "location"`
	fs_info=`LANG=C /usr/bin/df -m ${root_loc} | /usr/bin/awk '(NR==2){print $3":"$7}'`
	fs_sz=${fs_info%%:*}
	root_loc=${fs_info##*:}
	/usr/bin/dspmsg -s ${MSG_SET} cmdnim.cat ${MSG_SPACE_FS} 'Checking %s space requirement...' $root_loc

	if (( $inst_root_sz > $fs_sz )); then
		let inst_root_sz=inst_root_sz+10
		/usr/sbin/chfs -a size=+${inst_root_sz}M $root_loc
		if [[ $? -ne 0 ]]; then
			return 1
		fi
	fi

	# resolve client ip address to hostname
	clientname=`/usr/bin/host ${ipaddr} | /usr/bin/cut -f1 -d" " | /usr/bin/cut -f1 -d"."`

	if [[ -n $clientname ]]; then
		/usr/bin/dspmsg -s ${MSG_SET} cmdnim.cat ${MSG_DEFINING_OBJECT} 'Defining %1$s object...' "${name}"
		/usr/sbin/nim -o define -t $type  \
			-a if1="find_net ${clientname} 0" -a cable_type1=N/A \
			-a netboot_kernel=mp -a net_definition="ent ${mask} ${gateway}" \
			-a net_settings1="$speed $duplex" -a comments="$type client defined with mkts" ${name} 
	        if [[ $(obj_exist "master" $name; echo $?) -ne 0 ]]; then
			/usr/bin/dspmsg -s ${MSG_SET} cmdnim.cat ${MSG_FAILED} 'failed\n'
        	        return 1
	        fi
		/usr/bin/dspmsg -s ${MSG_SET} cmdnim.cat ${MSG_DONE} 'done\n'
	else
		return 1
	fi

# Remote Dump specific function,  only. dump_$cosi needs to be removed, eventually
	arg_string="-a spot=$cosi -a root=root \
		    ${dump:+-a dump=dump_$cosi} \
		    ${psize:+-a size=$psize} \
                    ${home:+-a home=$home} \
                    ${shared_home:+-a shared_home=$shared_home} \
		    ${tmp:+-a tmp=$tmp} \
		    ${resolv_conf:+-a resolv_conf=$resolv_conf}"

        /usr/bin/dspmsg -s ${MSG_SET} cmdnim.cat ${MSG_ROOT_SYNC_DD_CLIENTS_INST} \
        	'\n Installing software in the root directories of any diskless or dataless\n\ clients served by this SPOT.  This may take several minutes ...\n\n' "${PROGNAME}" "${cosi}"

	if [[ $type = "diskless" ]]; then
		/usr/sbin/nim -o dkls_init $arg_string -a paging=paging ${name}
	else
		/usr/sbin/nim -o dtls_init $arg_string ${name}
	fi

	if [[ $? -ne 0 ]]; then 
		undo
	fi

	return $?
}


# --------------------------------------------------------------------------- #
# NAME:         undo
#
# FUNCTION:     Remove the thinserver being define on error
#
# PARAMETERS:   None.
#
# RETURNS:      1 - always return 1
# --------------------------------------------------------------------------- #
function undo {

	if [[ $(obj_exist "master" $ARGUMENT; echo $?) -eq 0 ]]; then
		rmts -f "$ARGUMENT"
	fi

	return 1
}

# --------------------------------------------------------------------------- #
# NAME:         mkts_res
#
# FUNCTION:     Make thinsever resources.
#
# PARAMETERS:   None.
#
# RETURNS:      0 - successful
#               1 - unsuccessful
# --------------------------------------------------------------------------- #
function mkts_res {

	[[ $(obj_exist "master" root;   echo $?) -ne 0 ]] && (define_res "root"   root   $server $location/root   || return 1)
	if [[ $dump = "yes" ]]; then
		# POC only dump_$cosi
		[[ $(obj_exist "master" dump_$cosi;   echo $?) -ne 0 ]] && (define_res dump "dump_$cosi" $server $location/dump_$cosi   || return 1)
	fi
#	[[ $(obj_exist "master" dump;   echo $?) -ne 0 ]] && (define_res "dump"   dump   $server $location/dump   || return 1)
	[[ $(obj_exist "master" paging; echo $?) -ne 0 ]] && (define_res "paging" paging $server $location/paging || return 1)

        if [[ $shared_home = "yes" ]]; then
		if [[ $(obj_exist "master" shared_home; echo $?) -ne 0 ]]; then
			mkpath $location/shared_home || return 1			
			define_res "shared_home" shared_home $server $location/shared_home || return 1
		fi
		shared_home="shared_home"
	fi

	if [[ $tmp = "yes" ]]; then
		if [[ $(obj_exist "master" tmp; echo $?) -ne 0 ]]; then
			define_res "tmp" tmp $server $location/tmp || return 1
		fi
		tmp="tmp"
	fi

	if [[ $home = "yes" ]]; then
		if [[ $(obj_exist "master" home; echo $?) -ne 0 ]]; then
			define_res "home" home $server $location/home || return 1
		fi
		home="home"
	fi

	if [[ $(obj_exist "master" master_net_conf; echo $?) -ne 0 ]]; then
		if [[ ! -s "${location}/resolv.conf" ]]; then
			cp_file /etc/resolv.conf "${location}/resolv.conf" 
			if [[ $? -eq 0 ]]; then 
				define_res "resolv_conf" master_net_conf $server $location/resolv.conf 2>/dev/null
				[[ $? -eq 0 ]] && resolv_conf="master_net_conf"
			fi 
		fi
	fi

	return 0
}

# ----------------------------------- mkts ---------------------------------- #
#
# NAME: mkts
#
# FUNCTION:	 /usr/sbin/mkts command 
#
# NOTES:
#
# RETURNS: (int)
#	0	= SUCCESS
#	1	= FAILURE
#
# --------------------------------------------------------------------------- #
trap cleanup 0
trap 'undo' 1 2 11 15

# NIM initialization
nim_init

# set parameters from command line
while getopts :Hc:d:g:hi:lm:p:s:tvD x
do
	case ${x} in

		H)	# Specify that the Shared_home resource should be use.
			shared_home=yes
			;;

		c)	# Specify the common image.
			cosi=${OPTARG}
			;;

		d)	# Specify the duplex setting.
			duplex=${OPTARG}
			;;

		g)	# Specify the gateway for the thinserver
			gateway=${OPTARG}
			;;

		h)	# Specify that the home resource should be use.
			home=yes
			;;

		i)	# Specify the ipaddress for the thinserver
			ipaddr=${OPTARG}
			;;

		l)	# Specify whether local resources should be used
			# for the thinserver, (diskless)
			local=yes
			;;

		m)	# Specify the subnetmask for the thinserver
			mask=${OPTARG}
			;;

		p)	# Specify the paging size for the thinserver
			psize=${OPTARG}
			;;

		s)	# Specify the speed setting for the thinserver.
			speed=${OPTARG}
			;;

		t)	# Specify the tmp resource should be use
			tmp=yes
			;;

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

		D)	# Specify a dump device is needed
			dump=yes
			;;

		\?)	# unknown option
			usage
			exit 1
			;;
	esac
done

shift $((OPTIND - 1))

# The ARGUMENT is the name of the thinserver to be created.
ARGUMENT=$*

ck_nim_env  || exit 1
ck_attr	    || exit 1
mkts_res    || exit 1

if [[ $local = "yes" ]]; then
	define_ts "${ARGUMENT}" "diskless" $ipaddr $mask $gateway $cosi $speed $duplex $psize || exit 1
else
	define_ts "${ARGUMENT}" "dataless" $ipaddr $mask $gateway $cosi $speed $duplex $psize || exit 1
fi

rc=$?
exit $rc

# end of script
