Merge "Fix _poll_bandwidth_usage if no network on vif"

This commit is contained in:
Jenkins
2012-02-06 23:59:01 +00:00
committed by Gerrit Code Review
13 changed files with 224 additions and 44 deletions
+7 -3
View File
@@ -2088,10 +2088,14 @@ class ComputeManager(manager.SchedulerDependentManager):
return
for usage in bw_usage:
vif = usage['virtual_interface']
mac = usage['mac_address']
vif = self.network_api.get_vif_by_mac_address(context, mac)
if not vif:
continue
self.db.bw_usage_update(context,
vif.instance_id,
vif.network.label,
vif['instance_id'],
mac,
start_time,
usage['bw_in'], usage['bw_out'])
+19 -1
View File
@@ -22,6 +22,8 @@ from nova import context
from nova import db
from nova import exception
from nova import flags
from nova import network
from nova.network import model as network_model
from nova.notifier import api as notifier_api
from nova import utils
@@ -44,10 +46,26 @@ def notify_usage_exists(instance_ref, current_period=False):
else:
audit_start = begin
audit_end = end
if (instance_ref.get('info_cache') and
instance_ref['info_cache'].get('network_info')):
cached_info = instance_ref['info_cache']['network_info']
nw_info = network_model.NetworkInfo.hydrate(cached_info)
else:
nw_info = network.API().get_instance_nw_info(admin_context,
instance_ref)
for b in db.bw_usage_get_by_instance(admin_context,
instance_ref['id'],
audit_start):
bw[b.network_label] = dict(bw_in=b.bw_in, bw_out=b.bw_out)
label = 'net-name-not-found-%s' % b['mac']
for vif in nw_info:
if vif['address'] == b['mac']:
label = vif['network']['label']
break
bw[label] = dict(bw_in=b.bw_in, bw_out=b.bw_out)
usage_info = utils.usage_from_instance(instance_ref,
audit_period_beginning=str(audit_start),
audit_period_ending=str(audit_end),
+2 -2
View File
@@ -1549,14 +1549,14 @@ def bw_usage_get_all_by_filters(context, filters):
def bw_usage_update(context,
instance_id,
network_label,
mac,
start_period,
bw_in, bw_out):
"""Update cached bw usage for an instance and network
Creates new record if needed."""
return IMPL.bw_usage_update(context,
instance_id,
network_label,
mac,
start_period,
bw_in, bw_out)
+3 -3
View File
@@ -3710,7 +3710,7 @@ def bw_usage_get_all_by_filters(context, filters):
@require_context
def bw_usage_update(context,
instance_id,
network_label,
mac,
start_period,
bw_in, bw_out,
session=None):
@@ -3722,14 +3722,14 @@ def bw_usage_update(context,
read_deleted="yes").\
filter_by(instance_id=instance_id).\
filter_by(start_period=start_period).\
filter_by(network_label=network_label).\
filter_by(mac=mac).\
first()
if not bwusage:
bwusage = models.BandwidthUsage()
bwusage.instance_id = instance_id
bwusage.start_period = start_period
bwusage.network_label = network_label
bwusage.mac = mac
bwusage.last_refreshed = utils.utcnow()
bwusage.bw_in = bw_in
@@ -0,0 +1,90 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# 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.
from sqlalchemy import *
from migrate import *
from nova import utils
meta = MetaData()
def upgrade(migrate_engine):
meta.bind = migrate_engine
bw_usage_cache = Table('bw_usage_cache', meta,
Column('id', Integer, primary_key=True),
Column('network_label', String(255)),
Column('instance_id', Integer, nullable=False),
Column('start_period', DateTime, nullable=False),
Column('last_refreshed', DateTime),
Column('bw_in', BigInteger),
Column('bw_out', BigInteger),
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)))
vifs = Table('virtual_interfaces', meta, autoload=True)
networks = Table('networks', meta, autoload=True)
mac_column = Column('mac', String(255))
bw_usage_cache.create_column(mac_column)
bw_usage_cache.update()\
.values(mac=select([vifs.c.address])\
.where(and_(networks.c.label == bw_usage_cache.c.network_label,
networks.c.id == vifs.c.network_id))\
.as_scalar()).execute()
bw_usage_cache.c.network_label.drop()
def downgrade(migrate_engine):
meta.bind = migrate_engine
bw_usage_cache = Table('bw_usage_cache', meta,
Column('id', Integer, primary_key=True),
Column('network_uuid', String(36)),
Column('instance_id', Integer, nullable=False),
Column('start_period', DateTime, nullable=False),
Column('last_refreshed', DateTime),
Column('bw_in', BigInteger),
Column('bw_out', BigInteger),
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)))
vifs = Table('virtual_interfaces', meta, autoload=True)
network = Table('networks', meta, autoload=True)
network_label_column = Column('network_label', String(255))
bw_usage_cache.create_column(network_label_column)
bw_usage_cache.update()\
.values(network_label=select([network.c.label])\
.where(and_(network.c.id == vifs.c.network_id,
vifs.c.address == bw_usage_cache.c.mac))\
.as_scalar()).execute()
bw_usage_cache.c.network_uuid.drop()
+1 -1
View File
@@ -927,7 +927,7 @@ class BandwidthUsage(BASE, NovaBase):
__tablename__ = 'bw_usage_cache'
id = Column(Integer, primary_key=True, nullable=False)
instance_id = Column(Integer, nullable=False)
network_label = Column(String(255))
mac = Column(String(255), nullable=False)
start_period = Column(DateTime, nullable=False)
last_refreshed = Column(DateTime)
bw_in = Column(BigInteger)
+6
View File
@@ -99,6 +99,12 @@ class API(base.Base):
{'method': 'get_vifs_by_instance',
'args': {'instance_id': instance['id']}})
def get_vif_by_mac_address(self, context, mac_address):
return rpc.call(context,
FLAGS.network_topic,
{'method': 'get_vif_by_mac_address',
'args': {'mac_address': mac_address}})
def allocate_floating_ip(self, context, pool=None):
"""Adds a floating ip to a project from a pool. (allocates)"""
# NOTE(vish): We don't know which network host should get the ip
+5
View File
@@ -1476,6 +1476,11 @@ class NetworkManager(manager.SchedulerDependentManager):
fixed = self.db.fixed_ip_get(context, id)
return dict(fixed.iteritems())
def get_vif_by_mac_address(self, context, mac_address):
"""Returns the vifs record for the mac_address"""
return self.db.virtual_interface_get_by_address(context,
mac_address)
class FlatManager(NetworkManager):
"""Basic network where no vlans are used.
+75 -26
View File
@@ -190,6 +190,15 @@ class BaseTestCase(test.TestCase):
class ComputeTestCase(BaseTestCase):
def setUp(self):
def fake_get_nw_info(cls, ctxt, instance):
self.assertTrue(ctxt.is_admin)
return fake_network.fake_get_instance_nw_info(self.stubs, 1, 1,
spectacular=True)
super(ComputeTestCase, self).setUp()
self.stubs.Set(nova.network.API, 'get_instance_nw_info',
fake_get_nw_info)
def test_wrap_instance_fault(self):
inst_uuid = "fake_uuid"
@@ -966,38 +975,66 @@ class ComputeTestCase(BaseTestCase):
def test_finish_resize(self):
"""Contrived test to ensure finish_resize doesn't raise anything"""
nw_info = fake_network.fake_get_instance_nw_info(self.stubs,
spectacular=True)
def fake(*args, **kwargs):
pass
def fake_nw_info(*args, **kwargs):
return nw_info
# NOTE(jkoelker) There is a bit of a stubbing issue here.
# fake_network stubs out a bunch of stuff which
# this functional test expects to be acting on
# the db or the stubs it sets.
self.stubs.UnsetAll()
self.stubs.SmartUnsetAll()
self.setUp()
self.stubs.Set(self.compute.driver, 'finish_migration', fake)
self.stubs.Set(self.compute.network_api, 'get_instance_nw_info', fake)
self.stubs.Set(self.compute.network_api, 'get_instance_nw_info',
fake_nw_info)
fake_network.stub_out_nw_api_get_instance_nw_info(self.stubs,
func=fake_nw_info)
context = self.context.elevated()
instance = self._create_fake_instance()
self.compute.prep_resize(context, instance['uuid'], 1,
filter_properties={})
migration_ref = db.migration_get_by_instance_and_status(context,
instance['uuid'], 'pre-migrating')
try:
self.compute.finish_resize(context, instance['uuid'],
int(migration_ref['id']), {})
except KeyError, e:
# Only catch key errors. We want other reasons for the test to
# fail to actually error out so we don't obscure anything
self.fail()
self.compute.finish_resize(context, instance['uuid'],
int(migration_ref['id']), {})
self.compute.terminate_instance(self.context, instance['uuid'])
def test_finish_resize_handles_error(self):
"""Make sure we don't leave the instance in RESIZE on error"""
nw_info = fake_network.fake_get_instance_nw_info(self.stubs,
spectacular=True)
def throw_up(*args, **kwargs):
raise Exception()
def fake(*args, **kwargs):
pass
def fake_nw_info(*args, **kwargs):
return nw_info
# NOTE(jkoelker) There is a bit of a stubbing issue here.
# fake_network stubs out a bunch of stuff which
# this functional test expects to be acting on
# the db or the stubs it sets.
self.stubs.UnsetAll()
self.stubs.SmartUnsetAll()
self.setUp()
self.stubs.Set(self.compute.driver, 'finish_migration', throw_up)
self.stubs.Set(self.compute.network_api, 'get_instance_nw_info', fake)
fake_network.stub_out_nw_api_get_instance_nw_info(self.stubs,
func=fake_nw_info)
context = self.context.elevated()
instance = self._create_fake_instance()
self.compute.prep_resize(context, instance['uuid'], 1,
@@ -1123,13 +1160,32 @@ class ComputeTestCase(BaseTestCase):
def test_finish_revert_resize(self):
"""Ensure that the flavor is reverted to the original on revert"""
context = self.context.elevated()
instance = self._create_fake_instance()
instance_uuid = instance['uuid']
nw_info = fake_network.fake_get_instance_nw_info(self.stubs,
spectacular=True)
def fake(*args, **kwargs):
pass
def fake_nw_info(*args, **kwargs):
return nw_info
# NOTE(jkoelker) There is a bit of a stubbing issue here.
# fake_network stubs out a bunch of stuff which
# this functional test expects to be acting on
# the db or the stubs it sets.
self.stubs.UnsetAll()
self.stubs.SmartUnsetAll()
self.setUp()
self.stubs.Set(self.compute.network_api, 'get_instance_nw_info',
fake_nw_info)
fake_network.stub_out_nw_api_get_instance_nw_info(self.stubs,
func=fake_nw_info)
context = self.context.elevated()
instance = self._create_fake_instance()
instance_uuid = instance['uuid']
self.stubs.Set(self.compute.driver, 'finish_migration', fake)
self.stubs.Set(self.compute.driver, 'finish_revert_migration', fake)
self.stubs.Set(self.compute.network_api, 'get_instance_nw_info', fake)
@@ -1450,7 +1506,14 @@ class ComputeTestCase(BaseTestCase):
class ComputeAPITestCase(BaseTestCase):
def setUp(self):
def fake_get_nw_info(cls, ctxt, instance):
self.assertTrue(ctxt.is_admin)
return fake_network.fake_get_instance_nw_info(self.stubs, 1, 1,
spectacular=True)
super(ComputeAPITestCase, self).setUp()
self.stubs.Set(nova.network.API, 'get_instance_nw_info',
fake_get_nw_info)
self.compute_api = compute.API()
self.fake_image = {
'id': 1,
@@ -2267,17 +2330,9 @@ class ComputeAPITestCase(BaseTestCase):
fixed_address):
called['associate'] = True
def fake_get_nw_info(cls, ctxt, instance):
self.assertTrue(ctxt.is_admin)
return fake_network.fake_get_instance_nw_info(self.stubs, 1, 1,
spectacular=True)
self.stubs.Set(nova.network.API, 'associate_floating_ip',
fake_associate_ip_network_api)
self.stubs.Set(nova.network.API, 'get_instance_nw_info',
fake_get_nw_info)
instance = self._create_fake_instance()
instance_uuid = instance['uuid']
address = '0.1.2.3'
@@ -2995,12 +3050,6 @@ class ComputeAPITestCase(BaseTestCase):
self.assertTrue(self.compute_api.get_lock(self.context, instance))
def test_add_remove_security_group(self):
def fake_get_nw_info(cls, ctxt, instance):
return fake_network.fake_get_instance_nw_info(self.stubs, 1, 1,
spectacular=True)
self.stubs.Set(nova.network.API, 'get_instance_nw_info',
fake_get_nw_info)
instance = self._create_fake_instance()
self.compute.run_instance(self.context, instance['uuid'])
+9
View File
@@ -29,6 +29,7 @@ import nova.image.fake
from nova.compute import utils as compute_utils
from nova.compute import instance_types
from nova.notifier import test_notifier
from nova.tests import fake_network
LOG = logging.getLogger('nova.tests.compute_utils')
@@ -39,7 +40,15 @@ flags.DECLARE('stub_network', 'nova.compute.manager')
class UsageInfoTestCase(test.TestCase):
def setUp(self):
def fake_get_nw_info(cls, ctxt, instance):
self.assertTrue(ctxt.is_admin)
return fake_network.fake_get_instance_nw_info(self.stubs, 1, 1,
spectacular=True)
super(UsageInfoTestCase, self).setUp()
self.stubs.Set(nova.network.API, 'get_instance_nw_info',
fake_get_nw_info)
self.flags(connection_type='fake',
stub_network=True,
notification_driver='nova.notifier.test_notifier',
+2
View File
@@ -16,6 +16,7 @@
import stubout
import nova
import nova.notifier.no_op_notifier
from nova import log
import nova.notifier.api
from nova.notifier.api import notify
@@ -26,6 +27,7 @@ class NotifierTestCase(test.TestCase):
"""Test case for notifications"""
def setUp(self):
super(NotifierTestCase, self).setUp()
self.flags(notification_driver='nova.notifier.no_op_notifier')
self.stubs = stubout.StubOutForTesting()
def tearDown(self):
+2 -1
View File
@@ -46,7 +46,8 @@ class QuotaTestCase(test.TestCase):
quota_cores=4,
quota_volumes=2,
quota_gigabytes=20,
quota_floating_ips=1)
quota_floating_ips=1,
network_manager='nova.network.manager.FlatDHCPManager')
self.network = self.network = self.start_service('network')
self.user_id = 'admin'
+3 -7
View File
@@ -328,13 +328,9 @@ class XenAPIConnection(driver.ComputeDriver):
for iusage in self._vmops.get_all_bw_usage(start_time, stop_time).\
values():
for macaddr, usage in iusage.iteritems():
vi = db.virtual_interface_get_by_address(
context.get_admin_context(),
macaddr)
if vi:
bwusage.append(dict(virtual_interface=vi,
bw_in=usage['bw_in'],
bw_out=usage['bw_out']))
bwusage.append(dict(mac_address=macaddr,
bw_in=usage['bw_in'],
bw_out=usage['bw_out']))
return bwusage
def get_console_output(self, instance):