From d8e84937c19169e3de73e7ad6b7382d954d753ac Mon Sep 17 00:00:00 2001 From: Trey Morris Date: Thu, 1 Dec 2011 16:54:40 -0600 Subject: Adds network model and network info cache. The next merge will prepopulate the cache, and use the model to keep the cache up to date. I realize "cache" is a bit of a stretch for what this is doing. blueprint network-info-model blueprint compute-network-info Change-Id: I0f0f4ba3de1310e1ff89239dab6ea8e24c85f2c8 --- nova/db/api.py | 42 +++++++++++++ nova/db/sqlalchemy/api.py | 71 ++++++++++++++++++++++ .../versions/062_add_instance_info_cache_table.py | 62 +++++++++++++++++++ nova/db/sqlalchemy/models.py | 21 +++++++ 4 files changed, 196 insertions(+) create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/062_add_instance_info_cache_table.py (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index 4af79b13c..bc413319e 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -649,6 +649,48 @@ def instance_get_id_to_uuid_mapping(context, ids): ################### +def instance_info_cache_create(context, values): + """Create a new instance cache record in the table. + + :param context: = request context object + :param values: = dict containing column values + """ + return IMPL.instance_info_cache_create(context, values) + + +def instance_info_cache_get(context, instance_id, session=None): + """Gets an instance info cache from the table. + + :param instance_id: = id of the info cache's instance + :param session: = optional session object + """ + return IMPL.instance_info_cache_get(context, instance_id, session=None) + + +def instance_info_cache_update(context, instance_id, values, + session=None): + """Update an instance info cache record in the table. + + :param instance_id: = id of info cache's instance + :param values: = dict containing column values to update + """ + return IMPL.instance_info_cache_update(context, instance_id, values, + session) + + +def instance_info_cache_delete_by_instance_id(context, instance_id, + session=None): + """Deletes an existing instance_info_cache record + + :param instance_id: = id of the instance tied to the cache record + """ + return IMPL.instance_info_cache_delete_by_instance_id(context, instance_id, + session) + + +################### + + def key_pair_create(context, values): """Create a key_pair from the values dictionary.""" return IMPL.key_pair_create(context, values) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index a8424686f..2619c247f 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1132,6 +1132,8 @@ def instance_destroy(context, instance_id): update({'deleted': True, 'deleted_at': utils.utcnow(), 'updated_at': literal_column('updated_at')}) + instance_info_cache_delete_by_instance_id(context, instance_id, + session=session) @require_context @@ -1557,6 +1559,75 @@ def instance_get_id_to_uuid_mapping(context, ids): ################### +@require_context +def instance_info_cache_create(context, values): + """Create a new instance cache record in the table. + + :param context: = request context object + :param values: = dict containing column values + """ + info_cache = models.InstanceInfoCache() + info_cache['id'] = str(utils.gen_uuid()) + info_cache.update(values) + + session = get_session() + with session.begin(): + info_cache.save(session=session) + return info_cache + + +@require_context +def instance_info_cache_get(context, instance_id, session=None): + """Gets an instance info cache from the table. + + :param instance_id: = id of the info cache's instance + :param session: = optional session object + """ + session = session or get_session() + + info_cache = session.query(models.InstanceInfoCache).\ + filter_by(instance_id=instance_id).\ + first() + return info_cache + + +@require_context +def instance_info_cache_update(context, instance_id, values, + session=None): + """Update an instance info cache record in the table. + + :param instance_id: = id of info cache's instance + :param values: = dict containing column values to update + :param session: = optional session object + """ + session = session or get_session() + info_cache = instance_info_cache_get(context, instance_id, + session=session) + + values['updated_at'] = literal_column('updated_at') + + if info_cache: + info_cache.update(values) + info_cache.save(session=session) + return info_cache + + +@require_context +def instance_info_cache_delete_by_instance_id(context, instance_id, + session=None): + """Deletes an existing instance_info_cache record + + :param instance_id: = id of the instance tied to the cache record + :param session: = optional session object + """ + values = {'deleted': True, + 'deleted_at': utils.utcnow()} + instance_info_cache_update(context, instance_id, values, session) + + +################### + + @require_context def key_pair_create(context, values): key_pair_ref = models.KeyPair() diff --git a/nova/db/sqlalchemy/migrate_repo/versions/062_add_instance_info_cache_table.py b/nova/db/sqlalchemy/migrate_repo/versions/062_add_instance_info_cache_table.py new file mode 100644 index 000000000..99479bbf9 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/062_add_instance_info_cache_table.py @@ -0,0 +1,62 @@ +# Copyright 2011 OpenStack LLC. +# 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. + +import datetime + +from sqlalchemy import * +from migrate import * + +from nova import log as logging +from nova import utils + +meta = MetaData() + +# instance info cache table to add to DB +instance_info_caches = Table('instance_info_caches', meta, + Column('created_at', DateTime(timezone=False), + default=utils.utcnow()), + Column('updated_at', DateTime(timezone=False), + onupdate=utils.utcnow()), + Column('deleted_at', DateTime(timezone=False)), + Column('deleted', Boolean(create_constraint=True, name=None)), + Column('id', Integer(), primary_key=True), + Column('network_info', Text()), + Column('instance_id', String(36), + ForeignKey('instances.uuid'), + nullable=False, + unique=True), + mysql_engine='InnoDB') + + +def upgrade(migrate_engine): + meta.bind = migrate_engine + + # load instances for fk + instances = Table('instances', meta, autoload=True) + + # create instance_info_caches table + try: + instance_info_caches.create() + except Exception: + logging.error(_("Table |%s| not created!"), repr(instance_info_caches)) + raise + + +def downgrade(migrate_engine): + try: + instance_info_caches.drop() + except Exception: + logging.error(_("instance_info_caches tables not dropped")) + raise diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 407c9e2e7..1774e9ea8 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -257,6 +257,27 @@ class Instance(BASE, NovaBase): progress = Column(Integer) +class InstanceInfoCache(BASE, NovaBase): + """ + Represents a cache of information about an instance + """ + __tablename__ = 'instance_info_caches' + id = Column(String(36), primary_key=True) + + # text column used for storing a json object of network data for api + network_info = Column(Text) + + # this is all uuid based, we have them might as well start using them + instance_id = Column(String(36), ForeignKey('instances.uuid'), + nullable=False, unique=True) + instance = relationship(Instance, + backref=backref('info_cache', uselist=False), + foreign_keys=instance_id, + primaryjoin='and_(' + 'InstanceInfoCache.instance_id == Instance.uuid,' + 'InstanceInfoCache.deleted == False)') + + class VirtualStorageArray(BASE, NovaBase): """ Represents a virtual storage array supplying block storage to instances. -- cgit