Skip to content

Instantly share code, notes, and snippets.

@turtlebender
Created January 12, 2012 22:14
Show Gist options
  • Save turtlebender/1603468 to your computer and use it in GitHub Desktop.
Save turtlebender/1603468 to your computer and use it in GitHub Desktop.
from __future__ import absolute_import
"""
This will configure and run the nosetests for graph against remove ec2 servers.
Running this makes a few assumptions.
1) You must have access to graph on github. This will checkout the repo to run the tests
2) You must have an account on EC2 and be able to create instances.
In order to configure, you need to create a file in your home called ~/.boto that looks like:
[Credentials]
aws_access_key_id = XXXXXXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXXX
In addition, you need the following dependencies:
pip install boto
pip install -e git+https://github.com/fabric/fabric.git#egg=fabric
"""
import collections
from multiprocessing import Process, Manager
import time
import urllib2
from fabric.api import env, run, sudo
from fabric.context_managers import settings, cd, hide
from boto.ec2.connection import EC2Connection
from boto.ec2.blockdevicemapping import BlockDeviceType
from boto.ec2.blockdevicemapping import BlockDeviceMapping
import boto
def get_or_create_security_group(c, group_name, description=""):
"""
"""
groups = [g for g in c.get_all_security_groups() if g.name == group_name]
group = groups[0] if groups else None
if not group:
group = c.create_security_group(group_name, "A group for %s"%(group_name,))
return group
def modify_sg(c, group, rule, authorize=False, revoke=False):
src_group = None
if rule.src_group_name:
src_group = c.get_all_security_groups([rule.src_group_name,])[0]
if authorize and not revoke:
print "Authorizing rule %s..."%(rule,)
group.authorize(ip_protocol=rule.ip_protocol,
from_port=rule.from_port,
to_port=rule.to_port,
cidr_ip=rule.cidr_ip,
src_group=src_group)
elif not authorize and revoke:
print "Revoking rule %s..."%(rule,)
group.revoke(ip_protocol=rule.ip_protocol,
from_port=rule.from_port,
to_port=rule.to_port,
cidr_ip=rule.cidr_ip,
src_group=src_group)
def authorize(c, group, rule):
"""Authorize `rule` on `group`."""
return modify_sg(c, group, rule, authorize=True)
def revoke(c, group, rule):
"""Revoke `rule` on `group`."""
return modify_sg(c, group, rule, revoke=True)
def update_security_group(c, group, expected_rules):
"""
"""
print 'Updating group "%s"...'%(group.name,)
current_rules = []
for rule in group.rules:
if not rule.grants[0].cidr_ip:
current_rule = SecurityGroupRule(rule.ip_protocol,
rule.from_port,
rule.to_port,
"0.0.0.0/0",
rule.grants[0].name)
else:
current_rule = SecurityGroupRule(rule.ip_protocol,
rule.from_port,
rule.to_port,
rule.grants[0].cidr_ip,
None)
if current_rule not in expected_rules:
revoke(c, group, current_rule)
else:
current_rules.append(current_rule)
for rule in expected_rules:
if rule not in current_rules:
authorize(c, group, rule)
def wait_for_instance(instance):
time.sleep(2)
status = instance.update()
while status == 'pending':
time.sleep(10)
status = instance.update()
if status == 'running':
print('New instance "' + instance.id + '" accessible at ' + instance.public_dns_name)
else:
print('Instance status: ' + status)
def wait_for_ssh(instance):
count = 0
env.host_string = instance.public_dns_name
while count < 20:
time.sleep(5)
count = count + 1
print('Waiting for SSH')
try:
with hide('running', 'stdout', 'stderr'):
run('hostname')
break
except SystemExit, e: print(e)
print "SSH is now available"
def create_test_instance(results, test_sec_group):
print "Starting Test instance"
#Create the instance
reservation = conn.run_instances('ami-1933fe70', min_count=1, max_count=1, security_groups=[test_sec_group], instance_type='m1.large', key_name='tom', placement='us-east-1a')
test_instance = reservation.instances[0]
print('Waiting for test instance to start')
wait_for_instance(test_instance)
wait_for_ssh(test_instance)
with settings(warn_only=True):
run('wget http://www.globus.org/ftppub/gt5/5.2/5.2.0/installers/repo/globus-repository-maverick_0.0.2_all.deb')
sudo('dpkg -i globus-repository-maverick_0.0.2_all.deb')
sudo('apt-get update')
sudo('apt-get install -y libglobus-gss-assist-dev libglobus-gsi-credential-dev libglobus-gsi-sysconfig-dev libglobus-gsi-cert-utils-dev libglobus-gsi-cert-utils0 libglobus-usage-dev myproxy')
sudo('apt-get install -y git python-setuptools libxml2-dev libxslt1-dev swig gnupg python-dev')
sudo('easy_install pip')
sudo('pip install virtualenv')
results['test'] = test_instance.id
def run_tests(test_instance, cass_instance):
env.host_string = test_instance.public_dns_name
#Install globus
with settings(warn_only=True):
run('virtualenv --no-site-packages ${HOME}/graph-env')
run('echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config')
run('git clone [email protected]:/globusonline/globusonline-graph ${HOME}/graph')
run("sed -i -e 's/localhost:9160/%s:9160/' ${HOME}/graph/development.ini" % cass_instance.private_ip_address)
#run('GLOBUS_LOCATION=/usr GLOBUS_FLAVOR= ${HOME}/graph-env/bin/pip install --no-deps file://${HOME}/graph/graph.bundle')
#run('git clone [email protected]:/globusonline/slimer.git ${HOME}/slimer')
#sudo('apt-get install rubygems')
#sudo('gem install haml')
#sudo('gem install sass')
#with cd('${HOME}/slimer'):
#run('PATH=$PATH:/var/lib/gems/1.8/bin python merge.py _default GO ${HOME}/graph/globusonline/graph/GOST')
#with cd('${HOME}/graph'):
#run('X509_CERT_DIR=/tmp ${HOME}/graph-env/bin/nosetests -x')
def create_cassandra_instance(results, cass_sec_group):
print('Starting cassandra instance')
reservation = conn.run_instances('ami-fd23ec94', security_groups=[cass_sec_group], instance_type='m1.large', key_name='tom', placement='us-east-1a', user_data='-v community -c test -n 1')
cass_instance = reservation.instances[0]
print('Waiting for cassandra instance to start')
wait_for_instance(cass_instance)
env.host_string = cass_instance.public_dns_name
print "Initializing Cassandra DB"
count = 0
while count < 20:
count = count + 1
try:
with settings(warn_only=True):
run('uname')
break
except SystemExit, e: print(e)
time.sleep(5)
results['cassandra'] = cass_instance.id
def terminate_instance(instance):
print('Terminating instance: {0}'.format(instance.id))
conn.terminate_instances([instance.id])
status = instance.update()
while status == 'terminating' or status == 'shutting-down' or status == 'running' or status == 'stopping' or status == 'stopped':
time.sleep(5)
status = instance.update()
print('Waiting for the instance to shut down')
def delete_security_group(conn, group_name):
conn.delete_security_group(group_name)
def get_instance(conn, instance_id):
reservations = conn.get_all_instances()
for reservation in reservations:
if reservation.instances[0].id == instance_id:
print reservation.instances[0]
return reservation.instances[0]
raise Exception("No matching instance")
env.user = 'ubuntu'
my_ip = "{0}/32".format(urllib2.urlopen('http://automation.whatismyip.com/n09230945.asp').read())
SecurityGroupRule = collections.namedtuple("SecurityGroupRule", ["ip_protocol", "from_port", "to_port", "cidr_ip", "src_group_name"])
base_rules = [
SecurityGroupRule('tcp', 0, 65535, my_ip, None),
SecurityGroupRule('udp', 0, 65535, my_ip, None),
SecurityGroupRule('icmp', -1, -1, my_ip, None),
]
conn = EC2Connection()
test_instance = None
test_sec_group = None
cass_instance = None
cass_sec_group = None
#Create temporary security group
test_sec_group_name = "test_instance_{0}".format(int(time.time()))
test_sec_group = get_or_create_security_group(conn, test_sec_group_name)
update_security_group(conn, test_sec_group, base_rules)
cass_sec_group_name = "test_cass_{0}".format(int(time.time()))
cass_sec_group = get_or_create_security_group(conn, cass_sec_group_name)
update_security_group(conn, cass_sec_group, base_rules)
manager = Manager()
results = manager.dict()
try:
test_process = Process(target=create_test_instance, args=(results, test_sec_group.name))
cass_process = Process(target=create_cassandra_instance, args=(results, cass_sec_group.name))
test_process.start()
cass_process.start()
while(test_process.is_alive() or cass_process.is_alive()):
time.sleep(5)
test_instance = get_instance(conn, results['test'])
cass_instance = get_instance(conn, results['cassandra'])
except Exception as e:
print(e)
print "Cassandra instance: {0} - {1}".format(cass_instance.id, test_instance.public_dns_name)
print "Test instance: {0} - {1}".format(test_instance.id, test_instance.public_dns_name)
print "Security Group Test: {0} : {1}".format(type(test_sec_group), test_sec_group)
print "Security Group Cassandra: {0} : {1}".format(type(cass_sec_group), cass_sec_group)
print "Updating cassandra security Group Rules"
cass_sec_group.authorize('tcp', 22, 22, None, test_sec_group)
cass_sec_group.authorize('tcp', 9160, 9160, None, test_sec_group)
cass_sec_group.authorize('tcp', 7199, 7199, None, test_sec_group)
cass_sec_group.authorize('tcp', 8888, 8888, None, test_sec_group)
cass_sec_group.authorize('tcp', 1024, 65535, None, test_sec_group)
cass_sec_group.authorize('tcp', 7000, 7000, None, test_sec_group)
cass_sec_group.authorize('tcp', 9160, 9160, None, cass_sec_group)
cass_sec_group.authorize('tcp', 7199, 7199, None, cass_sec_group)
cass_sec_group.authorize('tcp', 8888, 8888, None, cass_sec_group)
cass_sec_group.authorize('tcp', 1024, 65535, None, cass_sec_group)
cass_sec_group.authorize('tcp', 7000, 7000, None, cass_sec_group)
try:
if test_instance is not None:
run_tests(test_instance, cass_instance)
except Exception as e:
print(e)
try:
if test_instance is not None:
terminate_instance(test_instance)
except Exception as e:
print(e)
try:
if cass_instance is not None:
terminate_instance(cass_instance)
except Exception as e:
print(e)
if cass_sec_group is not None:
count = 0
while count < 5:
count = count + 1
try:
delete_security_group(conn, cass_sec_group.name)
except: pass
time.sleep(2)
if test_sec_group is not None:
count = 0
while count < 5:
count = count + 1
try:
delete_security_group(conn, test_sec_group.name)
except: pass
time.sleep(2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment