~ubuntu-branches/ubuntu/trusty/cloud-utils/trusty-201404031857

« back to all changes in this revision

Viewing changes to .pc/sync-to-trunk.patch/bin/ubuntu-ec2-run

  • Committer: Scott Moser
  • Date: 2014-04-03 16:30:11 UTC
  • Revision ID: smoser@ubuntu.com-20140403163011-vbjvnapc54hwl069
* sync to trunk at revno 259
  * fix mount-image-callback args --dev, --sys, or --proc (LP: #1302052)
  * ubuntu-ec2-run: know about more instance types
  * growpart: better --dry-run output for gpt disks

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/python
2
 
#
3
 
#    ubuntu-ec2-run: ec2-run-instances that support human readable
4
 
#                    aliases for AMI's
5
 
#
6
 
#    Copyright (C) 2011 Dustin Kirkland <kirkland@ubuntu.com>
7
 
#
8
 
#    Authors: Dustin Kirkland <kirkland@ubuntu.com>
9
 
#
10
 
#    This program is free software: you can redistribute it and/or modify
11
 
#    it under the terms of the GNU General Public License as published by
12
 
#    the Free Software Foundation, version 3 of the License.
13
 
#
14
 
#    This program is distributed in the hope that it will be useful,
15
 
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 
#    GNU General Public License for more details.
18
 
#
19
 
#    You should have received a copy of the GNU General Public License
20
 
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 
 
22
 
KNOWN_RELEASES = ["lucid", "maverick", "natty", "oneiric", "precise",
23
 
                  "quantal", "raring"]
24
 
 
25
 
USAGE = """
26
 
Usage: ubuntu-ec2-run [ options ] arguments
27
 
 
28
 
  Run an ec2 instance of Ubuntu.
29
 
 
30
 
  options:
31
 
    --dry-run: only report what would be done
32
 
 
33
 
   All non-understood options are passed through to $EC2_PRE-run-instances
34
 
 
35
 
   ubuntu-ec2-run passes the following arguments to cloud-image-query
36
 
   in order to select an AMI to run.  Defaults are marked with a '*':
37
 
 
38
 
     releases: %(rels)s
39
 
     stream: release* daily
40
 
     arch: amd64*, x86_64, i386
41
 
     store: ebs*, instance-store, instance
42
 
     pvtype: pv*, hvm, paravirtual
43
 
 
44
 
   Note, that --instance-type/-t will modify arch appropriately
45
 
 
46
 
  Example:
47
 
   * ubuntu-ec2-run oneiric daily --dry-run
48
 
     # us-east-1/ebs/ubuntu-oneiric-daily-amd64-server-20110902
49
 
     ec2-run-instances --instance-type=t1.micro ami-0ba16262
50
 
   * EC2_PRE=euca- ubuntu-ec2-run lucid released --dry-run
51
 
     # us-east-1/ebs/ubuntu-oneiric-daily-amd64-server-20110902
52
 
     euca-run-instances released --instance-type=t1.micro ami-0ba16262
53
 
   * ubuntu-ec2-run oneiric hvm --dry-run
54
 
     # us-east-1/hvm/ubuntu-oneiric-11.10-beta1-amd64-server-20110831
55
 
     ec2-run-instances ./bin/ubuntu-ec2-run --instance-type=cc1.4xlarge \\
56
 
         --block-device-mapping /dev/sdb=ephemeral0 \\
57
 
         --block-device-mapping /dev/sdc=ephemeral1 ami-b79754de
58
 
   * ubuntu-ec2-run --region us-west-1 --instance-type \\
59
 
         m1.small oneiric instance --dry-run
60
 
     # us-west-1/instance-store/ubuntu-oneiric-11.10-beta1-i386-server-20110831
61
 
     ec2-run-instances --region us-west-1 --instance-type m1.small ami-39bfe27c
62
 
""" % {'rels': ' '.join(KNOWN_RELEASES)}
63
 
 
64
 
import os
65
 
import string
66
 
import subprocess
67
 
import sys
68
 
import urllib2
69
 
 
70
 
# This could/should use `distro-info --supported`
71
 
aliases = [
72
 
  "amd64", "x86_64", "i386",
73
 
  "server", "desktop",
74
 
  "release", "daily",
75
 
  "ebs", "instance-store", "instance",
76
 
  "hvm", "paravirtual", "pv",
77
 
]
78
 
 
79
 
 
80
 
def get_argopt(args, optnames):
81
 
    ret = None
82
 
    i = 0
83
 
    while i < len(args):
84
 
        cur = args[i]
85
 
        for opt in optnames:
86
 
            if opt.startswith("--"):
87
 
                if cur == opt:
88
 
                    ret = args[i + 1]
89
 
                    i = i + 1
90
 
                    break
91
 
                elif cur.startswith("%s=" % opt):
92
 
                    ret = args[i].split("=")[1]
93
 
                    break
94
 
            else:
95
 
                if args[i] == opt:
96
 
                    ret = args[i + 1]
97
 
                    i = i + 1
98
 
                    break
99
 
        i = i + 1
100
 
    return ret
101
 
 
102
 
 
103
 
def get_block_device_mappings(itype):
104
 
    # cleaned from http://aws.amazon.com/ec2/instance-types/
105
 
    # t1.micro        0   # m1.large      850   # cg1.4xlarge  1690
106
 
    # m1.small      160   # m2.2xlarge    850   # m1.xlarge    1690
107
 
    # c1.medium     350   # c1.xlarge    1690   # m2.4xlarge   1690
108
 
    # m1.medium     410   # cc1.4xlarge  1690   # hi1.4xlarge  2048
109
 
    # m2.xlarge     420   # cc1.4xlarge  1690   # cc2.8xlarge  3370
110
 
    # m3.xlarge       0
111
 
    # m3.2xlarge      0
112
 
    bdmaps = []
113
 
    if (itype in ("t1.micro", "m1.small", "c1.medium") or
114
 
        itype.startswith("m3.")):
115
 
        pass  # the first one is always attached. ephemeral0=sda2
116
 
    elif itype in ("m2.xlarge", "m1.medium"):
117
 
        bdmaps = ["/dev/sdb=ephemeral0"]
118
 
    elif (itype in ("m1.large", "m2.2xlarge", "hi1.4xlarge") or
119
 
          itype.startswith("cg1.") or itype.startswith("cc1.")):
120
 
        bdmaps = ["/dev/sdb=ephemeral0", "/dev/sdc=ephemeral1"]
121
 
    elif (itype in ("m1.xlarge", "m2.4xlarge", "c1.xlarge") or
122
 
          itype.startswith("cc2.8xlarge")):
123
 
        bdmaps = ["sdb=ephemeral0", "sdc=ephemeral1",
124
 
                  "sdd=ephemeral2", "sde=ephemeral3"]
125
 
    args = []
126
 
    for m in bdmaps:
127
 
        args.extend(("--block-device-mapping", m,))
128
 
    return(args)
129
 
 
130
 
if "--help" in sys.argv or "-h" in sys.argv:
131
 
    sys.stdout.write(USAGE)
132
 
    sys.exit(0)
133
 
 
134
 
if len(sys.argv) == 1:
135
 
    sys.stderr.write(USAGE)
136
 
    sys.exit(1)
137
 
 
138
 
pre = "ec2-"
139
 
for name in ("EC2_PRE", "EC2PRE"):
140
 
    if name in os.environ:
141
 
        pre = os.environ[name]
142
 
 
143
 
# if the prefix is something like "myec2 "
144
 
# then assume that 'myec2' is a command itself
145
 
if pre.strip() == pre:
146
 
    ri_cmd = ["%srun-instances" % pre]
147
 
else:
148
 
    ri_cmd = [pre.strip(), "run-instances"]
149
 
 
150
 
query_cmd = ["ubuntu-cloudimg-query",
151
 
    "--format=%{ami}\n%{itype}\n%{summary}\n%{store}\n"]
152
 
 
153
 
 
154
 
# Get the list of releases.  If they have 'ubuntu-distro-info', then use that
155
 
# otherwise, fall back to our builtin list of releases
156
 
try:
157
 
    out = subprocess.check_output(["ubuntu-distro-info", "--all"])
158
 
    all_rels = out.strip().split("\n")
159
 
    releases = []
160
 
    seen_lucid = False
161
 
    for r in all_rels:
162
 
        if seen_lucid or r == "lucid":
163
 
            seen_lucid = True
164
 
            releases.append(r)
165
 
except OSError as e:
166
 
    releases = KNOWN_RELEASES
167
 
 
168
 
 
169
 
# each arg_group is a list of arguments and a boolean that indicates
170
 
# if the value of that argument should be passed to query_cmd
171
 
# ec2-run-instances default instance-type is m1.small
172
 
arg_groups = (
173
 
    (("--region",), True),
174
 
    (("--instance-type", "-t"), True),
175
 
    (("--block-device-mapping", "-b"), False),
176
 
)
177
 
 
178
 
flags = {}
179
 
for opts, passthrough in arg_groups:
180
 
    arg_value = get_argopt(sys.argv, opts)
181
 
    if arg_value is not None and passthrough:
182
 
        query_cmd.append(arg_value)
183
 
    flags[opts[0]] = arg_value
184
 
 
185
 
dry_run = False
186
 
 
187
 
for arg in sys.argv[1:]:
188
 
    if arg in aliases or arg in releases:
189
 
        query_cmd.append(arg)
190
 
    elif arg == "--dry-run":
191
 
        dry_run = True
192
 
    else:
193
 
        ri_cmd.append(arg)
194
 
 
195
 
cmd = ""
196
 
for i in query_cmd:
197
 
    cmd += " '%s'" % i.replace("\n", "\\n")
198
 
cmd = cmd[1:]
199
 
 
200
 
try:
201
 
    (ami, itype, summary, store, endl) = \
202
 
        subprocess.check_output(query_cmd).split("\n")
203
 
    if endl.strip():
204
 
        sys.stderr.write("Unexpected output of command:\n  %s" % cmd)
205
 
except subprocess.CalledProcessError as e:
206
 
    sys.stderr.write("Failed. The following command returned failure:\n")
207
 
    sys.stderr.write("  %s\n" % cmd)
208
 
    sys.exit(1)
209
 
except OSError as e:
210
 
    sys.stderr.write("You do not have '%s' in your path\n" % query_cmd[0])
211
 
    sys.exit(1)
212
 
 
213
 
if flags.get("--instance-type", None) is None:
214
 
    ri_cmd.append("--instance-type=%s" % itype)
215
 
 
216
 
if store == "ebs" and flags.get("--block-device-mapping", None) is None:
217
 
    ri_cmd.extend(get_block_device_mappings(itype))
218
 
 
219
 
ri_cmd.append(ami)
220
 
 
221
 
sys.stderr.write("# %s\n" % summary)
222
 
if dry_run:
223
 
    print ' '.join(ri_cmd)
224
 
else:
225
 
    os.execvp(ri_cmd[0], ri_cmd)
226
 
###############################################################################
227
 
 
228
 
# vi: ts=4 expandtab