diff --git a/nova/compute/manager.py b/nova/compute/manager.py index e4266fcbdc62..d2d80bc44a67 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -1607,25 +1607,6 @@ class ComputeManager(manager.Manager): network_info = self._allocate_network(context, instance, requested_networks, macs, security_groups, dhcp_options) - if not instance.access_ip_v4 and not instance.access_ip_v6: - # If CONF.default_access_ip_network_name is set, grab the - # corresponding network and set the access ip values accordingly. - # Note that when there are multiple ips to choose from, an - # arbitrary one will be chosen. - network_name = CONF.default_access_ip_network_name - if not network_name: - return network_info - - for vif in network_info: - if vif['network']['label'] == network_name: - for ip in vif.fixed_ips(): - if ip['version'] == 4: - instance.access_ip_v4 = ip['address'] - if ip['version'] == 6: - instance.access_ip_v6 = ip['address'] - instance.save() - break - return network_info def _allocate_network(self, context, instance, requested_networks, macs, @@ -2075,6 +2056,22 @@ class ComputeManager(manager.Manager): # NOTE(alaski): This is only useful during reschedules, remove it now. instance.system_metadata.pop('network_allocated', None) + # If CONF.default_access_ip_network_name is set, grab the + # corresponding network and set the access ip values accordingly. + network_name = CONF.default_access_ip_network_name + if (network_name and not instance.access_ip_v4 and + not instance.access_ip_v6): + # Note that when there are multiple ips to choose from, an + # arbitrary one will be chosen. + for vif in network_info: + if vif['network']['label'] == network_name: + for ip in vif.fixed_ips(): + if not instance.access_ip_v4 and ip['version'] == 4: + instance.access_ip_v4 = ip['address'] + if not instance.access_ip_v6 and ip['version'] == 6: + instance.access_ip_v6 = ip['address'] + break + self._update_instance_after_spawn(context, instance) try: diff --git a/nova/tests/unit/compute/test_compute_mgr.py b/nova/tests/unit/compute/test_compute_mgr.py index 8dc65d695825..1132584a3019 100644 --- a/nova/tests/unit/compute/test_compute_mgr.py +++ b/nova/tests/unit/compute/test_compute_mgr.py @@ -20,6 +20,7 @@ from cinderclient import exceptions as cinder_exception from eventlet import event as eventlet_event import mock from mox3 import mox +import netaddr from oslo_config import cfg import oslo_messaging as messaging from oslo_utils import importutils @@ -46,6 +47,7 @@ from nova import test from nova.tests.unit.compute import fake_resource_tracker from nova.tests.unit import fake_block_device from nova.tests.unit import fake_instance +from nova.tests.unit import fake_network from nova.tests.unit import fake_network_cache_model from nova.tests.unit import fake_server_actions from nova.tests.unit.objects import test_instance_fault @@ -3830,6 +3832,41 @@ class ComputeManagerBuildInstanceTestCase(test.NoDBTestCase): mock_notify.call_count - 1] self.assertEqual(expected_call, create_end_call) + def test_access_ip_set_when_instance_set_to_active(self): + + self.flags(default_access_ip_network_name='test1') + instance = fake_instance.fake_db_instance() + + @mock.patch.object(db, 'instance_update_and_get_original', + return_value=({}, instance)) + @mock.patch.object(self.compute.driver, 'spawn') + @mock.patch.object(self.compute, '_build_networks_for_instance', + return_value=fake_network.fake_get_instance_nw_info( + self.stubs)) + @mock.patch.object(db, 'instance_extra_update_by_uuid') + @mock.patch.object(self.compute, '_notify_about_instance_usage') + def _check_access_ip(mock_notify, mock_extra, mock_networks, + mock_spawn, mock_db_update): + self.compute._build_and_run_instance(self.context, self.instance, + self.image, self.injected_files, self.admin_pass, + self.requested_networks, self.security_groups, + self.block_device_mapping, self.node, self.limits, + self.filter_properties) + + updates = {'vm_state': u'active', 'access_ip_v6': + netaddr.IPAddress('2001:db8:0:1:dcad:beff:feef:1'), + 'access_ip_v4': netaddr.IPAddress('192.168.1.100'), + 'power_state': 0, 'task_state': None, 'launched_at': + mock.ANY, 'expected_task_state': 'spawning'} + expected_call = mock.call(self.context, self.instance.uuid, + updates, columns_to_join=['metadata', 'system_metadata', + 'info_cache']) + last_update_call = mock_db_update.call_args_list[ + mock_db_update.call_count - 1] + self.assertEqual(expected_call, last_update_call) + + _check_access_ip() + @mock.patch.object(manager.ComputeManager, '_instance_update') def test_create_end_on_instance_delete(self, mock_instance_update):