Merge "Invalidate AZ cache when the instance AZ information is different"

This commit is contained in:
Jenkins 2015-09-14 05:44:39 +00:00 committed by Gerrit Code Review
commit e70ff282f8
3 changed files with 34 additions and 3 deletions

View File

@ -178,6 +178,20 @@ def get_instance_availability_zone(context, instance):
cache_key = _make_cache_key(host)
cache = _get_cache()
az = cache.get(cache_key)
az_inst = instance.get('availability_zone')
if az_inst is not None and az != az_inst:
# NOTE(sbauza): Cache is wrong, we need to invalidate it by fetching
# again the right AZ related to the aggregate the host belongs to.
# As the API is also calling this method for setting the instance
# AZ field, we don't need to update the instance.az field.
# This case can happen because the cache is populated before the
# instance has been assigned to the host so that it would keep the
# former reference which was incorrect. Instead of just taking the
# instance AZ information for refilling the cache, we prefer to
# invalidate the cache and fetch it again because there could be some
# corner cases where this method could be called before the instance
# has been assigned to the host also.
az = None
if not az:
elevated = context.elevated()
az = get_host_availability_zone(elevated, host)

View File

@ -17,6 +17,7 @@
Tests for availability zones
"""
import mock
from oslo_config import cfg
import six
@ -239,7 +240,8 @@ class AvailabilityZoneTestCases(test.TestCase):
def test_get_instance_availability_zone_default_value(self):
"""Test get right availability zone by given an instance."""
fake_inst = objects.Instance(host=self.host)
fake_inst = objects.Instance(host=self.host,
availability_zone=None)
self.assertEqual(self.default_az,
az.get_instance_availability_zone(self.context, fake_inst))
@ -250,11 +252,25 @@ class AvailabilityZoneTestCases(test.TestCase):
service = self._create_service_with_topic('compute', host)
self._add_to_aggregate(service, self.agg)
fake_inst = objects.Instance(host=host)
fake_inst = objects.Instance(host=host,
availability_zone=self.availability_zone)
self.assertEqual(self.availability_zone,
az.get_instance_availability_zone(self.context, fake_inst))
@mock.patch.object(az._get_cache(), 'get')
def test_get_instance_availability_zone_cache_differs(self, cache_get):
host = 'host170'
service = self._create_service_with_topic('compute', host)
self._add_to_aggregate(service, self.agg)
cache_get.return_value = self.default_az
fake_inst = objects.Instance(host=host,
availability_zone=self.availability_zone)
self.assertEqual(
self.availability_zone,
az.get_instance_availability_zone(self.context, fake_inst))
def test_get_instance_availability_zone_no_host(self):
"""Test get availability zone from instance if host not set."""
fake_inst = objects.Instance(host=None, availability_zone='inst-az')

View File

@ -83,7 +83,8 @@ def fake_inst_obj(context):
metadata={},
default_ephemeral_device=None,
default_swap_device=None,
system_metadata={})
system_metadata={},
availability_zone=None)
nwinfo = network_model.NetworkInfo([])
inst.info_cache = objects.InstanceInfoCache(context=context,
instance_uuid=inst.uuid,