#!/bin/bash
#
#  Copyright (c) 2008, Oracle. All rights reserved
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, version 2.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

usage() {
    echo "Usage: ${0##*/} [--config {--force}|--enable|--disable|--status|--cleanup]"
    echo "Options:"
    echo "  --config   Run template configuration"
    echo "             with --force option, to force running template configuration,"
    echo "             ignoring RUN_TEMPLATE_CONF value in /etc/sysconfig/oraclevm-template"
    echo "  --enable   Allow template configuration to run at next boot"
    echo "  --disable  Prevent template configuration to run at next boot"
    echo "  --status   Show if template configuration is to be run at next boot"
    echo "  --cleanup  Perform OS clean up and launch product clean up script"
}

do_enable() {
    ovm_log "Running ${0##*/} --enable"
    if [ ! -e "$CONF_FILE" ]; then
        echo 'RUN_TEMPLATE_CONF=YES' >> $CONF_FILE
    else
        if ! egrep -q '^RUN_TEMPLATE_CONF=' $CONF_FILE ; then
            echo 'RUN_TEMPLATE_CONF=YES' >> $CONF_FILE
        else
            sed -i -e 's/^RUN_TEMPLATE_CONF=.*/RUN_TEMPLATE_CONF=YES/' $CONF_FILE
        fi
    fi
    chkconfig oraclevm-template reset
    ovm_log "Changed RUN_TEMPLATE_CONF=YES in $CONF_FILE"
    ovm_info "Template configuration enabled."
}

do_disable() {
    ovm_log "Running ${0##*/} --disable"
    if [ ! -e "$CONF_FILE" ]; then
        echo 'RUN_TEMPLATE_CONF=NO' >> $CONF_FILE
    else
        if ! egrep -q '^RUN_TEMPLATE_CONF=' $CONF_FILE ; then
            echo 'RUN_TEMPLATE_CONF=NO' >> $CONF_FILE
        else
            sed -i -e 's/^RUN_TEMPLATE_CONF=.*/RUN_TEMPLATE_CONF=NO/' $CONF_FILE
        fi
    fi
    ovm_log "Changed RUN_TEMPLATE_CONF=NO in $CONF_FILE"
    ovm_info "Template configuration disabled."
}

do_status() {
    if ! ovm_load_config "$CONF_FILE"; then
        ovm_error "** Configuration file $CONF_FILE not found."
        return 2
    fi
    case  "$RUN_TEMPLATE_CONF" in
      yes|YES|Yes|1) echo "Template configuration is enabled."
                   return 0
                   ;;
      no|NO|No|0) echo "Template configuration is disabled."
                   return 1
                   ;;
      *) ovm_error "** Template configuration is not configured."
                   return 2
                   ;;
    esac
}

do_cleanup () {
    ovm_log "Running ${0##*/} --cleanup"

    if ! ovm_load_config "$CONF_FILE"; then
        ovm_warn "Configuration file $CONF_FILE not found."
    fi

    [ -z "$TEMPLATE_CLEANUP_SCRIPT" ] && \
        TEMPLATE_CLEANUP_SCRIPT=/u01/template-cleanup.sh

    # Run template cleanup script
    # user can set a $PROD_CONF_FILE as a argument for template cleanup script
    # Example: PROD_CONF_FILE=/u01/my.conf oraclevm-template --cleanup

    # new from 1.1.0-4
    # user can set a $TEMPLATE_CLEANUP_SCRIPT_ARGS as a argument for template cleanup script
    # TEMPLATE_CLEANUP_SCRIPT_ARGS can be set in /etc/sysconfig/oraclevm-template or cmdline
    # Example: TEMPLATE_CLEANUP_SCRIPT_ARGS='-all' /u01/my.conf oraclevm-template --cleanup
    cmd="$TEMPLATE_CLEANUP_SCRIPT $PROD_CONF_FILE $TEMPLATE_CLEANUP_SCRIPT_ARGS"
    if [ -x "$TEMPLATE_CLEANUP_SCRIPT" ]; then
        ovm_log "Calling $cmd"
        $cmd
        ovm_debug "$cmd returns $?"
    else
        ovm_log "$TEMPLATE_CLEANUP_SCRIPT not found."
    fi

    # force to cleanup os logs, reset network, etc.
    ovm_cleanup_os
    return 0
}

trap_cleanup () {
    :
}

do_config() {
    local ret=0

    ovm_log "Running ${0##*/} --config"

    trap trap_cleanup 0

    if ! ovm_load_config "$CONF_FILE" ; then
        ovm_warn "$CONF_FILE not found."
    fi

    # Save RUN_TEMPLATE_CONF value in config file before force flag set.
    _ETC_RUN_TEMPLATE_CONF=$(echo $RUN_TEMPLATE_CONF | tr '[:upper:]' '[:lower:]')

    if [ $force -eq 1 ]; then
        RUN_TEMPLATE_CONF=YES
        ovm_info "Force running template reconfiguration."
    fi

    case "$RUN_TEMPLATE_CONF" in
        NO|no|No) 
            ovm_log "Skip as RUN_TEMPLATE_CONF=$RUN_TEMPLATE_CONF."
            return 0
            ;;
        YES|yes|Yes)
            ;;
        *)
            ovm_log "Skip as RUN_TEMPLATE_CONF is invalid or null."
            return 1
            ;;
    esac

    [ -z "$TEMPLATE_CONFIG_SCRIPT" ] && \
        TEMPLATE_CONFIG_SCRIPT=oraclevm-template.sh

    [ -z "$TEMPLATE_MOUNT_POINT" ] && \
        TEMPLATE_MOUNT_POINT=/u01
    
    # force OS reconfiguration
    ovm_reconfigure_os 

    # run product reconfig script
    # user can set a $PROD_CONF_FILE as a argument for template config script
    # Example: PROD_CONF_FILE=/u01/my.conf oraclevm-template --config

    # new from 1.1.0-4
    # user can set a $TEMPLATE_CONFIG_SCRIPT_ARGS as a argument for template config script
    # TEMPLATE_CONFIG_SCRIPT_ARGS can be set in /etc/sysconfig/oraclevm-template or cmdline
    # Example: TEMPLATE_CONFIG_SCRIPT_ARGS='-n 2' /u01/my.conf oraclevm-template --config
    # 

    template_config_script_args="$TEMPLATE_CONFIG_SCRIPT_ARGS"
    # if 'template-reconfig' is found in kernel cmdline, it is forced to do reconfig
    # Allows passing arguments from grub menu to config script
    # e.g template-reconfig-args=-n2  (single argument)
    # if spaces are needed they must be quoted
    # e.g template-reconfig-args='-n2 -R'  (single quotes)
    # e.g template-reconfig-args=\"-n2 -R\"  (double quotes)
    cmdline="$(</proc/cmdline)"
    if echo "$cmdline" | grep -q "template-reconfig"; then
        cmdargs="${cmdline##*template-reconfig-args=}"
        if [ -n "$cmdargs" -a "$cmdargs" != "$cmdline" ]; then
           quote="${cmdargs:0:1}"
           [ "$quote" = "'" -o "$quote" = '"' ] && cmdargs="${cmdargs:1}" || quote=" "
           # Return everything up to first quote or space
           cmdargs="${cmdargs%%${quote}*}" 
           template_config_script_args="$cmdargs"
        fi
    fi

    cmd="$TEMPLATE_CONFIG_SCRIPT $PROD_CONF_FILE $template_config_script_args"

    if [ -x "$TEMPLATE_CONFIG_SCRIPT" ]; then
        ovm_log "calling $cmd"
        $cmd
        ret=$?
    elif [ -x "$TEMPLATE_MOUNT_POINT/$TEMPLATE_CONFIG_SCRIPT" ]; then
        ovm_log "calling $TEMPLATE_MOUNT_POINT/$cmd"
        $TEMPLATE_MOUNT_POINT/$cmd
        ret=$?
    elif ovm_mount_product_disk $TEMPLATE_MOUNT_POINT; then
        if [ -x "$TEMPLATE_CONFIG_SCRIPT" ]; then
            ovm_log "calling $cmd"
            $cmd
            ret=$?
        elif [ -x "$TEMPLATE_MOUNT_POINT/$TEMPLATE_CONFIG_SCRIPT" ]; then
            ovm_log "calling $cmd"
            $TEMPLATE_MOUNT_POINT/$cmd
            ret=$?
        else
            ovm_log "Reconfiguration script not found."
	    # diable network config for EC2
            if [ "$AMAZON_EC2_AMI" = YES -o "$AMAZON_EC2_AMI" = yes ]; then
                ret=0
            else
                if [ "${_ETC_RUN_TEMPLATE_CONF}" = yes ]; then
                    ovm_set_password root 
                else
                    :
                fi
                ovm_configure_network
                ret=$?
                if [ $ret -ne 0 ]; then
                    ovm_error "Network configuration failed."
                fi
            fi
        fi
    else
        ovm_log "Product disk not found."
        # diable network config for EC2
        if [ "$AMAZON_EC2_AMI" = YES -o "$AMAZON_EC2_AMI" = yes ]; then
            ret=0
        else
            if [ "${_ETC_RUN_TEMPLATE_CONF}" = yes ]; then
                ovm_set_password root 
            else
                :
            fi
            ovm_configure_network
            ret=$?
            if [ $ret -ne 0 ]; then
                ovm_error "Network configuration failed."
            fi
        fi
    fi

    if [ "$AMAZON_EC2_AMI" = YES -o "$AMAZON_EC2_AMI" = yes ]; then
        :
    else
        ovm_press_anykey 10
    fi
    ovm_debug "ret code:$ret"
    return $ret
}

# main #################################

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

case "$ORACLE_TRACE" in
  T) set -x;;
  *) ;;
esac

if [ -r /usr/lib/oraclevm-template/functions ] ; then
    . /usr/lib/oraclevm-template/functions
else
    echo "${0##*/}: Unable to source function library"
    exit 1
fi

if [ $(id -u) -ne 0 ]; then
    echo "${0##*/}: Must be executed as the root user."
    exit 1
fi

# start log
ovm_log "==> $(date +'%Y-%m-%d %H:%M:%S'): ${0##*/} $* <=="

action=
force=0

while [ $# -gt 0 ]; do
    case "$1" in
        --enable)
            action="enable"
            ;;
        --disable)
            action="disable"
            ;;
        --status)
            action="status"
            ;;
        --cleanup)
            action="cleanup"
            ;;
        --config)
            action="config"
            ;;
       --force)
            force=1
            ;;
        *)
            usage
            exit 1
            ;;
    esac
    shift
done

case "$action" in
    enable)
        do_enable;;
    disable)
        do_disable;;
    status)
        do_status;;
    cleanup)
        do_cleanup;;
    config)
        do_config;;
    *)
        usage
        exit 1
        ;;
esac
