diff --git a/nova/conductor/manager.py b/nova/conductor/manager.py index 1409720c914c..0240e62fafb9 100644 --- a/nova/conductor/manager.py +++ b/nova/conductor/manager.py @@ -1214,6 +1214,7 @@ class ComputeTaskManager(base.Base): host_mapping_cache = {} cell_mapping_cache = {} instances = [] + host_az = {} # host=az cache to optimize multi-create for (build_request, request_spec, host_list) in six.moves.zip( build_requests, request_specs, host_lists): @@ -1259,9 +1260,11 @@ class ComputeTaskManager(base.Base): rc.delete_allocation_for_instance(context, instance.uuid) continue else: - instance.availability_zone = ( - availability_zones.get_host_availability_zone( - context, host.service_host)) + if host.service_host not in host_az: + host_az[host.service_host] = ( + availability_zones.get_host_availability_zone( + context, host.service_host)) + instance.availability_zone = host_az[host.service_host] with obj_target_cell(instance, cell): instance.create() instances.append(instance) diff --git a/nova/tests/unit/conductor/test_conductor.py b/nova/tests/unit/conductor/test_conductor.py index 9e2ea4a455eb..84df38f9a2e3 100644 --- a/nova/tests/unit/conductor/test_conductor.py +++ b/nova/tests/unit/conductor/test_conductor.py @@ -1626,7 +1626,9 @@ class ConductorTaskTestCase(_BaseTaskTestCase, test_compute.BaseTestCase): @mock.patch('nova.compute.rpcapi.ComputeAPI.build_and_run_instance') @mock.patch('nova.scheduler.rpcapi.SchedulerAPI.select_destinations') @mock.patch('nova.objects.HostMapping.get_by_host') - def test_schedule_and_build_multiple_instances(self, + @mock.patch('nova.availability_zones.get_host_availability_zone', + return_value='nova') + def test_schedule_and_build_multiple_instances(self, mock_get_az, get_hostmapping, select_destinations, build_and_run_instance): @@ -1679,6 +1681,11 @@ class ConductorTaskTestCase(_BaseTaskTestCase, test_compute.BaseTestCase): build_and_run_instance.side_effect = _build_and_run_instance self.conductor.schedule_and_build_instances(**params) self.assertEqual(3, build_and_run_instance.call_count) + # We're processing 4 instances over 2 hosts, so we should only lookup + # the AZ per host once. + mock_get_az.assert_has_calls([ + mock.call(self.ctxt, 'host1'), mock.call(self.ctxt, 'host2')], + any_order=True) @mock.patch('nova.compute.rpcapi.ComputeAPI.build_and_run_instance') @mock.patch('nova.scheduler.rpcapi.SchedulerAPI.select_destinations')