#!/bin/bash
#
# update.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> [-hV]"
	echo "-d <directory>            destination directory of Warden server"
	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"
	echo
	echo "For more information about update process, see README file (section Update)."
	echo
	exit 0
}


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


err()
{
	echo "FAILED!"
	cat "$err"
	rm -f "$backup"
	rm -f "$err"
	echo
	echo "Update from $old_package_version to $package_version package FAILED!!!"
	exit 1
}


errClean()
{
	echo "FAILED!"
	echo " -> Reverting changes of Warden server package ... OK"
	rm -r ${server_path}/* > /dev/null 2>&1
	cp -R ${backup_dir}/* $server_path
	cat $err
	rm -r $err $backup
	echo
	echo "Update from $old_package_version to $package_version package FAILED!!!"
	exit 1
}


paramsChck()
{
	if [ -z "$basedir" ]; then
		echo "Parameter -d <directory> is not set!"
		exit 1
	fi
}


#-------------------------------------------------------------------------------
#                               Installation functions
#-------------------------------------------------------------------------------
wardenDirChck()
{
        echo -n "Checking Warden server directory ... "
        if [[ ! -d "$basedir" ]] && [[ ! -w "$basedir" ]]; then
                echo "FAILED!"
                echo "No version of Warden server is not installed!"
                exit 1
        else
                echo "OK"
        fi  
}


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")
		if [ "$old_package_version" == "$package_version" ]; then
			echo "Sorry, but $package_version package is already installed!"
			exit 1
		elif [ "$old_package_version" == "warden-server-2.0" ]; then
			echo "Sorry, first of all you must upgrade to package warden-server-2.1!"
			exit 1
		fi
	else
		echo "Sorry, but Warden server package is not yet installed!"
		echo "For installation of Warden server package please use install.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 "Error: 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
}


backup()
{
	echo -n "Making Warden server backup ... "
	mkdir "$backup"
	if cp -R "${basedir}/"* "$backup" 2> "$err"; then
		echo "OK"
	else
		err
	fi
}


updateWardenDir()
{ 
	echo -n "Updating Warden server ... "
        for file in $(<"$manifest")
        do
		dir="$basedir/${file%/*}"
		[[ ! -d "$dir" ]] && mkdir -p "$dir"
		cp "$file" "${basedir}/$file" 2> "$err" || errClean
        done
	echo "OK"
}


getConfValue() {
	perl -e "require \"$1\"; print \"\$$2\";"
}


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##*/}"
        done
}


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

# read input
while getopts "d:s:Vh" options; do
	case "$options" in
		d ) basedir="$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"
backup="/tmp/warden-server-backup"
hostname=$(hostname -f || echo "unspecified.server")
dirname=${0%/*}
doc="${basedir}/doc"
etc="${basedir}/etc"
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.update"
apache_conf_tmpl="${dirname}/etc/warden-apache.conf.tmpl.update"
watchdog_conf_tmpl="${dirname}/etc/warden-watchdog.conf.tmpl.update"
package_version=$(<"${dirname}/etc/package_version")
manifest="${dirname}/doc/MANIFEST"


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

# check warden server directory
wardenDirChck

# check previous Warden server instalation
oldPackageChck

# Perl interpreter test
perlChck

# Perl modules test
modulesChck

echo
echo "------------------------- Update process --------------------------------"

# backup old warden server installation
backup

# make warden server directory
updateWardenDir

# update server configuration file
echo -n "Updating Warden server configuration file ... "
syslog=$(getConfValue "$server_conf" SYSLOG)
syslog_verbose=$(getConfValue "$server_conf" SYSLOG_VERBOSE)
syslog_facility=$(getConfValue "$server_conf" SYSLOG_FACILITY)
db_name=$(getConfValue "$server_conf" DB_NAME)
db_user=$(getConfValue "$server_conf" DB_USER)
db_pass=$(getConfValue "$server_conf" DB_PASS)
db_host=$(getConfValue "$server_conf" DB_HOST)
max_events_limit=$(getConfValue "$server_conf" MAX_EVENTS_LIMIT)
doTemplate \
        _BASEDIR_		"$basedir" \
        _SYSLOG_		"$syslog" \
        _SYSLOG_VERBOSE_	"$syslog_verbose" \
        _SYSLOG_FACILITY_	"$syslog_facility" \
        _DB_NAME_		"$db_name" \
        _DB_USER_		"$db_user" \
        _DB_PASS_		"$db_pass" \
        _DB_HOST_		"$db_host" \
        _MAX_EVENTS_LIMIT_	"$max_events_limit" \
        < $server_conf_tmpl \
        > $server_conf && echo "OK" || errClean

# update Apache configuration file
echo -n "Updating Apache configuration file ... "
cert_file=$(getConfValue "$server_conf" CERT_FILE)
key_file=$(getConfValue "$server_conf" KEY_FILE)
ca_file=$(getConfValue "$server_conf" CA_FILE)
lib=$(getConfValue "$server_conf" LIB)
doTemplate \
        _CERT_FILE_     "$cert_file" \
        _KEY_FILE_      "$key_file" \
        _CA_FILE_       "$ca_file" \
        _LIB_           "$lib" \
        < $apache_conf_tmpl \
        > $apache_conf && echo "OK" || errClean

# update wardenWatchdog configuration file
echo -n "Updating Warden Watchdog configuration file ... "
hostname=$(getConfValue "$watchdog_conf" hostname)
contact=$(getConfValue "$watchdog_conf" contact)
email_subject=$(getConfValue "$warden_conf" email_subject)
email_server_conf=$(getConfValue "$warden_conf" email_server_conf)
doTemplate \
        _HOSTNAME_		"$hostname" \
        _CONTACT_		"$contact" \
        _EMAIL_SUBJECT_		"$email_subject" \
        _EMAIL_SERVER_CONF_	"$email_server_conf" \
        < $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 updated configuration files:"
echo " - $server_conf"
echo " - $server_conf"
echo " - $watchdog_conf"
echo
echo "Warden server directory: $basedir"
echo
echo "Update from $old_package_version to $package_version package was SUCCESSFUL!!!"
echo
echo "Please follow post-update steps in ${doc}/UPDATE!"
echo

# cleanup section
rm -f "$err" "$backup"

exit 0
