~ubuntu-branches/ubuntu/precise/euca2ools/precise-proposed

« back to all changes in this revision

Viewing changes to .pc/debian-changes-2.0.0~bzr464-0ubuntu1/euca2ools/commands/eucacommand.py

  • Committer: Bazaar Package Importer
  • Author(s): Scott Moser
  • Date: 2011-08-15 11:16:29 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20110815111629-3u49jvtwabwozpb7
Tags: 2.0.0~bzr464-0ubuntu1
* new upstream snapshot of bzr revno 464. (LP: #826022)
* Note, previous upload was incorrectly named 'bzr451'.  It should have
  been named bzr461 as it was a snapshot of revision 461.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Software License Agreement (BSD License)
 
2
#
 
3
# Copyright (c) 2009-2011, Eucalyptus Systems, Inc.
 
4
# All rights reserved.
 
5
#
 
6
# Redistribution and use of this software in source and binary forms, with or
 
7
# without modification, are permitted provided that the following conditions
 
8
# are met:
 
9
#
 
10
#   Redistributions of source code must retain the above
 
11
#   copyright notice, this list of conditions and the
 
12
#   following disclaimer.
 
13
#
 
14
#   Redistributions in binary form must reproduce the above
 
15
#   copyright notice, this list of conditions and the
 
16
#   following disclaimer in the documentation and/or other
 
17
#   materials provided with the distribution.
 
18
#
 
19
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
20
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
21
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
22
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 
23
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
24
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
25
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
26
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
27
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
28
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
29
# POSSIBILITY OF SUCH DAMAGE.
 
30
#
 
31
# Author: Neil Soman neil@eucalyptus.com
 
32
#         Mitch Garnaat mgarnaat@eucalyptus.com
 
33
 
 
34
import getopt
 
35
import sys
 
36
import os
 
37
import textwrap
 
38
import urlparse
 
39
import boto
 
40
import euca2ools
 
41
import euca2ools.utils
 
42
import euca2ools.exceptions
 
43
import euca2ools.nc.auth
 
44
import euca2ools.nc.connection
 
45
from boto.ec2.regioninfo import RegionInfo
 
46
from boto.s3.connection import OrdinaryCallingFormat
 
47
from boto.ec2.blockdevicemapping import BlockDeviceMapping, BlockDeviceType
 
48
from boto.roboto.param import Param
 
49
 
 
50
SYSTEM_EUCARC_PATH = os.path.join('/etc', 'euca2ools', 'eucarc')
 
51
 
 
52
EC2RegionData = {
 
53
    'us-east-1' : 'ec2.us-east-1.amazonaws.com',
 
54
    'us-west-1' : 'ec2.us-west-1.amazonaws.com',
 
55
    'eu-west-1' : 'ec2.eu-west-1.amazonaws.com',
 
56
    'ap-southeast-1' : 'ec2.ap-southeast-1.amazonaws.com'}
 
57
 
 
58
import bdb
 
59
import traceback
 
60
try:
 
61
    import epdb as debugger
 
62
except ImportError:
 
63
    import pdb as debugger
 
64
 
 
65
def euca_except_hook(debugger_flag, debug_flag):
 
66
    def excepthook(typ, value, tb):
 
67
        if typ is bdb.BdbQuit:
 
68
            sys.exit(1)
 
69
        sys.excepthook = sys.__excepthook__
 
70
 
 
71
        if debugger_flag and sys.stdout.isatty() and sys.stdin.isatty():
 
72
            if debugger.__name__ == 'epdb':
 
73
                debugger.post_mortem(tb, typ, value)
 
74
            else:
 
75
                debugger.post_mortem(tb)
 
76
        elif debug_flag:
 
77
            print traceback.print_tb(tb)
 
78
            sys.exit(1)
 
79
        else:
 
80
            print value
 
81
            sys.exit(1)
 
82
 
 
83
    return excepthook
 
84
 
 
85
class EucaCommand(object):
 
86
 
 
87
    Description = 'Base class'
 
88
    StandardOptions = [Param(name='access_key',
 
89
                             short_name='a', long_name='access-key',
 
90
                             doc="User's Access Key ID.",
 
91
                             optional=True),
 
92
                       Param(name='secret_key',
 
93
                             short_name='s', long_name='secret-key',
 
94
                             doc="User's Secret Key.",
 
95
                             optional=True),
 
96
                       Param(name='config_path',
 
97
                             short_name=None, long_name='config',
 
98
                             doc="""Read credentials and cloud settings
 
99
                             from the specified config file (defaults to
 
100
                             $HOME/.eucarc or /etc/euca2ools/eucarc).""",
 
101
                             optional=True),
 
102
                       Param(short_name=None, long_name='debug',
 
103
                             doc='Turn on debugging output.',
 
104
                             optional=True, ptype='boolean'),
 
105
                       Param(short_name=None, long_name='debugger',
 
106
                             doc='Enable interactive debugger on error',
 
107
                             optional=True, ptype='boolean'),
 
108
                       Param(short_name='h', long_name='help',
 
109
                             doc='Display this help message.',
 
110
                             optional=True, ptype='boolean'),
 
111
                       Param(name='region_name',
 
112
                             short_name=None, long_name='region',
 
113
                             doc='region to direct requests to',
 
114
                             optional=True),
 
115
                       Param(short_name='U', long_name='url',
 
116
                             doc='URL of the Cloud to connect to.',
 
117
                             optional=True),
 
118
                       Param(short_name=None, long_name='version',
 
119
                             doc='Display the version of this tool.',
 
120
                             optional=True, ptype='boolean'),
 
121
                       Param(long_name='euca-auth',
 
122
                             doc='Use NC authentication mode',
 
123
                             optional=True, ptype='boolean')]
 
124
    Options = []
 
125
    Args = []
 
126
    Filters = []
 
127
    APIVersion = '2009-11-30'
 
128
 
 
129
    def __init__(self, is_euca=False, debug=False):
 
130
        self.access_key_short_name = '-a'
 
131
        self.secret_key_short_name = '-s'
 
132
        self.ec2_user_access_key = None
 
133
        self.ec2_user_secret_key = None
 
134
        self.url = None
 
135
        self.filters = {}
 
136
        self.region_name = None
 
137
        self.region = RegionInfo()
 
138
        self.config_file_path = None
 
139
        self.is_secure = True
 
140
        self.port = 443
 
141
        self.service_path = '/'
 
142
        self.is_euca = is_euca
 
143
        self.euca_cert_path = None
 
144
        self.euca_private_key_path = None
 
145
        self.debug = 0
 
146
        self.debugger = False
 
147
        self.set_debug(debug)
 
148
        self.cmd_name = os.path.basename(sys.argv[0])
 
149
        self.setup_environ()
 
150
        self.check_for_conflict()
 
151
        self.process_cli_args()
 
152
        # h = NullHandler()
 
153
        # logging.getLogger('boto').addHandler(h)
 
154
 
 
155
    def set_debug(self, debug=False):
 
156
        if debug:
 
157
            boto.set_stream_logger('euca2ools')
 
158
            self.debug = 2
 
159
 
 
160
    def process_cli_args(self):
 
161
        (opts, args) = getopt.gnu_getopt(sys.argv[1:],
 
162
                                         self.short_options(),
 
163
                                         self.long_options())
 
164
        for (name, value) in opts:
 
165
            if name in ('-h', '--help'):
 
166
                self.usage()
 
167
                sys.exit()
 
168
            elif name == '--version':
 
169
                self.version()
 
170
            elif name == '--debug':
 
171
                self.set_debug(True)
 
172
            elif name == '--debugger':
 
173
                self.debugger = True
 
174
            elif name in (self.access_key_short_name, '--access-key'):
 
175
                self.ec2_user_access_key = value
 
176
            elif name in (self.secret_key_short_name, '--secret-key'):
 
177
                self.ec2_user_secret_key = value
 
178
            elif name in ('-U', '--url'):
 
179
                self.url = value
 
180
            elif name == '--region':
 
181
                self.region_name = value
 
182
            elif name == '--config':
 
183
                self.config_file_path = value
 
184
            elif name == '--euca-auth':
 
185
                self.is_euca = True
 
186
            elif name == '--filter':
 
187
                try:
 
188
                    name, value = value.split('=')
 
189
                except ValueError:
 
190
                    msg = 'Filters must be of the form name=value'
 
191
                    self.display_error_and_exit(msg)
 
192
                self.filters[name] = value
 
193
            else:
 
194
                option = self.find_option(name)
 
195
                if option:
 
196
                    try:
 
197
                        value = option.convert(value)
 
198
                    except:
 
199
                        msg = '%s should be of type %s' % (option.long_name,
 
200
                                                           option.ptype)
 
201
                        self.display_error_and_exit(msg)
 
202
                    if option.cardinality in ('*', '+'):
 
203
                        if not hasattr(self, option.name):
 
204
                            setattr(self, option.name, [])
 
205
                        getattr(self, option.name).append(value)
 
206
                    else:
 
207
                        setattr(self, option.name, value)
 
208
        self.handle_defaults()
 
209
        self.check_required_options()
 
210
 
 
211
        for arg in self.Args:
 
212
            if not arg.optional and len(args)==0:
 
213
                self.usage()
 
214
                msg = 'Argument (%s) was not provided' % arg.name
 
215
                self.display_error_and_exit(msg)
 
216
            if arg.cardinality in ('*', '+'):
 
217
                setattr(self, arg.name, args)
 
218
            elif arg.cardinality == 1:
 
219
                if len(args) == 0 and arg.optional:
 
220
                    continue
 
221
                try:
 
222
                    value = arg.convert(args[0])
 
223
                except:
 
224
                    msg = '%s should be of type %s' % (arg.name,
 
225
                                                       arg.ptype)
 
226
                setattr(self, arg.name, value)
 
227
                if len(args) > 1:
 
228
                    msg = 'Only 1 argument (%s) permitted' % arg.name
 
229
                    self.display_error_and_exit(msg)
 
230
 
 
231
        sys.excepthook = euca_except_hook(self.debugger, self.debug)
 
232
 
 
233
 
 
234
    def check_for_conflict(self):
 
235
        for option in self.Options:
 
236
            if option.short_name == 'a' or option.short_name == 's':
 
237
                self.access_key_short_name = '-A'
 
238
                self.secret_key_short_name = '-S'
 
239
                opt = self.find_option('--access-key')
 
240
                opt.short_name = 'A'
 
241
                opt = self.find_option('--secret-key')
 
242
                opt.short_name = 'A'
 
243
 
 
244
    def find_option(self, op_name):
 
245
        for option in self.StandardOptions+self.Options:
 
246
            if option.synopsis_short_name == op_name or option.synopsis_long_name == op_name:
 
247
                return option
 
248
        return None
 
249
 
 
250
    def short_options(self):
 
251
        s = ''
 
252
        for option in self.StandardOptions + self.Options:
 
253
            if option.short_name:
 
254
                s += option.getopt_short_name
 
255
        return s
 
256
 
 
257
    def long_options(self):
 
258
        l = []
 
259
        for option in self.StandardOptions+self.Options:
 
260
            if option.long_name:
 
261
                l.append(option.getopt_long_name)
 
262
        if self.Filters:
 
263
            l.append('filter=')
 
264
        return l
 
265
 
 
266
    def required(self):
 
267
        return [ opt for opt in self.StandardOptions+self.Options if not opt.optional ]
 
268
 
 
269
    def required_args(self):
 
270
        return [ arg for arg in self.Args if not arg.optional ]
 
271
 
 
272
    def optional(self):
 
273
        return [ opt for opt in self.StandardOptions+self.Options if opt.optional ]
 
274
 
 
275
    def optional_args(self):
 
276
        return [ arg for arg in self.Args if arg.optional ]
 
277
 
 
278
    def handle_defaults(self):
 
279
        for option in self.Options+self.Args:
 
280
            if not hasattr(self, option.name):
 
281
                value = option.default
 
282
                if value is None and option.cardinality in ('+', '*'):
 
283
                    value = []
 
284
                elif value is None and option.ptype == 'boolean':
 
285
                    value = False
 
286
                elif value is None and option.ptype == 'integer':
 
287
                    value = 0
 
288
                setattr(self, option.name, value)
 
289
 
 
290
    def check_required_options(self):
 
291
        missing = []
 
292
        for option in self.required():
 
293
            if not hasattr(self, option.name) or getattr(self, option.name) is None:
 
294
                missing.append(option.long_name)
 
295
        if missing:
 
296
            msg = 'These required options are missing: %s' % ','.join(missing)
 
297
            self.display_error_and_exit(msg)
 
298
 
 
299
    def version(self):
 
300
        print '\tVersion: %s (BSD)' % euca2ools.__version__
 
301
        sys.exit(0)
 
302
 
 
303
    def param_usage(self, plist, label, n=30):
 
304
        nn = 80 - n - 4
 
305
        if plist:
 
306
            print '\n%s' % label
 
307
            for opt in plist:
 
308
                names = []
 
309
                if opt.short_name:
 
310
                    names.append(opt.synopsis_short_name)
 
311
                if opt.long_name:
 
312
                    names.append(opt.synopsis_long_name)
 
313
                if not names:
 
314
                    names.append(opt.name)
 
315
                doc = textwrap.dedent(opt.doc)
 
316
                doclines = textwrap.wrap(doc, nn)
 
317
                if doclines:
 
318
                    print '    %s%s' % (','.join(names).ljust(n), doclines[0])
 
319
                    for line in doclines[1:]:
 
320
                        print '%s%s' % (' '*(n+4), line)
 
321
 
 
322
    def filter_usage(self, n=30):
 
323
        if self.Filters:
 
324
            nn = 80 - n - 4
 
325
            print '\nAVAILABLE FILTERS'
 
326
            for filter in self.Filters:
 
327
                doc = textwrap.dedent(filter.doc)
 
328
                doclines = textwrap.wrap(doc, nn, fix_sentence_endings=True)
 
329
                print '    %s%s' % (filter.name.ljust(n), doclines[0])
 
330
                for line in doclines[1:]:
 
331
                    print '%s%s' % (' '*(n+4), line)
 
332
                
 
333
 
 
334
    def option_synopsis(self, options):
 
335
        s = ''
 
336
        for option in options:
 
337
            names = []
 
338
            if option.short_name:
 
339
                names.append(option.synopsis_short_name)
 
340
            if option.long_name:
 
341
                names.append(option.synopsis_long_name)
 
342
            if option.optional:
 
343
                s += '['
 
344
            s += ', '.join(names)
 
345
            if option.ptype != 'boolean':
 
346
                if option.metavar:
 
347
                    n = option.metavar
 
348
                elif option.name:
 
349
                    n = option.name
 
350
                else:
 
351
                    n = option.long_name
 
352
                s += ' <%s> ' % n
 
353
            if option.optional:
 
354
                s += ']'
 
355
        return s
 
356
 
 
357
    def synopsis(self):
 
358
        s = '%s ' % self.cmd_name
 
359
        n = len(s) + 1
 
360
        t = ''
 
361
        t += self.option_synopsis(self.required())
 
362
        t += self.option_synopsis(self.optional())
 
363
        if self.Filters:
 
364
            t += ' [--filter name=value]'
 
365
        if self.Args:
 
366
            t += ' '
 
367
            arg_names = []
 
368
            for arg in self.Args:
 
369
                name = arg.name
 
370
                if arg.optional:
 
371
                    name = '[ %s ]' % name
 
372
                arg_names.append(name)
 
373
            t += ' '.join(arg_names)
 
374
        lines = textwrap.wrap(t, 80-n)
 
375
        print s, lines[0]
 
376
        for line in lines[1:]:
 
377
            print '%s%s' % (' '*n, line)
 
378
                
 
379
    def usage(self):
 
380
        print '%s\n' % self.Description
 
381
        self.synopsis()
 
382
        self.param_usage(self.required()+self.required_args(),
 
383
                         'REQUIRED PARAMETERS')
 
384
        self.param_usage(self.optional()+self.optional_args(),
 
385
                         'OPTIONAL PARAMETERS')
 
386
        self.filter_usage()
 
387
 
 
388
    def display_error_and_exit(self, exc):
 
389
        try:
 
390
            print '%s: %s' % (exc.error_code, exc.error_message)
 
391
        except:
 
392
            print '%s' % exc
 
393
        finally:
 
394
            sys.exit(1)
 
395
            
 
396
    def setup_environ(self):
 
397
        envlist = ('EC2_ACCESS_KEY', 'EC2_SECRET_KEY',
 
398
                   'S3_URL', 'EC2_URL', 'EC2_CERT', 'EC2_PRIVATE_KEY',
 
399
                   'EUCALYPTUS_CERT', 'EC2_USER_ID',
 
400
                   'EUCA_CERT', 'EUCA_PRIVATE_KEY')
 
401
        self.environ = {}
 
402
        user_eucarc = None
 
403
        if 'HOME' in os.environ:
 
404
            user_eucarc = os.path.join(os.getenv('HOME'), '.eucarc')
 
405
        read_config = False
 
406
        if self.config_file_path \
 
407
            and os.path.exists(self.config_file_path):
 
408
            read_config = self.config_file_path
 
409
        elif user_eucarc is not None and os.path.exists(user_eucarc):
 
410
            if os.path.isdir(user_eucarc):
 
411
                user_eucarc = os.path.join(user_eucarc, 'eucarc')
 
412
                if os.path.isfile(user_eucarc):
 
413
                    read_config = user_eucarc
 
414
            elif os.path.isfile(user_eucarc):
 
415
                read_config = user_eucarc
 
416
        elif os.path.exists(SYSTEM_EUCARC_PATH):
 
417
            read_config = SYSTEM_EUCARC_PATH
 
418
        if read_config:
 
419
            euca2ools.utils.parse_config(read_config, self.environ, envlist)
 
420
        else:
 
421
            for v in envlist:
 
422
                self.environ[v] = os.getenv(v)
 
423
 
 
424
    def get_environ(self, name):
 
425
        if self.environ.has_key(name):
 
426
            value = self.environ[name]
 
427
            if value:
 
428
                return self.environ[name]
 
429
        msg = 'Environment variable: %s not found' % name
 
430
        self.display_error_and_exit(msg)
 
431
 
 
432
    def get_credentials(self):
 
433
        if self.is_euca:
 
434
            if not self.euca_cert_path:
 
435
                self.euca_cert_path = self.environ['EUCA_CERT']
 
436
                if not self.euca_cert_path:
 
437
                    print 'EUCA_CERT variable must be set.'
 
438
                    raise euca2ools.exceptions.ConnectionFailed
 
439
            if not self.euca_private_key_path:
 
440
                self.euca_private_key_path = self.environ['EUCA_PRIVATE_KEY']
 
441
                if not self.euca_private_key_path:
 
442
                    print 'EUCA_PRIVATE_KEY variable must be set.'
 
443
                    raise euca2ools.exceptions.ConnectionFailed
 
444
        if not self.ec2_user_access_key:
 
445
            self.ec2_user_access_key = self.environ['EC2_ACCESS_KEY']
 
446
            if not self.ec2_user_access_key:
 
447
                print 'EC2_ACCESS_KEY environment variable must be set.'
 
448
                raise euca2ools.exceptions.ConnectionFailed
 
449
 
 
450
        if not self.ec2_user_secret_key:
 
451
            self.ec2_user_secret_key = self.environ['EC2_SECRET_KEY']
 
452
            if not self.ec2_user_secret_key:
 
453
                print 'EC2_SECRET_KEY environment variable must be set.'
 
454
                raise euca2ools.exceptions.ConnectionFailed
 
455
 
 
456
    def get_connection_details(self):
 
457
        self.port = None
 
458
        self.service_path = '/'
 
459
        
 
460
        rslt = urlparse.urlparse(self.url)
 
461
        if rslt.scheme == 'https':
 
462
            self.is_secure = True
 
463
        else:
 
464
            self.is_secure = False
 
465
 
 
466
        self.host = rslt.netloc
 
467
        l = self.host.split(':')
 
468
        if len(l) > 1:
 
469
            self.host = l[0]
 
470
            self.port = int(l[1])
 
471
 
 
472
        if rslt.path:
 
473
            self.service_path = rslt.path
 
474
 
 
475
    def make_s3_connection(self):
 
476
        if not self.url:
 
477
            self.url = self.environ['S3_URL']
 
478
            if not self.url:
 
479
                self.url = \
 
480
                    'http://localhost:8773/services/Walrus'
 
481
                print 'S3_URL not specified. Trying %s' \
 
482
                    % self.url
 
483
 
 
484
        self.get_connection_details()
 
485
 
 
486
        if self.is_euca:
 
487
            return euca2ools.nc.connection.EucaConnection(
 
488
                private_key_path=self.euca_private_key_path,
 
489
                cert_path=self.euca_cert_path,
 
490
                aws_access_key_id=self.ec2_user_access_key,
 
491
                aws_secret_access_key=self.ec2_user_secret_key,
 
492
                is_secure=self.is_secure, debug=self.debug,
 
493
                host=self.host,
 
494
                port=self.port,
 
495
                path=self.service_path)
 
496
        else:
 
497
            return boto.connect_s3(
 
498
                aws_access_key_id=self.ec2_user_access_key,
 
499
                aws_secret_access_key=self.ec2_user_secret_key,
 
500
                is_secure=self.is_secure, debug=self.debug,
 
501
                host=self.host,
 
502
                port=self.port,
 
503
                calling_format=OrdinaryCallingFormat(),
 
504
                path=self.service_path)
 
505
 
 
506
    def make_ec2_connection(self):
 
507
        if self.region_name:
 
508
            self.region.name = self.region_name
 
509
            try:
 
510
                self.region.endpoint = EC2RegionData[self.region_name]
 
511
            except KeyError:
 
512
                print 'Unknown region: %s' % self.region_name
 
513
                sys.exit(1)
 
514
        elif not self.url:
 
515
            self.url = self.environ['EC2_URL']
 
516
            if not self.url:
 
517
                self.url = \
 
518
                    'http://localhost:8773/services/Eucalyptus'
 
519
                print 'EC2_URL not specified. Trying %s' \
 
520
                    % self.url
 
521
 
 
522
        if not self.region.endpoint:
 
523
            self.get_connection_details()
 
524
            self.region.name = 'eucalyptus'
 
525
            self.region.endpoint = self.host
 
526
 
 
527
        return boto.connect_ec2(aws_access_key_id=self.ec2_user_access_key,
 
528
                                aws_secret_access_key=self.ec2_user_secret_key,
 
529
                                is_secure=self.is_secure,
 
530
                                debug=self.debug,
 
531
                                region=self.region,
 
532
                                port=self.port,
 
533
                                path=self.service_path,
 
534
                                api_version=self.APIVersion)
 
535
    
 
536
    def make_connection(self, conn_type='ec2'):
 
537
        self.get_credentials()
 
538
        if conn_type == 's3':
 
539
            conn = self.make_s3_connection()
 
540
        elif conn_type == 'ec2':
 
541
            conn = self.make_ec2_connection()
 
542
        else:
 
543
            conn = None
 
544
        return conn
 
545
 
 
546
    def make_connection_cli(self, conn_type='ec2'):
 
547
        """
 
548
        This just wraps up the make_connection call with appropriate
 
549
        try/except logic to print out an error message and exit if
 
550
        a EucaError is encountered.  This keeps the try/except logic
 
551
        out of all the command files.
 
552
        """
 
553
        try:
 
554
            conn = self.make_connection(conn_type)
 
555
            if not conn:
 
556
                msg = 'Unknown connection type: %s' % conn_type
 
557
                self.display_error_and_exit(msg)
 
558
            return conn
 
559
        except euca2ools.exceptions.EucaError, ex:
 
560
            self.display_error_and_exit(ex)
 
561
 
 
562
    def make_request_cli(self, connection, request_name, **params):
 
563
        """
 
564
        This provides a simple
 
565
        This just wraps up the make_connection call with appropriate
 
566
        try/except logic to print out an error message and exit if
 
567
        a EucaError is encountered.  This keeps the try/except logic
 
568
        out of all the command files.
 
569
        """
 
570
        try:
 
571
            if self.filters:
 
572
                params['filters'] = self.filters
 
573
            method = getattr(connection, request_name)
 
574
        except AttributeError:
 
575
            print 'Unknown request: %s' % request_name
 
576
            sys.exit(1)
 
577
        try:
 
578
            return method(**params)
 
579
        except Exception, ex:
 
580
            self.display_error_and_exit(ex)
 
581
 
 
582
    def get_relative_filename(self, filename):
 
583
        return os.path.split(filename)[-1]
 
584
 
 
585
    def get_file_path(self, filename):
 
586
        relative_filename = self.get_relative_filename(filename)
 
587
        file_path = os.path.dirname(filename)
 
588
        if len(file_path) == 0:
 
589
            file_path = '.'
 
590
        return file_path
 
591
 
 
592
    def parse_block_device_args(self, block_device_maps_args):
 
593
        block_device_map = BlockDeviceMapping()
 
594
        for block_device_map_arg in block_device_maps_args:
 
595
            parts = block_device_map_arg.split('=')
 
596
            if len(parts) > 1:
 
597
                device_name = parts[0]
 
598
                block_dev_type = BlockDeviceType()
 
599
                value_parts = parts[1].split(':')
 
600
                if value_parts[0].startswith('snap'):
 
601
                    block_dev_type.snapshot_id = value_parts[0]
 
602
                else:
 
603
                    if value_parts[0].startswith('ephemeral'):
 
604
                        block_dev_type.ephemeral_name = value_parts[0]
 
605
                if len(value_parts) > 1:
 
606
                    try:
 
607
                        block_dev_type.size = int(value_parts[1])
 
608
                    except ValueError:
 
609
                        pass
 
610
                if len(value_parts) > 2:
 
611
                    if value_parts[2] == 'true':
 
612
                        block_dev_type.delete_on_termination = True
 
613
                block_device_map[device_name] = block_dev_type
 
614
        return block_device_map
 
615