#!/usr/bin/ksh
#
# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
#
# ident	"@(#)svc-ocm	1.8	13/09/04 SMI"
#

# Load SMF constants and functions
. /lib/svc/share/smf_include.sh

PATH=/usr/bin:/usr/sbin; export PATH

TMPFILE=
INSTALLF=/var/tmp/autoreg_config
INSTALLK=/var/tmp/autoreg_key
SVCBASE="application/management/ocm:default"
FMRI="svc:/application/management/ocm:default"
ORACLE_HOME=/opt/ocm
RESPFILE=$ORACLE_HOME/ocm.rsp
OCMBIN=$ORACLE_HOME/ccr/bin
CCR_DISABLE_CRON_ENTRY=true


# ORACLE_CONFIG_HOME is hardcoded to this path in
# configCCR, emCCR, emocmrp wrapper scripts
ORACLE_CONFIG_HOME=/opt/ocm/config_home

OCM_CONFIG_CCR_DIR=$ORACLE_CONFIG_HOME/ccr

OCMSTATE=$OCM_CONFIG_CCR_DIR/state/sched.state

OCM_CONFIG_DIR=$OCM_CONFIG_CCR_DIR/config

REGISTERED_FILE=$OCM_CONFIG_DIR/default/uplinkreg.bin
REGISTERED_KEY="key.registered"

# Disconnected mode
DISCONNECTED_FILE=$OCM_CONFIG_DIR/collector.properties
DISCONNECTED_KEY="ccr.disconnected=true"

OCM_SCHEDULER_PS=$OCMBIN/nmz
OCM_SCHEDULER_CTL_PS="$OCMBIN/nmzctl start"
# Timeout in seconds after which we assume the scheduler is NOT running.
typeset OCM_SCHEDULER_PS_TIMEOUT=20

# OCM has a dependency on JDK1.6, only use this version
# this then requires http_client_12.jar to be used.
JAVA_HOME=/usr/jdk/instances/jdk1.6.0

OCM_LIBDIR=${ORACLE_HOME}/ccr/lib

CLASSPATH=$OCM_LIBDIR/emocmclnt.jar
CLASSPATH=$CLASSPATH:$OCM_LIBDIR/http_client_12.jar
CLASSPATH=$CLASSPATH:$ORACLE_HOME/bin/OCMsetupCLI.jar

CREATECODE=0
umask 077

# The # of seconds to wait between timing out on the initial OCM connection
# This timeout only guarantees that no additional OCM connection requests
# will be performed. If a OCM connection request is in progress it will
# no be interrupted
#
# The value specified here should be less than the timeout specified
# in the SMF manifest file for this service
TIMEOUT=300

# The # of times to attempt to make the initial connection
RETRIES=5

export ORACLE_HOME ORACLE_CONFIG_HOME JAVA_HOME CCR_DISABLE_CRON_ENTRY


#
# is_disconnected_collector_mode
#
#	return 0 if Collector is in disconnected mode
#		   1 if not in disconnected mode
#		   2 if unknown (file not present)
#
is_disconnected_collector_mode() {

    grep -w $DISCONNECTED_KEY $DISCONNECTED_FILE > /dev/null 2>&1
    return $?
}



#
# is_process_running
#
#	return 0 if process specified as argument is running
#
is_process_running() {
    pgrep -u root -f "$1" 2>&1
    return $?
}


#
# is_ocm_running
#
#	return 0 if OCM scheduler is running else return 1 if not running
#
is_ocm_running() {
	# OCM is running when both are TRUE:
	# - the $OCMBIN/bin/nmz is running
	# - the $OCMBIN/nmzctl start is NOT running
	let time=1
	while [ "$time" -le "$OCM_SCHEDULER_PS_TIMEOUT" ]
	do
        	is_process_running ${OCM_SCHEDULER_PS}
        	running_sched=$?
        	is_process_running ${OCM_SCHEDULER_CTL_PS}
        	running_sched_ctl=$?

        	if [ $running_sched_ctl -eq 1 ] && [ $running_sched -eq 0 ]; then
        		# OCM scheduler running
        		return 0
        	fi

        	sleep 1
        	let time=$time+1
	done

	# OCM scheduler not running
	return 1
}



ocm_resetup_msg() {
	cat <<EOF

1. Create a new response by executing:

   # $OCMBIN/emocmrsp -output $RESPFILE

2. Initiate the reconfigure of Oracle Configuration Manager by executing:

   # $OCMBIN/configCCR -R $RESPFILE

3. Re-enable the SMF service by executing:

   # svcadm disable $SMF_FMRI
   # svcadm enable $SMF_FMRI

EOF
}

no_response_file_msg()
{
	cat <<EOF

The Oracle Configuration Manager response file is not readable or present
on the system.  In order to correct this it will be necessary to reconfigure
Oracle Configuration Manager by by following these steps outlined below.

EOF
	ocm_resetup_msg
}

#
# Decrypt the autoreg credentials
#
decrypt_credentials() {
	decrypt -a aes -k $INSTALLK -i $INSTALLF -o $TMPFILE 2>/dev/null
	STATUS=$?
	if [ $STATUS -ne 0 ]; then
		rm -f $TMPFILE > /dev/null
		cat <<EOF
		
The registration credentials provided by the installer could not be decrypted.
To correct this issue it will be necessary to reconfigure Oracle 
Configuration Manager by following the steps outlined below.

EOF
		ocm_resetup_msg
	fi
	rm -f $INSTALLK $INSTALLF
	return $STATUS
}

#
# Create an OCM response file /opt/ocm/ocm.rsp based on credentials
#
create_response_file() {
	echo "Creating Response file from Install Credentials"
	$JAVA_HOME/bin/java -classpath $CLASSPATH com.oracle.ocm.reg.OCMsetupCLI \
		$TMPFILE $RESPFILE $TIMEOUT $RETRIES
	CREATECODE=$?
	# Immediately remove the credential files
	rm -f $TMPFILE > /dev/null
	if [ $CREATECODE -ne 0 ]; then
		if [ $CREATECODE -eq 2 ]; then
			
			# Handle Registration Successful with Failure Case:
			# 
			# The user entered MOS credentials but we where unable to
			# register with those credentials.  The system was still registered
			# and configured.
			#
			# In this case the manner to correct the problem is the same as it
			# is for all other type of failures so we want to output a how to
			# fix message.
			logger -p daemon.warning -t $FMRI \
				"The system was registered with" \
				"Oracle Configuration Manager but" \
				"encountered an error using the credentials supplied" \
				"during installation. See SMF log for details."
			cat <<EOF

The system was registered but encountered an error using the MOS credentials
supplied during installation.  To correct this issue it will be necessary
to reconfigure Oracle Configuration Manager by following the steps outlined
below.
EOF
		else
			# No response file exists as we had an error condition
			logger -p daemon.error -t $FMRI \
				"Initial Oracle Configuration Manager Registration of system" \
				"failed. See SMF log for details."
			cat <<EOF

The initial registration of the system failed.  Oracle Configuration Manager 
will be configured in disconnected mode.  In order to correct the reported
problem it will be necessary to reconfigure Oracle Configuration Manager by 
following the steps outlined below.
EOF
		fi
		ocm_resetup_msg
	fi
}


ocm_config_failed()
{
	STATUS=$1
	cat <<EOF

The configuration of Oracle Configuration Manager failed.  

Status: $STATUS

For more information consult the configCCR(1M) man page.

EOF
}

#
# Configure OCM for Disconnected Mode
#
configure_OCM_as_disconnected()
{
	# Set DISCONNECTED mode
	echo "Configuring Oracle Configuration Manager as Disconnected"
	CONFIG_ARG=
	if [ ! -d $OCM_CONFIG_CCR_DIR/config ]; then
		CONFIG_ARG=-a
	fi
	$OCMBIN/configCCR $CONFIG_ARG -s -d -S Solaris -V S10
	status=$?
	if [ $status -eq 0 ]; then
		if [ ! -z "$CONFIG_ARG" ]; then 
                	echo "Reconstitued writable/state directories under $OCM_CONFIG_CCR_DIR"
		fi
		logger -p daemon.notice -t $FMRI \
			"Oracle Configuration Manager configured for disconnected mode."
		return
	fi
	ocm_config_failed $status
	exit $SMF_EXIT_ERR_FATAL
}

#
# Configure OCM with the response file if it exists.  Otherwise
# configure OCM for disconnected mode
#
configure_OCM()
{
	if [ -r $RESPFILE ] && [ -s $RESPFILE ]; then
		# Configure OCM with the response file
		echo "Configuring Oracle Configuration Manager with $RESPFILE"
		CONFIG_ARG=
		if [ ! -d $OCM_CONFIG_CCR_DIR/config ]; then
			CONFIG_ARG=-a
		fi
		$OCMBIN/configCCR $CONFIG_ARG -R $RESPFILE -c -S Solaris -V S10
		status=$?
		if [ $status -eq 0 ]; then
			if [ ! -z "$CONFIG_ARG" ]; then
				echo "Reconstitued writable/state directories under $OCM_CONFIG_CCR_DIR"
			fi
			return
		fi
		ocm_config_failed $status
	fi
	configure_OCM_as_disconnected
}

#
# Get credentials and config OCM
#
first_time_setup()
{
	TMPFILE=$(mktemp -p /var/tmp -q -t tmp.XXXXXX)
	[ -z "$TMPFILE" ] && exit $SMF_EXIT_ERR_FATAL
	
	# decrypt the credentials from autoreg
	decrypt_credentials
	if [ $? -eq 0 ]; then
		# generate the OCM response file
		# remove the credential files
		create_response_file
	fi

	configure_OCM
}

#
# Re-register OCM
#
ocm_register()
{
	echo "Performing registration via Oracle Configuration Manager"
	$OCMBIN/emCCR register
	status=$?
	if [ $status -ne 0 ]; then
		cat << EOF
Oracle Configuration Manager Registration failed.  See emCCR(1M)
				
To retry the registration command enter:

# $OCMBIN/emCCR register

EOF
		exit $SMF_EXIT_ERR_FATAL
	fi
}


#
# OCM is in disconnected mode.  Output a syslog message to
# notify the admin of this condition.  Provide details
# of how to leave disconnect mode in SMF log
#
ocm_disconnected_mode()
{
	logger -p daemon.notice -t $FMRI \
			"Oracle Configuration Manager running in Disconnected mode"
	cat <<EOF
	
Oracle Configuration Manager is running in Disconnected mode.   If you wish
to place Oracle Configuration Manager in Connected Mode follow these steps:

EOF
	ocm_resetup_msg
}

#
# Main
#

# make sure this operates in global zone only
zone=`/sbin/zonename`
[ $zone = "global" ] || exit $SMF_EXIT_OK

# make sure OCM has been installed
[ -x $OCMBIN/../engines ] || exit $SMF_EXIT_OK

case "$1" in
'start')
	# If Jumpstart configured system with auto_reg=disable
	# or if the user exists Installer and deletes credentials there
	# will be no $INSTALLF $INSTALLK or $RESPFILE
	#
	# The reconfigure file is present when a flash archive has been installed
	if [ -f $ORACLE_HOME/reconfigure ]; then
		if [ -f $INSTALLF ] && [ -f $INSTALLK ]; then
			# credentials exist so treat first install
			if [ -f $RESPFILE ]; then
				rm -f $RESPFILE
			fi
		elif [ -r $RESPFILE ] && [ -s $RESPFILE ]; then
			ocm_register
		fi
		rm -f $ORACLE_HOME/reconfigure
	fi
	if [ -f $INSTALLF ] && [ -f $INSTALLK ]; then
		# Make sure that all the initial setup files setup by the installer
		# on first boot are removed if any error ocurrs
		trap 'rm -f $INSTALLF $INSTALLK $TMPFILE > /dev/null' 0
		trap "exit $SMF_EXIT_ERR_FATAL" 1 2 3 15
		first_time_setup
		exit $SMF_EXIT_OK
	fi

	if [ ! -d $OCM_CONFIG_CCR_DIR/config ]; then
		# A configuration structure is not complete
		# attempt to reconsistue the directory structure
		echo "Writable/state directory structure under $OCM_CONFIG_CCR_DIR is incomplete/missing."
		configure_OCM
		exit $SMF_EXIT_OK
	fi
	
	is_disconnected_collector_mode
	if [ $? -eq 0 ]; then
		ocm_disconnected_mode
		exit $SMF_EXIT_OK
	fi
	
	if [ ! -r $RESPFILE ] || [ ! -s $RESPFILE ]; then
		no_response_file_msg
		configure_OCM_as_disconnected
		exit $SMF_EXIT_OK
	fi
	
	is_ocm_running
	if [ $? -ne 0 ]; then 
		
		# ensure that the sched.state file isn't stale by removing it
		# sched.state is an internal OCM file
		if [ -f $OCMSTATE ]; then
			rm -f $OCMSTATE
		fi 
		
		# Attempt to start OCM
		echo "Starting Oracle Configuration Manager Collector"
		STATUS=`$OCMBIN/emCCR start`
		status=$?
		if [ $status -ne 0 ]; then
			echo "Oracle Configuration Manager could not be started."
			exit $SMF_EXIT_ERR_FATAL
		fi
	fi
	;;

'stop')
	#
	# stop automatic collection if OCM is running and not already in
	# Disconnected mode
	#
	is_disconnected_collector_mode
        if [ $? -eq 0 ]; then
		# Nothing to stop
                exit $SMF_EXIT_OK
        fi	
	is_ocm_running
	if [ $? -eq 0 ]; then
		$OCMBIN/emCCR stop_abort
		CODE=$?
		if [ $CODE -ne 0 ]; then
			echo "Failed stopping Oracle Configuration Manager" \
				"Collector, status $CODE"
			exit $SMF_EXIT_ERR_FATAL
		fi
	fi
	;;

*)
	echo "Usage: $0 { start | stop }"
	exit $SMF_EXIT_ERR_CONFIG
	;;

esac
exit $SMF_EXIT_OK

