#!/bin/bash

# (C) Copyright Canonical 2011,2012

# What lxc container to clone
LXC_BASE=""
# $2 is a path to bind mount e.g. /tmp/foo.
LXC_BIND=""

usage() {
    echo "usage: lxc-start-ephemeral [-h] [-b bdir] -o orig -- [COMMAND [ARGS...]]"
}

help() {
    usage
    echo
    echo "Runs an ephemeral (one-off) container"
    echo
    echo "Options:"
    echo "orig        : name of the original container"
    echo "bdir        : directory to bind mount into container"
    echo
    echo "if a COMMAND is given, then the container will run only as long"
    echo "as the command runs.  If no COMMAND is given, this command will"
    echo "wait until the container is shut down"
}

shortoptions='hb:o:'
longoptions='help,orig:,bdir:'

LXC_RUNNING=0
LXC_BIND_MOUNTED=0
LXC_MOUNTED=0

cleanup() {
    if [ $LXC_RUNNING -eq 1 ]; then
        sudo lxc-stop -n $LXC_NAME
    fi
    if [ $LXC_BIND_MOUNTED -eq 1 ]; then
        sudo umount $LXC_DIR/rootfs$LXC_BIND
    fi
    if [ $LXC_MOUNTED -eq 1 ]; then
        sudo umount $LXC_DIR
        sudo umount $OVERLAY_DIR
        sudo rmdir $LXC_DIR
        sudo rmdir $OVERLAY_DIR
    fi
    exit 1
}

trap cleanup SIGTERM SIGINT SIGQUIT 

getopt=$(getopt -o $shortoptions --longoptions  $longoptions -- "$@")
if [ $? != 0 ]; then
    usage
    exit 1;
fi

eval set -- "$getopt"

while true; do
        case "$1" in
	    -h|--help)
		help
		exit 1
		;;
	    -o|--orig)
		shift
		LXC_BASE=$1
		shift
		;;
	    -b|--bdir)
		shift
		LXC_BIND=$1
		shift
		;;
            --)
		shift
		break;;
            *)
		echo $1
		usage
		exit 1
		;;
        esac
done

LXC_USER=`id -un`

# validation

if [ -z $LXC_BASE ]; then
    echo "original container must be specified"
    usage
    exit 1
fi
if [ ! -d /var/lib/lxc/$LXC_BASE ] ; then
    echo 'no such lxc container $LXC_BASE'
    exit 1
fi

echo "Setting up ephemeral container..."
OVERLAY_DIR=`mktemp -d /tmp/lxc-lp-XXXXXXX`
sudo mount -t tmpfs none $OVERLAY_DIR
LXC_DIR=`sudo mktemp -d --tmpdir=/var/lib/lxc $LXC_BASE-temp-XXXXXXX`
LXC_NAME=`basename $LXC_DIR`
sudo mount -t overlayfs -oupperdir=$OVERLAY_DIR,lowerdir=/var/lib/lxc/$LXC_BASE none $LXC_DIR
LXC_MOUNTED=1
if [ -n "$LXC_BIND" ]; then
    sudo mkdir -p $LXC_DIR/rootfs$LXC_BIND
    sudo mount --bind $LXC_BIND $LXC_DIR/rootfs$LXC_BIND
    LXC_BIND_MOUNTED=1
fi
sudo sed -i -e "s/$LXC_BASE/$LXC_NAME/" $LXC_DIR/fstab $LXC_DIR/config $LXC_DIR/rootfs/etc/hostname $LXC_DIR/rootfs/etc/hosts

# precise is now the worst - its dhclient *uses*
# /var/lib/dhcp3/dhclient.eth0.leases but ships without that
# directory, so you get no leases file at all.
LEASES=$LXC_DIR/rootfs/var/lib/dhcp3/dhclient.eth0.leases
LEASES2=$LXC_DIR/rootfs/var/lib/dhcp/dhclient.leases
sudo mkdir -p $LXC_DIR/rootfs/var/lib/dhcp3
sudo mkdir -p $LXC_DIR/rootfs/var/lib/dhcp
sudo truncate -c -s0 $LEASES
sudo truncate -c -s0 $LEASES2

echo "Starting up the container..."
sudo lxc-start -n $LXC_NAME -d
LXC_RUNNING=1
sudo lxc-wait -n $LXC_NAME -s RUNNING

if [ $# -gt 0 ]; then
	# when lxc-attach support arrives in the kernel, we can switch to
	# that
	delay=30
	while [ $delay -gt 0 -a ! -s $LEASES -a ! -s $LEASES2 ]
	do
	    delay=$(( $delay - 1 ))
	    sleep 1
	done

	[ -s $LEASES ] || LEASES=$LEASES2
	IP_ADDRESS=`sudo grep fixed-address $LEASES | tail -n 1 | sed -r 's/.* ([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*/\1/'`
	if [ 0 -eq $? -a -n "$IP_ADDRESS" ]; then
	    ssh -n -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null $LXC_USER@$IP_ADDRESS -- "$@"
	else
	    echo "could not get IP address - aborting." >&2
	    echo "content of $LEASES:" >&2
	    cat $LEASES >&2
	    echo "content of $LEASES2:" >&2
	    cat $LEASES2 >&2
	fi
else
	echo "$LXC_NAME is running"
	echo "You connect with the command:"
	echo "    sudo lxc-console -n $LXC_NAME"
	sudo lxc-wait -n $LXC_NAME -s STOPPED
fi

echo "Stopping lxc" >&2
sudo lxc-stop -n $LXC_NAME
sleep 2
if [ -n "$LXC_BIND" ]; then
    echo "umounting bind" >&2
    sudo umount $LXC_DIR/rootfs$LXC_BIND
fi
# echo "umounting lxc_dir $LXC_DIR" >&2
sudo umount $LXC_DIR
# echo "umounting overlay" >&2
sudo umount $OVERLAY_DIR
# echo "rming lxc_dir $LXC_DIR" >&2
sudo rmdir $LXC_DIR
# echo "rming overlay dir $OVERLAY_DIR" >&2
sudo rmdir $OVERLAY_DIR
