#!/bin/ksh -p
#
# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#
# ident	"@(#)s9_servicetag.ksh	1.1	08/05/06 SMI"
#

# usage: s9_servicetag (-a | -X) [-R rootpath] [-m msgprefix] \
#            [-l logfile] zonename
#

MODE=
VERBOSE=
MSG_PREFIX="`basename $0`: "
STCLIENT=/usr/bin/stclient
BRANDNAME=solaris9

PRODUCT_NAME="Solaris 9 Containers"
PRODUCT_REV="1.0"
PRODUCT_INSTALLER="$PRODUCT_NAME $PRODUCT_REV Installer"
PRODUCT_UUID="urn:uuid:61d43591-01ad-11dd-8282-080020a9ed93"

v_gathering=$(gettext "Gathering information about zone %s")
e_badinfo=$(gettext "Failed to get '%s' zone resource")
e_notags=$(gettext "Service tags facility not present.")
v_servicetag_ok=$(gettext "Operation successful.")
e_servicetag_fail=$(gettext "Operation failed.  (Error %s)")
e_rnotsup=$(gettext "-R not supported in this mode.")
v_delall=$(gettext "Deleting service tags for %s on %s")
v_delete=$(gettext "Deleting tag %s")
v_reconfig=$(gettext "Reconfiguring service tags for %s on %s")

usage()
{
	echo "$0 (-a | -C | -X) [-R rootpath] [-m msgprefix] [-l logfile] zonename" >&2
	exit 1
}

# Log passed arguments to file descriptor 2
error()
{
        typeset fmt="$1"
        shift

        printf "${MSG_PREFIX}ERROR: ${fmt}\n" "$@"
        [[ -n $LOGFILE ]] && \
	    printf "[`date`] ${MSG_PREFIX}ERROR: ${fmt}\n" "$@" >&2
}

# Print and log provided text if the shell variable "verbose_mode" is set
verbose()
{
        typeset fmt="$1"
        shift

        [[ -n $VERBOSE ]] && printf "${MSG_PREFIX}${fmt}\n" "$@"
        [[ -n $LOGFILE ]] && printf "[`date`] ${MSG_PREFIX}${fmt}\n" "$@" >&2
}

#
# Add a Service Tag for a given zone.  We use two UUIDs-- the first,
# the Product UUID, comes from the Sun swoRDFish ontology.  The second
# is the UUID of the zone itself, which forms the instance UUID.
#
# It is an error to call add_tag on a zone
#
add_tag()
{
        typeset ZONENAME="$1"

	verbose "$v_gathering" "$ZONENAME"

	ZONEBRAND=`zoneadm -R $BASEDIR -z $ZONENAME list -p | nawk -F: '{print $6}'`
	if [ $ZONEBRAND != $BRANDNAME ]; then
		error "$e_badinfo" "brand"
		error "$e_exitfail"
		return 1
	fi

	ZONEUUID=`zoneadm -R $BASEDIR -z $ZONENAME list -p | nawk -F: '{print $5}'`
	if [[ $? -ne 0 || -z $ZONEUUID ]]; then
		error "$e_badinfo" "uuid"
		return 1
	fi

	INSTANCE_UUID="urn:st:${ZONEUUID}"
	verbose "Adding service tag: $INSTANCE_UUID"

	$STCLIENT -a \
	    -p "$PRODUCT_NAME" \
	    -e "$PRODUCT_REV" \
	    -t "$PRODUCT_UUID" \
	    -i "$INSTANCE_UUID" \
	    -P "none" \
	    -m "Sun" \
	    -A "sparc" \
	    -z "global" \
	    -r "$BASEDIR" \
	    -S "$PRODUCT_INSTALLER" 1>&2

	err=$?

	# 226 means "duplicate record," which we can ignore.
	if [[ $err -ne 0 && $err -ne 226 ]]; then
		error "$e_servicetag_fail" "$err" 
		return 1
	fi
	verbose "$v_servicetag_ok"
	return 0
}

delete_all()
{
        $STCLIENT -f -t "$PRODUCT_UUID" -r $BASEDIR | \
                while read uuid; do
			verbose "$v_delete" "$uuid"
			
                        stclient -d -i "$uuid" -r $BASEDIR >/dev/null 2>&1
                done
	return 0
}

add_all()
{
	zoneadm -R $BASEDIR list -cp | \
	    nawk -F: '{printf("%s %s %s\n", $2, $3, $6);}' |
                while read name state brand; do
			if [[ $brand = $BRANDNAME && \
			    $state != "configured" ]]; then
				add_tag $name || return 1
			fi
                done
}

unset LD_LIBRARY_PATH
PATH=/usr/sbin:/usr/bin
export PATH

# Setup i18n output
TEXTDOMAIN="SUNW_OST_OSCMD"
export TEXTDOMAIN

BASEDIR=/
export BASEDIR
#
# Parse the command line options.
#
while getopts "aACl:m:vR:X" opt
do
	case "$opt" in
		a)	MODE="add";;
		C)	MODE="reconfigure";;
		X)	MODE="delete-all";;
		l)	LOGFILE="$OPTARG";;
		m)	MSG_PREFIX="$OPTARG";;
		R)	BASEDIR="$OPTARG";;
		v)	VERBOSE=1;;
		*)	usage;;
	esac
done
shift OPTIND-1

if [[ $MODE = "add" ]]; then
 	if [[ $# -ne 1 ]]; then
		usage
	fi
else
 	if [[ $# -ne 0 ]]; then
		usage
	fi
fi

if [ -z $MODE ]; then
	usage
fi

if [[ -n $LOGFILE ]]; then
	exec 2>>$LOGFILE
fi

ZONENAME=$1
export ZONENAME

#
# If servicetags is not present, just exit gracefully.
#
if [ ! -x /usr/bin/stclient ]; then
	verbose "$e_notags"
	exit 0
fi

if [[ $MODE = "add" ]]; then
	if [[ $BASEDIR != "/" ]]; then
		error "$e_rnotsup"
		error "$e_exitfail"
		exit 1;
	fi
	add_tag "$ZONENAME" || error "$e_exitfail"; exit 1

elif [[ $MODE = "delete-all" ]]; then
	verbose "$v_delall" "$PRODUCT_NAME" "$BASEDIR"
	delete_all || error "$e_exitfail"; exit 1

elif [[ $MODE = "reconfigure" ]]; then
	#
	# Reconfigure is a sort of forceable "fix it."  We also use
	# this at postinstall time-- it's possible to add the solaris9
	# brand package, make some zones, remove the package, and then
	# add it back.  To support that, we do a "reconfigure" to
	# [re-]add the service tags at postinstall time.
	#
	verbose "$v_reconfig" "$PRODUCT_NAME" "$BASEDIR"
	(delete_all && add_all ) || error "$e_exitfail"; exit 1
fi

exit 0
