#!/bin/sh

# Creates an Amazon EC2 virtual machine (an instance), uploads a POV
# <http://www.povray.org/> scene description file and process it,
# before terminating the machine. Just an example.
# Stephane Bortzmeyer <stephane@bortzmeyer.org>

# Parameters you can set.
# Choose an AMI you like (ami-02103876 is a Debian "lenny"). 
AMI=ami-02103876
# If POV-ray is not installed in the AMI, install it (warning: works
# only on Debian). On october 2011, there was no public AMI with
# POV-ray.
INSTALL_POV=1
# Create your key pair first
KEY=test-b
KEYDIR=.
# The user name to use depends on the AMI. "root" is common but check
# the documentation of the AMI.
USERNAME=root
# Small machines are less expensive, large machines are faster. See
# <http://aws.amazon.com/ec2/instance-types/>. Must match the AMI
# (32-bits AMI do not run on large machines, which are all 64-bits).
MACHINE_TYPE=m1.small
POV_OPTIONS="-D -V +W2000 +H2000 +Q11 +A0.1"
MAX_CONNECTS=5
MAX_TESTS=7

# If you want to change from the default region, set the environment
# variable EC2_URL for instance 'export
# EC2_URL=https://ec2.eu-west-1.amazonaws.com' to use the 'eu-west-1'
# region

# Also, be sure your default security group allows incoming SSH.

if [ "${EC2_PRIVATE_KEY}" = "" ] || [ "${EC2_CERT}" = "" ]; then
    echo "You need to have X.509 certificate and private key locally, and to set the environment variables EC2_PRIVATE_KEY and EC2_CERT to indicate their locations" 1>&2
    exit 1
fi

POV_FFILE=$1
if [ "${POV_FFILE}" = "" ]; then
    echo "Usage: $0 POV-file (without the extension)" 1>&2
    exit 1
fi
POV_FILE=$(basename $POV_FFILE)

start=$(ec2-run-instances --instance-type ${MACHINE_TYPE} --key ${KEY} $AMI)
if [ $? != 0 ]; then
    echo "Machine did not start" 1>&2
    exit 1
fi

AMI_E=$(echo "$start" | awk '/^INSTANCE/ {print $3}')
if [ "$AMI_E" != "$AMI" ]; then
    echo "AMI does not match (got $AMI_E instead of $AMI), the machine probably did not start" 1>&2
    exit 1
fi
INSTANCE=$(echo "$start" | awk '/^INSTANCE/ {print $2}')

# I do not find a way to block until the machine is ready. We
# apparently have to poll.
OVER=0
TESTS=0
while [ $OVER != 1 ] && [ $TESTS -lt $MAX_TESTS ]; do
    description=$(ec2-describe-instances ${INSTANCE})
    STATE=$(echo "$description" | awk '/^INSTANCE/ {print $6}')
    NAME=$(echo "$description" | awk '/^INSTANCE/ {print $4}')
    if [ "$NAME" = "" ]; then
	echo "No instance ${INSTANCE} available. Crashed or was terminated." 1>&2
	exit 1
    fi
    if [ $STATE = "running" ]; then
	OVER=1
    else
	# I like bc but 'echo $(( TESTS+=1 ))' should work, too. Or expr.
	TESTS=$(echo $TESTS+1 | bc)
	sleep 2
    fi
done
if [ $TESTS = $MAX_TESTS ]; then
    echo "${INSTANCE} never got to running state" 1>&2
    ec2-terminate-instances ${INSTANCE}
    exit 1
fi
echo "$INSTANCE is running, name is $NAME"
# The SSH server does not seem reachable immediately. We again have to poll
OVER=0
TESTS=0
while [ $OVER != 1 ] && [ $TESTS -lt $MAX_CONNECTS ]; do
    ssh -o "StrictHostKeyChecking no" -i ${KEYDIR}/${KEY}.pem ${USERNAME}@$NAME id
    if [ $? != 255 ]; then
	OVER=1
    else
	TESTS=$(echo $TESTS+1 | bc)
	sleep 3
    fi
done
if [ $TESTS = $MAX_CONNECTS ]; then
    echo "Cannot connect to ${NAME}" 1>&2
    ec2-terminate-instances ${INSTANCE}
    exit 1
fi
if [ $INSTALL_POV = 1 ]; then
    # TODO: another solution would be to put the code in a script in user_data
    ssh -o "StrictHostKeyChecking no" -i ${KEYDIR}/${KEY}.pem ${USERNAME}@$NAME \
	"echo 'deb http://ftp.proxad.net/mirrors/ftp.debian.org/ lenny non-free' >> /etc/apt/sources.list; aptitude update; aptitude --allow-untrusted --assume-yes install povray povray-includes"
fi
# TODO: test the installation was successful
scp -o "StrictHostKeyChecking no" -i ${KEYDIR}/${KEY}.pem ${POV_FFILE}.pov ${USERNAME}@$NAME:/tmp/${POV_FILE}.pov
ssh -o "StrictHostKeyChecking no" -i ${KEYDIR}/${KEY}.pem ${USERNAME}@$NAME \
    "cd /tmp; povray +O${POV_FILE}.png ${POV_OPTIONS} ${POV_FILE}.pov"
scp -o "StrictHostKeyChecking no" -i ${KEYDIR}/${KEY}.pem ${USERNAME}@$NAME:/tmp/${POV_FILE}.png ${POV_FFILE}.png

ec2-terminate-instances ${INSTANCE}


