Created
June 20, 2011 07:14
-
-
Save anonymous/1035249 to your computer and use it in GitHub Desktop.
One-file Pyramid app
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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