diff --git a/exercise.sh b/exercise.sh index cca9a13..7703f40 100755 --- a/exercise.sh +++ b/exercise.sh @@ -1,214 +1,46 @@ #!/usr/bin/env bash -# **exercise.sh** - using the cloud can be fun - -# we will use the ``nova`` cli tool provided by the ``python-novaclient`` -# package -# - - -# This script exits on an error so that errors don't compound and you see -# only the first error that occured. -set -o errexit - -# Print the commands being run so that we can see the command that triggers -# an error. It is also useful for following allowing as the install occurs. -set -o xtrace - - -# Settings -# ======== - -# Use openrc + stackrc + localrc for settings -source ./openrc - -# Get a token for clients that don't support service catalog -# ========================================================== - -# manually create a token by querying keystone (sending JSON data). Keystone -# returns a token and catalog of endpoints. We use python to parse the token -# and save it. - -TOKEN=`curl -s -d "{\"auth\":{\"passwordCredentials\": {\"username\": \"$NOVA_USERNAME\", \"password\": \"$NOVA_API_KEY\"}}}" -H "Content-type: application/json" http://$HOST_IP:5000/v2.0/tokens | python -c "import sys; import json; tok = json.loads(sys.stdin.read()); print tok['access']['token']['id'];"` - -# Launching a server -# ================== - -# List servers for tenant: -nova list - -# Images -# ------ - -# Nova has a **deprecated** way of listing images. -nova image-list - -# But we recommend using glance directly -glance -A $TOKEN index - -# Let's grab the id of the first AMI image to launch -IMAGE=`glance -A $TOKEN index | egrep ami | cut -d" " -f1` - -# Security Groups -# --------------- -SECGROUP=test_secgroup - -# List of secgroups: -nova secgroup-list - -# Create a secgroup -nova secgroup-create $SECGROUP "test_secgroup description" - -# determine flavor -# ---------------- - -# List of flavors: -nova flavor-list - -# and grab the first flavor in the list to launch -FLAVOR=`nova flavor-list | head -n 4 | tail -n 1 | cut -d"|" -f2` - -NAME="myserver" - -nova boot --flavor $FLAVOR --image $IMAGE $NAME --security_groups=$SECGROUP - -# Testing -# ======= - -# First check if it spins up (becomes active and responds to ping on -# internal ip). If you run this script from a nova node, you should -# bypass security groups and have direct access to the server. - -# Waiting for boot -# ---------------- - -# Max time to wait while vm goes from build to active state -ACTIVE_TIMEOUT=${ACTIVE_TIMEOUT:-10} - -# Max time till the vm is bootable -BOOT_TIMEOUT=${BOOT_TIMEOUT:-15} - -# Max time to wait for proper association and dis-association. -ASSOCIATE_TIMEOUT=${ASSOCIATE_TIMEOUT:-10} - -# check that the status is active within ACTIVE_TIMEOUT seconds -if ! timeout $ACTIVE_TIMEOUT sh -c "while ! nova show $NAME | grep status | grep -q ACTIVE; do sleep 1; done"; then - echo "server didn't become active!" - exit 1 -fi - -# get the IP of the server -IP=`nova show $NAME | grep "private network" | cut -d"|" -f3` - -# for single node deployments, we can ping private ips -MULTI_HOST=${MULTI_HOST:-0} -if [ "$MULTI_HOST" = "0" ]; then - # sometimes the first ping fails (10 seconds isn't enough time for the VM's - # network to respond?), so let's ping for a default of 15 seconds with a - # timeout of a second for each ping. - if ! timeout $BOOT_TIMEOUT sh -c "while ! ping -c1 -w1 $IP; do sleep 1; done"; then - echo "Couldn't ping server" - exit 1 +# Run everything in the exercises/ directory that isn't explicitly disabled + +# comma separated list of script basenames to skip +# to refrain from exercising euca.sh use SKIP_EXERCISES=euca +SKIP_EXERCISES=${SKIP_EXERCISES:-""} + +# Locate the scripts we should run +EXERCISE_DIR=$(dirname "$0")/exercises +basenames=$(for b in `ls $EXERCISE_DIR/*.sh`; do basename $b .sh; done) + +# Track the state of each script +passes="" +failures="" +skips="" + +# Loop over each possible script (by basename) +for script in $basenames; do + if [[ "$SKIP_EXERCISES" =~ $script ]] ; then + skips="$skips $script" + else + echo ========================= + echo Running $script + echo ========================= + $EXERCISE_DIR/$script.sh + if [[ $? -ne 0 ]] ; then + failures="$failures $script" + else + passes="$passes $script" + fi fi -else - # On a multi-host system, without vm net access, do a sleep to wait for the boot - sleep $BOOT_TIMEOUT -fi - -# Security Groups & Floating IPs -# ------------------------------ - -# allow icmp traffic (ping) -nova secgroup-add-rule $SECGROUP icmp -1 -1 0.0.0.0/0 - -# List rules for a secgroup -nova secgroup-list-rules $SECGROUP - -# allocate a floating ip -nova floating-ip-create - -# store floating address -FLOATING_IP=`nova floating-ip-list | grep None | head -1 | cut -d '|' -f2 | sed 's/ //g'` - -# add floating ip to our server -nova add-floating-ip $NAME $FLOATING_IP - -# test we can ping our floating ip within ASSOCIATE_TIMEOUT seconds -if ! timeout $ASSOCIATE_TIMEOUT sh -c "while ! ping -c1 -w1 $FLOATING_IP; do sleep 1; done"; then - echo "Couldn't ping server with floating ip" - exit 1 -fi - -# pause the VM and verify we can't ping it anymore -nova pause $NAME - -sleep 2 - -if ( ping -c1 -w1 $IP); then - echo "Pause failure - ping shouldn't work" - exit 1 -fi - -if ( ping -c1 -w1 $FLOATING_IP); then - echo "Pause failure - ping floating ips shouldn't work" - exit 1 -fi - -# unpause the VM and verify we can ping it again -nova unpause $NAME - -sleep 2 - -ping -c1 -w1 $IP - -# dis-allow icmp traffic (ping) -nova secgroup-delete-rule $SECGROUP icmp -1 -1 0.0.0.0/0 - -# FIXME (anthony): make xs support security groups -if [ "$VIRT_DRIVER" != "xenserver" ]; then - # test we can aren't able to ping our floating ip within ASSOCIATE_TIMEOUT seconds - if ! timeout $ASSOCIATE_TIMEOUT sh -c "while ping -c1 -w1 $FLOATING_IP; do sleep 1; done"; then - print "Security group failure - ping should not be allowed!" - echo "Couldn't ping server with floating ip" - exit 1 - fi -fi - -# de-allocate the floating ip -nova floating-ip-delete $FLOATING_IP - -# shutdown the server -nova delete $NAME - -# Delete a secgroup -nova secgroup-delete $SECGROUP - -# FIXME: validate shutdown within 5 seconds -# (nova show $NAME returns 1 or status != ACTIVE)? - -# Testing Euca2ools -# ================== - -# make sure that we can describe instances -euca-describe-instances - -if [[ "$ENABLED_SERVICES" =~ "swift" ]]; then - # Testing Swift - # ============= - - # Check if we have to swift via keystone - swift --auth-version 2 -A http://${HOST_IP}:5000/v2.0 -U admin -K $ADMIN_PASSWORD stat - - # We start by creating a test container - swift --auth-version 2 -A http://${HOST_IP}:5000/v2.0 -U admin -K $ADMIN_PASSWORD post testcontainer - - # add some files into it. - swift --auth-version 2 -A http://${HOST_IP}:5000/v2.0 -U admin -K $ADMIN_PASSWORD upload testcontainer /etc/issue - - # list them - swift --auth-version 2 -A http://${HOST_IP}:5000/v2.0 -U admin -K $ADMIN_PASSWORD list testcontainer - - # And we may want to delete them now that we have tested that - # everything works. - swift --auth-version 2 -A http://${HOST_IP}:5000/v2.0 -U admin -K $ADMIN_PASSWORD delete testcontainer -fi +done + +# output status of exercise run +echo ========================= +echo ========================= +for script in $skips; do + echo SKIP $script +done +for script in $passes; do + echo PASS $script +done +for script in $failures; do + echo FAILED $script +done diff --git a/exercises/euca.sh b/exercises/euca.sh new file mode 100755 index 0000000..9605ace --- /dev/null +++ b/exercises/euca.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +# we will use the ``euca2ools`` cli tool that wraps the python boto +# library to test ec2 compatibility +# + +# This script exits on an error so that errors don't compound and you see +# only the first error that occured. +set -o errexit + +# Print the commands being run so that we can see the command that triggers +# an error. It is also useful for following allowing as the install occurs. +set -o xtrace + + +# Settings +# ======== + +# Use openrc + stackrc + localrc for settings +pushd $(cd $(dirname "$0")/.. && pwd) +source ./openrc +popd + +# find a machine image to boot +IMAGE=`euca-describe-images | grep machine | cut -f2` + +# launch it +INSTANCE=`euca-run-instances $IMAGE | grep INSTANCE | cut -f2` + +# assure it has booted within a reasonable time +if ! timeout $RUNNING_TIMEOUT sh -c "while euca-describe-instances $INSTANCE | grep -q running; do sleep 1; done"; then + echo "server didn't become active within $RUNNING_TIMEOUT seconds" + exit 1 +fi + +euca-terminate-instances $INSTANCE diff --git a/exercises/floating_ips.sh b/exercises/floating_ips.sh new file mode 100755 index 0000000..75046d1 --- /dev/null +++ b/exercises/floating_ips.sh @@ -0,0 +1,190 @@ +#!/usr/bin/env bash + +# **exercise.sh** - using the cloud can be fun + +# we will use the ``nova`` cli tool provided by the ``python-novaclient`` +# package +# + + +# This script exits on an error so that errors don't compound and you see +# only the first error that occured. +set -o errexit + +# Print the commands being run so that we can see the command that triggers +# an error. It is also useful for following allowing as the install occurs. +set -o xtrace + + +# Settings +# ======== + +# Use openrc + stackrc + localrc for settings +pushd $(cd $(dirname "$0")/.. && pwd) +source ./openrc +popd + +# Get a token for clients that don't support service catalog +# ========================================================== + +# manually create a token by querying keystone (sending JSON data). Keystone +# returns a token and catalog of endpoints. We use python to parse the token +# and save it. + +TOKEN=`curl -s -d "{\"auth\":{\"passwordCredentials\": {\"username\": \"$NOVA_USERNAME\", \"password\": \"$NOVA_API_KEY\"}}}" -H "Content-type: application/json" http://$HOST_IP:5000/v2.0/tokens | python -c "import sys; import json; tok = json.loads(sys.stdin.read()); print tok['access']['token']['id'];"` + +# Launching a server +# ================== + +# List servers for tenant: +nova list + +# Images +# ------ + +# Nova has a **deprecated** way of listing images. +nova image-list + +# But we recommend using glance directly +glance -A $TOKEN index + +# Let's grab the id of the first AMI image to launch +IMAGE=`glance -A $TOKEN index | egrep ami | cut -d" " -f1` + +# Security Groups +# --------------- +SECGROUP=test_secgroup + +# List of secgroups: +nova secgroup-list + +# Create a secgroup +nova secgroup-create $SECGROUP "test_secgroup description" + +# determine flavor +# ---------------- + +# List of flavors: +nova flavor-list + +# and grab the first flavor in the list to launch +FLAVOR=`nova flavor-list | head -n 4 | tail -n 1 | cut -d"|" -f2` + +NAME="myserver" + +nova boot --flavor $FLAVOR --image $IMAGE $NAME --security_groups=$SECGROUP + +# Testing +# ======= + +# First check if it spins up (becomes active and responds to ping on +# internal ip). If you run this script from a nova node, you should +# bypass security groups and have direct access to the server. + +# Waiting for boot +# ---------------- + +# Max time to wait while vm goes from build to active state +ACTIVE_TIMEOUT=${ACTIVE_TIMEOUT:-10} + +# Max time till the vm is bootable +BOOT_TIMEOUT=${BOOT_TIMEOUT:-15} + +# Max time to wait for proper association and dis-association. +ASSOCIATE_TIMEOUT=${ASSOCIATE_TIMEOUT:-10} + +# check that the status is active within ACTIVE_TIMEOUT seconds +if ! timeout $ACTIVE_TIMEOUT sh -c "while ! nova show $NAME | grep status | grep -q ACTIVE; do sleep 1; done"; then + echo "server didn't become active!" + exit 1 +fi + +# get the IP of the server +IP=`nova show $NAME | grep "private network" | cut -d"|" -f3` + +# for single node deployments, we can ping private ips +MULTI_HOST=${MULTI_HOST:-0} +if [ "$MULTI_HOST" = "0" ]; then + # sometimes the first ping fails (10 seconds isn't enough time for the VM's + # network to respond?), so let's ping for a default of 15 seconds with a + # timeout of a second for each ping. + if ! timeout $BOOT_TIMEOUT sh -c "while ! ping -c1 -w1 $IP; do sleep 1; done"; then + echo "Couldn't ping server" + exit 1 + fi +else + # On a multi-host system, without vm net access, do a sleep to wait for the boot + sleep $BOOT_TIMEOUT +fi + +# Security Groups & Floating IPs +# ------------------------------ + +# allow icmp traffic (ping) +nova secgroup-add-rule $SECGROUP icmp -1 -1 0.0.0.0/0 + +# List rules for a secgroup +nova secgroup-list-rules $SECGROUP + +# allocate a floating ip +nova floating-ip-create + +# store floating address +FLOATING_IP=`nova floating-ip-list | grep None | head -1 | cut -d '|' -f2 | sed 's/ //g'` + +# add floating ip to our server +nova add-floating-ip $NAME $FLOATING_IP + +# test we can ping our floating ip within ASSOCIATE_TIMEOUT seconds +if ! timeout $ASSOCIATE_TIMEOUT sh -c "while ! ping -c1 -w1 $FLOATING_IP; do sleep 1; done"; then + echo "Couldn't ping server with floating ip" + exit 1 +fi + +# pause the VM and verify we can't ping it anymore +nova pause $NAME + +sleep 2 + +if ( ping -c1 -w1 $IP); then + echo "Pause failure - ping shouldn't work" + exit 1 +fi + +if ( ping -c1 -w1 $FLOATING_IP); then + echo "Pause failure - ping floating ips shouldn't work" + exit 1 +fi + +# unpause the VM and verify we can ping it again +nova unpause $NAME + +sleep 2 + +ping -c1 -w1 $IP + +# dis-allow icmp traffic (ping) +nova secgroup-delete-rule $SECGROUP icmp -1 -1 0.0.0.0/0 + +# FIXME (anthony): make xs support security groups +if [ "$VIRT_DRIVER" != "xenserver" ]; then + # test we can aren't able to ping our floating ip within ASSOCIATE_TIMEOUT seconds + if ! timeout $ASSOCIATE_TIMEOUT sh -c "while ping -c1 -w1 $FLOATING_IP; do sleep 1; done"; then + print "Security group failure - ping should not be allowed!" + echo "Couldn't ping server with floating ip" + exit 1 + fi +fi + +# de-allocate the floating ip +nova floating-ip-delete $FLOATING_IP + +# shutdown the server +nova delete $NAME + +# Delete a secgroup +nova secgroup-delete $SECGROUP + +# FIXME: validate shutdown within 5 seconds +# (nova show $NAME returns 1 or status != ACTIVE)? + diff --git a/exercises/swift.sh b/exercises/swift.sh new file mode 100755 index 0000000..f7be099 --- /dev/null +++ b/exercises/swift.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +# Test swift via the command line tools that ship with it. + +# This script exits on an error so that errors don't compound and you see +# only the first error that occured. +set -o errexit + +# Print the commands being run so that we can see the command that triggers +# an error. It is also useful for following allowing as the install occurs. +set -o xtrace + + +# Settings +# ======== + +# Use openrc + stackrc + localrc for settings +pushd $(cd $(dirname "$0")/.. && pwd) +source ./openrc +popd + + +# Testing Swift +# ============= + +# Check if we have to swift via keystone +swift --auth-version 2 -A http://${HOST_IP}:5000/v2.0 -U admin -K $ADMIN_PASSWORD stat + +# We start by creating a test container +swift --auth-version 2 -A http://${HOST_IP}:5000/v2.0 -U admin -K $ADMIN_PASSWORD post testcontainer + +# add some files into it. +swift --auth-version 2 -A http://${HOST_IP}:5000/v2.0 -U admin -K $ADMIN_PASSWORD upload testcontainer /etc/issue + +# list them +swift --auth-version 2 -A http://${HOST_IP}:5000/v2.0 -U admin -K $ADMIN_PASSWORD list testcontainer + +# And we may want to delete them now that we have tested that +# everything works. +swift --auth-version 2 -A http://${HOST_IP}:5000/v2.0 -U admin -K $ADMIN_PASSWORD delete testcontainer diff --git a/openrc b/openrc index 324780b..4b36112 100644 --- a/openrc +++ b/openrc @@ -49,3 +49,14 @@ export EC2_SECRET_KEY=${ADMIN_PASSWORD:-secrete} # set log level to DEBUG (helps debug issues) # export NOVACLIENT_DEBUG=1 +# Max time till the vm is bootable +export BOOT_TIMEOUT=${BOOT_TIMEOUT:-15} + +# Max time to wait while vm goes from build to active state +export ACTIVE_TIMEOUT=${ACTIVE_TIMEOUT:-10} + +# Max time from run instance command until it is running +export RUNNING_TIMEOUT=${RUNNING_TIMEOUT:-$(($BOOT_TIMEOUT + $ACTIVE_TIMEOUT))} + +# Max time to wait for proper IP association and dis-association. +export ASSOCIATE_TIMEOUT=${ASSOCIATE_TIMEOUT:-10}