diff options
| author | Yaguang Tang <heut2008@gmail.com> | 2012-06-28 17:07:08 +0800 |
|---|---|---|
| committer | Vishvananda Ishaya <vishvananda@gmail.com> | 2012-06-28 13:01:55 -0700 |
| commit | 0dc32690fe158e4cb11c2c9bcc65acaf73b94a7a (patch) | |
| tree | 26e210b370783165edaf86f5ab8b03ab12313947 /nova/db | |
| parent | 2264c1c0b6ccfe7dc3e4c7e448b4a5eac92758d4 (diff) | |
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
Diffstat (limited to 'nova/db')
| -rw-r--r-- | nova/db/api.py | 18 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/api.py | 50 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/migrate_repo/versions/107_add_instance_id_mappings.py | 67 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/models.py | 7 |
4 files changed, 142 insertions, 0 deletions
diff --git a/nova/db/api.py b/nova/db/api.py index 989864a2b..695c083c9 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -1930,3 +1930,21 @@ def instance_fault_create(context, values): def instance_fault_get_by_instance_uuids(context, instance_uuids): """Get all instance faults for the provided instance_uuids.""" return IMPL.instance_fault_get_by_instance_uuids(context, instance_uuids) + + +#################### + + +def get_ec2_instance_id_by_uuid(context, instance_id): + """Get ec2 id through uuid from instance_id_mappings table""" + return IMPL.get_ec2_instance_id_by_uuid(context, instance_id) + + +def get_instance_uuid_by_ec2_id(context, instance_id): + """Get uuid through ec2 id from instance_id_mappings table""" + return IMPL.get_instance_uuid_by_ec2_id(context, instance_id) + + +def ec2_instance_create(context, instance_ec2_id): + """Create the ec2 id to instance uuid mapping on demand""" + return IMPL.ec2_instance_create(context, instance_ec2_id) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 76578e061..bc0ba5307 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1367,6 +1367,9 @@ def instance_create(context, values): # exists in the ref when we return. Fixes lazy loading issues. instance_ref.instance_type + # create the instance uuid to ec2_id mapping entry for instance + ec2_instance_create(context, instance_ref['uuid']) + return instance_ref @@ -5163,3 +5166,50 @@ def instance_fault_get_by_instance_uuids(context, instance_uuids): output[row['instance_uuid']].append(data) return output + + +################## + + +@require_context +def ec2_instance_create(context, instance_uuid, id=None): + """Create ec2 compatable instance by provided uuid""" + ec2_instance_ref = models.InstanceIdMapping() + ec2_instance_ref.update({'uuid': instance_uuid}) + if id is not None: + ec2_instance_ref.update({'id': id}) + + ec2_instance_ref.save() + + return ec2_instance_ref + + +@require_context +def get_ec2_instance_id_by_uuid(context, instance_id, session=None): + result = _ec2_instance_get_query(context, + session=session).\ + filter_by(uuid=instance_id).\ + first() + + if not result: + raise exception.InstanceNotFound(uuid=instance_id) + + return result['id'] + + +@require_context +def get_instance_uuid_by_ec2_id(context, instance_id, session=None): + result = _ec2_instance_get_query(context, + session=session).\ + filter_by(id=instance_id).\ + first() + + if not result: + raise exception.InstanceNotFound(id=instance_id) + + return result['uuid'] + + +@require_context +def _ec2_instance_get_query(context, session=None): + return model_query(context, models.InstanceIdMapping, session=session) diff --git a/nova/db/sqlalchemy/migrate_repo/versions/107_add_instance_id_mappings.py b/nova/db/sqlalchemy/migrate_repo/versions/107_add_instance_id_mappings.py new file mode 100644 index 000000000..94adbd89b --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/107_add_instance_id_mappings.py @@ -0,0 +1,67 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# Copyright 2012 SINA Corp. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from sqlalchemy import Boolean, Column, DateTime, Integer +from sqlalchemy import Index, MetaData, String, Table +from nova import log as logging + +LOG = logging.getLogger(__name__) + + +def upgrade(migrate_engine): + meta = MetaData() + meta.bind = migrate_engine + + # create new table + instance_id_mappings = Table('instance_id_mappings', meta, + Column('created_at', DateTime(timezone=False)), + Column('updated_at', DateTime(timezone=False)), + Column('deleted_at', DateTime(timezone=False)), + Column('deleted', + Boolean(create_constraint=True, name=None)), + Column('id', Integer(), + primary_key=True, + nullable=False, + autoincrement=True), + Column('uuid', String(36), index=True, nullable=False)) + try: + instance_id_mappings.create() + except Exception: + LOG.exception("Exception while creating table 'instance_id_mappings'") + meta.drop_all(tables=[instance_id_mappings]) + raise + + if migrate_engine.name == "mysql": + migrate_engine.execute("ALTER TABLE instance_id_mappings " + "Engine=InnoDB") + + instances = Table('instances', meta, autoload=True) + instance_id_mappings = Table('instance_id_mappings', meta, autoload=True) + + instance_list = list(instances.select().execute()) + for instance in instance_list: + instance_id = instance['id'] + uuid = instance['uuid'] + row = instance_id_mappings.insert() + row.execute({'id': instance_id, 'uuid': uuid}) + + +def downgrade(migrate_engine): + meta = MetaData() + meta.bind = migrate_engine + + instance_id_mappings = Table('instance_id_mappings', meta, autoload=True) + instance_id_mappings.drop() diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index f63004386..335989135 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -1036,3 +1036,10 @@ class InstanceFault(BASE, NovaBase): code = Column(Integer(), nullable=False) message = Column(String(255)) details = Column(Text) + + +class InstanceIdMapping(BASE, NovaBase): + """Compatability layer for the EC2 instance service""" + __tablename__ = 'instance_id_mappings' + id = Column(Integer, primary_key=True, nullable=False, autoincrement=True) + uuid = Column(String(36), nullable=False) |
