#!/bin/bash
# $Id: cache-os,v 1.14 2005/10/27 11:04:21 kir Exp $
#
# Copyright (C) 2003, 2004, 2005 by SWsoft. Licensed under QPL.
#
# Creates/updates OS template cache.

#DEBUG_LEVEL=5
TOOLDIR=/usr/share/vzpkg


. ${TOOLDIR}/functions
VZCTL="$VZCTL --quiet --skiplock"

log4 Started $0 $*

### Functions

function usage()
{
	echo "Usage: $PROGNAME [-r | -f] <template>"
	exit 0
}

# Kills/umounts/destroys VPS.
# Parameters:
#  $1 - VPS ID
function cleanup()
{
	local vps=$1
	log4 "Called cleanup($vps)"
	log4 "Calling vzctl stop $vps"
	$VZCTL stop $vps --fast
	log4 "Calling vzctl umount $vps"
	$VZCTL umount $vps
	log4 "Calling vzctl destroy $vps"
	$VZCTL destroy $vps
	log4 "Calling rm -f $VECFGDIR/$vps.*"
	rm -f $VECFGDIR/$vps.*
	unlock_ve $vps
}

if test $# -lt 1; then
	log2 "Wrong number of parameters specified"
	usage
fi

REMOVE=''
FORCE=''
case $1 in
	-r | --remove)
		REMOVE=yes
		shift
		;;
	-f | --force)
		FORCE=yes
		shift
		;;
	-*)
		log2 "Unknown option: $1"
		usage
esac

TEMPLATE=`get_vz_var TEMPLATE`

OST=`ost2full $1` || abort "No such OS template: $1"
set $OST
OSNAME=$1
OSVER=$2
OSSET=$3
OSARCH=$4
TDIR=$5
check_ost_exists $OSNAME $OSVER $OSSET $OSARCH || exit 1

OSTEMPLATE="$OSNAME-$OSVER-$OSARCH-$OSSET"
CACHE=$OSTEMPLATE.tar.gz
CACHEDIR=`get_cache_dir`

if test "x$REMOVE" != "x"; then
	log3 "Removing OS template cache for $OSTEMPLATE template"
	log4 "Cache file name: $CACHEDIR/$CACHE"
	test -f $CACHEDIR/$CACHE || \
		log2 "Cache file $CACHEDIR/$CACHE is not found!"
	rm -f $CACHEDIR/$CACHE
	# If there is a symlink (for older vzctl) remove it as well
	test -L $TEMPLATE/$CACHE && rm -f $TEMPLATE/$CACHE
	exit 0
fi

VEID=`find_lock_nearest_veid 100000` || abort "Can't find free VPS ID"
log4 "Using temporary VPS $VEID"
VE_PRIVATE=`get_vz_var VE_PRIVATE`
VE_ROOT=`get_vz_var VE_ROOT`


VECFG=$VECFGDIR/$VEID.conf
VECFGSAMPLE=$VECFGDIR/ve-vps.basic.conf-sample
# simple init - for initial VPS startup, statically linked
MYINIT=${TOOLDIR}/myinit.${OSARCH}

function terminate()
{
	log4 "\ncalling cleanup()"
	cleanup $VEID
}
trap terminate EXIT

set -u
cp -f $VECFGSAMPLE $VECFG || abort "Can't copy VPS config"
echo "DISK_QUOTA=no" >> $VECFG
echo "OSTEMPLATE=$OSTEMPLATE" >> $VECFG
mkdir -p $VE_ROOT $VE_PRIVATE || abort "Can't create VPS dirs"
log4 Mounting VPS private area
$VZCTL mount $VEID || abort "Can't mount VPS $VEID"

test -f $CACHEDIR/$CACHE && log4 "File $CACHEDIR/$CACHE exists"

# Set up PYTHONPATH for our vzyum
PYTHONPATH=`get_rpm_pythonhome $TDIR`
export PYTHONPATH
log4 PYTHONPATH=$PYTHONPATH
YUM_CONF_FILE=`yum_conf $TDIR`

# Check if we are going to update cache
if test -f $CACHEDIR/$CACHE -a "x$FORCE" = "x"; then
	log3 "Updating cache for $OSTEMPLATE OS template"
	OPERATION="update"
	log4 "Untarring $CACHEDIR/$CACHE"
	export VE_PRVT=$VE_PRIVATE
	export PRIVATE_TEMPLATE=$CACHEDIR/$CACHE
	$VZLIB_SCRIPTDIR/vps-create || \
		abort "Failed to create a VPS based on cache $CACHE"
	# Check if updates are available
	# We use $YUM not vzyum here as latter requires VPS to be running
	$YUM --installroot $VE_ROOT $YUM_CONF_FILE \
		--vps=$VEID check-update
	YUMEC=$?
	if test $YUMEC -eq 0; then
		log3 "No updates are available"
		exit 0
	elif test $YUMEC -eq 100; then
		log3 "Updates are available - proceeding with update"
	else
		abort "Command yum check-update failed with $YUMEC exit code"
	fi
else
	log3 "Creating cache for $OSTEMPLATE OS template"
	OPERATION="install"
	# Fake init placed in order for VPS to be able to start
	mkdir $VE_ROOT/sbin || abort "Can't create dir $VE_ROOT/sbin"
	cp -f $MYINIT $VE_ROOT/sbin/init || \
		abort "Unable to copy $MYINIT to VPS root ($VE_ROOT)"
	mkdir $VE_ROOT/proc || abort "Can't create dir $VE_ROOT/proc"
fi


# Run setup-pre script
call_template_script $TDIR $OPERATION-pre || \
	abort "Script $OPERATION-pre failed"

# Start VPS now
log4 Starting VPS
$VZCTL start $VEID || abort "Can't start VPS $VEID"


# install packages
if test $OPERATION = 'install'; then
	LIST=`get_packages $TDIR $OSSET`
	YUM_CMD="install $LIST"
	# install gpg keys
	import_gpgkeys $TDIR
elif test $OPERATION = 'update'; then
	YUM_CMD="update"
else
	# this shouldn't happen
	abort "Internal error: unknown OPERATION $OPERATION"
fi

# Dirty dirty hack for yum/rpm to read RPM macros from the file .rpmmacros
# which resides in our template configuration directory. If you know a better
# way of doing it, please enlighten me.
XX_HOME=$HOME
export HOME=$TDIR/config

YUM_CMD="--installroot=$VE_ROOT --vps=$VEID $YUM_CONF_FILE -y $YUM_CMD"
# -d $DEBUG_LEVEL
log4 "Running $YUM $YUM_CMD"
# FIXME1: We use $YUM not vzyum because latter requires OSTEMPLATE to be set.
# FIXME2: We do set OSTEMPLATE, so what's the problem? Need to find out.
$YUM $YUM_CMD || abort "yum failed with $? exit code"
export HOME=$XX_HOME
unset XX_HOME

call_template_script $TDIR $OPERATION-post || \
	abort "Script $OPERATION-post failed"

# Stop this VPS
log4 Stopping VPS
$VZCTL stop $VEID --fast
log4 vzctl exit code $?

# Umount VPS
log4 Unmounting VPS
$VZCTL umount $VEID
log4 vzctl exit code $?

# Create tarball
pushd $VE_PRIVATE > /dev/null
log3 "Packing cache file $CACHE ... "
mkdir -p $CACHEDIR
tar --numeric-owner --exclude $CACHE -zcf $CACHE . || abort "tar failed"
#pwd
#ls -lh
test -f $CACHEDIR/$CACHE && mv $CACHEDIR/$CACHE $CACHEDIR/$CACHE-old
mv $CACHE $CACHEDIR

CACHESIZE=`ls -lh $CACHEDIR/$CACHE | awk '{print $5}'`

log3 "Cache file $CACHE [$CACHESIZE] created."
popd > /dev/null

log4 Destroying VPS
$VZCTL destroy $VEID
log4 vzctl exit code $?
log4 rm -f $VECFGDIR/$VEID.*
rm -f $VECFGDIR/$VEID.*
unlock_ve $VEID
