#!/bin/sh

## vlan.sh
## ---------------------------------------------------------------------------
##   Author:		Daniel creo Haslinger	http://creo.blackmesa.at
##   Description:	Bridge virtual ethernet interfaces of virtual entities
##   			to their devices on the host based on configuration.
##   Version:		0.2 (2011-07-29)
## ---------------------------------------------------------------------------



# This name appears in all terminal outputs when I'm working
my_procname="Bridging::PostPrepare"

# After how many seconds should I give up waiting for the VE to come up?
VE_STATUS_TIMEOUT=30




## --------------- obviously you ran out of arguments here ..


if [ $# -eq 0 ]
then
	echo "usage: $0 <container_id>"
	exit 1
fi





## --------------- glad to see you here, lets check our for our dependencies

which brctl > /dev/null 2>&1
if [ $? -gt 0 ]
then

	# we depend on bridge-utils here, so sorry for that but ...

	echo "$my_procname: FAILED! brctl is not installed or brctl is not in PATH."
	echo "$my_procname: Install the bridge-utils package or check your environment settings."
	echo "$my_procname: Quitting PostPreparation. VE startup will resume though."

	exit 1

fi





## --------------- okaaay, so we need this kernel module, do we not?


veth_module_mounted=`lsmod | grep vzethdev | wc -l`
	
if [ $veth_module_mounted -eq 0 ]
then

	# The openVZ eth Kernel Module is not loaded.
	# When we start up the VE, this might cause the VE to hang
	# within the boot procedure, so we load the module manually here.
	# In a perfect world, vzethdev would be written into /etc/modules!

	echo "$my_procname: Loading VZETHDEV module to kernel..."
	modprobe vzethdev > /dev/null 2>&1
	if [ $? -gt 0 ]
	then
		echo "$my_procname: FAILED! The kernel rejected to load VZETHDEV."
		echo "$my_procname: Quitting PostPreparation. VE startup will resume."
		exit 2
	else
		echo "$my_procname: Module ready. Please consider putting it into /etc/modules!"
	fi

fi





## --------------- what about the VE we're going to work for here ... is it all OK?


health=`/usr/sbin/vzctl status $1 | cut -d\  -f3`

if [ "$health" = "deleted" ]
then
	echo "$my_procname: This container does not exist [status:deleted]."
	exit 3
fi





## --------------- so we go to sleep for a while and wait for the VE to start up

sleep 5
secondswaited=5

while :
do



	## ------- are we here already?


	status=`/usr/sbin/vzctl status $1 | cut -d\  -f5`

	if [ "$status" = "running" ]
	then



		##  oh well, the VE is finally started and we can move on to configure
		##  this shiny bridge to connect the virtual ethernet device(s) to our (semi-)physical one(s)


		for a in `grep "NETIF" /etc/vz/conf/$1.conf | grep "bridge" | grep -v "#"`
		do
			
			# the interface within our virtual entity
			container_interface=`echo $a | sed -n -e 's/.*host_ifname=\(.*\),.*/\1/p' | cut -d, -f1`

			# where do we patch that up to?
			desired_bridge=`echo $a | sed -n -e 's/.*bridge=\(.*\)./\1/p'`

			# so let's do this
			/usr/sbin/brctl addif $desired_bridge $container_interface > /var/log/vz_postconfigure.log 2>&1

			echo "$my_procname: Bridging of $container_interface to $desired_bridge completed."

		done

		echo "$my_procname: Succeeded! Quitting PostPreparation."

		exit 0

	else


		##  so the VEs still not up and running .. well, let's give it a few more seconds
		##  just to be sure ...


		sleep 3
		let secondswaited=$secondswaited+3

		if [ $secondswaited -gt $VE_STATUS_TIMEOUT ]
		then

			# oh my, this really took too long now. I'm going to quit, maybe you should
			# check what's wrong with the VE or get a faster host node.

			# NOTICE: Though I never saw some, slow startups might happen on some system
			#         configurations, so adapt the value ( VE_STATUS_TIMEOUT ) to whatever
			#         suits to your situation.

			echo "$my_procname: FAILED! VE not running after 30 seconds."
			echo "$my_procname: Quitting PostPreparation."
			exit 4
		fi	

	fi

done
