Merge "Handle new hosts for updating instance info in scheduler"

This commit is contained in:
Jenkins 2017-06-03 00:57:34 +00:00 committed by Gerrit Code Review
commit 5d95cb9dbc
4 changed files with 55 additions and 3 deletions

View File

@ -1150,7 +1150,14 @@ class ComputeManager(manager.Manager):
finally:
if CONF.defer_iptables_apply:
self.driver.filter_defer_apply_off()
self._update_scheduler_instance_info(context, instances)
if instances:
# We only send the instance info to the scheduler on startup
# if there is anything to send, otherwise this host might
# not be mapped yet in a cell and the scheduler may have
# issues dealing with the information. Later changes to
# instances on this host will update the scheduler, or the
# _sync_scheduler_instance_info periodic task will.
self._update_scheduler_instance_info(context, instances)
def cleanup_host(self):
self.driver.register_event_listener(None)

View File

@ -706,7 +706,15 @@ class HostManager(object):
self.host_aggregates_map[host]]
def _get_instances_by_host(self, context, host_name):
hm = objects.HostMapping.get_by_host(context, host_name)
try:
hm = objects.HostMapping.get_by_host(context, host_name)
except exception.HostMappingNotFound:
# It's possible to hit this when the compute service first starts
# up and casts to update_instance_info with an empty list but
# before the host is mapped in the API database.
LOG.info('Host mapping not found for host %s. Not tracking '
'instance info for this host.', host_name)
return {}
with context_module.target_cell(context, hm.cell_mapping) as cctxt:
inst_list = objects.InstanceList.get_by_host(cctxt, host_name)
return {inst.uuid: inst for inst in inst_list}

View File

@ -546,7 +546,8 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase):
@mock.patch.object(manager.ComputeManager,
'_destroy_evacuated_instances')
@mock.patch.object(manager.ComputeManager, '_init_instance')
def _do_mock_calls(mock_inst_init,
@mock.patch.object(self.compute, '_update_scheduler_instance_info')
def _do_mock_calls(mock_update_scheduler, mock_inst_init,
mock_destroy, mock_admin_ctxt, mock_host_get,
mock_filter_off, mock_filter_on, mock_init_host,
defer_iptables_apply):
@ -570,6 +571,9 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase):
mock_host_get.assert_called_once_with(self.context, our_host,
expected_attrs=['info_cache', 'metadata'])
mock_update_scheduler.assert_called_once_with(
self.context, inst_list)
# Test with defer_iptables_apply
self.flags(defer_iptables_apply=True)
_do_mock_calls(defer_iptables_apply=True)
@ -578,6 +582,22 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase):
self.flags(defer_iptables_apply=False)
_do_mock_calls(defer_iptables_apply=False)
@mock.patch('nova.objects.InstanceList.get_by_host',
return_value=objects.InstanceList())
@mock.patch('nova.compute.manager.ComputeManager.'
'_destroy_evacuated_instances')
@mock.patch('nova.compute.manager.ComputeManager._init_instance',
mock.NonCallableMock())
@mock.patch('nova.compute.manager.ComputeManager.'
'_update_scheduler_instance_info', mock.NonCallableMock())
def test_init_host_no_instances(self, mock_destroy_evac_instances,
mock_get_by_host):
"""Tests the case that init_host runs and there are no instances
on this host yet (it's brand new). Uses NonCallableMock for the
methods we assert should not be called.
"""
self.compute.init_host()
@mock.patch('nova.objects.InstanceList')
@mock.patch('nova.objects.MigrationList.get_by_filters')
def test_cleanup_host(self, mock_miglist_get, mock_instance_list):

View File

@ -769,6 +769,23 @@ class HostManagerTestCase(test.NoDBTestCase):
self.assertEqual(len(new_info['instances']), len(orig_inst_dict))
self.assertFalse(new_info['updated'])
@mock.patch('nova.objects.HostMapping.get_by_host',
side_effect=exception.HostMappingNotFound(name='host1'))
def test_update_instance_info_unknown_host_mapping_not_found(self,
get_by_host):
"""Tests that case that update_instance_info is called with an
unregistered host so the host manager attempts to recreate the
instance list, but there is no host mapping found for the given
host (it might have just started not be discovered for cells
v2 yet).
"""
ctxt = nova_context.RequestContext()
instance_info = objects.InstanceList()
self.host_manager.update_instance_info(ctxt, 'host1', instance_info)
self.assertDictEqual(
{}, self.host_manager._instance_info['host1']['instances'])
get_by_host.assert_called_once_with(ctxt, 'host1')
def test_delete_instance_info(self):
host_name = 'fake_host'
inst1 = fake_instance.fake_instance_obj('fake_context',