Mercurial > repos > shellac > guppy_basecaller
comparison env/bin/launch_instance @ 0:26e78fe6e8c4 draft
"planemo upload commit c699937486c35866861690329de38ec1a5d9f783"
author | shellac |
---|---|
date | Sat, 02 May 2020 07:14:21 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:26e78fe6e8c4 |
---|---|
1 #!/Users/pldms/Development/Projects/2020/david-matthews-galaxy/guppy_basecaller/env/bin/python3 | |
2 # Copyright (c) 2009 Chris Moyer http://coredumped.org/ | |
3 # | |
4 # Permission is hereby granted, free of charge, to any person obtaining a | |
5 # copy of this software and associated documentation files (the | |
6 # "Software"), to deal in the Software without restriction, including | |
7 # without limitation the rights to use, copy, modify, merge, publish, dis- | |
8 # tribute, sublicense, and/or sell copies of the Software, and to permit | |
9 # persons to whom the Software is furnished to do so, subject to the fol- | |
10 # lowing conditions: | |
11 # | |
12 # The above copyright notice and this permission notice shall be included | |
13 # in all copies or substantial portions of the Software. | |
14 # | |
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
16 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- | |
17 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT | |
18 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |
19 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | |
21 | |
22 # | |
23 # Utility to launch an EC2 Instance | |
24 # | |
25 VERSION="0.2" | |
26 | |
27 | |
28 CLOUD_INIT_SCRIPT = """#!/usr/bin/env python | |
29 f = open("/etc/boto.cfg", "w") | |
30 f.write(\"\"\"%s\"\"\") | |
31 f.close() | |
32 """ | |
33 import boto.pyami.config | |
34 import boto.utils | |
35 import re, os | |
36 from boto.compat import ConfigParser | |
37 | |
38 class Config(boto.pyami.config.Config): | |
39 """A special config class that also adds import abilities | |
40 Directly in the config file. To have a config file import | |
41 another config file, simply use "#import <path>" where <path> | |
42 is either a relative path or a full URL to another config | |
43 """ | |
44 | |
45 def __init__(self): | |
46 ConfigParser.__init__(self, {'working_dir' : '/mnt/pyami', 'debug' : '0'}) | |
47 | |
48 def add_config(self, file_url): | |
49 """Add a config file to this configuration | |
50 :param file_url: URL for the file to add, or a local path | |
51 :type file_url: str | |
52 """ | |
53 if not re.match("^([a-zA-Z0-9]*:\/\/)(.*)", file_url): | |
54 if not file_url.startswith("/"): | |
55 file_url = os.path.join(os.getcwd(), file_url) | |
56 file_url = "file://%s" % file_url | |
57 (base_url, file_name) = file_url.rsplit("/", 1) | |
58 base_config = boto.utils.fetch_file(file_url) | |
59 base_config.seek(0) | |
60 for line in base_config.readlines(): | |
61 match = re.match("^#import[\s\t]*([^\s^\t]*)[\s\t]*$", line) | |
62 if match: | |
63 self.add_config("%s/%s" % (base_url, match.group(1))) | |
64 base_config.seek(0) | |
65 self.readfp(base_config) | |
66 | |
67 def add_creds(self, ec2): | |
68 """Add the credentials to this config if they don't already exist""" | |
69 if not self.has_section('Credentials'): | |
70 self.add_section('Credentials') | |
71 self.set('Credentials', 'aws_access_key_id', ec2.aws_access_key_id) | |
72 self.set('Credentials', 'aws_secret_access_key', ec2.aws_secret_access_key) | |
73 | |
74 | |
75 def __str__(self): | |
76 """Get config as string""" | |
77 from StringIO import StringIO | |
78 s = StringIO() | |
79 self.write(s) | |
80 return s.getvalue() | |
81 | |
82 SCRIPTS = [] | |
83 | |
84 def scripts_callback(option, opt, value, parser): | |
85 arg = value.split(',') | |
86 if len(arg) == 1: | |
87 SCRIPTS.append(arg[0]) | |
88 else: | |
89 SCRIPTS.extend(arg) | |
90 setattr(parser.values, option.dest, SCRIPTS) | |
91 | |
92 def add_script(scr_url): | |
93 """Read a script and any scripts that are added using #import""" | |
94 base_url = '/'.join(scr_url.split('/')[:-1]) + '/' | |
95 script_raw = boto.utils.fetch_file(scr_url) | |
96 script_content = '' | |
97 for line in script_raw.readlines(): | |
98 match = re.match("^#import[\s\t]*([^\s^\t]*)[\s\t]*$", line) | |
99 #if there is an import | |
100 if match: | |
101 #Read the other script and put it in that spot | |
102 script_content += add_script("%s/%s" % (base_url, match.group(1))) | |
103 else: | |
104 #Otherwise, add the line and move on | |
105 script_content += line | |
106 return script_content | |
107 | |
108 if __name__ == "__main__": | |
109 try: | |
110 import readline | |
111 except ImportError: | |
112 pass | |
113 import sys | |
114 import time | |
115 import boto | |
116 from boto.ec2 import regions | |
117 from optparse import OptionParser | |
118 from boto.mashups.iobject import IObject | |
119 parser = OptionParser(version=VERSION, usage="%prog [options] config_url") | |
120 parser.add_option("-c", "--max-count", help="Maximum number of this type of instance to launch", dest="max_count", default="1") | |
121 parser.add_option("--min-count", help="Minimum number of this type of instance to launch", dest="min_count", default="1") | |
122 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") | |
123 parser.add_option("-g", "--groups", help="Security Groups to add this instance to", action="append", dest="groups") | |
124 parser.add_option("-a", "--ami", help="AMI to launch", dest="ami_id") | |
125 parser.add_option("-t", "--type", help="Type of Instance (default m1.small)", dest="type", default="m1.small") | |
126 parser.add_option("-k", "--key", help="Keypair", dest="key_name") | |
127 parser.add_option("-z", "--zone", help="Zone (default us-east-1a)", dest="zone", default="us-east-1a") | |
128 parser.add_option("-r", "--region", help="Region (default us-east-1)", dest="region", default="us-east-1") | |
129 parser.add_option("-i", "--ip", help="Elastic IP", dest="elastic_ip") | |
130 parser.add_option("-n", "--no-add-cred", help="Don't add a credentials section", default=False, action="store_true", dest="nocred") | |
131 parser.add_option("--save-ebs", help="Save the EBS volume on shutdown, instead of deleting it", default=False, action="store_true", dest="save_ebs") | |
132 parser.add_option("-w", "--wait", help="Wait until instance is running", default=False, action="store_true", dest="wait") | |
133 parser.add_option("-d", "--dns", help="Returns public and private DNS (implicates --wait)", default=False, action="store_true", dest="dns") | |
134 parser.add_option("-T", "--tag", help="Set tag", default=None, action="append", dest="tags", metavar="key:value") | |
135 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) | |
136 parser.add_option("--role", help="IAM Role to use, this implies --no-add-cred", dest="role") | |
137 | |
138 (options, args) = parser.parse_args() | |
139 | |
140 if len(args) < 1: | |
141 parser.print_help() | |
142 sys.exit(1) | |
143 file_url = os.path.expanduser(args[0]) | |
144 | |
145 cfg = Config() | |
146 cfg.add_config(file_url) | |
147 | |
148 for r in regions(): | |
149 if r.name == options.region: | |
150 region = r | |
151 break | |
152 else: | |
153 print("Region %s not found." % options.region) | |
154 sys.exit(1) | |
155 ec2 = boto.connect_ec2(region=region) | |
156 if not options.nocred and not options.role: | |
157 cfg.add_creds(ec2) | |
158 | |
159 iobj = IObject() | |
160 if options.ami_id: | |
161 ami = ec2.get_image(options.ami_id) | |
162 else: | |
163 ami_id = options.ami_id | |
164 l = [(a, a.id, a.location) for a in ec2.get_all_images()] | |
165 ami = iobj.choose_from_list(l, prompt='Choose AMI') | |
166 | |
167 if options.key_name: | |
168 key_name = options.key_name | |
169 else: | |
170 l = [(k, k.name, '') for k in ec2.get_all_key_pairs()] | |
171 key_name = iobj.choose_from_list(l, prompt='Choose Keypair').name | |
172 | |
173 if options.groups: | |
174 groups = options.groups | |
175 else: | |
176 groups = [] | |
177 l = [(g, g.name, g.description) for g in ec2.get_all_security_groups()] | |
178 g = iobj.choose_from_list(l, prompt='Choose Primary Security Group') | |
179 while g != None: | |
180 groups.append(g) | |
181 l.remove((g, g.name, g.description)) | |
182 g = iobj.choose_from_list(l, prompt='Choose Additional Security Group (0 to quit)') | |
183 | |
184 user_data = str(cfg) | |
185 # If it's a cloud init AMI, | |
186 # then we need to wrap the config in our | |
187 # little wrapper shell script | |
188 | |
189 if options.cloud_init: | |
190 user_data = CLOUD_INIT_SCRIPT % user_data | |
191 scriptuples = [] | |
192 if options.scripts: | |
193 scripts = options.scripts | |
194 scriptuples.append(('user_data', user_data)) | |
195 for scr in scripts: | |
196 scr_url = scr | |
197 if not re.match("^([a-zA-Z0-9]*:\/\/)(.*)", scr_url): | |
198 if not scr_url.startswith("/"): | |
199 scr_url = os.path.join(os.getcwd(), scr_url) | |
200 try: | |
201 newfiles = os.listdir(scr_url) | |
202 for f in newfiles: | |
203 #put the scripts in the folder in the array such that they run in the correct order | |
204 scripts.insert(scripts.index(scr) + 1, scr.split("/")[-1] + "/" + f) | |
205 except OSError: | |
206 scr_url = "file://%s" % scr_url | |
207 try: | |
208 scriptuples.append((scr, add_script(scr_url))) | |
209 except Exception as e: | |
210 pass | |
211 | |
212 user_data = boto.utils.write_mime_multipart(scriptuples, compress=True) | |
213 | |
214 shutdown_proc = "terminate" | |
215 if options.save_ebs: | |
216 shutdown_proc = "save" | |
217 | |
218 instance_profile_name = None | |
219 if options.role: | |
220 instance_profile_name = options.role | |
221 | |
222 r = ami.run(min_count=int(options.min_count), max_count=int(options.max_count), | |
223 key_name=key_name, user_data=user_data, | |
224 security_groups=groups, instance_type=options.type, | |
225 placement=options.zone, instance_initiated_shutdown_behavior=shutdown_proc, | |
226 instance_profile_name=instance_profile_name) | |
227 | |
228 instance = r.instances[0] | |
229 | |
230 if options.tags: | |
231 for tag_pair in options.tags: | |
232 name = tag_pair | |
233 value = '' | |
234 if ':' in tag_pair: | |
235 name, value = tag_pair.split(':', 1) | |
236 instance.add_tag(name, value) | |
237 | |
238 if options.dns: | |
239 options.wait = True | |
240 | |
241 if not options.wait: | |
242 sys.exit(0) | |
243 | |
244 while True: | |
245 instance.update() | |
246 if instance.state == 'running': | |
247 break | |
248 time.sleep(3) | |
249 | |
250 if options.dns: | |
251 print("Public DNS name: %s" % instance.public_dns_name) | |
252 print("Private DNS name: %s" % instance.private_dns_name) |