diff --git a/nova/compute/resource_tracker.py b/nova/compute/resource_tracker.py index e903acc5660b..2c3e15496870 100644 --- a/nova/compute/resource_tracker.py +++ b/nova/compute/resource_tracker.py @@ -1114,8 +1114,14 @@ class ResourceTracker(object): itype = self._get_instance_type(instance, 'old_', migration) numa_topology = self._get_migration_context_resource( 'numa_topology', instance, prefix='old_') - LOG.debug('Starting to track outgoing migration %s with flavor %s', - migration.uuid, itype.flavorid, instance=instance) + # We could be racing with confirm_resize setting the + # instance.old_flavor field to None before the migration status + # is "confirmed" so if we did not find the flavor in the outgoing + # resized instance we won't track it. + if itype: + LOG.debug('Starting to track outgoing migration %s with ' + 'flavor %s', migration.uuid, itype.flavorid, + instance=instance) if itype: cn = self.compute_nodes[nodename] diff --git a/nova/tests/unit/compute/test_resource_tracker.py b/nova/tests/unit/compute/test_resource_tracker.py index 17943e0484a4..f6ed4e5b8323 100644 --- a/nova/tests/unit/compute/test_resource_tracker.py +++ b/nova/tests/unit/compute/test_resource_tracker.py @@ -2761,6 +2761,29 @@ class TestUpdateUsageFromMigration(test.NoDBTestCase): _NODENAME) self.assertFalse(get_mock.called) + def test_missing_old_flavor_outbound_resize(self): + """Tests the case that an instance is not being tracked on the source + host because it has been resized to a dest host. The confirm_resize + operation in ComputeManager sets instance.old_flavor to None before + the migration.status is changed to "confirmed" so the source compute + RT considers it an in-progress migration and tries to update tracked + usage from the instance.old_flavor (which is None when + _update_usage_from_migration runs). This test just makes sure that the + RT method gracefully handles the instance.old_flavor being gone. + """ + migration = _MIGRATION_FIXTURES['source-only'] + rt = resource_tracker.ResourceTracker( + migration.source_compute, mock.sentinel.virt_driver) + ctxt = context.get_admin_context() + instance = objects.Instance( + uuid=migration.instance_uuid, old_flavor=None, + migration_context=objects.MigrationContext()) + rt._update_usage_from_migration( + ctxt, instance, migration, migration.source_node) + self.assertNotIn('Starting to track outgoing migration', + self.stdlog.logger.output) + self.assertNotIn(migration.instance_uuid, rt.tracked_migrations) + class TestUpdateUsageFromMigrations(BaseTestCase): @mock.patch('nova.compute.resource_tracker.ResourceTracker.'