#!/usr/bin/bash
#
# This script obtains the IP address of a marvin-based KVM instance. It can
# optionally timeout
#
# VM name is passed as first parameter, i.e., `--vm foo`. If no `--vm` param
# is passed, the VM name is assumed to be in $MARVIN_KVM_DOMAIN. If such
# variable is undefined, we fall back to `marvin-mmtests`.
#
# If both VM name and timeout must be specified, `--vm foo` should be the
# first parameter and timeout the second.
#
# Mel Gorman <mgorman@suse.com> 2016

if [ "$MARVIN_KVM_DOMAIN" = "" ]; then
	export MARVIN_KVM_DOMAIN="marvin-mmtests"
fi

if [ "$1" = "--vm" ]; then
	shift
	VM="$1"
	shift
else
	VM=$MARVIN_KVM_DOMAIN
fi

GUEST_IP=
TIMEOUT=$1
STARTTIME=`date +%s`

lookup_state() {
	local _ip=$1
	local _state="REACHABLE"

	if [ "`which ip 2> /dev/null`" != "" ]; then
		_state=`ip n show | grep ^$_ip | awk '{print $NF}'`
	fi
	echo $_state
}

while [ "$GUEST_IP" = "" ]; do
	if [ "$TIMEOUT" != "" ]; then
		CURRENTTIME=`date +%s`
		RUNNING=$((CURRENTTIME-STARTTIME))
		if [ $RUNNING -gt $TIMEOUT ]; then
			echo "ERROR: Timeout exceeded for discovering $VM IP address" >&2
			exit -1
		fi
	fi

	if [ "`virsh dumpxml $VM | grep "mac addres"`" = "" ]; then
		sleep 10
		continue
	fi

	# There could be more than one NIC in the VM
	for MAC_ADDRESS in `virsh dumpxml $VM | grep "mac address" | sed "s/.*'\(.*\)'.*/\1/g"`; do
		if [ "`which arp 2> /dev/null`" != "" ]; then
			GUEST_IP=`arp -an | grep "$MAC_ADDRESS" | awk '{ gsub(/[\(\)]/,"",$2); print $2 }'`
		else
			GUEST_IP=`ip n show | grep "$MAC_ADDRESS" | awk '{print $1}'`
		fi

		# We may have got more than one address. Go over the list and
		# pick the first that answers to a ping.
		for IP in $GUEST_IP ; do
			if ping -c 1 -q $IP &> /dev/null ; then
				while [ "$(lookup_state $IP)" != "REACHABLE" ]; do
					sleep 1
				done
				echo $IP
				exit 0
			fi
		done
	done

	if [ "$GUEST_IP" = "" ]; then
		sleep 10
	fi
done

exit -1
