Index: third_party/gsutil/boto/boto/pyami/launch_ami.py |
diff --git a/third_party/gsutil/boto/boto/pyami/launch_ami.py b/third_party/gsutil/boto/boto/pyami/launch_ami.py |
new file mode 100755 |
index 0000000000000000000000000000000000000000..243d56d2eb4d15d5332b5da9c4426f11230e3e3f |
--- /dev/null |
+++ b/third_party/gsutil/boto/boto/pyami/launch_ami.py |
@@ -0,0 +1,178 @@ |
+#!/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() |
+ |