From 5aa522908264b5ef97387821e18c13ad9a9b95a1 Mon Sep 17 00:00:00 2001 From: Monsyne Dragon Date: Fri, 30 Sep 2011 00:39:46 +0000 Subject: Adds more usage data to Nova's usage notifications. Adds in bandwidth, state and IP data on standard notifications, and new notifications on add/remove IP. These were missing before, and are needed to meet spec. This fixes bug 849117 Change-Id: Ie586ff3a91a56e5f5eff8abc6905ba6a0b624451 --- nova/db/api.py | 24 +++++++++ nova/db/sqlalchemy/api.py | 36 ++++++++++++++ .../versions/054_add_bw_usage_data_cache.py | 57 ++++++++++++++++++++++ nova/db/sqlalchemy/models.py | 14 +++++- 4 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 nova/db/sqlalchemy/migrate_repo/versions/054_add_bw_usage_data_cache.py (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index 0e00be3f6..a26cb3908 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -1438,6 +1438,30 @@ def agent_build_update(context, agent_build_id, values): #################### +def bw_usage_get_by_instance(context, instance_id, start_period): + """Return bw usages for an instance in a given audit period.""" + return IMPL.bw_usage_get_by_instance(context, instance_id, start_period) + + +def bw_usage_update(context, + instance_id, + network_label, + start_period, + bw_in, bw_out, + session=None): + """Update cached bw usage for an instance and network + Creates new record if needed.""" + return IMPL.bw_usage_update(context, + instance_id, + network_label, + start_period, + bw_in, bw_out, + session=None) + + +#################### + + def instance_type_extra_specs_get(context, instance_type_id): """Get all extra specs for an instance type.""" return IMPL.instance_type_extra_specs_get(context, instance_type_id) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 8e5df8dd8..077471e95 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -3617,6 +3617,42 @@ def agent_build_update(context, agent_build_id, values): agent_build_ref.save(session=session) +#################### + +@require_context +def bw_usage_get_by_instance(context, instance_id, start_period): + session = get_session() + return session.query(models.BandwidthUsage).\ + filter_by(instance_id=instance_id).\ + filter_by(start_period=start_period).\ + all() + + +@require_context +def bw_usage_update(context, + instance_id, + network_label, + start_period, + bw_in, bw_out, + session=None): + session = session if session else get_session() + with session.begin(): + bwusage = session.query(models.BandwidthUsage).\ + filter_by(instance_id=instance_id).\ + filter_by(start_period=start_period).\ + filter_by(network_label=network_label).\ + first() + if not bwusage: + bwusage = models.BandwidthUsage() + bwusage.instance_id = instance_id + bwusage.start_period = start_period + bwusage.network_label = network_label + bwusage.last_refreshed = utils.utcnow() + bwusage.bw_in = bw_in + bwusage.bw_out = bw_out + bwusage.save(session=session) + + #################### diff --git a/nova/db/sqlalchemy/migrate_repo/versions/054_add_bw_usage_data_cache.py b/nova/db/sqlalchemy/migrate_repo/versions/054_add_bw_usage_data_cache.py new file mode 100644 index 000000000..4276df5c2 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/054_add_bw_usage_data_cache.py @@ -0,0 +1,57 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 MORITA Kazutaka. +# 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 Column, Table, MetaData +from sqlalchemy import Integer, BigInteger, DateTime, Boolean, String + +from nova import log as logging + +meta = MetaData() + +bw_cache = Table('bw_usage_cache', 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), + Column('instance_id', Integer(), nullable=False), + Column('network_label', + String(length=255, convert_unicode=False, assert_unicode=None, + unicode_error=None, _warn_on_bytestring=False)), + Column('start_period', DateTime(timezone=False), nullable=False), + Column('last_refreshed', DateTime(timezone=False)), + Column('bw_in', BigInteger()), + Column('bw_out', BigInteger())) + + +def upgrade(migrate_engine): + # Upgrade operations go here. Don't create your own engine; + # bind migrate_engine to your metadata + meta.bind = migrate_engine + + try: + bw_cache.create() + except Exception: + logging.info(repr(bw_cache)) + logging.exception('Exception while creating table') + meta.drop_all(tables=[bw_cache]) + raise + + +def downgrade(migrate_engine): + # Operations to reverse the above upgrade go here. + bw_cache.drop() diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 7a4321544..d4b8c89cb 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -21,7 +21,7 @@ SQLAlchemy models for nova data. """ from sqlalchemy.orm import relationship, backref, object_mapper -from sqlalchemy import Column, Integer, String, schema +from sqlalchemy import Column, Integer, BigInteger, String, schema from sqlalchemy import ForeignKey, DateTime, Boolean, Text, Float from sqlalchemy.exc import IntegrityError from sqlalchemy.ext.declarative import declarative_base @@ -846,6 +846,18 @@ class AgentBuild(BASE, NovaBase): md5hash = Column(String(255)) +class BandwidthUsage(BASE, NovaBase): + """Cache for instance bandwidth usage data pulled from the hypervisor""" + __tablename__ = 'bw_usage_cache' + id = Column(Integer, primary_key=True, nullable=False) + instance_id = Column(Integer, nullable=False) + network_label = Column(String(255)) + start_period = Column(DateTime, nullable=False) + last_refreshed = Column(DateTime) + bw_in = Column(BigInteger) + bw_out = Column(BigInteger) + + def register_models(): """Register Models and create metadata. -- cgit