diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 54736f3b3700..4019d0089692 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -32,13 +32,11 @@ import urllib from nova import block_device from nova import compute -from nova import context from nova import crypto from nova import db from nova import exception from nova import flags -from nova import ipv6 from nova import log as logging from nova import network from nova import rpc @@ -54,7 +52,7 @@ FLAGS = flags.FLAGS flags.DECLARE('dhcp_domain', 'nova.network.manager') flags.DECLARE('service_down_time', 'nova.scheduler.driver') -LOG = logging.getLogger("nova.api.cloud") +LOG = logging.getLogger("nova.api.ec2.cloud") def _gen_key(context, user_id, key_name): @@ -104,14 +102,6 @@ def state_description_from_vm_state(vm_state): return _STATE_DESCRIPTION_MAP.get(vm_state, vm_state) -# TODO(yamahata): hypervisor dependent default device name -_DEFAULT_ROOT_DEVICE_NAME = '/dev/sda1' -_DEFAULT_MAPPINGS = {'ami': 'sda1', - 'ephemeral0': 'sda2', - 'root': _DEFAULT_ROOT_DEVICE_NAME, - 'swap': 'sda3'} - - def _parse_block_device_mapping(bdm): """Parse BlockDeviceMappingItemType into flat hash BlockDevicedMapping..DeviceName @@ -237,58 +227,6 @@ class CloudController(object): utils.runthis(_("Generating root CA: %s"), "sh", genrootca_sh_path) os.chdir(start) - def _get_ip_info_for_instance(self, context, instance): - """Return a list of all fixed IPs for an instance""" - - ip_info = dict(fixed_ips=[], fixed_ip6s=[], floating_ips=[]) - - fixed_ips = instance['fixed_ips'] - for fixed_ip in fixed_ips: - fixed_addr = fixed_ip['address'] - network = fixed_ip.get('network') - vif = fixed_ip.get('virtual_interface') - if not network or not vif: - name = instance['name'] - ip = fixed_ip['address'] - LOG.warn(_("Instance %(name)s has stale IP " - "address: %(ip)s (no network or vif)") % locals()) - continue - cidr_v6 = network.get('cidr_v6') - if FLAGS.use_ipv6 and cidr_v6: - ipv6_addr = ipv6.to_global(cidr_v6, vif['address'], - network['project_id']) - if ipv6_addr not in ip_info['fixed_ip6s']: - ip_info['fixed_ip6s'].append(ipv6_addr) - - for floating_ip in fixed_ip.get('floating_ips', []): - float_addr = floating_ip['address'] - ip_info['floating_ips'].append(float_addr) - ip_info['fixed_ips'].append(fixed_addr) - return ip_info - - def _get_mpi_data(self, context, project_id): - result = {} - search_opts = {'project_id': project_id, 'deleted': False} - for instance in self.compute_api.get_all(context, - search_opts=search_opts): - ip_info = self._get_ip_info_for_instance(context, instance) - # only look at ipv4 addresses - fixed_ips = ip_info['fixed_ips'] - if fixed_ips: - line = '%s slots=%d' % (fixed_ips[0], instance['vcpus']) - key = str(instance['key_name']) - if key in result: - result[key].append(line) - else: - result[key] = [line] - return result - - def _get_availability_zone_by_host(self, context, host): - services = db.service_get_all_by_host(context.elevated(), host) - if len(services) > 0: - return services[0]['availability_zone'] - return 'unknown zone' - def _get_image_state(self, image): # NOTE(vish): fallback status if image_state isn't set state = image.get('status') @@ -296,120 +234,6 @@ class CloudController(object): state = 'available' return image['properties'].get('image_state', state) - def _format_instance_mapping(self, ctxt, instance_ref): - root_device_name = instance_ref['root_device_name'] - if root_device_name is None: - return _DEFAULT_MAPPINGS - - mappings = {} - mappings['ami'] = block_device.strip_dev(root_device_name) - mappings['root'] = root_device_name - default_local_device = instance_ref.get('default_local_device') - if default_local_device: - mappings['ephemeral0'] = default_local_device - default_swap_device = instance_ref.get('default_swap_device') - if default_swap_device: - mappings['swap'] = default_swap_device - ebs_devices = [] - - # 'ephemeralN', 'swap' and ebs - for bdm in db.block_device_mapping_get_all_by_instance( - ctxt, instance_ref['id']): - if bdm['no_device']: - continue - - # ebs volume case - if (bdm['volume_id'] or bdm['snapshot_id']): - ebs_devices.append(bdm['device_name']) - continue - - virtual_name = bdm['virtual_name'] - if not virtual_name: - continue - - if block_device.is_swap_or_ephemeral(virtual_name): - mappings[virtual_name] = bdm['device_name'] - - # NOTE(yamahata): I'm not sure how ebs device should be numbered. - # Right now sort by device name for deterministic - # result. - if ebs_devices: - nebs = 0 - ebs_devices.sort() - for ebs in ebs_devices: - mappings['ebs%d' % nebs] = ebs - nebs += 1 - - return mappings - - def get_metadata(self, address): - ctxt = context.get_admin_context() - search_opts = {'fixed_ip': address, 'deleted': False} - try: - instance_ref = self.compute_api.get_all(ctxt, - search_opts=search_opts) - except exception.NotFound: - instance_ref = None - if not instance_ref: - return None - - # This ensures that all attributes of the instance - # are populated. - instance_ref = db.instance_get(ctxt, instance_ref[0]['id']) - - mpi = self._get_mpi_data(ctxt, instance_ref['project_id']) - hostname = "%s.%s" % (instance_ref['hostname'], FLAGS.dhcp_domain) - host = instance_ref['host'] - availability_zone = self._get_availability_zone_by_host(ctxt, host) - - ip_info = self._get_ip_info_for_instance(ctxt, instance_ref) - floating_ips = ip_info['floating_ips'] - floating_ip = floating_ips and floating_ips[0] or '' - - ec2_id = ec2utils.id_to_ec2_id(instance_ref['id']) - image_ec2_id = self.image_ec2_id(instance_ref['image_ref']) - security_groups = db.security_group_get_by_instance(ctxt, - instance_ref['id']) - security_groups = [x['name'] for x in security_groups] - mappings = self._format_instance_mapping(ctxt, instance_ref) - data = { - 'user-data': self._format_user_data(instance_ref), - 'meta-data': { - 'ami-id': image_ec2_id, - 'ami-launch-index': instance_ref['launch_index'], - 'ami-manifest-path': 'FIXME', - 'block-device-mapping': mappings, - 'hostname': hostname, - 'instance-action': 'none', - 'instance-id': ec2_id, - 'instance-type': instance_ref['instance_type']['name'], - 'local-hostname': hostname, - 'local-ipv4': address, - 'placement': {'availability-zone': availability_zone}, - 'public-hostname': hostname, - 'public-ipv4': floating_ip, - 'reservation-id': instance_ref['reservation_id'], - 'security-groups': security_groups, - 'mpi': mpi}} - - # public-keys should be in meta-data only if user specified one - if instance_ref['key_name']: - data['meta-data']['public-keys'] = { - '0': {'_name': instance_ref['key_name'], - 'openssh-key': instance_ref['key_data']}} - - for image_type in ['kernel', 'ramdisk']: - if instance_ref.get('%s_id' % image_type): - ec2_id = self.image_ec2_id(instance_ref['%s_id' % image_type], - self._image_type(image_type)) - data['meta-data']['%s-id' % image_type] = ec2_id - - if False: # TODO(vish): store ancestor ids - data['ancestor-ami-ids'] = [] - if False: # TODO(vish): store product codes - data['product-codes'] = [] - return data - def describe_availability_zones(self, context, **kwargs): if ('zone_name' in kwargs and 'verbose' in kwargs['zone_name'] and @@ -1124,18 +948,14 @@ class CloudController(object): if kernel_uuid is None or kernel_uuid == '': return kernel_id = self._get_image_id(context, kernel_uuid) - result[key] = self.image_ec2_id(kernel_id, 'aki') + result[key] = ec2utils.image_ec2_id(kernel_id, 'aki') def _format_ramdisk_id(self, context, instance_ref, result, key): ramdisk_uuid = instance_ref['ramdisk_id'] if ramdisk_uuid is None or ramdisk_uuid == '': return ramdisk_id = self._get_image_id(context, ramdisk_uuid) - result[key] = self.image_ec2_id(ramdisk_id, 'ari') - - @staticmethod - def _format_user_data(instance_ref): - return base64.b64decode(instance_ref['user_data']) + result[key] = ec2utils.image_ec2_id(ramdisk_id, 'ari') def describe_instance_attribute(self, context, instance_id, attribute, **kwargs): @@ -1182,7 +1002,7 @@ class CloudController(object): _unsupported_attribute(instance, result) def _format_attr_user_data(instance, result): - result['userData'] = self._format_user_data(instance) + result['userData'] = base64.b64decode(instance['user_data']) attribute_formatter = { 'blockDeviceMapping': _format_attr_block_device_mapping, @@ -1264,7 +1084,7 @@ class CloudController(object): @staticmethod def _format_instance_root_device_name(instance, result): result['rootDeviceName'] = (instance.get('root_device_name') or - _DEFAULT_ROOT_DEVICE_NAME) + block_device.DEFAULT_ROOT_DEV_NAME) @staticmethod def _format_instance_type(instance, result): @@ -1317,7 +1137,7 @@ class CloudController(object): i['instanceId'] = ec2_id image_uuid = instance['image_ref'] image_id = self._get_image_id(context, image_uuid) - i['imageId'] = self.image_ec2_id(image_id) + i['imageId'] = ec2utils.image_ec2_id(image_id) self._format_kernel_id(context, instance, i, 'kernelId') self._format_ramdisk_id(context, instance, i, 'ramdiskId') i['instanceState'] = { @@ -1326,7 +1146,7 @@ class CloudController(object): fixed_ip = None floating_ip = None - ip_info = self._get_ip_info_for_instance(context, instance) + ip_info = ec2utils.get_ip_info_for_instance(context, instance) if ip_info['fixed_ips']: fixed_ip = ip_info['fixed_ips'][0] if ip_info['floating_ips']: @@ -1355,7 +1175,8 @@ class CloudController(object): self._format_instance_bdm(context, instance_id, i['rootDeviceName'], i) host = instance['host'] - zone = self._get_availability_zone_by_host(context, host) + services = db.service_get_all_by_host(context.elevated(), host) + zone = ec2utils.get_availability_zone_by_host(services, host) i['placement'] = {'availabilityZone': zone} if instance['reservation_id'] not in reservations: r = {} @@ -1537,34 +1358,6 @@ class CloudController(object): **changes) return True - @staticmethod - def _image_type(image_type): - """Converts to a three letter image type. - - aki, kernel => aki - ari, ramdisk => ari - anything else => ami - - """ - if image_type == 'kernel': - return 'aki' - if image_type == 'ramdisk': - return 'ari' - if image_type not in ['aki', 'ari']: - return 'ami' - return image_type - - @staticmethod - def image_ec2_id(image_id, image_type='ami'): - """Returns image ec2_id using id and three letter type.""" - template = image_type + '-%08x' - try: - return ec2utils.id_to_ec2_id(image_id, template=template) - except ValueError: - #TODO(wwolf): once we have ec2_id -> glance_id mapping - # in place, this wont be necessary - return "ami-00000000" - def _get_image(self, context, ec2_id): try: internal_id = ec2utils.ec2_id_to_id(ec2_id) @@ -1575,7 +1368,7 @@ class CloudController(object): except exception.NotFound: raise exception.ImageNotFound(image_id=ec2_id) image_type = ec2_id.split('-')[0] - if self._image_type(image.get('container_format')) != image_type: + if ec2utils.image_type(image.get('container_format')) != image_type: raise exception.ImageNotFound(image_id=ec2_id) return image @@ -1591,16 +1384,16 @@ class CloudController(object): def _format_image(self, image): """Convert from format defined by GlanceImageService to S3 format.""" i = {} - image_type = self._image_type(image.get('container_format')) - ec2_id = self.image_ec2_id(image.get('id'), image_type) + image_type = ec2utils.image_type(image.get('container_format')) + ec2_id = ec2utils.image_ec2_id(image.get('id'), image_type) name = image.get('name') i['imageId'] = ec2_id kernel_id = image['properties'].get('kernel_id') if kernel_id: - i['kernelId'] = self.image_ec2_id(kernel_id, 'aki') + i['kernelId'] = ec2utils.image_ec2_id(kernel_id, 'aki') ramdisk_id = image['properties'].get('ramdisk_id') if ramdisk_id: - i['ramdiskId'] = self.image_ec2_id(ramdisk_id, 'ari') + i['ramdiskId'] = ec2utils.image_ec2_id(ramdisk_id, 'ari') i['imageOwnerId'] = image['properties'].get('owner_id') if name: i['imageLocation'] = "%s (%s)" % (image['properties']. @@ -1626,7 +1419,8 @@ class CloudController(object): ('snapshot_id' in bdm or 'volume_id' in bdm) and not bdm.get('no_device')): root_device_type = 'ebs' - i['rootDeviceName'] = (root_device_name or _DEFAULT_ROOT_DEVICE_NAME) + i['rootDeviceName'] = (root_device_name or + block_device.DEFAULT_ROOT_DEV_NAME) i['rootDeviceType'] = root_device_type _format_mappings(properties, i) @@ -1657,8 +1451,8 @@ class CloudController(object): def _register_image(self, context, metadata): image = self.image_service.create(context, metadata) - image_type = self._image_type(image.get('container_format')) - image_id = self.image_ec2_id(image['id'], image_type) + image_type = ec2utils.image_type(image.get('container_format')) + image_id = ec2utils.image_ec2_id(image['id'], image_type) return image_id def register_image(self, context, image_location=None, **kwargs): @@ -1694,7 +1488,7 @@ class CloudController(object): result['rootDeviceName'] = \ block_device.properties_root_device_name(image['properties']) if result['rootDeviceName'] is None: - result['rootDeviceName'] = _DEFAULT_ROOT_DEVICE_NAME + result['rootDeviceName'] = block_device.DEFAULT_ROOT_DEV_NAME supported_attributes = { 'blockDeviceMapping': _block_device_mapping_attribute, diff --git a/nova/api/ec2/ec2utils.py b/nova/api/ec2/ec2utils.py index ee68edbd7da3..641929b21e8a 100644 --- a/nova/api/ec2/ec2utils.py +++ b/nova/api/ec2/ec2utils.py @@ -19,6 +19,30 @@ import re from nova import exception +from nova import flags +from nova import log as logging +from nova import ipv6 + + +FLAGS = flags.FLAGS +LOG = logging.getLogger("nova.api.ec2.ec2utils") + + +def image_type(image_type): + """Converts to a three letter image type. + + aki, kernel => aki + ari, ramdisk => ari + anything else => ami + + """ + if image_type == 'kernel': + return 'aki' + if image_type == 'ramdisk': + return 'ari' + if image_type not in ['aki', 'ari']: + return 'ami' + return image_type def ec2_id_to_id(ec2_id): @@ -29,6 +53,53 @@ def ec2_id_to_id(ec2_id): raise exception.InvalidEc2Id(ec2_id=ec2_id) +def image_ec2_id(image_id, image_type='ami'): + """Returns image ec2_id using id and three letter type.""" + template = image_type + '-%08x' + try: + return id_to_ec2_id(image_id, template=template) + except ValueError: + #TODO(wwolf): once we have ec2_id -> glance_id mapping + # in place, this wont be necessary + return "ami-00000000" + + +def get_ip_info_for_instance(context, instance): + """Return a list of all fixed IPs for an instance""" + + ip_info = dict(fixed_ips=[], fixed_ip6s=[], floating_ips=[]) + + fixed_ips = instance['fixed_ips'] + for fixed_ip in fixed_ips: + fixed_addr = fixed_ip['address'] + network = fixed_ip.get('network') + vif = fixed_ip.get('virtual_interface') + if not network or not vif: + name = instance['name'] + ip = fixed_ip['address'] + LOG.warn(_("Instance %(name)s has stale IP " + "address: %(ip)s (no network or vif)") % locals()) + continue + cidr_v6 = network.get('cidr_v6') + if FLAGS.use_ipv6 and cidr_v6: + ipv6_addr = ipv6.to_global(cidr_v6, vif['address'], + network['project_id']) + if ipv6_addr not in ip_info['fixed_ip6s']: + ip_info['fixed_ip6s'].append(ipv6_addr) + + for floating_ip in fixed_ip.get('floating_ips', []): + float_addr = floating_ip['address'] + ip_info['floating_ips'].append(float_addr) + ip_info['fixed_ips'].append(fixed_addr) + return ip_info + + +def get_availability_zone_by_host(services, host): + if len(services) > 0: + return services[0]['availability_zone'] + return 'unknown zone' + + def id_to_ec2_id(instance_id, template='i-%08x'): """Convert an instance ID (int) to an ec2 ID (i-[base 16 number])""" return template % int(instance_id) diff --git a/nova/api/metadata/handler.py b/nova/api/metadata/handler.py index 5d63c6dceaeb..aa6f04310f04 100644 --- a/nova/api/metadata/handler.py +++ b/nova/api/metadata/handler.py @@ -18,19 +18,33 @@ """Metadata request handler.""" +import base64 + import webob.dec import webob.exc -from nova import log as logging +from nova import block_device +from nova import compute +from nova import context +from nova import db +from nova import exception from nova import flags +from nova import log as logging +from nova import network +from nova import volume from nova import wsgi -from nova.api.ec2 import cloud +from nova.api.ec2 import ec2utils LOG = logging.getLogger('nova.api.metadata') FLAGS = flags.FLAGS flags.DECLARE('use_forwarded_for', 'nova.api.auth') +_DEFAULT_MAPPINGS = {'ami': 'sda1', + 'ephemeral0': 'sda2', + 'root': block_device.DEFAULT_ROOT_DEV_NAME, + 'swap': 'sda3'} + class Versions(wsgi.Application): @@ -56,7 +70,143 @@ class MetadataRequestHandler(wsgi.Application): """Serve metadata.""" def __init__(self): - self.cc = cloud.CloudController() + self.compute_api = compute.API( + network_api=network.API(), + volume_api=volume.API()) + + def _get_mpi_data(self, context, project_id): + result = {} + search_opts = {'project_id': project_id, 'deleted': False} + for instance in self.compute_api.get_all(context, + search_opts=search_opts): + ip_info = ec2utils.get_ip_info_for_instance(context, instance) + # only look at ipv4 addresses + fixed_ips = ip_info['fixed_ips'] + if fixed_ips: + line = '%s slots=%d' % (fixed_ips[0], instance['vcpus']) + key = str(instance['key_name']) + if key in result: + result[key].append(line) + else: + result[key] = [line] + return result + + def _format_instance_mapping(self, ctxt, instance_ref): + root_device_name = instance_ref['root_device_name'] + if root_device_name is None: + return _DEFAULT_MAPPINGS + + mappings = {} + mappings['ami'] = block_device.strip_dev(root_device_name) + mappings['root'] = root_device_name + default_local_device = instance_ref.get('default_local_device') + if default_local_device: + mappings['ephemeral0'] = default_local_device + default_swap_device = instance_ref.get('default_swap_device') + if default_swap_device: + mappings['swap'] = default_swap_device + ebs_devices = [] + + # 'ephemeralN', 'swap' and ebs + for bdm in db.block_device_mapping_get_all_by_instance( + ctxt, instance_ref['id']): + if bdm['no_device']: + continue + + # ebs volume case + if (bdm['volume_id'] or bdm['snapshot_id']): + ebs_devices.append(bdm['device_name']) + continue + + virtual_name = bdm['virtual_name'] + if not virtual_name: + continue + + if block_device.is_swap_or_ephemeral(virtual_name): + mappings[virtual_name] = bdm['device_name'] + + # NOTE(yamahata): I'm not sure how ebs device should be numbered. + # Right now sort by device name for deterministic + # result. + if ebs_devices: + nebs = 0 + ebs_devices.sort() + for ebs in ebs_devices: + mappings['ebs%d' % nebs] = ebs + nebs += 1 + + return mappings + + def get_metadata(self, address): + ctxt = context.get_admin_context() + search_opts = {'fixed_ip': address, 'deleted': False} + try: + instance_ref = self.compute_api.get_all(ctxt, + search_opts=search_opts) + except exception.NotFound: + instance_ref = None + if not instance_ref: + return None + + # This ensures that all attributes of the instance + # are populated. + instance_ref = db.instance_get(ctxt, instance_ref[0]['id']) + + mpi = self._get_mpi_data(ctxt, instance_ref['project_id']) + hostname = "%s.%s" % (instance_ref['hostname'], FLAGS.dhcp_domain) + host = instance_ref['host'] + services = db.service_get_all_by_host(ctxt.elevated(), host) + availability_zone = ec2utils.get_availability_zone_by_host(services, + host) + + ip_info = ec2utils.get_ip_info_for_instance(ctxt, instance_ref) + floating_ips = ip_info['floating_ips'] + floating_ip = floating_ips and floating_ips[0] or '' + + ec2_id = ec2utils.id_to_ec2_id(instance_ref['id']) + image_ec2_id = ec2utils.image_ec2_id(instance_ref['image_ref']) + security_groups = db.security_group_get_by_instance(ctxt, + instance_ref['id']) + security_groups = [x['name'] for x in security_groups] + mappings = self._format_instance_mapping(ctxt, instance_ref) + data = { + 'user-data': base64.b64decode(instance_ref['user_data']), + 'meta-data': { + 'ami-id': image_ec2_id, + 'ami-launch-index': instance_ref['launch_index'], + 'ami-manifest-path': 'FIXME', + 'block-device-mapping': mappings, + 'hostname': hostname, + 'instance-action': 'none', + 'instance-id': ec2_id, + 'instance-type': instance_ref['instance_type']['name'], + 'local-hostname': hostname, + 'local-ipv4': address, + 'placement': {'availability-zone': availability_zone}, + 'public-hostname': hostname, + 'public-ipv4': floating_ip, + 'reservation-id': instance_ref['reservation_id'], + 'security-groups': security_groups, + 'mpi': mpi}} + + # public-keys should be in meta-data only if user specified one + if instance_ref['key_name']: + data['meta-data']['public-keys'] = { + '0': {'_name': instance_ref['key_name'], + 'openssh-key': instance_ref['key_data']}} + + for image_type in ['kernel', 'ramdisk']: + if instance_ref.get('%s_id' % image_type): + ec2_id = ec2utils.image_ec2_id( + instance_ref['%s_id' % image_type], + ec2utils.image_type(image_type)) + data['meta-data']['%s-id' % image_type] = ec2_id + + if False: # TODO(vish): store ancestor ids + data['ancestor-ami-ids'] = [] + if False: # TODO(vish): store product codes + data['product-codes'] = [] + return data def print_data(self, data): if isinstance(data, dict): @@ -95,7 +245,7 @@ class MetadataRequestHandler(wsgi.Application): if FLAGS.use_forwarded_for: remote_address = req.headers.get('X-Forwarded-For', remote_address) try: - meta_data = self.cc.get_metadata(remote_address) + meta_data = self.get_metadata(remote_address) except Exception: LOG.exception(_('Failed to get metadata for ip: %s'), remote_address) diff --git a/nova/block_device.py b/nova/block_device.py index 8d95e0029bb8..1b7d38145500 100644 --- a/nova/block_device.py +++ b/nova/block_device.py @@ -18,6 +18,9 @@ import re +DEFAULT_ROOT_DEV_NAME = '/dev/sda1' + + def properties_root_device_name(properties): """get root device name from image meta data. If it isn't specified, return None. diff --git a/nova/cloudpipe/pipelib.py b/nova/cloudpipe/pipelib.py index 3eb372844c05..0e86f89b1fb2 100644 --- a/nova/cloudpipe/pipelib.py +++ b/nova/cloudpipe/pipelib.py @@ -36,6 +36,7 @@ from nova import log as logging from nova import utils # TODO(eday): Eventually changes these to something not ec2-specific from nova.api.ec2 import cloud +from nova.api.ec2 import ec2utils FLAGS = flags.FLAGS @@ -98,7 +99,7 @@ class CloudPipe(object): key_name = self.setup_key_pair(ctxt) group_name = self.setup_security_group(ctxt) - ec2_id = self.controller.image_ec2_id(FLAGS.vpn_image_id) + ec2_id = ec2utils.image_ec2_id(FLAGS.vpn_image_id) reservation = self.controller.run_instances(ctxt, user_data=self.get_encoded_zip(project_id), max_count=1, diff --git a/nova/tests/api/ec2/test_cloud.py b/nova/tests/api/ec2/test_cloud.py index 45f15706ca9d..e7cb4289b260 100644 --- a/nova/tests/api/ec2/test_cloud.py +++ b/nova/tests/api/ec2/test_cloud.py @@ -24,7 +24,6 @@ import os from eventlet import greenthread from M2Crypto import BIO from M2Crypto import RSA -import mox from nova.api.ec2 import cloud from nova.api.ec2 import ec2utils @@ -37,7 +36,6 @@ from nova import flags from nova.image import fake from nova import log as logging from nova import manager -from nova import network from nova import rpc from nova import test from nova import utils @@ -1750,33 +1748,6 @@ class CloudTestCase(test.TestCase): 'device_name': '/dev/sd3'}, ] - def test_get_instance_mapping(self): - """Make sure that _get_instance_mapping works""" - ctxt = None - instance_ref0 = {'id': 0, - 'root_device_name': None} - instance_ref1 = {'id': 0, - 'root_device_name': '/dev/sda1'} - - self.stubs.Set(db, 'block_device_mapping_get_all_by_instance', - self._fake_bdm_get) - - expected = {'ami': 'sda1', - 'root': '/dev/sda1', - 'ephemeral0': '/dev/sdb', - 'swap': '/dev/sdc', - 'ephemeral1': '/dev/sdd', - 'ephemeral2': '/dev/sd3', - 'ebs0': '/dev/sdh', - 'ebs1': '/dev/sdi'} - - self.assertEqual(self.cloud._format_instance_mapping(ctxt, - instance_ref0), - cloud._DEFAULT_MAPPINGS) - self.assertEqual(self.cloud._format_instance_mapping(ctxt, - instance_ref1), - expected) - def test_describe_instance_attribute(self): """Make sure that describe_instance_attribute works""" self.stubs.Set(db, 'block_device_mapping_get_all_by_instance', diff --git a/nova/tests/test_metadata.py b/nova/tests/test_metadata.py index 283b6a7cb2c9..b3884c06e6f0 100644 --- a/nova/tests/test_metadata.py +++ b/nova/tests/test_metadata.py @@ -23,6 +23,7 @@ import webob from nova.api.metadata import handler from nova.db.sqlalchemy import api +from nova import db from nova import exception from nova import flags from nova import network @@ -88,7 +89,7 @@ class MetadataTestCase(test.TestCase): self.stubs.Set(api, 'instance_get_floating_address', floating_get) self.app = handler.MetadataRequestHandler() network_manager = fake_network.FakeNetworkManager() - self.stubs.Set(self.app.cc.network_api, + self.stubs.Set(self.app.compute_api.network_api, 'get_instance_uuids_by_ip_filter', network_manager.get_instance_uuids_by_ip_filter) @@ -145,3 +146,47 @@ class MetadataTestCase(test.TestCase): def test_local_hostname_fqdn(self): self.assertEqual(self.request('/meta-data/local-hostname'), "%s.%s" % (self.instance['hostname'], FLAGS.dhcp_domain)) + + def test_get_instance_mapping(self): + """Make sure that _get_instance_mapping works""" + ctxt = None + instance_ref0 = {'id': 0, + 'root_device_name': None} + instance_ref1 = {'id': 0, + 'root_device_name': '/dev/sda1'} + + def fake_bdm_get(ctxt, id): + return [{'volume_id': 87654321, + 'snapshot_id': None, + 'no_device': None, + 'virtual_name': None, + 'delete_on_termination': True, + 'device_name': '/dev/sdh'}, + {'volume_id': None, + 'snapshot_id': None, + 'no_device': None, + 'virtual_name': 'swap', + 'delete_on_termination': None, + 'device_name': '/dev/sdc'}, + {'volume_id': None, + 'snapshot_id': None, + 'no_device': None, + 'virtual_name': 'ephemeral0', + 'delete_on_termination': None, + 'device_name': '/dev/sdb'}] + + self.stubs.Set(db, 'block_device_mapping_get_all_by_instance', + fake_bdm_get) + + expected = {'ami': 'sda1', + 'root': '/dev/sda1', + 'ephemeral0': '/dev/sdb', + 'swap': '/dev/sdc', + 'ebs0': '/dev/sdh'} + + self.assertEqual(self.app._format_instance_mapping(ctxt, + instance_ref0), + handler._DEFAULT_MAPPINGS) + self.assertEqual(self.app._format_instance_mapping(ctxt, + instance_ref1), + expected)