#!/bin/bash
#
# install.sh
#
# Copyright (C) 2011-2014 Cesnet z.s.p.o
#
# Use of this source is governed by a BSD-style license, see LICENSE file.


VERSION="2.2"

#-------------------------------------------------------------------------------
#				Script functions
#-------------------------------------------------------------------------------
usage()
{
	echo "Usage: ${0##*/} -d <directory> -k <ssl_key_file> -c <ssl_cert_file> -a <ssl_ca_file> -e <email_address> [-s <directory>] [-hV]"
	echo "-d <directory>            installation directory of Warden server"
	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 "-e <e-mail address>       e-mail address to Warden server administrator"
	echo "-s <directory>            directory for symlinks to Warden server control scripts (optional)"
	echo "-h                        print this help"
	echo "-V                        print script version number and exit"
	echo
	echo "Example: $ ./${0##*/} -d /opt/warden-server -k /etc/ssl/private/server.key -c /etc/ssl/certs/server.pem -a /etc/ssl/certs/tcs-ca-bundle.pem -e admin@domain.com -s /usr/local/bin"
	echo
	echo "For more information about installation process, see README file (section Installation)."
	echo
	exit 0
}


version()
{
	echo "${0##*/} - current version is $VERSION"
	exit 0
}


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


errClean()
{
	echo "FAILED!"
	echo " -> Uninstalling server package ..."
	for file in $(<"$manifest")
	do
		directory="${file%/*}"
		rm -f "${basedir}/$file"
		rmdir --ignore-fail-on-non-empty "${basedir}/$directory"
		rm -f "${basedir}/uninstall.sh"

	done
	cat "$err"
	rm -f "$err"
	echo
	echo "Installation of $package_version package FAILED!!!"
	exit 1
}


paramsChck()
{
	if [ -z "$basedir" ]; then
		echo "Parameter -d <directory> is not set!"
		exit 1
	fi
	if [ -z "$key_file" ]; then
		echo "Parameter -k <ssl_key_file> is not set!"
		exit 1
	fi
	if [ -z "$cert_file" ]; 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
	if [ -z "$contact" ]; then
		echo "Parameter -e <e-mail address> is not set!"
		exit 1
	fi
}


#-------------------------------------------------------------------------------
#				Installation functions
#-------------------------------------------------------------------------------

oldPackageChck()
{
	echo -n "Checking previous Warden server installation ... "
	old_package_version_file=$(find "$basedir" -name package_version)
	if [ -f "$old_package_version_file" ]; then
		old_package_version=$(<"$old_package_version_file")
		echo "FAILED!"
		echo
		echo "Package $old_package_version is already installed!"
		echo "For update of Warden server package please use update.sh."
		exit 1
	fi
	echo "OK"
}


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


modulesChck()
{
	sed '/^use [A-Z]/!d; /Warden/d' $(find "${dirname}" -type f) 2>/dev/null | cut -f 2 -d " " | sed 's/;//' | sort -u | \
	while read module;
	do
		echo -n "Checking $module module ... "
		perl -e "use $module" 2> "$err" && echo "OK" || err
	done
}


createWardenDir()
{
	echo -n "Creating Warden server directory ... "
	test -d "$basedir" && test -w "$basedir" || mkdir -p "$basedir" 2> "$err" || err
	for dir in "${dirname}/"*
	do
		if [ -d "$dir" ]; then
			cp -R "$dir" "$basedir" 2> "$err" || errClean
		fi
	done
	rm -f "${etc}/"*.tmpl*
	ln -s "${sh}/uninstall.sh" "$basedir"
	echo "OK"
}


doTemplate()
{
        vars=""
        while (($#)); do
                vars="'$1'=>'$2', $vars"
                shift 2
        done
        perl -e "my %repl=($vars); foreach my \$l (<>) {\$l =~ s/\$_/\$repl{\$_}/g for keys %repl; print \$l}"
}


createManifest()
{
	echo -n "Creating MANIFEST file ... "
	cd "$basedir" && find . -mindepth 2 -type f | sed 's/.\///' | sort > "${doc}/MANIFEST" && cd $OLDPWD 2> "$err" || errClean
	echo "OK"
}


createSymlinks()
{
	echo "Creating symbolic links to $symbin ..."
	for file in "${bin}/"*
	do
		echo "- making symlink: ${symbin}/${file##*/} -> $file"
		ln -s "$file" "${symbin}/${file##*/}" 2>/dev/null
	done
}


#-------------------------------------------------------------------------------
#				MAIN
#-------------------------------------------------------------------------------
# read input
while getopts "d:k:c:a:e:s:Vh" options; do
	case "$options" in
		d ) basedir="$OPTARG";;
		k ) key_file="$OPTARG";;
		c ) cert_file="$OPTARG";;
		a ) ca_file="$OPTARG";;
		e ) contact="$OPTARG";;
		s ) symbin="$OPTARG";;
		h ) usage;;
		V ) version;;
		* ) usage;;
	esac
done

# remove last char (slash) from name of directories
[[ "$basedir" == */ ]] && basedir="${basedir%?}"
[[ "$symbin" == */ ]] && symbin="${symbin%?}"

# params test
paramsChck

# set variables
err="/tmp/warden-err"
domain_name=$(hostname -f || echo "unspecified.server")
dirname=${0%/*}
bin="${basedir}/bin"
lib="${basedir}/lib"
doc="${basedir}/doc"
etc="${basedir}/etc"
sh="${basedir}/sh"
server_conf="${etc}/warden-server.conf"
apache_conf="${etc}/warden-apache.conf"
watchdog_conf="${etc}/warden-watchdog.conf"
server_conf_tmpl="${dirname}/etc/warden-server.conf.tmpl"
apache_conf_tmpl="${dirname}/etc/warden-apache.conf.tmpl"
watchdog_conf_tmpl="${dirname}/etc/warden-watchdog.conf.tmpl"
package_version=$(<"${dirname}/etc/package_version")
manifest="${dirname}/doc/MANIFEST"


echo "Installation of Warden server package ($package_version) ..."
echo
echo "----------------------- Checking for Dependencies -----------------------"

# check if warden-server is installed
[[ ! -z "$basedir" ]] && [[ -d "$basedir" ]] && oldPackageChck

# Perl interpreter test
perlChck

# Perl modules test
modulesChck || exit 1

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

# make warden server directory
createWardenDir || exit 1

# create server configuration file
echo -n "Creating Warden server configuration file ... "
doTemplate \
        _BASEDIR_       "$basedir" \
        < $server_conf_tmpl \
        > $server_conf && echo "OK" || errClean

# create Apache configuration file
echo -n "Creating Apache configuration file ... "
doTemplate \
        _CERT_FILE_	"$cert_file" \
        _KEY_FILE_	"$key_file" \
        _CA_FILE_	"$ca_file" \
        _LIB_		"$lib" \
        < $apache_conf_tmpl \
        > $apache_conf && echo "OK" || errClean

# create wardenWatchdog configuration file
echo -n "Creating Warden Watchdog configuration file ... "
doTemplate \
        _DOMAIN_NAME_	"$domain_name" \
        _CONTACT_	"$contact" \
        < $watchdog_conf_tmpl \
        > $watchdog_conf && echo "OK" || errClean

# create MANIFEST file
createManifest

# crate symlinks from warden server bin to user path (if -s option is set)
[[ ! -z "$symbin" ]] && [[ -d "$symbin" ]] && [[ -w "$symbin" ]] && createSymlinks

echo
echo "Please check configuration files:"
echo " - $server_conf"
echo " - $server_conf"
echo " - $watchdog_conf"
echo
echo "Warden server directory: $basedir"
echo
echo "Please follow post-installation steps in ${doc}/INSTALL."
echo
echo "Installation of $package_version package was SUCCESSFUL!!!"
echo

# cleanup section
rm -f "$err"

exit 0
