#!/bin/sh

set -e

if [ -r /etc/default/openstack-tempest-ci ] ; then
	. /etc/default/openstack-tempest-ci
fi

if [ -n "${1}" ] ; then
	OTCI_DEBIAN_REPO_URL=${1}
else
	if [ -z "${OTCI_DEBIAN_REPO_URL}" ] ; then
		OTCI_DEBIAN_REPO_URL=http://http.debian.net/debian
	fi
fi

if [ "${OTCI_VIRT_MODE}" = "xen" ] || [ "${OTCI_VIRT_MODE}" = "ipmi" ] ; then
	OTCI_SSH_USER=root
else
	OTCI_SSH_USER=debian
fi

APT_INSTALL="sudo DEBIAN_FRONTEND=noninteractive apt-get install -y"

get_id () {
	"$@" | awk '/ id / { print $4 }'
}

otci_delete_if_already_running () {
	echo "===> Searching for already running instance (to eventually delete)..."
	# Kill the VM if it is online already
	RUNNING_ID=`nova list | grep ${OTCI_VM_HOSTNAME} | awk '{print $2}'`
	if [ -n "${RUNNING_ID}" ] ; then
		echo "===> Deleting instance ${RUNNING_ID}..."
		nova delete ${RUNNING_ID}
		echo "-> Killed"
	else
		echo "-> Instance not running"
	fi
}

otci_launch_vm () {
	echo "===> Starting instance"
	OTCI_VM_ID=`get_id nova boot --flavor ${OTCI_INSTANCE_FLAVOR} --nic net-id=${OTCI_ETH0_NET_ID} --nic net-id=${OTCI_ETH1_NET_ID} --image ${OTCI_DEBIAN_IMAGE_ID} --key-name ${OTCI_KEYPAIR_NAME} ${OTCI_VM_HOSTNAME}`
	echo "-> Got ID: ${OTCI_VM_ID}"
}

otci_wait_until_active () {
	COUNT=50
	CYCLES=0
	OTCI_STATUS=BUILD
	echo "===> Wait until status is active"
	echo "Waiting: "
	while [ "${OTCI_STATUS}" != "ACTIVE" ] && [ ${COUNT} != 0 ] ; do
		echo ${CYCLES}
		OTCI_STATUS=`nova list | grep ${OTCI_VM_HOSTNAME} | awk '{print $6}'`
		COUNT=$(( ${COUNT} - 1 ))
		CYCLES=$(( ${CYCLES} + 1 ))
	done
	if [ "${OTCI_STATUS}" != "ACTIVE"  ] ; then
		echo "-> Timed out spawning the OTCI VM: exiting"
		exit 1
	else
		echo " -> VM is spawned \o/"
	fi
}

otci_associate_ip () {
	echo "===> Associating floating IP"
	nova floating-ip-associate ${OTCI_VM_ID} ${OTCI_FLOATING_IP_ADDR}
}


otci_provision_new_vm () {
	if [ "${OTCI_VIRT_MODE}" = "xen" ] ; then
		rm -f /var/lib/jenkins/.ssh/known_hosts
		ssh -o "StrictHostKeyChecking no" root@${OTCI_XEN_DOM0_IP} /root/p
	elif [ "${OTCI_VIRT_MODE}" = "ipmi" ] ; then
		# In the case of ipmi provisionning, we expect the machine to be setup to
		# just run Debian live with the Jenkins /var/lib/jenkins/.ssh/id_rsa.pub key
		# setup in /root/.ssh/authorized_keys2. So just a reboot of the machine
		# brings it fresh and ready. Therefore, we just turn the machine off, then
		# on again, using IPMI.
		echo "===> Powering the tempest machine down"
		IPMI_PASSWORD=${OTCI_IPMI_PASS} ipmitool -H ${OTCI_IPMI_IP_ADDR} -U ${OTCI_IPMI_LOGIN} -I lan -E chassis power off
		echo "===> Waiting 10 seconds before starting it again"
		for i in `seq 0 10` ; do
			echo $i
			sleep 1
		done
		echo "===> Powering the machine on again"
		IPMI_PASSWORD=${OTCI_IPMI_PASS} ipmitool -H ${OTCI_IPMI_IP_ADDR} -U ${OTCI_IPMI_LOGIN} -I lan -E chassis power on
		echo "===> Waiting 90 seconds for the machine to be up again"
		for i in `seq 0 90` ; do
			echo $i
			sleep 1
		done
	else
		otci_delete_if_already_running
		otci_launch_vm
		otci_wait_until_active
		otci_associate_ip
		otci_wait_for_ssh
		otci_aptget_update
		otci_upgrade_kernel
		otci_reboot
	fi
}

otci_wait_for_ssh () {
	if [ -e /var/lib/jenkins/.ssh/known_hosts ] ; then
		rm /var/lib/jenkins/.ssh/known_hosts
	fi
	COUNT=120
	CYCLES=0
	OTCI_CAN_SSH=no
	echo "===> Wait until we can ssh"
	echo "Waiting: "
	while [ "${OTCI_CAN_SSH}" != "yes" ] && [ ${COUNT} != 0 ] ; do
		echo ${CYCLES}
		if ssh -o "StrictHostKeyChecking no" root@${OTCI_FLOATING_IP_ADDR} 'echo -n ""' ; then
			OTCI_CAN_SSH=yes
		else
			COUNT=$(( ${COUNT} - 1 ))
			CYCLES=$(( ${CYCLES} + 1 ))
			sleep 1
		fi
	done
}


otci_remote () {
	ssh -o "StrictHostKeyChecking no" ${OTCI_SSH_USER}@${OTCI_FLOATING_IP_ADDR} $@
}

otci_scp () {
	scp -o "StrictHostKeyChecking no" ${1} ${OTCI_SSH_USER}@${OTCI_FLOATING_IP_ADDR}:${2}
}

otci_aptget_update () {
	# Do not use pdiffs, they are bad...
	echo "Acquire::PDiffs \"false\";" >temp_file
	otci_scp temp_file ""
	otci_remote "sudo cp temp_file /etc/apt/apt.conf.d/98nopdiff"
	rm temp_file
	# Use the closest mirror, as defined in pkgos.conf
	otci_remote "sudo sed -i 's#http://http.debian.net/debian#${OTCI_DEBIAN_REPO_URL}#' /etc/apt/sources.list"
	# Add the current repos
	otci_scp /etc/openstack-tempest-ci/openstack-ci.list ""
	otci_remote "cp openstack-ci.list /etc/apt/sources.list.d/openstack.list"
	# Add the key repo
	gpg --export -a >repo-key.gpg
	otci_scp repo-key.gpg ""
	otci_remote "apt-key add repo-key.gpg"
	# Finally update
	otci_remote "sudo apt-get update"
}

otci_upgrade_kernel () {
	otci_remote "sudo ${APT_INSTALL} -t wheezy-backports linux-image-amd64"
	otci_remote "sudo ${APT_INSTALL} grub-pc"
}

otci_reboot () {
	otci_remote "sudo shutdown -r now"
	sleep 5
}

otci_add_source_list () {
	echo "===> Hacking source list and apt keys: TODO: make this better..."
	echo "-> scp source list"
	otci_scp /etc/openstack-tempest-ci/openstack-ci.list
	echo "-> Install new source list"
	otci_remote "sudo mv openstack-ci.list /etc/apt/sources.list.d/openstack.list"
	DEBIAN_RELEASE_NAME=`lsb_release -c | awk '{print $2}'`
	if [ -r /etc/pkgos/pkgos.conf ] ; then
		. /etc/pkgos/pkgos.conf
	fi
	if [ -z "${TARGET_OPENSTACK_REL}" ] ; then
		TARGET_OPENSTACK_REL=mitaka
	fi
	echo "-> wget Jenkins key"
	otci_remote "wget http://${TARGET_OPENSTACK_REL}-${DEBIAN_RELEASE_NAME}.pkgs.mirantis.com/debian/dists/pubkey.gpg"
	echo "-> Install Jenkins key"
	otci_remote "sudo apt-key add pubkey.gpg"
	echo "-> Updating source list"
	otci_remote "sudo apt-get update"
}

otci_install_openstack_deploy () {
	echo "===> Installing openstack-deploy"
	otci_remote "${APT_INSTALL} openstack-deploy"
	echo "===> Deploying OpenStack"
	otci_remote "sudo openstack-deploy --non-interactive all-in-one"
	if ! [ "${OTCI_VIRT_MODE}" = "ipmi" ] ; then
		echo "===> Switching to qemu"
		otci_remote "${APT_INSTALL} nova-compute-qemu"
		otci_remote "/etc/init.d/nova-compute restart"
	else
		otci_remote "${APT_INSTALL} qemu-utils"
	fi
	echo "===> Running openstack-deploy-proxy-network"
	otci_remote "sudo openstack-deploy-proxy-network --mgmt-ip-cidr ${OTCI_ETH1_CIDR} --mgmt-if eth1 --ext-host-min ${OTCI_PUBIP_START} --ext-host-max ${OTCI_PUBIP_END} --local-ip ${OTCI_LOCAL_IP}"
	echo "===> Deploying tempest"
	if [ "${OTCI_VIRT_MODE}" = "ipmi" ] ; then
		LVMTYPE="resetup --otci-lvm-device sda"
	else
		LVMTYPE=loopback
	fi
	echo "-> Running: otci_remote sudo openstack-deploy-tempest --otci-lvmtype ${LVMTYPE} --otci-openstack-debian-images-deb-repo ${OTCI_DEBIAN_REPO_URL}"
	otci_remote "sudo openstack-deploy-tempest --otci-lvmtype ${LVMTYPE} --otci-openstack-debian-images-deb-repo ${OTCI_DEBIAN_REPO_URL}"
}

otci_add_ovs_ip () {
	otci_remote "ifconfig eth1:0 ${OTCI_LOCAL_IP} netmask 255.255.255.0 up"
}

otci_run_tempest () {
	echo "===> Running tempest"
	otci_remote tempest_debian_shell_wrapper
	echo "
All tests passed:                                                                               
______  _______ ______  _____ _______ __   _       ______ _     _        _______ ______   /
|     \ |______ |_____]   |   |_____| | \  |      |_____/ |     | |      |______  ____/  / 
|_____/ |______ |_____] __|__ |     | |  \_|      |    \_ |_____| |_____ |______ /_____ .  
"
	echo "===> Merging repos"
	openstack-tempest-merge-repo

	echo "
 █████╗ ██╗     ██╗         ██████╗  █████╗ ███████╗███████╗███████╗██████╗ ██╗
██╔══██╗██║     ██║         ██╔══██╗██╔══██╗██╔════╝██╔════╝██╔════╝██╔══██╗██║
███████║██║     ██║         ██████╔╝███████║███████╗███████╗█████╗  ██║  ██║██║
██╔══██║██║     ██║         ██╔═══╝ ██╔══██║╚════██║╚════██║██╔══╝  ██║  ██║╚═╝
██║  ██║███████╗███████╗    ██║     ██║  ██║███████║███████║███████╗██████╔╝██╗
╚═╝  ╚═╝╚══════╝╚══════╝    ╚═╝     ╚═╝  ╚═╝╚══════╝╚══════╝╚══════╝╚═════╝ ╚═╝"

}

otci_provision_new_vm
otci_wait_for_ssh
otci_aptget_update
if ! [ "${OTCI_VIRT_MODE}" = "ipmi" ] ; then
	otci_add_source_list
else
	otci_add_ovs_ip
fi
otci_install_openstack_deploy
otci_run_tempest
