#!/bin/bash

CT_OSTEMPLATE="vzlinux-7-x86_64"
TEMPLATE_CPATH="/vz/template/vzlinux/7/x86_64/config/os/default"
MLISTS_F=$TEMPLATE_CPATH/mirrorlist
BURLS_F=$TEMPLATE_CPATH/repositories
VA_MN_MIRRORLISTS="http://repo.virtuozzo.com/va-mn/mirrorlists/7.0/releases-os.mirrorlist http://repo.virtuozzo.com/va-mn/mirrorlists/7.0/updates-os.mirrorlist"
VZPKG="/usr/sbin/vzpkg"
VZCTL="/usr/sbin/vzctl"
VZLIST="/usr/sbin/vzlist"
YUM="/usr/bin/yum"
UUIDGEN="/usr/bin/uuidgen"
GROUPS_INSTALL="va-mn va-cc"
PKGS_INSTALL="va-mn-release"
CT_NAME="va-mn"
CT_PARAMS="--ram 1G --diskspace 40G --name $CT_NAME"
ROOTPW=""
CT_IP=""
CT_HOSTNAME=""
NAMESERVERS=""
SKIP_RECACHE=0
PROGNAME=`basename ${0}`
TMPDIR=`mktemp -d /tmp/${PROGNAME}_XXXXXX`

function cleanup() {
	umount $MLISTS_F >/dev/null 2>&1
	umount $BURLS_F >/dev/null 2>&1
	[ -d $TMPDIR ] && rm -rf $TMPDIR >/dev/null 2>&1
}

function error() {
	cleanup
	echo $*
	[ "x$CTID" = "x" ] && exit 1
	echo "Removing $CTID..."
	$VZCTL stop $CTID --fast >/dev/null 2>&1
	$VZCTL destroy $CTID >/dev/null 2>&1
	exit 1
}

function check_existance() {
	local b

	for b in $*; do
		[ -x $b ] && continue
		error "$b does not exist"
	done
}

function create_script() {
	local sdata=$1
	local tpath=$2

	echo -e $sdata > $tpath 2>/dev/null
	[ $? -ne 0 ] && error "Failed to create $tpath script"
	chmod 0755 $tpath >/dev/null 2>&1
	[ $? -ne 0 ] && error "failed to chmod $tpath script"
}

function replace_file() {
	local tfile=$1
	local tmpfile=$2
	local newurls=$3

	[ ! -f $tfile ] && touch $tfile
	if [ ! -z "$newurls" ]; then
		cp $tfile $TMPDIR
		[ $? -ne 0 ] && error "Failed to prepare mirrorlists"
		for u in $newurls; do
			echo $u >> $tmpfile
			[ $? -ne 0 ] && error "Failed to add $u to $tfile"
		done
		mount -o bind $tmpfile $tfile
		[ $? -ne 0 ] && error "Failed to replace $tfile"
	fi
}

function exec_ct_cmd() {
	if [ "x$2" = "xverbose" ]; then
		$VZCTL exec $CTID $1
	else
		$VZCTL exec $CTID $1 >/dev/null 2>&1
	fi
	[ $? -ne 0 ] && error "Failed to exec $1 cmd inside $CTID"
}

function cleanup_reinstall() {
	echo "Reinstalling $CT_OSTEMPLATE..."
	if [ $SKIP_RECACHE -eq 0 ]; then
		$YUM reinstall $CT_OSTEMPLATE-ez -y >/dev/null 2>&1
		[ $? -ne 0 ] && error "Failed to reinstall $CT_OSTEMPLATE"
	fi
	$VZPKG clean $CT_OSTEMPLATE >/dev/null 2>&1
	[ $? -ne 0 ] && error "Failed to clean $CT_OSTEMPLATE"
}

function usage() {
	echo "Usage: $0 (-p|--rootpw) PASSWORD (-i|--ip) IP1[,IP2[,IP3]...] [-n|--nameserver IP1,IP2] [-h|--hostname HOSTNAME] [-s|--skip-recache]"
	cleanup
	exit 1
}

check_existance $VZPKG $VZCTL $UUIDGEN $YUM $VZLIST
[ ! -d $TMPDIR ] && error "Failed to create tmpdir!"

# Getopt
OPTS=$(getopt -o p:i:n:h:s --long rootpw:,ip:,nameserver:,hostname:,skip-recache -- "$@")

eval set -- "$OPTS"

while true; do
	case $1 in
	   -p|--rootpw)
		ROOTPW="$2"
		shift 2
		;;
	   -i|--ip)
		CT_IP="$2"
		shift 2
		;;
	   -h|--hostname)
		CT_HOSTNAME="$2"
		shift 2
		;;
	   -n|--nameserver)
		NAMESERVERS=`echo $2 | sed "s,\,, ,g"`
		shift 2
		;;
	   -s|--skip-recache)
		SKIP_RECACHE=1
		shift
		;;
	   --)
		break
		;;
	   *)
		echo "Invalid argument: $1" 1>&2
		exit 1
	esac
done

[ "x$ROOTPW" = "x" -o "x$CT_IP" = "x" ] && usage

# Get it from resolv.conf
[ "x$NAMESERVERS" = "x" ] && NAMESERVERS=`cat /etc/resolv.conf 2>/dev/null | grep ^nameserver | sed "s,^nameserver ,,g"`

trap 'error "Terminating..."' 1 2 3 15

# Check that Ct with required name doe not exist
if [ "x$($VZLIST -H -o name -N $CT_NAME)" = "x$CT_NAME" ]; then
	echo "Container with name $CT_NAME already exists!.."
	echo
	$VZLIST -n -N $CT_NAME 2>/dev/null
	error ""
fi

# Generate ctid
CTID=`$UUIDGEN 2>/dev/null`
[ "x$CTID" = "x" ] && error "failed to generate CTID"

# 0. Do prevent template reinstall to avoid any user modifications
[ $SKIP_RECACHE -eq 0 ] && cleanup_reinstall

# 1. Modify template config

# 1.1 Add virtuozzo URLs
echo "Updating $CT_OSTEMPLATE cache..."
replace_file $MLISTS_F $TMPDIR/mirrorlist "$VA_MN_MIRRORLISTS"

# 1.2 Update cache
if [ $SKIP_RECACHE -eq 0 ]; then
	$VZPKG update cache $CT_OSTEMPLATE >/dev/null 2>&1
	[ $? -ne 0 ] && error "Failed to update $CT_OSTEMPLATE cache"
fi

# 1.3 Create UI Container
echo "Creating $CTID..."
$VZCTL create $CTID --ostemplate $CT_OSTEMPLATE >/dev/null 2>&1
[ $? -ne 0 ] && error "Failed to create $CTID"

# Source ct config
CT_CONF="/etc/vz/conf/$CTID.conf"
. $CT_CONF

echo "TYPE=\"temporary\"" >> $CT_CONF
echo "AUTOSTOP=\"stop\"" >> $CT_CONF

echo "Setting up $CTID..."
for ip in `echo $CT_IP | sed "s,\,, ,g"`; do
	CT_PARAMS="$CT_PARAMS --ipadd $ip"
done
[ "x$CT_HOSTNAME" != "x" ] && CT_PARAMS="$CT_PARAMS --hostname $CT_HOSTNAME"
[ "x$ROOTPW" != "x" ] && CT_PARAMS="$CT_PARAMS --userpasswd root:$ROOTPW"
for ns in $NAMESERVERS; do
	CT_PARAMS="$CT_PARAMS --nameserver $ns"
done
$VZCTL set $CTID $CT_PARAMS --save >/dev/null 2>&1
[ $? -ne 0 ] && error "failed to set $CT_PARAMS to $CTID"

echo "Starting $CTID..."
$VZCTL start $CTID --wait >/dev/null 2>&1
[ $? -ne 0 ] && error "Failed to start $CTID"

CONF_FIREWALL="/tmp/conf_firewall"

create_script "#!/bin/bash\n
\n
FIREWALL_CMD=\"/usr/bin/firewall-cmd\"\n
FIREWALL_OFFLINE_CMD=\"/usr/bin/firewall-offline-cmd\"\n
MN_PORTS=\"389 4533 4534 4648 4450 4452 80 443 1433 22\"\n
\n
. \`dirname \$0\`/../ve.conf\n
\n
[ \"x\$IP_ADDRESS\" = \"x\" ] && exit 0\n
\n
if [ \"x\$1\" = \"x\" ]; then\n
\t    ACTION=\"add\"\n
elif [ \"\$1\" = \"--remove\" ]; then\n
\t    ACTION=\"remove\"\n
else\n
\t    exit 0\n
fi\n
\n
for ctip in \$IP_ADDRESS; do\n
\t    for port in \$MN_PORTS; do\n
\t        [ \"\${ctip#*:}\" = \"\${ctip}\" ] && ip=\"ipv4\" || ip=\"ipv6\"\n
\t        ARGS=\"--direct --\$ACTION-rule \$ip filter INPUT_direct 0 -i venet0 -s \$ctip -m tcp -p tcp --dport \$port -j ACCEPT\"\n
\t        \$FIREWALL_CMD --permanent \$ARGS && \$FIREWALL_CMD --reload || \$FIREWALL_OFFLINE_CMD \$ARGS\n
\t    done\n
done\n
\n
exit 0\n" $VE_ROOT/$CTID/$CONF_FIREWALL

echo "Installing $GROUPS_INSTALL to $CTID..."
$VZPKG install $CTID -p $PKGS_INSTALL >/dev/null 2>&1
[ $? -ne 0 ] && error "Failed to install $PKGS_INSTALL to $CTID"
$VZPKG install $CTID -g $GROUPS_INSTALL >/dev/null 2>&1
[ $? -ne 0 ] && error "Failed to install $GROUPS_INSTALL to $CTID"

$VZCTL exec $CTID $CONF_FIREWALL >/dev/null 2>&1
[ $? -ne 0 ] && error "Failed to configure firewall inside $CTID"

$VZCTL restart $CTID >/dev/null 2>&1
[ $? -ne 0 ] && error "Failed to restart $CTID"

cleanup_reinstall

echo "All done!"
cleanup

exit 0
