[pkg-eucalyptus-commits] [SCM] managing cloud instances for Eucalyptus branch, master, updated. 3.0.0-alpha3-257-g1da8e3a
Garrett Holmstrom
gholms at fedoraproject.org
Sun Jun 16 02:31:29 UTC 2013
The following commit has been merged in the master branch:
commit a5aa93b9f4e1bb297a3c0a9543fbf3859f814e7e
Author: Garrett Holmstrom <gholms at fedoraproject.org>
Date: Wed May 22 16:31:18 2013 -0700
Drop remaining boto and m2crypto code
Fixes TOOLS-160, TOOLS-191
diff --git a/euca2ools/commands/bundle/bundleimage.py b/euca2ools/commands/bundle/bundleimage.py
index fd0cd4c..55de5a4 100644
--- a/euca2ools/commands/bundle/bundleimage.py
+++ b/euca2ools/commands/bundle/bundleimage.py
@@ -33,7 +33,7 @@ import binascii
import euca2ools
from euca2ools.commands.bundle import BundleCreator
from euca2ools.commands.bundle.bundle import Bundle
-from euca2ools.utils import mkdtemp_for_large_files
+from euca2ools.util import mkdtemp_for_large_files
import hashlib
import lxml.etree
import lxml.objectify
diff --git a/euca2ools/commands/bundle/downloadbundle.py b/euca2ools/commands/bundle/downloadbundle.py
index 0f65718..5babb5a 100644
--- a/euca2ools/commands/bundle/downloadbundle.py
+++ b/euca2ools/commands/bundle/downloadbundle.py
@@ -34,7 +34,7 @@ from euca2ools.commands.bundle.helpers import get_manifest_parts
from euca2ools.commands.walrus import WalrusRequest
from euca2ools.commands.walrus.checkbucket import CheckBucket
from euca2ools.exceptions import AWSError
-from euca2ools.utils import mkdtemp_for_large_files
+from euca2ools.util import mkdtemp_for_large_files
import os
from requestbuilder import Arg, MutuallyExclusiveArgList
from requestbuilder.exceptions import ArgumentError
diff --git a/euca2ools/commands/bundle/imagecreator.py b/euca2ools/commands/bundle/imagecreator.py
index 0a9a64d..f86aa7a 100644
--- a/euca2ools/commands/bundle/imagecreator.py
+++ b/euca2ools/commands/bundle/imagecreator.py
@@ -28,8 +28,8 @@
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
-from euca2ools.utils import sanitize_path
-from euca2ools.utils import mkdtemp_for_large_files as mkdtemp
+from euca2ools.util import sanitize_path
+from euca2ools.util import mkdtemp_for_large_files as mkdtemp
import glob
import os
import sys
diff --git a/euca2ools/commands/euca/describeavailabilityzones.py b/euca2ools/commands/euca/describeavailabilityzones.py
index 710a74c..3df625b 100644
--- a/euca2ools/commands/euca/describeavailabilityzones.py
+++ b/euca2ools/commands/euca/describeavailabilityzones.py
@@ -29,7 +29,6 @@
# POSSIBILITY OF SUCH DAMAGE.
from euca2ools.commands.euca import EucalyptusRequest
-import euca2ools.utils
from requestbuilder import Arg, Filter
@@ -45,17 +44,6 @@ class DescribeAvailabilityZones(EucalyptusRequest):
Filter('zone-name', help='name of the availability zone')]
LIST_TAGS = ['availabilityZoneInfo', 'messageSet']
- def send(self):
- try:
- response = EucalyptusRequest.send(self)
- return response
- except:
- response = None
- raise
- finally:
- euca2ools.utils.handle_availability_zones(self.args['ZoneName'],
- response)
-
def print_result(self, result):
for zone in result.get('availabilityZoneInfo', []):
msgs = ', '.join(msg for msg in zone.get('messageSet', []))
diff --git a/euca2ools/commands/eucacommand.py b/euca2ools/commands/eucacommand.py
deleted file mode 100644
index b17d8e4..0000000
--- a/euca2ools/commands/eucacommand.py
+++ /dev/null
@@ -1,643 +0,0 @@
-# Software License Agreement (BSD License)
-#
-# Copyright (c) 2009-2011, Eucalyptus Systems, Inc.
-# All rights reserved.
-#
-# Redistribution and use of this software in source and binary forms, with or
-# without modification, are permitted provided that the following conditions
-# are met:
-#
-# Redistributions of source code must retain the above
-# copyright notice, this list of conditions and the
-# following disclaimer.
-#
-# Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the
-# following disclaimer in the documentation and/or other
-# materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-#
-# Author: Neil Soman neil at eucalyptus.com
-# Mitch Garnaat mgarnaat at eucalyptus.com
-
-import boto
-import getopt
-import os
-import socket
-import sys
-import textwrap
-import urlparse
-import euca2ools
-import euca2ools.utils
-import euca2ools.exceptions
-import euca2ools.nc.auth
-import euca2ools.nc.connection
-from boto.ec2.regioninfo import RegionInfo
-from boto.s3.connection import OrdinaryCallingFormat
-from boto.ec2.blockdevicemapping import BlockDeviceMapping, BlockDeviceType
-from boto.roboto.param import Param
-
-SYSTEM_EUCARC_PATH = os.path.join('/etc', 'euca2ools', 'eucarc')
-
-import bdb
-import traceback
-try:
- import epdb as debugger
-except ImportError:
- import pdb as debugger
-
-def euca_except_hook(debugger_flag, debug_flag):
- def excepthook(typ, value, tb):
- if typ is bdb.BdbQuit:
- sys.exit(1)
- sys.excepthook = sys.__excepthook__
-
- if debugger_flag and sys.stdout.isatty() and sys.stdin.isatty():
- if debugger.__name__ == 'epdb':
- debugger.post_mortem(tb, typ, value)
- else:
- debugger.post_mortem(tb)
- elif debug_flag:
- print >> sys.stderr, traceback.print_tb(tb)
- sys.exit(1)
- else:
- print >> sys.stderr, value
- sys.exit(1)
-
- return excepthook
-
-class EucaCommand(object):
-
- Description = 'Base class'
- StandardOptions = [Param(name='access_key',
- short_name='a', long_name='access-key',
- doc="User's Access Key ID.",
- optional=True),
- Param(name='secret_key',
- short_name='s', long_name='secret-key',
- doc="User's Secret Key.",
- optional=True),
- Param(name='config_path',
- short_name=None, long_name='config',
- doc="""Read credentials and cloud settings
- from the specified config file (defaults to
- $HOME/.eucarc or /etc/euca2ools/eucarc).""",
- optional=True),
- Param(short_name=None, long_name='debug',
- doc='Turn on debugging output.',
- optional=True, ptype='boolean'),
- Param(short_name=None, long_name='debugger',
- doc='Enable interactive debugger on error',
- optional=True, ptype='boolean'),
- Param(short_name='h', long_name='help',
- doc='Display this help message.',
- optional=True, ptype='boolean'),
- Param(name='region_name',
- short_name=None, long_name='region',
- doc='region to direct requests to',
- optional=True),
- Param(short_name='U', long_name='url',
- doc='URL of the Cloud to connect to.',
- optional=True),
- Param(short_name=None, long_name='version',
- doc='Display the version of this tool.',
- optional=True, ptype='boolean'),
- Param(long_name='euca-auth',
- doc='Use NC authentication mode',
- optional=True, ptype='boolean')]
- Options = []
- Args = []
- Filters = []
- APIVersion = '2009-11-30'
-
- def __init__(self, is_euca=False, debug=False):
- self.access_key_short_name = '-a'
- self.secret_key_short_name = '-s'
- self.ec2_user_access_key = None
- self.ec2_user_secret_key = None
- self.url = None
- self.filters = {}
- self.region_name = None
- self.region = RegionInfo()
- self.config_file_path = None
- self.is_secure = True
- self.port = 443
- self.service_path = '/'
- self.is_euca = is_euca
- self.euca_cert_path = None
- self.euca_private_key_path = None
- self.debug = 0
- self.debugger = False
- self.set_debug(debug)
- self.cmd_name = os.path.basename(sys.argv[0])
- self.check_for_conflict()
- self.process_cli_args()
- self.setup_environ()
- # h = NullHandler()
- # logging.getLogger('boto').addHandler(h)
-
- def set_debug(self, debug=False):
- if debug:
- boto.set_stream_logger('euca2ools')
- self.debug = 2
-
- def process_cli_args(self):
- try:
- (opts, args) = getopt.gnu_getopt(sys.argv[1:],
- self.short_options(),
- self.long_options())
- except getopt.GetoptError, e:
- print >> sys.stderr, e
- sys.exit(1)
- for (name, value) in opts:
- if name in ('-h', '--help'):
- self.usage()
- sys.exit()
- elif name == '--version':
- self.version()
- elif name == '--debug':
- self.set_debug(True)
- elif name == '--debugger':
- self.debugger = True
- elif name in (self.access_key_short_name, '--access-key'):
- self.ec2_user_access_key = value
- elif name in (self.secret_key_short_name, '--secret-key'):
- self.ec2_user_secret_key = value
- elif name in ('-U', '--url'):
- self.url = value
- elif name == '--region':
- self.region_name = value
- elif name == '--config':
- self.config_file_path = value
- elif name == '--euca-auth':
- self.is_euca = True
- elif name == '--filter':
- try:
- name, value = value.split('=')
- except ValueError:
- msg = 'Filters must be of the form name=value'
- self.display_error_and_exit(msg)
- self.filters[name] = value
- else:
- option = self.find_option(name)
- if option:
- try:
- value = option.convert(value)
- except:
- msg = '%s should be of type %s' % (option.long_name,
- option.ptype)
- self.display_error_and_exit(msg)
- if option.choices:
- if value not in option.choices:
- msg = 'Value must be one of: %s' % '|'.join(option.choices)
- self.display_error_and_exit(msg)
- if option.cardinality in ('*', '+'):
- if not hasattr(self, option.name):
- setattr(self, option.name, [])
- getattr(self, option.name).append(value)
- else:
- setattr(self, option.name, value)
- self.handle_defaults()
- self.check_required_options()
-
- for arg in self.Args:
- if not arg.optional and len(args)==0:
- self.usage()
- msg = 'Argument (%s) was not provided' % arg.name
- self.display_error_and_exit(msg)
- if arg.cardinality in ('*', '+'):
- setattr(self, arg.name, args)
- elif arg.cardinality == 1:
- if len(args) == 0 and arg.optional:
- continue
- try:
- value = arg.convert(args[0])
- except:
- msg = '%s should be of type %s' % (arg.name,
- arg.ptype)
- setattr(self, arg.name, value)
- if len(args) > 1:
- msg = 'Only 1 argument (%s) permitted' % arg.name
- self.display_error_and_exit(msg)
-
- sys.excepthook = euca_except_hook(self.debugger, self.debug)
-
-
- def check_for_conflict(self):
- for option in self.Options:
- if option.short_name == 'a' or option.short_name == 's':
- self.access_key_short_name = '-A'
- self.secret_key_short_name = '-S'
- opt = self.find_option('--access-key')
- opt.short_name = 'A'
- opt = self.find_option('--secret-key')
- opt.short_name = 'S'
-
- def find_option(self, op_name):
- for option in self.StandardOptions+self.Options:
- if option.synopsis_short_name == op_name or option.synopsis_long_name == op_name:
- return option
- return None
-
- def short_options(self):
- s = ''
- for option in self.StandardOptions + self.Options:
- if option.short_name:
- s += option.getopt_short_name
- return s
-
- def long_options(self):
- l = []
- for option in self.StandardOptions+self.Options:
- if option.long_name:
- l.append(option.getopt_long_name)
- if self.Filters:
- l.append('filter=')
- return l
-
- def required(self):
- return [ opt for opt in self.StandardOptions+self.Options if not opt.optional ]
-
- def required_args(self):
- return [ arg for arg in self.Args if not arg.optional ]
-
- def optional(self):
- return [ opt for opt in self.StandardOptions+self.Options if opt.optional ]
-
- def optional_args(self):
- return [ arg for arg in self.Args if arg.optional ]
-
- def handle_defaults(self):
- for option in self.Options+self.Args:
- if not hasattr(self, option.name):
- value = option.default
- if value is None and option.cardinality in ('+', '*'):
- value = []
- elif value is None and option.ptype == 'boolean':
- value = False
- elif value is None and option.ptype == 'integer':
- value = 0
- setattr(self, option.name, value)
-
- def check_required_options(self):
- missing = []
- for option in self.required():
- if not hasattr(self, option.name) or getattr(self, option.name) is None:
- missing.append(option.long_name)
- if missing:
- msg = 'These required options are missing: %s' % ','.join(missing)
- self.display_error_and_exit(msg)
-
- def version(self):
- print 'euca2ools %s (%s)' % (euca2ools.__version__, euca2ools.__codename__)
- if os.path.isfile('/etc/eucalyptus/eucalyptus-version'):
- with open('/etc/eucalyptus/eucalyptus-version') as version_file:
- print 'eucalyptus %s' % version_file.readline().strip()
- sys.exit(0)
-
- def param_usage(self, plist, label, n=30):
- nn = 80 - n - 4
- if plist:
- print '\n%s' % label
- for opt in plist:
- names = []
- if opt.short_name:
- names.append(opt.synopsis_short_name)
- if opt.long_name:
- names.append(opt.synopsis_long_name)
- if not names:
- names.append(opt.name)
- doc = textwrap.dedent(opt.doc)
- doclines = textwrap.wrap(doc, nn)
- if opt.choices:
- vv = 'Valid Values: %s' % '|'.join(opt.choices)
- doclines += textwrap.wrap(vv, nn)
- if doclines:
- print ' %s%s' % (','.join(names).ljust(n), doclines[0])
- for line in doclines[1:]:
- print '%s%s' % (' '*(n+4), line)
-
- def filter_usage(self, n=30):
- if self.Filters:
- nn = 80 - n - 4
- print '\nAVAILABLE FILTERS'
- for filter in self.Filters:
- doc = textwrap.dedent(filter.doc)
- doclines = textwrap.wrap(doc, nn, fix_sentence_endings=True)
- print ' %s%s' % (filter.name.ljust(n), doclines[0])
- for line in doclines[1:]:
- print '%s%s' % (' '*(n+4), line)
-
-
- def option_synopsis(self, options):
- s = ''
- for option in options:
- names = []
- if option.short_name:
- names.append(option.synopsis_short_name)
- if option.long_name:
- names.append(option.synopsis_long_name)
- if option.optional:
- s += '['
- s += ', '.join(names)
- if option.ptype != 'boolean':
- if option.metavar:
- n = option.metavar
- elif option.name:
- n = option.name
- else:
- n = option.long_name
- s += ' <%s> ' % n
- if option.optional:
- s += ']'
- return s
-
- def synopsis(self):
- s = '%s ' % self.cmd_name
- n = len(s) + 1
- t = ''
- t += self.option_synopsis(self.required())
- t += self.option_synopsis(self.optional())
- if self.Filters:
- t += ' [--filter name=value]'
- if self.Args:
- t += ' '
- arg_names = []
- for arg in self.Args:
- name = arg.name
- if arg.optional:
- name = '[ %s ]' % name
- arg_names.append(name)
- t += ' '.join(arg_names)
- lines = textwrap.wrap(t, 80-n)
- print s, lines[0]
- for line in lines[1:]:
- print '%s%s' % (' '*n, line)
-
- def usage(self):
- print '%s\n' % self.Description
- self.synopsis()
- self.param_usage(self.required()+self.required_args(),
- 'REQUIRED PARAMETERS')
- self.param_usage(self.optional()+self.optional_args(),
- 'OPTIONAL PARAMETERS')
- self.filter_usage()
-
- def display_error_and_exit(self, exc):
- try:
- print >> sys.stderr, '%s: %s' % (exc.error_code, exc.error_message)
- except:
- print >> sys.stderr, '%s' % exc
- finally:
- sys.exit(1)
-
- def error_exit(self):
- sys.exit(1)
-
- def setup_environ(self):
- envlist = ('EC2_ACCESS_KEY', 'EC2_SECRET_KEY',
- 'S3_URL', 'EC2_URL', 'EC2_CERT', 'EC2_PRIVATE_KEY',
- 'EUCALYPTUS_CERT', 'EC2_USER_ID',
- 'EUCA_CERT', 'EUCA_PRIVATE_KEY')
- self.environ = {}
- user_eucarc = None
- if 'HOME' in os.environ:
- user_eucarc = os.path.join(os.getenv('HOME'), '.eucarc')
- read_config = False
- if self.config_file_path \
- and os.path.exists(self.config_file_path):
- read_config = self.config_file_path
- elif user_eucarc is not None and os.path.exists(user_eucarc):
- if os.path.isdir(user_eucarc):
- user_eucarc = os.path.join(user_eucarc, 'eucarc')
- if os.path.isfile(user_eucarc):
- read_config = user_eucarc
- elif os.path.isfile(user_eucarc):
- read_config = user_eucarc
- elif os.path.exists(SYSTEM_EUCARC_PATH):
- read_config = SYSTEM_EUCARC_PATH
- if read_config:
- euca2ools.utils.parse_config(read_config, self.environ, envlist)
- else:
- for v in envlist:
- self.environ[v] = os.getenv(v)
-
- def get_environ(self, name):
- if self.environ.has_key(name):
- value = self.environ[name]
- if value:
- return self.environ[name]
- msg = 'Environment variable: %s not found' % name
- self.display_error_and_exit(msg)
-
- def get_credentials(self):
- if self.is_euca:
- if not self.euca_cert_path:
- self.euca_cert_path = self.environ['EUCA_CERT']
- if not self.euca_cert_path:
- print >> sys.stderr, 'EUCA_CERT variable must be set.'
- raise euca2ools.exceptions.ConnectionFailed
- if not self.euca_private_key_path:
- self.euca_private_key_path = self.environ['EUCA_PRIVATE_KEY']
- if not self.euca_private_key_path:
- print >> sys.stderr, 'EUCA_PRIVATE_KEY variable must be set.'
- raise euca2ools.exceptions.ConnectionFailed
- if not self.ec2_user_access_key:
- self.ec2_user_access_key = self.environ['EC2_ACCESS_KEY']
- if not self.ec2_user_access_key:
- print >> sys.stderr, 'EC2_ACCESS_KEY environment variable must be set.'
- raise euca2ools.exceptions.ConnectionFailed
-
- if not self.ec2_user_secret_key:
- self.ec2_user_secret_key = self.environ['EC2_SECRET_KEY']
- if not self.ec2_user_secret_key:
- print >> sys.stderr, 'EC2_SECRET_KEY environment variable must be set.'
- raise euca2ools.exceptions.ConnectionFailed
-
- def get_connection_details(self):
- self.port = None
- self.service_path = '/'
-
- rslt = urlparse.urlparse(self.url)
- if rslt.scheme == 'https':
- self.is_secure = True
- else:
- self.is_secure = False
-
- self.host = rslt.netloc
- l = self.host.split(':')
- if len(l) > 1:
- self.host = l[0]
- self.port = int(l[1])
-
- if rslt.path:
- self.service_path = rslt.path
-
- def make_s3_connection(self):
- if not self.url:
- self.url = self.environ['S3_URL']
- if not self.url:
- self.url = \
- 'http://localhost:8773/services/Walrus'
- print >> sys.stderr, 'S3_URL not specified. Trying %s' \
- % self.url
-
- self.get_connection_details()
-
- if self.is_euca:
- return euca2ools.nc.connection.EucaConnection(
- private_key_path=self.euca_private_key_path,
- cert_path=self.euca_cert_path,
- aws_access_key_id=self.ec2_user_access_key,
- aws_secret_access_key=self.ec2_user_secret_key,
- is_secure=self.is_secure, debug=self.debug,
- host=self.host,
- port=self.port,
- path=self.service_path)
- else:
- return boto.connect_s3(
- aws_access_key_id=self.ec2_user_access_key,
- aws_secret_access_key=self.ec2_user_secret_key,
- is_secure=self.is_secure, debug=self.debug,
- host=self.host,
- port=self.port,
- calling_format=OrdinaryCallingFormat(),
- path=self.service_path)
-
- def make_ec2_connection(self):
- if self.region_name:
- self.region.name = self.region_name
- try:
- self.url = self.get_endpoint_url(self.region.name)
- except KeyError, err:
- self.display_error_and_exit(err.message)
- elif not self.url:
- self.url = self.environ['EC2_URL']
- if not self.url:
- self.url = \
- 'http://localhost:8773/services/Eucalyptus'
- print >> sys.stderr, 'EC2_URL not specified. Trying %s' \
- % self.url
-
- if not self.region.endpoint:
- self.get_connection_details()
- self.region.endpoint = self.host
- if not self.region.name:
- self.region.name = 'eucalyptus'
-
- return boto.connect_ec2(aws_access_key_id=self.ec2_user_access_key,
- aws_secret_access_key=self.ec2_user_secret_key,
- is_secure=self.is_secure,
- debug=self.debug,
- region=self.region,
- port=self.port,
- path=self.service_path,
- api_version=self.APIVersion)
-
- def make_connection(self, conn_type='ec2'):
- self.get_credentials()
- if conn_type == 's3':
- conn = self.make_s3_connection()
- elif conn_type == 'ec2':
- conn = self.make_ec2_connection()
- else:
- conn = None
- return conn
-
- def make_connection_cli(self, conn_type='ec2'):
- """
- This just wraps up the make_connection call with appropriate
- try/except logic to print out an error message and exit if
- a EucaError is encountered. This keeps the try/except logic
- out of all the command files.
- """
- try:
- conn = self.make_connection(conn_type)
- if not conn:
- msg = 'Unknown connection type: %s' % conn_type
- self.display_error_and_exit(msg)
- return conn
- except euca2ools.exceptions.EucaError, ex:
- self.display_error_and_exit(ex)
-
- def make_request_cli(self, connection, request_name, **params):
- """
- This provides a simple
- This just wraps up the make_connection call with appropriate
- try/except logic to print out an error message and exit if
- a EucaError is encountered. This keeps the try/except logic
- out of all the command files.
- """
- try:
- if self.filters:
- params['filters'] = self.filters
- method = getattr(connection, request_name)
- except AttributeError:
- print >> sys.stderr, 'Unknown request: %s' % request_name
- sys.exit(1)
- try:
- return method(**params)
- except Exception, ex:
- self.display_error_and_exit(ex)
-
- def get_relative_filename(self, filename):
- return os.path.split(filename)[-1]
-
- def get_file_path(self, filename):
- relative_filename = self.get_relative_filename(filename)
- file_path = os.path.dirname(filename)
- if len(file_path) == 0:
- file_path = '.'
- return file_path
-
- def parse_block_device_args(self, block_device_maps_args):
- block_device_map = BlockDeviceMapping()
- for block_device_map_arg in block_device_maps_args:
- parts = block_device_map_arg.split('=')
- if len(parts) > 1:
- device_name = parts[0]
- block_dev_type = BlockDeviceType()
- block_dev_type.delete_on_termination = True
- value_parts = parts[1].split(':')
- if value_parts[0].startswith('snap'):
- block_dev_type.snapshot_id = value_parts[0]
- else:
- if value_parts[0].startswith('ephemeral'):
- block_dev_type.ephemeral_name = value_parts[0]
- if len(value_parts) > 1:
- try:
- block_dev_type.size = int(value_parts[1])
- except ValueError:
- pass
- if len(value_parts) > 2:
- if value_parts[2] == 'false':
- block_dev_type.delete_on_termination = False
- block_device_map[device_name] = block_dev_type
- return block_device_map
-
- def get_endpoint_url(self, region_name):
- """
- Get the URL needed to reach a region with a given name.
-
- This currently only works with EC2. In the future it may use other
- means to also work with Eucalyptus.
- """
- endpoint_template = 'https://ec2.%s.amazonaws.com/'
- endpoint_url = endpoint_template % region_name
- endpoint_dnsname = urlparse.urlparse(endpoint_url).hostname
- try:
- socket.getaddrinfo(endpoint_dnsname, None)
- except socket.gaierror:
- raise KeyError('Cannot resolve endpoint %s' % endpoint_dnsname)
- return endpoint_url
diff --git a/euca2ools/commands/eustore/installimage.py b/euca2ools/commands/eustore/installimage.py
index e40aef2..dff56eb 100644
--- a/euca2ools/commands/eustore/installimage.py
+++ b/euca2ools/commands/eustore/installimage.py
@@ -40,7 +40,7 @@ from euca2ools.commands.euca.registerimage import RegisterImage
from euca2ools.commands.eustore import EuStoreRequest
import euca2ools.commands.eustore.describeimages
from euca2ools.commands.walrus import Walrus
-from euca2ools.utils import mkdtemp_for_large_files
+from euca2ools.util import mkdtemp_for_large_files
import hashlib
import os.path
from requestbuilder import Arg, MutuallyExclusiveArgList
diff --git a/euca2ools/commands/walrus/getobject.py b/euca2ools/commands/walrus/getobject.py
index bcf11a0..1e88b81 100644
--- a/euca2ools/commands/walrus/getobject.py
+++ b/euca2ools/commands/walrus/getobject.py
@@ -29,7 +29,7 @@
# POSSIBILITY OF SUCH DAMAGE.
from euca2ools.commands.walrus import WalrusRequest
-from euca2ools.utils import build_progressbar_label_template
+from euca2ools.util import build_progressbar_label_template
import os.path
from requestbuilder import Arg
from requestbuilder.mixins import FileTransferProgressBarMixin
diff --git a/euca2ools/commands/walrus/putobject.py b/euca2ools/commands/walrus/putobject.py
index 9bf2fc1..0def6bc 100644
--- a/euca2ools/commands/walrus/putobject.py
+++ b/euca2ools/commands/walrus/putobject.py
@@ -30,7 +30,7 @@
import datetime
from euca2ools.commands.walrus import WalrusRequest
-from euca2ools.utils import build_progressbar_label_template
+from euca2ools.util import build_progressbar_label_template
import mimetypes
import os.path
from requestbuilder import Arg
diff --git a/euca2ools/exceptions.py b/euca2ools/exceptions.py
index d0dfd5a..133611b 100644
--- a/euca2ools/exceptions.py
+++ b/euca2ools/exceptions.py
@@ -28,115 +28,12 @@
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
-class EucaError(Exception):
-
- def __init__(self):
- self._message = ''
-
- @property
- def message(self):
- return self._message
-
- @property
- def args(self):
- return (self._message,)
-
-class ValidationError(Exception):
-
- @property
- def message(self):
- return self._message
-
-class AddressValidationError(ValidationError):
-
- def __init__(self):
- self._message = 'Invalid address'
-
-class InstanceValidationError(ValidationError):
-
- def __init__(self):
- self._message = 'Invalid instance id'
-
-class VolumeValidationError(ValidationError):
-
- def __init__(self):
- self._message = 'Invalid volume id'
-
-class SizeValidationError(ValidationError):
-
- def __init__(self):
- self._message = 'Invalid size'
-
-class SnapshotValidationError(ValidationError):
-
- def __init__(self):
- self._message = 'Invalid snapshot id'
-
-class ProtocolValidationError(ValidationError):
-
- def __init__(self):
- self._message = 'Invalid protocol'
-
-class FileValidationError(ValidationError):
-
- def __init__(self):
- self._message = 'Invalid file'
-
-class DirValidationError(ValidationError):
-
- def __init__(self):
- self._message = 'Invalid directory'
-
-class BundleValidationError(ValidationError):
-
- def __init__(self):
- self._message = 'Invalid bundle id'
-
-class CopyError(EucaError):
-
- def __init__(self):
- self._message = 'Unable to copy'
-
-class NotFoundError(EucaError):
-
- def __init__(self):
- self._message = 'Unable to find'
-
-class UnsupportedException(EucaError):
-
- def __init__(self, msg=None):
- if msg:
- self._message = 'Not supported: {0}'.format(msg)
- else:
- self._message = 'Not supported'
-
-class CommandFailed(EucaError):
-
- def __init__(self, cmd=None, err=None):
- self._message = 'Command failed'
- self.err = err
- if cmd:
- self._message += ': {0}'.format(cmd)
- if err:
- self._message += '\n{0}'.format(err)
-
-class ConnectionFailed(EucaError):
-
- def __init__(self):
- self._message = 'Connection failed'
-
-class ParseError(EucaError):
-
- def __init__(self, msg):
- self._message = msg
-
-######## NEW CODE STARTS HERE ########
-
import io
import requestbuilder.exceptions
from requestbuilder.xmlparse import parse_aws_xml
import six
+
class AWSError(requestbuilder.exceptions.ServerError):
def __init__(self, response, *args):
requestbuilder.exceptions.ServerError.__init__(self, response, *args)
diff --git a/euca2ools/commands/euca/createkeypair.py b/euca2ools/util.py
similarity index 54%
copy from euca2ools/commands/euca/createkeypair.py
copy to euca2ools/util.py
index 04fbce1..94b5377 100644
--- a/euca2ools/commands/euca/createkeypair.py
+++ b/euca2ools/util.py
@@ -28,25 +28,40 @@
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
-from euca2ools.commands.euca import EucalyptusRequest
import os
-from requestbuilder import Arg
-
-
-class CreateKeyPair(EucalyptusRequest):
- DESCRIPTION = 'Create a new SSH key pair for use with instances'
- ARGS = [Arg('KeyName', metavar='KEYPAIR',
- help='name of the new key pair (required)'),
- Arg('-f', '--filename', metavar='FILE', route_to=None,
- help='file name to save the private key to')]
-
- def print_result(self, result):
- print self.tabify(('KEYPAIR', result['keyName'],
- result['keyFingerprint']))
- if self.args.get('filename'):
- prev_umask = os.umask(0o077)
- with open(self.args['filename'], 'w') as privkeyfile:
- privkeyfile.write(result['keyMaterial'])
- os.umask(prev_umask)
- else:
- print result['keyMaterial']
+import tempfile
+
+
+def build_progressbar_label_template(fnames):
+ if len(fnames) == 0:
+ return None
+ elif len(fnames) == 1:
+ return '{fname}'
+ else:
+ max_fname_len = max(len(os.path.basename(fname)) for fname in fnames)
+ fmt_template = '{{fname:<{maxlen}}} ({{index:>{lenlen}}}/{total})'
+ return fmt_template.format(maxlen=max_fname_len,
+ lenlen=len(str(len(fnames))),
+ total=len(fnames))
+
+
+def mkdtemp_for_large_files(suffix='', prefix='tmp', dir=None):
+ '''
+ Like tempfile.mkdtemp, but using /var/tmp as a last resort instead of /tmp.
+
+ This is meant for utilities that create large files, as /tmp is often a
+ ramdisk.
+ '''
+
+ if dir is None:
+ dir = (os.getenv('TMPDIR') or os.getenv('TEMP') or os.getenv('TMP') or
+ '/var/tmp')
+ return tempfile.mkdtemp(suffix=suffix, prefix=prefix, dir=dir)
+
+
+def sanitize_path(path):
+ """Make a fully expanded and absolute path for us to work with.
+ Returns a santized path string.
+ :param path: The path string to sanitize.
+ """
+ return os.path.abspath(os.path.expandvars(os.path.expanduser(path)))
diff --git a/euca2ools/utils.py b/euca2ools/utils.py
deleted file mode 100644
index e05295c..0000000
--- a/euca2ools/utils.py
+++ /dev/null
@@ -1,175 +0,0 @@
-# Software License Agreement (BSD License)
-#
-# Copyright (c) 2009-2013, Eucalyptus Systems, Inc.
-# All rights reserved.
-#
-# Redistribution and use of this software in source and binary forms, with or
-# without modification, are permitted provided that the following conditions
-# are met:
-#
-# Redistributions of source code must retain the above
-# copyright notice, this list of conditions and the
-# following disclaimer.
-#
-# Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the
-# following disclaimer in the documentation and/or other
-# materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-#
-# Author: Neil Soman neil at eucalyptus.com
-# Mitch Garnaat mgarnaat at eucalyptus.com
-
-import base64
-import os
-import sys
-import tempfile
-from euca2ools import exceptions, __version__
-
-
-def sanitize_path(path):
- """Make a fully expanded and absolute path for us to work with.
- Returns a santized path string.
- :param path: The path string to sanitize.
- """
- return os.path.abspath(os.path.expandvars(os.path.expanduser(path)))
-
-
-def parse_config(config, dict, keylist):
- fmt = ''
- str = ''
- for v in keylist:
- str = '%s "${%s}" ' % (str, v)
- fmt = fmt + '%s%s' % ('%s', '\\0')
-
- cmd = ['bash', '-ec', ". '%s' >/dev/null; printf '%s' %s"
- % (config, fmt, str)]
-
- (out, err, retval) = execute(cmd, exception=False)
-
- if retval != 0:
- raise exceptions.ParseError('Parsing config file %s failed:\n\t%s'
- % (config, stderr))
-
- values = stdout.split("\0")
- for i in range(len(values) - 1):
- if values[i] != '':
- dict[keylist[i]] = values[i]
-
-
-def print_instances(instances, nil=""):
-
- # I was not able to correctly identify fields with an 'xx' below the
- # descriptions at
- # http://docs.amazonwebservices.com/AWSEC2/latest/CommandLineReference/ApiReference-cmd-DescribeInstances.html
- # were not sufficiently detailed, even when coupled with some limited
- # experimentation
- #
- # Additionally, in order to get 'hypervisor', the api request version
- # in the make_ec2_connection method would need to be increased.
- members=( "id", "image_id", "public_dns_name", "private_dns_name",
- "state", "key_name", "ami_launch_index", "product_codes",
- "instance_type", "launch_time", "placement", "kernel",
- "ramdisk", "xx", "_monitoring", 'ip_address', 'private_ip_address',
- "vpc_id", "subnet_id", "root_device_type", "xx", "xx", "xx", "xx",
- "virtualizationType", "hypervisor", "xx", "_groupnames", "_groupids" )
-
- for instance in instances:
- # in old describe-instances, there was a check for 'if instance:'
- # I (smoser) have carried this over, but dont know how instance
- # could be false
- if not instance: continue
- items=[ ]
- for member in members:
- # boto's "monitoring" item is blank string
- if member == "_monitoring":
- if instance.monitored:
- val = "monitoring-enabled"
- else:
- val = "monitoring-disabled"
- elif member == "_groupids":
- val = [x.name for x in instance.groups]
- elif member == "_groupnames":
- val = [x.id for x in instance.groups]
- else:
- val = getattr(instance,member,nil)
-
- # product_codes is a list
- if val is None: val = nil
- if hasattr(val,'__iter__'):
- val = ','.join(val)
- items.append(val)
- print "INSTANCE\t%s" % '\t'.join(items)
- if hasattr(instance, 'tags') and isinstance(instance.tags, dict):
- for tag in instance.tags:
- print '\t'.join(('TAG', 'instance', instance.id, tag,
- instance.tags[tag]))
-
-
-def print_version_if_necessary():
- """
- If '--version' appears in sys.argv then print the version and exit
- successfully.
-
- This is a hackish workaround for a roboto limitation in boto 2.1.1.
- """
- if '--version' in sys.argv:
- print 'euca2ools %s (Sparta)' % __version__
- if os.path.isfile('/etc/eucalyptus/eucalyptus-version'):
- with open('/etc/eucalyptus/eucalyptus-version') as version_file:
- print 'eucalyptus %s' % version_file.readline().strip()
- sys.exit()
-
-
-def handle_availability_zones(requested_zones, response=None):
- msg = base64.b64decode(
- 'ICAgICAgICAgICAgICAgICAgX19fXyAgICAKICAgICAgLi0tLS0tLS0tLS0nI'
- 'CAgICctLgogICAgIC8gIC4gICAgICAnICAgICAuICAgXCAgCiAgICAvICAgIC'
- 'AgICAnICAgIC4gICAgICAvfAogICAvICAgICAgLiAgICAgICAgICAgICBcIC8'
- 'gICAgIAogIC8gICcgLiAgICAgICAuICAgICAuICB8fCB8IAogLy5fX19fX19f'
- 'X19fXyAgICAnICAgIC8gLy8KIHwuXyAgICAgICAgICAnLS0tLS0tJ3wgL3wKI'
- 'CcuLi4uLi4uLi4uLi4uX19fX19fLi0nIC8KIHwtLiAgICAgICAgICAgICAgIC'
- 'AgIHwgLyAgICAgCiBgIiIiIiIiIiIiIiIiIi0uLi4uLi0n')
- if ((response is None or
- len(response.get('availabilityZoneInfo', [])) == 0) and
- 'sandwich' in requested_zones):
- # humor dfed
- print >> sys.stderr, msg
-
-
-def build_progressbar_label_template(fnames):
- if len(fnames) == 0:
- return None
- elif len(fnames) == 1:
- return '{fname}'
- else:
- max_fname_len = max(len(os.path.basename(fname)) for fname in fnames)
- fmt_template = '{{fname:<{maxlen}}} ({{index:>{lenlen}}}/{total})'
- return fmt_template.format(maxlen=max_fname_len,
- lenlen=len(str(len(fnames))),
- total=len(fnames))
-
-
-def mkdtemp_for_large_files(suffix='', prefix='tmp', dir=None):
- '''
- Like tempfile.mkdtemp, but using /var/tmp as a last resort instead of /tmp.
-
- This is meant for utilities that create large files, as /tmp is often a
- ramdisk.
- '''
-
- if dir is None:
- dir = (os.getenv('TMPDIR') or os.getenv('TEMP') or os.getenv('TMP') or
- '/var/tmp')
- return tempfile.mkdtemp(suffix=suffix, prefix=prefix, dir=dir)
diff --git a/requirements.txt b/requirements.txt
index c965b19..b903a60 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,3 @@
-boto>=2.3
-M2Crypto
-requestbuilder>=0.1.0-alpha4
+requestbuilder>=0.1.0-beta1
requests
+six
--
managing cloud instances for Eucalyptus
More information about the pkg-eucalyptus-commits
mailing list