From 0dc32690fe158e4cb11c2c9bcc65acaf73b94a7a Mon Sep 17 00:00:00 2001 From: Yaguang Tang Date: Thu, 28 Jun 2012 17:07:08 +0800 Subject: Implement blueprint ec2-id-compatibilty. Instance ids are used by the ec2 layer to create ec2-ids. This currently uses the id column in the instances table. This patch creates a new mapping table for ec2-ids. This decouples the ec2 layer from needing direct access to the instances table so that it can eventually be pulled out if necessary. It also matches the way that the ec2 layer maps image, volume, and snaphsot ids. Finally, it allows us to eventually remove the id column from the instances table and only have one canonical id (uuid) to refer to instances. Change-Id: I02ad9fad37e6a04675543398f686351634bc1bb9 --- nova/api/ec2/__init__.py | 2 +- nova/api/ec2/cloud.py | 18 +++++++++--------- nova/api/ec2/ec2utils.py | 36 +++++++++++++++++++++++++++++------- nova/api/metadata/base.py | 3 ++- 4 files changed, 41 insertions(+), 18 deletions(-) (limited to 'nova/api') diff --git a/nova/api/ec2/__init__.py b/nova/api/ec2/__init__.py index edde3a9e4..6bb19e7b3 100644 --- a/nova/api/ec2/__init__.py +++ b/nova/api/ec2/__init__.py @@ -472,7 +472,7 @@ class Executor(wsgi.Application): except exception.InstanceNotFound as ex: LOG.info(_('InstanceNotFound raised: %s'), unicode(ex), context=context) - ec2_id = ec2utils.id_to_ec2_id(ex.kwargs['instance_id']) + ec2_id = ec2utils.id_to_ec2_inst_id(ex.kwargs['instance_id']) message = ex.message % {'instance_id': ec2_id} return ec2_error(req, request_id, type(ex).__name__, message) except exception.VolumeNotFound as ex: diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 75f28d510..126df0f0a 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -690,8 +690,7 @@ class CloudController(object): instance = db.instance_get_by_uuid(context.elevated(), instance_uuid) - instance_id = instance['id'] - instance_ec2_id = ec2utils.id_to_ec2_id(instance_id) + instance_ec2_id = ec2utils.id_to_ec2_inst_id(instance_uuid) instance_data = '%s[%s]' % (instance_ec2_id, instance['host']) v = {} @@ -778,7 +777,7 @@ class CloudController(object): volume = self.volume_api.get(context, volume_id) return {'attachTime': volume['attach_time'], 'device': volume['mountpoint'], - 'instanceId': ec2utils.id_to_ec2_id(instance_id), + 'instanceId': ec2utils.id_to_ec2_inst_id(instance_id), 'requestId': context.request_id, 'status': volume['attach_status'], 'volumeId': ec2utils.id_to_ec2_vol_id(volume_id)} @@ -797,7 +796,7 @@ class CloudController(object): return {'attachTime': volume['attach_time'], 'device': volume['mountpoint'], - 'instanceId': ec2utils.id_to_ec2_id(instance['id']), + 'instanceId': ec2utils.id_to_ec2_inst_id(instance['uuid']), 'requestId': context.request_id, 'status': volume['attach_status'], 'volumeId': ec2utils.id_to_ec2_vol_id(volume_id)} @@ -987,9 +986,10 @@ class CloudController(object): if instance_id: instances = [] for ec2_id in instance_id: - internal_id = ec2utils.ec2_id_to_id(ec2_id) try: - instance = self.compute_api.get(context, internal_id) + instance_uuid = ec2utils.ec2_inst_id_to_uuid(context, + ec2_id) + instance = self.compute_api.get(context, instance_uuid) except exception.NotFound: continue instances.append(instance) @@ -1007,8 +1007,8 @@ class CloudController(object): if instance['image_ref'] == str(FLAGS.vpn_image_id): continue i = {} - instance_id = instance['id'] - ec2_id = ec2utils.id_to_ec2_id(instance_id) + instance_uuid = instance['uuid'] + ec2_id = ec2utils.id_to_ec2_inst_id(instance_uuid) i['instanceId'] = ec2_id image_uuid = instance['image_ref'] i['imageId'] = ec2utils.glance_id_to_ec2_id(context, image_uuid) @@ -1081,7 +1081,7 @@ class CloudController(object): fixed_id = floating_ip['fixed_ip_id'] fixed = self.network_api.get_fixed_ip(context, fixed_id) if fixed['instance_id'] is not None: - ec2_id = ec2utils.id_to_ec2_id(fixed['instance_id']) + ec2_id = ec2utils.id_to_ec2_inst_id(fixed['instance_id']) address = {'public_ip': floating_ip['address'], 'instance_id': ec2_id} if context.is_admin: diff --git a/nova/api/ec2/ec2utils.py b/nova/api/ec2/ec2utils.py index 1735f8b3e..608628209 100644 --- a/nova/api/ec2/ec2utils.py +++ b/nova/api/ec2/ec2utils.py @@ -81,13 +81,6 @@ def ec2_id_to_id(ec2_id): raise exception.InvalidEc2Id(ec2_id=ec2_id) -def ec2_id_to_uuid(context, ec2_id): - """Convert an ec2 ID into an instance UUID""" - instance_id = ec2_id_to_id(ec2_id) - instance = db.instance_get(context, instance_id) - return instance['uuid'] - - def image_ec2_id(image_id, image_type='ami'): """Returns image ec2_id using id and three letter type.""" template = image_type + '-%08x' @@ -134,6 +127,26 @@ def id_to_ec2_id(instance_id, template='i-%08x'): return template % int(instance_id) +def id_to_ec2_inst_id(instance_id): + """Get or create an ec2 instance ID (i-[base 16 number]) from uuid.""" + if utils.is_uuid_like(instance_id): + ctxt = context.get_admin_context() + int_id = get_int_id_from_instance_uuid(ctxt, instance_id) + return id_to_ec2_id(int_id) + else: + return id_to_ec2_id(instance_id) + + +def ec2_inst_id_to_uuid(context, ec2_id): + """"Convert an instance id to uuid.""" + int_id = ec2_id_to_id(ec2_id) + return get_instance_uuid_from_int_id(context, int_id) + + +def get_instance_uuid_from_int_id(context, int_id): + return db.get_instance_uuid_by_ec2_id(context, int_id) + + def id_to_ec2_snap_id(snapshot_id): """Get or create an ec2 volume ID (vol-[base 16 number]) from uuid.""" if utils.is_uuid_like(snapshot_id): @@ -163,6 +176,15 @@ def ec2_vol_id_to_uuid(ec2_id): return get_volume_uuid_from_int_id(ctxt, int_id) +def get_int_id_from_instance_uuid(context, instance_uuid): + if instance_uuid is None: + return + try: + return db.get_ec2_instance_id_by_uuid(context, instance_uuid) + except exception.NotFound: + return db.ec2_instance_create(context, instance_uuid)['id'] + + def get_int_id_from_volume_uuid(context, volume_uuid): if volume_uuid is None: return diff --git a/nova/api/metadata/base.py b/nova/api/metadata/base.py index 1b0ac441b..06e290917 100644 --- a/nova/api/metadata/base.py +++ b/nova/api/metadata/base.py @@ -88,7 +88,8 @@ class InstanceMetadata(): self.ec2_ids = {} - self.ec2_ids['instance-id'] = ec2utils.id_to_ec2_id(instance['id']) + self.ec2_ids['instance-id'] = ec2utils.id_to_ec2_inst_id( + instance['id']) self.ec2_ids['ami-id'] = ec2utils.glance_id_to_ec2_id(ctxt, instance['image_ref']) -- cgit