#!/usr/bin/env python
# Copyright (c) 2006,2007 Mitch Garnaat http://garnaat.org/
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish, dis-
# tribute, sublicense, and/or sell copies of the Software, and to permit
# persons to whom the Software is furnished to do so, subject to the fol-
# lowing conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
import getopt
import sys
import imp
import time
import boto

usage_string = """
SYNOPSIS
    launch_ami.py -a ami_id [-b script_bucket] [-s script_name]
                  [-m module] [-c class_name] [-r] 
                  [-g group] [-k key_name] [-n num_instances]
                  [-w] [extra_data]
    Where:
        ami_id - the id of the AMI you wish to launch
        module - The name of the Python module containing the class you
                 want to run when the instance is started.  If you use this
                 option the Python module must already be stored on the
                 instance in a location that is on the Python path.
        script_file - The name of a local Python module that you would like
                      to have copied to S3 and then run on the instance
                      when it is started.  The specified module must be
                      import'able (i.e. in your local Python path).  It
                      will then be copied to the specified bucket in S3
                      (see the -b option).  Once the new instance(s)
                      start up the script will be copied from S3 and then
                      run locally on the instance.
        class_name - The name of the class to be instantiated within the
                     module or script file specified.
        script_bucket - the name of the bucket in which the script will be
                        stored
        group - the name of the security group the instance will run in
        key_name - the name of the keypair to use when launching the AMI
        num_instances - how many instances of the AMI to launch (default 1)
        input_queue_name - Name of SQS to read input messages from
        output_queue_name - Name of SQS to write output messages to
        extra_data - additional name-value pairs that will be passed as
                     userdata to the newly launched instance.  These should
                     be of the form "name=value"
        The -r option reloads the Python module to S3 without launching
        another instance.  This can be useful during debugging to allow
        you to test a new version of your script without shutting down
        your instance and starting up another one.
        The -w option tells the script to run synchronously, meaning to
        wait until the instance is actually up and running.  It then prints
        the IP address and internal and external DNS names before exiting.
"""

def usage():
    print usage_string
    sys.exit()

def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:], 'a:b:c:g:hi:k:m:n:o:rs:w',
                                   ['ami', 'bucket', 'class', 'group', 'help',
                                    'inputqueue', 'keypair', 'module',
                                    'numinstances', 'outputqueue',
                                    'reload', 'script_name', 'wait'])
    except:
        usage()
    params = {'module_name' : None,
              'script_name' : None,
              'class_name' : None,
              'script_bucket' : None,
              'group' : 'default',
              'keypair' : None,
              'ami' : None,
              'num_instances' : 1,
              'input_queue_name' : None,
              'output_queue_name' : None}
    reload = None
    wait = None
    for o, a in opts:
        if o in ('-a', '--ami'):
            params['ami'] = a
        if o in ('-b', '--bucket'):
            params['script_bucket'] = a
        if o in ('-c', '--class'):
            params['class_name'] = a
        if o in ('-g', '--group'):
            params['group'] = a
        if o in ('-h', '--help'):
            usage()
        if o in ('-i', '--inputqueue'):
            params['input_queue_name'] = a
        if o in ('-k', '--keypair'):
            params['keypair'] = a
        if o in ('-m', '--module'):
            params['module_name'] = a
        if o in ('-n', '--num_instances'):
            params['num_instances'] = int(a)
        if o in ('-o', '--outputqueue'):
            params['output_queue_name'] = a
        if o in ('-r', '--reload'):
            reload = True
        if o in ('-s', '--script'):
            params['script_name'] = a
        if o in ('-w', '--wait'):
            wait = True

    # check required fields
    required = ['ami']
    for pname in required:
        if not params.get(pname, None):
            print '%s is required' % pname
            usage()
    if params['script_name']:
        # first copy the desired module file to S3 bucket
        if reload:
            print 'Reloading module %s to S3' % params['script_name']
        else:
            print 'Copying module %s to S3' % params['script_name']
        l = imp.find_module(params['script_name'])
        c = boto.connect_s3()
        bucket = c.get_bucket(params['script_bucket'])
        key = bucket.new_key(params['script_name']+'.py')
        key.set_contents_from_file(l[0])
        params['script_md5'] = key.md5
    # we have everything we need, now build userdata string
    l = []
    for k, v in params.items():
        if v:
            l.append('%s=%s' % (k, v))
    c = boto.connect_ec2()
    l.append('aws_access_key_id=%s' % c.aws_access_key_id)
    l.append('aws_secret_access_key=%s' % c.aws_secret_access_key)
    for kv in args:
        l.append(kv)
    s = '|'.join(l)
    if not reload:
        rs = c.get_all_images([params['ami']])
        img = rs[0]
        r = img.run(user_data=s, key_name=params['keypair'],
                    security_groups=[params['group']],
                    max_count=params.get('num_instances', 1))
        print 'AMI: %s - %s (Started)' % (params['ami'], img.location)
        print 'Reservation %s contains the following instances:' % r.id
        for i in r.instances:
            print '\t%s' % i.id
        if wait:
            running = False
            while not running:
                time.sleep(30)
                [i.update() for i in r.instances]
                status = [i.state for i in r.instances]
                print status
                if status.count('running') == len(r.instances):
                    running = True
            for i in r.instances:
                print 'Instance: %s' % i.ami_launch_index
                print 'Public DNS Name: %s' % i.public_dns_name
                print 'Private DNS Name: %s' % i.private_dns_name

if __name__ == "__main__":
    main()

