Merge "Resource tracker: improve resource tracker periodic task"
This commit is contained in:
commit
503025873c
|
@ -685,8 +685,7 @@ class ResourceTracker(object):
|
|||
|
||||
self._update_available_resource(context, resources)
|
||||
|
||||
def _pair_instances_to_migrations(self, migrations, instances):
|
||||
instance_by_uuid = {inst.uuid: inst for inst in instances}
|
||||
def _pair_instances_to_migrations(self, migrations, instance_by_uuid):
|
||||
for migration in migrations:
|
||||
try:
|
||||
migration.instance = instance_by_uuid[migration.instance_uuid]
|
||||
|
@ -724,17 +723,19 @@ class ResourceTracker(object):
|
|||
'flavor', 'migration_context'])
|
||||
|
||||
# Now calculate usage based on instance utilization:
|
||||
self._update_usage_from_instances(context, instances, nodename)
|
||||
instance_by_uuid = self._update_usage_from_instances(
|
||||
context, instances, nodename)
|
||||
|
||||
# Grab all in-progress migrations:
|
||||
migrations = objects.MigrationList.get_in_progress_by_host_and_node(
|
||||
context, self.host, nodename)
|
||||
|
||||
self._pair_instances_to_migrations(migrations, instances)
|
||||
self._pair_instances_to_migrations(migrations, instance_by_uuid)
|
||||
self._update_usage_from_migrations(context, migrations, nodename)
|
||||
|
||||
self._remove_deleted_instances_allocations(
|
||||
context, self.compute_nodes[nodename], migrations)
|
||||
context, self.compute_nodes[nodename], migrations,
|
||||
instance_by_uuid)
|
||||
|
||||
# Detect and account for orphaned instances that may exist on the
|
||||
# hypervisor, but are not in the DB:
|
||||
|
@ -1228,7 +1229,7 @@ class ResourceTracker(object):
|
|||
msg_allocation_refresh += (
|
||||
"Will auto-correct allocations to handle "
|
||||
"Ocata-style assumptions.")
|
||||
|
||||
instance_by_uuid = {}
|
||||
for instance in instances:
|
||||
if instance.vm_state not in vm_states.ALLOW_RESOURCE_REMOVAL:
|
||||
if msg_allocation_refresh:
|
||||
|
@ -1236,9 +1237,11 @@ class ResourceTracker(object):
|
|||
msg_allocation_refresh = False
|
||||
self._update_usage_from_instance(context, instance, nodename,
|
||||
require_allocation_refresh=require_allocation_refresh)
|
||||
instance_by_uuid[instance.uuid] = instance
|
||||
return instance_by_uuid
|
||||
|
||||
def _remove_deleted_instances_allocations(self, context, cn,
|
||||
migrations):
|
||||
migrations, instance_by_uuid):
|
||||
migration_uuids = [migration.uuid for migration in migrations
|
||||
if 'uuid' in migration]
|
||||
# NOTE(jaypipes): All of this code sucks. It's basically dealing with
|
||||
|
@ -1264,22 +1267,25 @@ class ResourceTracker(object):
|
|||
|
||||
# We know these are instances now, so proceed
|
||||
instance_uuid = consumer_uuid
|
||||
try:
|
||||
instance = objects.Instance.get_by_uuid(read_deleted_context,
|
||||
instance_uuid,
|
||||
expected_attrs=[])
|
||||
except exception.InstanceNotFound:
|
||||
# The instance isn't even in the database. Either the scheduler
|
||||
# _just_ created an allocation for it and we're racing with the
|
||||
# creation in the cell database, or the instance was deleted
|
||||
# and fully archived before we got a chance to run this. The
|
||||
# former is far more likely than the latter. Avoid deleting
|
||||
# allocations for a building instance here.
|
||||
LOG.info("Instance %(uuid)s has allocations against this "
|
||||
"compute host but is not found in the database.",
|
||||
{'uuid': instance_uuid},
|
||||
exc_info=False)
|
||||
continue
|
||||
instance = instance_by_uuid.get(instance_uuid)
|
||||
if not instance:
|
||||
try:
|
||||
instance = objects.Instance.get_by_uuid(
|
||||
read_deleted_context, consumer_uuid,
|
||||
expected_attrs=[])
|
||||
except exception.InstanceNotFound:
|
||||
# The instance isn't even in the database. Either the
|
||||
# scheduler _just_ created an allocation for it and we're
|
||||
# racing with the creation in the cell database, or the
|
||||
# instance was deleted and fully archived before we got a
|
||||
# chance to run this. The former is far more likely than
|
||||
# the latter. Avoid deleting allocations for a building
|
||||
# instance here.
|
||||
LOG.info("Instance %(uuid)s has allocations against this "
|
||||
"compute host but is not found in the database.",
|
||||
{'uuid': instance_uuid},
|
||||
exc_info=False)
|
||||
continue
|
||||
|
||||
if instance.deleted:
|
||||
# The instance is gone, so we definitely want to remove
|
||||
|
|
|
@ -2666,7 +2666,7 @@ class TestUpdateUsageFromInstance(BaseTestCase):
|
|||
cn = self.rt.compute_nodes[_NODENAME]
|
||||
ctx = mock.MagicMock()
|
||||
# Call the method.
|
||||
self.rt._remove_deleted_instances_allocations(ctx, cn, [])
|
||||
self.rt._remove_deleted_instances_allocations(ctx, cn, [], {})
|
||||
# Only one call should be made to delete allocations, and that should
|
||||
# be for the first instance created above
|
||||
rc.delete_allocation_for_instance.assert_called_once_with(
|
||||
|
@ -2691,7 +2691,7 @@ class TestUpdateUsageFromInstance(BaseTestCase):
|
|||
cn = self.rt.compute_nodes[_NODENAME]
|
||||
ctx = mock.MagicMock()
|
||||
# Call the method.
|
||||
self.rt._remove_deleted_instances_allocations(ctx, cn, [])
|
||||
self.rt._remove_deleted_instances_allocations(ctx, cn, [], {})
|
||||
# Instance wasn't found in the database at all, so the allocation
|
||||
# should not have been deleted
|
||||
self.assertFalse(rc.delete_allocation_for_instance.called)
|
||||
|
@ -2713,7 +2713,8 @@ class TestUpdateUsageFromInstance(BaseTestCase):
|
|||
ctx = mock.MagicMock()
|
||||
# Call the method.
|
||||
self.rt._remove_deleted_instances_allocations(
|
||||
ctx, cn, [mig])
|
||||
ctx, cn, [mig], {uuids.migration:
|
||||
objects.Instance(uuid=uuids.imigration)})
|
||||
# Only one call should be made to delete allocations, and that should
|
||||
# be for the first instance created above
|
||||
rc.delete_allocation_for_instance.assert_called_once_with(
|
||||
|
@ -2728,18 +2729,14 @@ class TestUpdateUsageFromInstance(BaseTestCase):
|
|||
rc.get_allocations_for_resource_provider = mock.MagicMock(
|
||||
return_value=allocs)
|
||||
rc.delete_allocation_for_instance = mock.MagicMock()
|
||||
|
||||
def get_by_uuid(ctx, inst_uuid, expected_attrs=None):
|
||||
ret = _INSTANCE_FIXTURES[0].obj_clone()
|
||||
ret.uuid = inst_uuid
|
||||
ret.host = None # This indicates the instance is being scheduled
|
||||
return ret
|
||||
|
||||
mock_inst_get.side_effect = get_by_uuid
|
||||
instance_by_uuid = {uuids.scheduled:
|
||||
objects.Instance(uuid=uuids.scheduled,
|
||||
deleted=False, host=None)}
|
||||
cn = self.rt.compute_nodes[_NODENAME]
|
||||
ctx = mock.MagicMock()
|
||||
# Call the method.
|
||||
self.rt._remove_deleted_instances_allocations(ctx, cn, [])
|
||||
self.rt._remove_deleted_instances_allocations(ctx, cn, [],
|
||||
instance_by_uuid)
|
||||
# Scheduled instances should not have their allocations removed
|
||||
rc.delete_allocation_for_instance.assert_not_called()
|
||||
|
||||
|
@ -2767,7 +2764,7 @@ class TestUpdateUsageFromInstance(BaseTestCase):
|
|||
|
||||
cn = self.rt.compute_nodes[_NODENAME]
|
||||
ctx = mock.MagicMock()
|
||||
self.rt._remove_deleted_instances_allocations(ctx, cn, [])
|
||||
self.rt._remove_deleted_instances_allocations(ctx, cn, [], mock.ANY)
|
||||
mock_delete_allocs.assert_not_called()
|
||||
|
||||
def test_remove_deleted_instances_allocations_known_instance(self):
|
||||
|
@ -2792,7 +2789,8 @@ class TestUpdateUsageFromInstance(BaseTestCase):
|
|||
cn = self.rt.compute_nodes[_NODENAME]
|
||||
ctx = mock.MagicMock()
|
||||
# Call the method.
|
||||
self.rt._remove_deleted_instances_allocations(ctx, cn, [])
|
||||
self.rt._remove_deleted_instances_allocations(ctx, cn, [],
|
||||
self.rt.tracked_instances)
|
||||
# We don't delete the allocation because the node is tracking the
|
||||
# instance and has allocations for it.
|
||||
rc.delete_allocation_for_instance.assert_not_called()
|
||||
|
@ -2826,7 +2824,8 @@ class TestUpdateUsageFromInstance(BaseTestCase):
|
|||
cn = self.rt.compute_nodes[_NODENAME]
|
||||
ctx = mock.MagicMock()
|
||||
# Call the method.
|
||||
self.rt._remove_deleted_instances_allocations(ctx, cn, [])
|
||||
self.rt._remove_deleted_instances_allocations(
|
||||
ctx, cn, [], self.rt.tracked_instances)
|
||||
# We don't delete the allocation because we're not sure what to do.
|
||||
# NOTE(mriedem): This is not actually the behavior we want. This is
|
||||
# testing the current behavior but in the future when we get smart
|
||||
|
|
Loading…
Reference in New Issue