#!/bin/bash
#
# Init file for the NorduGrid/ARC LDAP based local resource information system
#
# chkconfig: - 56 44
# description: NorduGrid/ARC local resource information system
#
# config: /etc/sysconfig/nordugrid
# config: /etc/sysconfig/nordugrid-arc-bdii
# config: /etc/arc.conf
#
######################################################################

### BEGIN INIT INFO
# Provides:          nordugrid-arc-bdii
# Required-Start:    $remote_fs $syslog nordugrid-arc-slapd
# Required-Stop:     $remote_fs $syslog nordugrid-arc-slapd
# Default-Stop:      0 1 2 3 4 5 6
# Short-Description: NorduGrid/ARC local resource information system
# Description:       NorduGrid/ARC LDAP based local resource information system
### END INIT INFO

# Helper functions
if [ -r /etc/init.d/functions ]; then
    . /etc/init.d/functions
    log_success_msg() {
	echo -n "$@"
	success "$@"
	echo
    }
    log_warning_msg() {
	echo -n "$@"
	warning "$@"
	echo
    }
    log_failure_msg() {
	echo -n "$@"
	failure "$@"
	echo
    }
elif [ -r /lib/lsb/init-functions ]; then
    . /lib/lsb/init-functions
else
    echo "Error: Cannot source neither init.d nor lsb functions"
    exit 1
fi

RETVAL=0
prog=nordugrid-arc-bdii
RUN=yes

# sysconfig files
if [ -r /etc/sysconfig/nordugrid ]; then
    . /etc/sysconfig/nordugrid
elif [ -r /etc/default/nordugrid ]; then
    . /etc/default/nordugrid
fi
if [ -r /etc/sysconfig/$prog ]; then
    . /etc/sysconfig/$prog
elif [ -r /etc/default/$prog ]; then
    . /etc/default/$prog
fi

if [ "x$RUN" != "xyes" ]; then
    log_warning_msg "$prog disabled, please adjust the configuration to your"
    log_warning_msg "needs and then set RUN to 'yes' in /etc/default/$prog to enable it."
    exit 0
fi

[ -n "$ARC_LOCATION" ] && export ARC_LOCATION
[ -n "$ARC_CONFIG" ]   && export ARC_CONFIG

ARC_LOCATION=${ARC_LOCATION:-/usr}
if [ ! -d "$ARC_LOCATION" ]; then
    log_failure_msg "ARC_LOCATION ($ARC_LOCATION) not found"
    exit 1
fi

# Source the config parsing routines
if [ -r "$ARC_LOCATION/share/arc/config_parser_compat.sh" ]; then
    . $ARC_LOCATION/share/arc/config_parser_compat.sh || exit $?
else
    log_failure_msg "Could not find $ARC_LOCATION/share/arc/config_parser_compat.sh"
    exit 1
fi

ARC_CONFIG=${ARC_CONFIG:-/etc/arc.conf}
if [ ! -r "$ARC_CONFIG" ]; then
    log_failure_msg "arc.conf was not found. If this file is in a non-standard place,"
    log_failure_msg "  it can be set with the ARC_CONFIG environment variable"
    exit 1
fi

# Read arc.conf
config_parse_file $ARC_CONFIG || exit $?

# Check for infosys-block
if ! config_match_section infosys; then
    log_warning_msg "Missing infosys configuration block"
    exit 0
fi

config_hide_all
config_import_section common

# These options need to come from the infosys-block, not from common
unset CONFIG_logfile
unset CONFIG_user
unset CONFIG_port

config_import_section infosys

debug=${CONFIG_debug:-$debug}

ldap_user=`getent passwd | grep ldap | sed 's/\([az]*\):.*/\1/g'`
if [ ! "xldap" = "x$ldap_user" ] && [ ! "xopenldap" = "x$ldap_user" ]; then
    log_warning_msg "Warning, could not find ldap or openldap user"
    log_warning_msg "resorting to using the root user."
    ldap_user=root
fi
bdii_user=${CONFIG_user:-$ldap_user}

# These values may be set in arc.conf, otherwise use sensible defaults
hostname_f=$(hostname -f)
hostname=${CONFIG_hostname:-$hostname_f}

# Use this command to change user
if [ -x /sbin/runuser ]; then
    RUNUSER=runuser
else
    RUNUSER=su
fi

# If missing, we have a problem
USERSHELL=${USERSHELL:-"/bin/sh"}
if [ ! -x ${USERSHELL} ]; then
    log_failure_msg "Could not find /bin/sh"
    exit 1
fi

bdii_location=${CONFIG_bdii_location:-/usr}
giis_location=${CONFIG_giis_location:-$ARC_LOCATION}

bdii_update_cmd=${CONFIG_bdii_update_cmd:-"${bdii_location}/sbin/bdii-update"}
if [ ! -e $bdii_update_cmd ]; then
    log_failure_msg "Can not find bdii-update command at: $bdii_update_cmd."
    log_failure_msg "Please set bdii_update_cmd in arc.conf"
    exit 1
fi

bdii_debug_level=${CONFIG_bdii_debug_level:-ERROR}

bdii_tmp_dir=${CONFIG_bdii_tmp_dir:-/var/tmp/arc/bdii}
if grep -q BDII_PID_FILE $bdii_update_cmd ; then
    bdii_var_dir=${CONFIG_bdii_var_dir:-/var/lib/arc/bdii}
    bdii_run_dir=${CONFIG_bdii_run_dir:-/var/run/arc/bdii}
else
    bdii_var_dir=${CONFIG_bdii_var_dir:-/var/run/arc/bdii}
    bdii_run_dir=$bdii_var_dir
fi
bdii_log_dir=${CONFIG_bdii_log_dir:-/var/log/arc/bdii}
bdii_log_file="${bdii_log_dir}/bdii-update.log"

mkdir -p $bdii_log_dir

bdii_default_ldif_ng=${bdii_tmp_dir}/provider/arc-default.ldif.pl
bdii_ldif_dir=${bdii_tmp_dir}/ldif
bdii_provider_dir=${bdii_tmp_dir}/provider
bdii_plugin_dir=${bdii_tmp_dir}/plugin

# Using uppercase characters in bdii_bind will break infosys.
bdii_bind="o=grid"

infosys_compat=${CONFIG_infosys_compat:-"disable"}
infosys_nordugrid=${CONFIG_infosys_nordugrid:-"enable"}
infosys_glue12=${CONFIG_infosys_glue12:-"disable"}
infosys_glue2_ldap=${CONFIG_infosys_glue2_ldap:-"disable"}

update_pid_file=${CONFIG_bdii_update_pid_file:-$bdii_run_dir/bdii-update.pid}

# Debian does not have /var/lock/subsys
if [ -d /var/lock/subsys ]; then
    update_lock_file=${update_lock_file:-/var/lock/subsys/$prog}
else
    update_lock_file=${update_lock_file:-/var/lock/$prog}
fi

chown ${bdii_user}: ${bdii_log_dir}

arc_runtime_config="/var/run/arc/infosys"
BDII_CONF=${CONFIG_bdii_conf:-${arc_runtime_config}/bdii.conf}

start () {
    if [ -r "${update_lock_file}" ]; then
	log_success_msg "$prog already started"
	RETVAL=0
	return ${RETVAL}
    fi

    ${ARC_LOCATION}/share/arc/create-bdii-config
    if [ ! $? = 0 ]; then
	log_failure_msg "Failed to create configration for $prog"
	exit 1
    fi

    $RUNUSER -s "$USERSHELL" -c "${bdii_update_cmd} -c ${BDII_CONF} -d" ${bdii_user}
    touch ${update_lock_file}

    if [ ! -r ${update_pid_file} ]; then
	sleep 2
    fi
    if [ ! -r ${update_pid_file} ]; then
	log_failure_msg "$prog failed to start"
	rm -f ${update_lock_file}
	exit 1
    else
	touch ${update_lock_file}
	RETVAL=0
    fi

    log_success_msg "$prog started"
}

stop () {
    if [ ! -r "${update_lock_file}" ]; then
	log_success_msg "$prog already stopped"
	RETVAL=0
	return ${RETVAL}
    fi

    if [ -r "${update_pid_file}" ]; then
	update_pid=$(cat ${update_pid_file})
	ps ${update_pid} >/dev/null 2>&1
	if [ ! $? = 0 ]; then
	    log_failure_msg "$prog pid file exists but the process died"
	    RETVAL=1
	    return ${RETVAL}
	fi
    else
	log_failure_msg "$prog process has no pid file"
	RETVAL=1
	return ${RETVAL}
    fi

    killall -u ${bdii_user} -15 arc-nordugrid-bdii-ldif 2>/dev/null

    if [ -n "${update_pid}" ]; then
	kill -15 ${update_pid} 2>/dev/null
	ps ${update_pid} >/dev/null 2>&1
	if [ $? = 0 ]; then
	    sleep 2
	    ps ${update_pid} >/dev/null 2>&1
	    if [ $? = 0 ]; then
		kill -9 ${update_pid} 2>/dev/null
		sleep 2
		ps ${update_pid} >/dev/null 2>&1
		if [ $? = 0 ]; then
		    RETVAL=1
		fi
	    fi
	fi
    fi

    if [ ${RETVAL} = 0 ];  then
	rm -f ${update_pid_file}
	rm -f ${update_lock_file}
    else
	log_failure_msg "Could not kill $prog with pid ${update_pid}"
    fi

    # Clean up
    rm -f ${arc_runtime_config}/arc-glue-bdii-ldif

    if [ ! ${RETVAL} = 0 ];  then
	log_failure_msg
	return 1
    else
	rm -f ${update_lock_file}
	log_success_msg "$prog stopped"
    fi

    return ${RETVAL}
}

status ()  {
    if [ ! -f "${update_lock_file}" ]; then
	log_success_msg "$prog is stopped"
	RETVAL=3
	return ${RETVAL}
    fi

    if [ -r ${update_pid_file} ]; then
	ps $(cat ${update_pid_file}) >/dev/null 2>&1
	if [ ! $? = 0 ]; then
	    log_failure_msg "$prog pid file exists but the process died"
	    RETVAL=1
	    return ${RETVAL}
	fi
    else
	log_failure_msg "$prog process has no pid file"
	RETVAL=1
	return ${RETVAL}
    fi

    log_success_msg "$prog is running"

    RETVAL=0
    return ${RETVAL}
}

case "$1" in
    start)
	start
	;;
    stop)
	stop
	;;
    restart | force-reload)
	stop
	# avoid race
	sleep 3
	start
	;;
    reload)
	;;
    status)
	status
	;;
    condrestart | try-restart)
	if [ -r ${update_lock_file} ]; then
	    stop
	    # avoid race
	    sleep 3
	    start
	fi
	;;
    *)
	echo "Usage: $0 {start|stop|restart|force-reload|reload|condrestart|try-restart|status}"
	exit 1
	;;
esac

exit $RETVAL
