#!/bin/bash
#
# update.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="1.0"

#-------------------------------------------------------------------------------
#				FUNCTIONS
#-------------------------------------------------------------------------------
usage()
{
	echo "Usage: `basename $0` [-d <directory>] [-hV]"
	echo "-d <directory>            destination directory (default: /opt)"
	echo "-h                        print this help"
	echo "-V                        print script version number and exit"
	echo
	echo "Example: # ./`basename $0` -d /opt"
	echo
	echo "Note: You must be root for running this script."
	echo "      For more information about update process, see README file (section Update)."
	echo
	exit 0
}


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


err()
{
	echo "FAILED!"
	cat $err
	rm -rf $err
	rm -rf $backup_dir
	echo
	echo "Update from $old_package_name to $package_name package FAILED!!!"
	exit 1
}


err_clean()
{
	echo "FAILED!"
	echo " -> Reverting changes of warden client package ... OK"
	rm -rf "$client_path/*" > /dev/null 2>&1
	cp -R "$backup_dir/*" $client_path
	cat $err
	rm -rf $err $backup_dir
	echo
	echo "Update from $old_package_name to $package_name 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
}


obtain_package_version()
{
	if [ -f $old_package_version_file ]; then 
		old_package_version=`cat $old_package_version_file`
		if [ "$old_package_version" == "$package_version" ]; then
			echo "Sorry, but $package_version package is already installed!"
			exit 1
		fi
	else
		echo "Sorry, but warden-client package is not installed!"
		echo "For installation of warden client package please use install.sh script."
		exit 1
	fi
}


perl_chck()
{
	echo -n "Checking Perl interpreter ... "
	which perl 1>/dev/null; ret_val=`echo $?`
	if [ $ret_val -eq 0 ]; then
		echo "OK"
	else
		echo "FAILED!"
		echo "Error: Perl interpreter is not installed!" 
		exit 1
	fi
}


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


warden_dir_chck()
{
	echo -n "Checking warden client directory ... "
	if [ ! -d $client_path ]; then
		echo "FAILED!"
		ls $client_path
		exit 1
	else
		echo "OK"
	fi
}


backup()
{
	echo -n "Backing-up warden client directory ... "
	mkdir $backup_dir
	cp -R $client_path $backup_dir 2> $err; ret_val=`echo $?`
	if [ $ret_val -eq 0 ]; then
		echo "OK"
	else
		err
	fi
}


obtain_warden_user()
{
	echo -n "Obtaining warden client directory owner ... "
	user=`stat -c %U $conf_file` 2> $err; ret_val=`echo $?`
	if [ $ret_val -eq 0 ]; then
		echo "OK"
	else
		err
	fi
}


update_warden_dir()
{
	echo -n "Updating warden client directory ... "
	rsync -q --recursive --archive --delete	--exclude='etc' --exclude='var' "$dirname/warden-client" $prefix 2> $err; ret_val=`echo $?`
	if [ $ret_val -eq 0 ]; then
		echo "OK"
	else
		err_clean
	fi

	files=(CHANGELOG INSTALL LICENSE README README.cesnet)
	for file in ${files[@]};
	do  
		cp -u "$dirname/$file" "$client_path/doc"
	done
	cp -u "$dirname/uninstall.sh" "$client_path"
	cp -u "$dirname/package_version.txt" "$client_path"
}


make_conf_file()
{
	echo -n "Creating configuration file ... "
	uri=`cat $conf_file | grep '$URI'`
	ssl_key_file=`cat $conf_file | grep '$SSL_KEY_FILE'`
	ssl_cert_file=`cat $conf_file | grep '$SSL_CERT_FILE'`
	ssl_ca_file=`cat $conf_file | grep '$SSL_CA_FILE'`
	echo "#
# warden-client.conf - configuration file for the warden sender/receiver client
#

#-------------------------------------------------------------------------------
# URI - URI address of Warden server
#-------------------------------------------------------------------------------
$uri

#-------------------------------------------------------------------------------
# SSL_KEY_FILE - path to client SSL certificate key file
#-------------------------------------------------------------------------------
$ssl_key_file

#-------------------------------------------------------------------------------
# SSL_CERT_FILE - path to client SSL certificate file
#-------------------------------------------------------------------------------
$ssl_cert_file

#-------------------------------------------------------------------------------
# SSL_CA_FILE - path to CA certificate file
#-------------------------------------------------------------------------------
$ssl_ca_file
" > $conf_file 2> $err; ret_val=`echo $?`

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


change_permissions()
{
	echo -n "Changing permissions to updated package ... "
	chown -R $user: $client_path 2>$err; ret_val=`echo $?`
	if [ $ret_val -eq 0 ]; then
		echo "OK"
	else
		err_clean
	fi
}



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

# list of used Perl modules
modules=(SOAP::Lite IO::Socket::SSL SOAP::Transport::TCP FindBin DateTime)

# OS test
os_chck

# Shell test
shell_chck

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

# root test
root_chck

# params test
params_chck

# create variables
dirname=`dirname $0`
package_version=`cat $dirname/package_version.txt`
[[ $prefix == */ ]] && prefix="${prefix%?}" # remove last char (slash) from prefix
client_path="$prefix/warden-client"
etc="$client_path/etc"
old_package_version_file="$client_path/package_version.txt"
conf_file="$etc/warden-client.conf"
err="/tmp/warden-err"
backup_dir="/tmp/warden-backup"

# obtain version of old warden client
#obtain_package_version		# ENABLE for next client package
old_package_version="1.0.0"

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

# Perl interpreter test
perl_chck

# Perl modules test
modules_chck

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

# check warden client directory
warden_dir_chck

# backup old warden client installation
backup

# obtain current warden client user
obtain_warden_user

# make warden client directory
update_warden_dir

# create conf file
make_conf_file

# change permissions
change_permissions

echo
echo "Please check configuration file in $conf_file!"
echo
echo "Update from $old_package_version to $package_version package was SUCCESSFUL!!!"

# cleanup section
rm -rf $err $backup_dir

exit 0
