3
# ubuntu-ec2-run: ec2-run-instances that support human readable aliases for AMI's
5
# Copyright (C) 2011 Dustin Kirkland <kirkland@ubuntu.com>
7
# Authors: Dustin Kirkland <kirkland@ubuntu.com>
9
# This program is free software: you can redistribute it and/or modify
10
# it under the terms of the GNU General Public License as published by
11
# the Free Software Foundation, version 3 of the License.
13
# This program is distributed in the hope that it will be useful,
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
# GNU General Public License for more details.
18
# You should have received a copy of the GNU General Public License
19
# along with this program. If not, see <http://www.gnu.org/licenses/>.
22
Usage: ubuntu-ec2-run [ options ] arguments
24
Run an ec2 instance of Ubuntu.
27
--dry-run: only report what would be done
29
All non-understood options are passed through to $EC2_PRE-run-instances
31
ubuntu-ec2-run passes the following arguments to cloud-image-query
32
in order to select an AMI to run. Defaults are marked with a '*':
34
releases: lucid* maverick natty oneiric precise
35
stream: release* daily
36
arch: amd64*, x86_64, i386
37
store: ebs*, instance-store, instance
38
pvtype: pv*, hvm, paravirtual
40
Note, that --instance-type/-t will modify arch appropriately
43
* ubuntu-ec2-run oneiric daily --dry-run
44
# us-east-1/ebs/ubuntu-oneiric-daily-amd64-server-20110902
45
ec2-run-instances --instance-type=t1.micro ami-0ba16262
46
* EC2_PRE=euca- ubuntu-ec2-run lucid released --dry-run
47
# us-east-1/ebs/ubuntu-oneiric-daily-amd64-server-20110902
48
euca-run-instances released --instance-type=t1.micro ami-0ba16262
49
* ubuntu-ec2-run oneiric hvm --dry-run
50
# us-east-1/hvm/ubuntu-oneiric-11.10-beta1-amd64-server-20110831
51
ec2-run-instances ./bin/ubuntu-ec2-run --instance-type=cc1.4xlarge \\
52
--block-device-mapping /dev/sdb=ephemeral0 \\
53
--block-device-mapping /dev/sdc=ephemeral1 ami-b79754de
54
* ubuntu-ec2-run --region us-west-1 --instance-type \\
55
m1.small oneiric instance --dry-run
56
# us-west-1/instance-store/ubuntu-oneiric-11.10-beta1-i386-server-20110831
57
ec2-run-instances --region us-west-1 --instance-type m1.small ami-39bfe27c
60
import os, string, sys, urllib2
63
# This could/should use `distro-info --supported`
65
"amd64", "x86_64", "i386",
68
"ebs", "instance-store", "instance",
69
"hvm", "paravirtual", "pv",
72
def get_argopt(args, optnames):
78
if opt.startswith("--"):
83
elif cur.startswith("%s=" % opt):
84
ret = args[i].split("=")[1]
94
def get_block_device_mappings(itype):
95
# cleaned from http://aws.amazon.com/ec2/instance-types/
96
# t1.micro NONE # m2.2xlarge 850 # c1.xlarge 1690
97
# m1.small 160 # m1.large 850 # m1.xlarge 1690
98
# c1.medium 350 # cc1.4xlarge 1690 # cc1.4xlarge 1690
99
# m2.xlarge 420 # m2.4xlarge 1690 # cg1.4xlarge 1690
102
if itype in ("t1.micro", "m1.small", "c1.medium"):
103
pass # the first one is always attached. ephemeral0=sda2
104
elif itype in ("m2.xlarge"):
105
pass # one 420 for m2.xlarge
106
elif ( itype in ("m1.large", "m2.2xlarge") or
107
itype.startswith("cg1.") or itype.startswith("cc1.")):
108
bdmaps=[ "/dev/sdb=ephemeral0", "/dev/sdc=ephemeral1", ]
109
elif ( itype in ("m1.xlarge", "m2.4xlarge", "c1.xlarge") or
110
itype.startswith("cc2.8xlarge")):
111
bdmaps=[ "sdb=ephemeral0", "sdc=ephemeral1",
112
"sdd=ephemeral2", "sde=ephemeral3", ]
115
args.extend(("--block-device-mapping", m,))
118
if "--help" in sys.argv or "-h" in sys.argv:
119
sys.stdout.write(USAGE)
122
if len(sys.argv) == 1:
123
sys.stderr.write(USAGE)
127
for name in ("EC2_PRE", "EC2PRE"):
128
if name in os.environ:
131
# if the prefix is something like "myec2 "
132
# then assume that 'myec2' is a command itself
133
if pre.strip() == pre:
134
ri_cmd = [ "%srun-instances" % pre ]
136
ri_cmd = [ pre.strip(), "run-instances" ]
138
query_cmd = [ "ubuntu-cloudimg-query", "--format=%{ami}\n%{itype}\n%{summary}\n%{store}\n" ]
141
# Get the list of releases. If they have 'ubuntu-distro-info', then use that
142
# otherwise, fall back to our builtin list of releases
144
out = subprocess.check_output(["ubuntu-distro-info", "--all"])
145
all_rels = out.strip().split("\n")
149
if seen_lucid or r == "lucid":
153
releases = [ "lucid", "maverick", "natty", "oneiric", "precise", ]
156
# each arg_group is a list of arguments and a default if not found
157
# ec2-run-instances default instance-type is m1.small
160
("--instance-type", "-t"),
161
("--block-device-mapping", "-b"),
165
for opts in arg_groups:
166
arg_value = get_argopt(sys.argv, opts)
167
if arg_value != None:
168
query_cmd.append(arg_value)
169
flags[opts[0]]=arg_value
173
for arg in sys.argv[1:]:
174
if arg in aliases or arg in releases:
175
query_cmd.append(arg)
176
elif arg == "--dry-run":
183
cmd += " '%s'" % i.replace("\n","\\n")
187
(ami, itype, summary, store, endl) = subprocess.check_output(query_cmd).split("\n")
189
sys.stderr.write("Unexpected output of command:\n %s" % cmd)
190
except subprocess.CalledProcessError as e:
191
sys.stderr.write("Failed. The following command returned failure:\n")
192
sys.stderr.write(" %s\n" % cmd)
195
sys.stderr.write("You do not have '%s' in your path\n" % query_cmd[0])
198
if flags.get("--instance-type",None) == None:
199
ri_cmd.append("--instance-type=%s" % itype)
201
if store == "ebs" and flags.get("--block-device-mapping",None) == None:
202
ri_cmd.extend(get_block_device_mappings(itype))
206
sys.stderr.write("# %s\n" % summary)
208
print ' '.join(ri_cmd)
210
os.execvp(ri_cmd[0], ri_cmd)
211
################################################################################