Skip to content

Instantly share code, notes, and snippets.

Created June 20, 2011 07:14
Show Gist options
  • Select an option

  • Save anonymous/1035249 to your computer and use it in GitHub Desktop.

Select an option

Save anonymous/1035249 to your computer and use it in GitHub Desktop.
One-file Pyramid app
# we'll use gevent to run the webserver, so one-thread, evented IO
import gevent.monkey
gevent.monkey.patch_all()
import gevent.pywsgi
from pyramid.config import Configurator
from pyramid.response import Response
from boto.ec2.connection import EC2Connection
# conf vars
USER_DATA = """#!/bin/bash
set -x -e
apt-get update
aptitude -y install less screen php5-cli php5-mysql php5-curl
"""
AWS_ID = 'id'
AWS_SECRET = 'secret'
AMI = 'ami'
INSTANCE_TYPE = 'm1.small'
SECURITY_GROUP = 'ssh'
KEYPAIR = 'secret'
AUTH_PASS = 'another secret'
def start_instance(conn, user_data):
"""Wrap starting a spot request."""
return conn.request_spot_instances('0.50', AMI, count=1, key_name=KEYPAIR, security_groups=[SECURITY_GROUP], user_data=user_data, instance_type=INSTANCE_TYPE)
def shutdown_and_start(request):
inst_id = int(request.matchdict['id'])
if 'password' in request.params:
if request.params['password'] == AUTH_PASS:
if inst_id in request.registry.settings['instances']:
inst = request.registry.settings['instances'][inst_id]
conn = EC2Connection(AWS_ID, AWS_SECRET)
match = conn.get_all_spot_instance_requests([inst['spot_id']])
if match:
# kill old
# since we're using spot instances, have to dig around a bit to get
# the instance itself
match = conn.get_all_instances([match[0].instance_id])
if match:
match[0].instances[0].terminate()
# start new
request.registry.settings['i_counter'] += 1
inst_id = request.registry.settings['i_counter']
r = start_instance(conn, USER_DATA)
request.registry.settings['instances'][inst_id] = {'spot_id': r[0].id}
return {'success': True}
else:
return {'success': False, 'reason': 'Unknown ID'}
else:
return {'success': False, 'reason': 'Bad Password'}
else:
return {'success': False, 'reason': 'No Password Specified'}
def new_server(request):
if 'password' in request.params:
if request.params['password'] == AUTH_PASS:
conn = EC2Connection(AWS_ID, AWS_SECRET)
request.registry.settings['i_counter'] += 1
inst_id = request.registry.settings['i_counter']
r = start_instance(conn, USER_DATA)
request.registry.settings['instances'][inst_id] = {'spot_id': r[0].id}
return {'success': True}
else:
return {'success': False, 'reason': 'Bad Password'}
else:
return {'success': False, 'reason': 'No Password Given'}
if __name__ == '__main__':
config = Configurator()
# url dispatch, just render results as JSON, really simple REST interface
config.add_route('main', '/cycle/{id}', shutdown_and_start, view_renderer='json')
config.add_route('new', '/new', new_server, view_renderer='json')
# these are available to every request and are essentially global (but note they are specific to a thread)
config.registry.settings['i_counter'] = 0
config.registry.settings['instances'] = {}
app = config.make_wsgi_app()
gevent.pywsgi.WSGIServer(('0.0.0.0', 8080), app).serve_forever()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment