#!/bin/bash
#
# install.sh
#
# Copyright (C) 2011-2012 Cesnet z.s.p.o
# Author(s): 	Tomas PLESNIK 	<plesnik@ics.muni.cz>
#		Jan SOUKAL	<soukal@ics.muni.cz>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# 3. Neither the name of the Cesnet z.s.p.o nor the names of its
#    contributors may be used to endorse or promote products derived from
#     this software without specific prior written permission.
#
# This software is provided ``as is'', and any express or implied
# warranties, including, but not limited to, the implied warranties of
# merchantability and fitness for a particular purpose are disclaimed.
# In no event shall the Cesnet z.s.p.o or contributors be liable for
# any direct, indirect, incidental, special, exemplary, or consequential
# damages (including, but not limited to, procurement of substitute
# goods or services; loss of use, data, or profits; or business
# interruption) however caused and on any theory of liability, whether
# in contract, strict liability, or tort (including negligence or
# otherwise) arising in any way out of the use of this software, even
# if advised of the possibility of such damage.

VERSION="0.1"

#-------------------------------------------------------------------------------
#				FUNCTIONS
#-------------------------------------------------------------------------------
usage()
{
	echo "Usage: `basename $0` [-d <directory>] [-k <ssl_key_file>] [-c <ssl_cert_file>] [-a <ssl_ca_file>] [-hV]"
	echo "-d <directory>            installation directory (default: /opt)"
	echo "-k <ssl_key_file>         path to SSL certificate key file"
	echo "-c <ssl_cert_file>        path to SSL certificate file"
	echo "-a <ssl_ca_file>          path to CA certificate file"
	echo "-h                        print this help"
	echo "-V                        print script version number and exit"
	echo
	echo "Example: # ./`basename $0` -d /opt -k /etc/ssl/private/server.key -c /etc/ssl/certs/server.pem -a /etc/ssl/certs/tcs-ca-bundle.pem"
	echo
	echo "Note: You must be root for running this script."
	echo "      For more information about installation process, see README file (section Installation)."
	echo
	exit 0
}


version()
{
	echo "`basename ${0}` - current version is $VERSION"
	exit 0
}


err()
{
	echo "FAILED!"
	cat $err
	rm -rf $err
	echo
	echo "Installation of $package_version package FAILED!!!"
	exit 1
}


err_clean()
{
	echo "FAILED!"
	echo " -> Uninstalling server package ... OK"
	rm -rf $server_path > /dev/null 2>&1
	cat $err
	rm -rf $err
	echo
	echo "Installation of $package_version package FAILED!!!"
	exit 1
}


os_chck()
{
	OS=`uname`
	if [ "$OS" != "Linux" ]; then
		echo "Sorry, unsupported operating system detected - \"$OS\"!"
		exit 1
	fi
}


shell_chck()
{
	SHELL=`echo $SHELL`
	if [ "$SHELL" != "/bin/bash" ]; then
		echo "Sorry, this script is usable in Bourne Again Shell (bash) only!"
		exit 1
	fi
}


root_chck()
{
	if [ $UID -ne 0 ]; then
		echo "You must be root for running this script!"
		exit 1
	fi
}


params_chck()
{
	if [ -z $prefix ]; then
		prefix=/opt
		echo "Warning: parameter -d <directory> is not set - default installation directory is $prefix!"
	fi
	if [ -z $key ]; then
		echo "Parameter -k <ssl_key_file> is not set!"
		exit 1
	fi
	if [ -z $cert ]; then
		echo "Parameter -c <ssl_cert_file> is not set!"
		exit 1
	fi
	if [ -z $ca_file ]; then
		echo "Parameter -a <ssl_ca_file> is not set!"
		exit 1
	fi
}


old_package_chck()
{
	old_package_version_file="$etc/package_version"
	if [ -f $old_package_version_file ]; then
		old_package_version=`cat $old_package_version_file`
		echo "Sorry, but $old_package_version package is installed!"
		echo "For update of warden server package please use update.sh"
		exit 1
	fi
}


perl_chck()
{
	echo -n "Checking Perl interpreter ... "
	if which perl 1> /dev/null; then
		echo "OK"
	else
		echo "FAILED!"
		echo "Error: Perl interpreter is not installed!"
		exit 1
	fi
}

sqlite_chck()
{
	echo -n "Checking SQLite database engine ... "
	if which sqlite3 1> /dev/null; then
		echo "OK"
	else
		echo "FAILED!"
		echo "Error: SQLite3 database engine is not installed!"
		exit 1
	fi
}

modules_chck()
{
	for module in ${modules[@]};
	do
		echo -n "Checking $module module ... "
		if perl -e "use $module" 2> $err; then
			echo "OK"
		else
			err
		fi
	done
}


make_warden_dir()
{
	echo -n "Creating warden server directory ... "
	if cp -R $dirname/warden-server $prefix 2> $err; then
		echo "OK"
	else
		err_clean
	fi

	files=(CHANGELOG INSTALL LICENSE README)
	for file in ${files[@]};
	do
		cp $dirname/$file $server_path/doc
	done
	cp $dirname/uninstall.sh $server_path
}


make_client_conf()
{
	echo -n "Creating client configuration file ... "
	echo "#
# warden-client.conf - configuration file for the warden sender/receiver client
#

#-------------------------------------------------------------------------------
# URI - URI address of Warden server
#-------------------------------------------------------------------------------
\$URI = \"https://${hostname}:443/Warden\";

#-------------------------------------------------------------------------------
# SSL_KEY_FILE - path to client SSL certificate key file
#-------------------------------------------------------------------------------
\$SSL_KEY_FILE = \"${etc}/${key_file}\";

#-------------------------------------------------------------------------------
# SSL_CERT_FILE - path to client SSL certificate file
#-------------------------------------------------------------------------------
\$SSL_CERT_FILE = \"${etc}/${cert_file}\";

#-------------------------------------------------------------------------------
# SSL_CA_FILE - path to CA certificate file
#-------------------------------------------------------------------------------
\$SSL_CA_FILE = \"${ca_file}\";
" > $client_conf 2> $err; ret_val=`echo $?`

	if [ $ret_val -eq 0 ]; then
		echo "OK"
	else
		err_clean
	fi
}


make_server_conf()
{
	echo -n "Creating server configuration file ... "
	echo "# 
# warden-server.conf - configuration file for Warden server
#

#-------------------------------------------------------------------------------
# ADDRESS - IP address of warden server
#-------------------------------------------------------------------------------
\$ADDRESS = \"${hostname}\";

#-------------------------------------------------------------------------------
# PORT - used TCP port for Warden server
#-------------------------------------------------------------------------------
\$PORT = \"443\";

#-------------------------------------------------------------------------------
# BASEDIR - base directory of Warden server
#-------------------------------------------------------------------------------
\$BASEDIR = \"${server_path}\";

#-------------------------------------------------------------------------------
# VARDIR - var directory
#-------------------------------------------------------------------------------
\$VARDIR = \"\$BASEDIR/var/\";

#-------------------------------------------------------------------------------
# LOGDIR - logging directory
#-------------------------------------------------------------------------------
\$LOGDIR = \"/var/log/\";

#-------------------------------------------------------------------------------
# PIDDIR - process ID directory
#-------------------------------------------------------------------------------
\$PIDDIR = \"/var/run/\";

#-------------------------------------------------------------------------------
# SSL_KEY_FILE - path to server SSL certificate key file
#-------------------------------------------------------------------------------
\$SSL_KEY_FILE = \"${key}\";

#-------------------------------------------------------------------------------
# SSL_CERT_FILE - path to server SSL certificate file
#-------------------------------------------------------------------------------
\$SSL_CERT_FILE = \"${cert}\";

#-------------------------------------------------------------------------------
# SSL_CA_FILE - path to CA ceritificate file
#-------------------------------------------------------------------------------
\$SSL_CA_FILE = \"${ca_file}\";

#-------------------------------------------------------------------------------
# FACILITY - syslog facility
#-------------------------------------------------------------------------------
\$FACILITY = \"local7\";
" > $server_conf 2> $err; ret_val=`echo $?`

	if [ $ret_val -eq 0 ]; then
		echo "OK"
	else
		err_clean
	fi
}


create_db()
{
	echo -n "Creating warden server database ... "
	$create_tables $db_file 2> $err || err_clean
	if chmod 600 $db_file 2> $err; then
		echo "OK"
	else
		err_clean
	fi
}


create_symlinks()
{
	echo "Creating symbolic links ..."
	for file in `ls -1 $bin | grep -v warden-alive | grep -v create_tables.sh | grep -v wardend`
	do
		echo "- making symlink: ${local_bin}/$file -> ${bin}/$file"
		ln -s ${bin}/$file ${local_bin}/$file
	done
	echo "- making symlink: ${bin}/wardend -> $init"
	ln -s ${bin}/wardend $init
}

#-------------------------------------------------------------------------------
#				MAIN
#-------------------------------------------------------------------------------

# list of used Perl modules
modules=(SOAP::Lite SOAP::Transport::TCP File::Pid POSIX DBI DBD::SQLite Format::Human::Bytes Sys::Syslog File::Basename FindBin Net::CIDR::Lite DateTime Getopt::Std Switch IO::Socket::SSL)

# OS test
os_chck

# Shell test
shell_chck

# read input
while getopts "d:k:c:a:Vh" options; do
	case $options in
		d ) prefix=$OPTARG;;
		k ) key=$OPTARG;;
		c ) cert=$OPTARG;;
		a ) ca_file=$OPTARG;;
		h ) usage;;
		V ) version;;
		* ) usage;;
	esac
done

# root test
root_chck

# params test
params_chck

# create variables
dirname=`dirname $0`
hostname=`hostname`
key_file=`basename $key`
cert_file=`basename $cert`
package_version=`cat ${dirname}/warden-server/etc/package_version`
create_tables="${dirname}/warden-server/bin/create_tables.sh"

[[ $prefix == */ ]] && prefix="${prefix%?}" # remove last char (slash) from prefix
server_path="${prefix}/warden-server"
bin="${server_path}/bin"
local_bin="/usr/local/bin"
etc="${server_path}/etc"
client_conf="${etc}/warden-client.conf"
server_conf="${etc}/warden-server.conf"
var="${server_path}/var"
db_file="${var}/warden.db"
err="/tmp/warden-err"
init="/etc/init.d/wardend"

# check if warden-server is installed
old_package_chck

echo
echo "------------------------- Dependencies check-in -------------------------"

# Perl interpreter test
perl_chck

# SQLite database engine test
sqlite_chck

# Perl modules test
modules_chck

echo
echo "------------------------- Installation process --------------------------"

# make warden client directory
make_warden_dir

# create client configuration file
make_client_conf

# create server configuration file
make_server_conf

# create warden server database
create_db

# crate symlinks from warden server bin directory to /usr/local/bin
create_symlinks

echo
echo "Please check client configuration file in $client_conf!"
echo "Please check server configuration file in $server_conf!"
echo
echo "Start Warden server by /etc/init.d/wardend start"
echo
echo "Installation of $package_version package was SUCCESSFUL!!!"

# cleanup section
rm -rf $err

exit 0