Mercurial > repos > shellac > guppy_basecaller
diff env/bin/launch_instance @ 0:26e78fe6e8c4 draft
"planemo upload commit c699937486c35866861690329de38ec1a5d9f783"
author | shellac |
---|---|
date | Sat, 02 May 2020 07:14:21 -0400 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/env/bin/launch_instance Sat May 02 07:14:21 2020 -0400 @@ -0,0 +1,252 @@ +#!/Users/pldms/Development/Projects/2020/david-matthews-galaxy/guppy_basecaller/env/bin/python3 +# Copyright (c) 2009 Chris Moyer http://coredumped.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 + +# +# Utility to launch an EC2 Instance +# +VERSION="0.2" + + +CLOUD_INIT_SCRIPT = """#!/usr/bin/env python +f = open("/etc/boto.cfg", "w") +f.write(\"\"\"%s\"\"\") +f.close() +""" +import boto.pyami.config +import boto.utils +import re, os +from boto.compat import ConfigParser + +class Config(boto.pyami.config.Config): + """A special config class that also adds import abilities + Directly in the config file. To have a config file import + another config file, simply use "#import <path>" where <path> + is either a relative path or a full URL to another config + """ + + def __init__(self): + ConfigParser.__init__(self, {'working_dir' : '/mnt/pyami', 'debug' : '0'}) + + def add_config(self, file_url): + """Add a config file to this configuration + :param file_url: URL for the file to add, or a local path + :type file_url: str + """ + if not re.match("^([a-zA-Z0-9]*:\/\/)(.*)", file_url): + if not file_url.startswith("/"): + file_url = os.path.join(os.getcwd(), file_url) + file_url = "file://%s" % file_url + (base_url, file_name) = file_url.rsplit("/", 1) + base_config = boto.utils.fetch_file(file_url) + base_config.seek(0) + for line in base_config.readlines(): + match = re.match("^#import[\s\t]*([^\s^\t]*)[\s\t]*$", line) + if match: + self.add_config("%s/%s" % (base_url, match.group(1))) + base_config.seek(0) + self.readfp(base_config) + + def add_creds(self, ec2): + """Add the credentials to this config if they don't already exist""" + if not self.has_section('Credentials'): + self.add_section('Credentials') + self.set('Credentials', 'aws_access_key_id', ec2.aws_access_key_id) + self.set('Credentials', 'aws_secret_access_key', ec2.aws_secret_access_key) + + + def __str__(self): + """Get config as string""" + from StringIO import StringIO + s = StringIO() + self.write(s) + return s.getvalue() + +SCRIPTS = [] + +def scripts_callback(option, opt, value, parser): + arg = value.split(',') + if len(arg) == 1: + SCRIPTS.append(arg[0]) + else: + SCRIPTS.extend(arg) + setattr(parser.values, option.dest, SCRIPTS) + +def add_script(scr_url): + """Read a script and any scripts that are added using #import""" + base_url = '/'.join(scr_url.split('/')[:-1]) + '/' + script_raw = boto.utils.fetch_file(scr_url) + script_content = '' + for line in script_raw.readlines(): + match = re.match("^#import[\s\t]*([^\s^\t]*)[\s\t]*$", line) + #if there is an import + if match: + #Read the other script and put it in that spot + script_content += add_script("%s/%s" % (base_url, match.group(1))) + else: + #Otherwise, add the line and move on + script_content += line + return script_content + +if __name__ == "__main__": + try: + import readline + except ImportError: + pass + import sys + import time + import boto + from boto.ec2 import regions + from optparse import OptionParser + from boto.mashups.iobject import IObject + parser = OptionParser(version=VERSION, usage="%prog [options] config_url") + parser.add_option("-c", "--max-count", help="Maximum number of this type of instance to launch", dest="max_count", default="1") + parser.add_option("--min-count", help="Minimum number of this type of instance to launch", dest="min_count", default="1") + parser.add_option("--cloud-init", help="Indicates that this is an instance that uses 'CloudInit', Ubuntu's cloud bootstrap process. This wraps the config in a shell script command instead of just passing it in directly", dest="cloud_init", default=False, action="store_true") + parser.add_option("-g", "--groups", help="Security Groups to add this instance to", action="append", dest="groups") + parser.add_option("-a", "--ami", help="AMI to launch", dest="ami_id") + parser.add_option("-t", "--type", help="Type of Instance (default m1.small)", dest="type", default="m1.small") + parser.add_option("-k", "--key", help="Keypair", dest="key_name") + parser.add_option("-z", "--zone", help="Zone (default us-east-1a)", dest="zone", default="us-east-1a") + parser.add_option("-r", "--region", help="Region (default us-east-1)", dest="region", default="us-east-1") + parser.add_option("-i", "--ip", help="Elastic IP", dest="elastic_ip") + parser.add_option("-n", "--no-add-cred", help="Don't add a credentials section", default=False, action="store_true", dest="nocred") + parser.add_option("--save-ebs", help="Save the EBS volume on shutdown, instead of deleting it", default=False, action="store_true", dest="save_ebs") + parser.add_option("-w", "--wait", help="Wait until instance is running", default=False, action="store_true", dest="wait") + parser.add_option("-d", "--dns", help="Returns public and private DNS (implicates --wait)", default=False, action="store_true", dest="dns") + parser.add_option("-T", "--tag", help="Set tag", default=None, action="append", dest="tags", metavar="key:value") + parser.add_option("-s", "--scripts", help="Pass in a script or a folder containing scripts to be run when the instance starts up, assumes cloud-init. Specify scripts in a list specified by commas. If multiple scripts are specified, they are run lexically (A good way to ensure they run in the order is to prefix filenames with numbers)", type='string', action="callback", callback=scripts_callback) + parser.add_option("--role", help="IAM Role to use, this implies --no-add-cred", dest="role") + + (options, args) = parser.parse_args() + + if len(args) < 1: + parser.print_help() + sys.exit(1) + file_url = os.path.expanduser(args[0]) + + cfg = Config() + cfg.add_config(file_url) + + for r in regions(): + if r.name == options.region: + region = r + break + else: + print("Region %s not found." % options.region) + sys.exit(1) + ec2 = boto.connect_ec2(region=region) + if not options.nocred and not options.role: + cfg.add_creds(ec2) + + iobj = IObject() + if options.ami_id: + ami = ec2.get_image(options.ami_id) + else: + ami_id = options.ami_id + l = [(a, a.id, a.location) for a in ec2.get_all_images()] + ami = iobj.choose_from_list(l, prompt='Choose AMI') + + if options.key_name: + key_name = options.key_name + else: + l = [(k, k.name, '') for k in ec2.get_all_key_pairs()] + key_name = iobj.choose_from_list(l, prompt='Choose Keypair').name + + if options.groups: + groups = options.groups + else: + groups = [] + l = [(g, g.name, g.description) for g in ec2.get_all_security_groups()] + g = iobj.choose_from_list(l, prompt='Choose Primary Security Group') + while g != None: + groups.append(g) + l.remove((g, g.name, g.description)) + g = iobj.choose_from_list(l, prompt='Choose Additional Security Group (0 to quit)') + + user_data = str(cfg) + # If it's a cloud init AMI, + # then we need to wrap the config in our + # little wrapper shell script + + if options.cloud_init: + user_data = CLOUD_INIT_SCRIPT % user_data + scriptuples = [] + if options.scripts: + scripts = options.scripts + scriptuples.append(('user_data', user_data)) + for scr in scripts: + scr_url = scr + if not re.match("^([a-zA-Z0-9]*:\/\/)(.*)", scr_url): + if not scr_url.startswith("/"): + scr_url = os.path.join(os.getcwd(), scr_url) + try: + newfiles = os.listdir(scr_url) + for f in newfiles: + #put the scripts in the folder in the array such that they run in the correct order + scripts.insert(scripts.index(scr) + 1, scr.split("/")[-1] + "/" + f) + except OSError: + scr_url = "file://%s" % scr_url + try: + scriptuples.append((scr, add_script(scr_url))) + except Exception as e: + pass + + user_data = boto.utils.write_mime_multipart(scriptuples, compress=True) + + shutdown_proc = "terminate" + if options.save_ebs: + shutdown_proc = "save" + + instance_profile_name = None + if options.role: + instance_profile_name = options.role + + r = ami.run(min_count=int(options.min_count), max_count=int(options.max_count), + key_name=key_name, user_data=user_data, + security_groups=groups, instance_type=options.type, + placement=options.zone, instance_initiated_shutdown_behavior=shutdown_proc, + instance_profile_name=instance_profile_name) + + instance = r.instances[0] + + if options.tags: + for tag_pair in options.tags: + name = tag_pair + value = '' + if ':' in tag_pair: + name, value = tag_pair.split(':', 1) + instance.add_tag(name, value) + + if options.dns: + options.wait = True + + if not options.wait: + sys.exit(0) + + while True: + instance.update() + if instance.state == 'running': + break + time.sleep(3) + + if options.dns: + print("Public DNS name: %s" % instance.public_dns_name) + print("Private DNS name: %s" % instance.private_dns_name)