Skip to content

Commit 73011cf

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Refresh instance network info on deletion" into stable/stein
2 parents acd2daa + 54ec03a commit 73011cf

File tree

3 files changed

+40
-1
lines changed

3 files changed

+40
-1
lines changed

nova/compute/manager.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2615,6 +2615,12 @@ def _shutdown_instance(self, context, instance,
26152615

26162616
network_info = instance.get_network_info()
26172617

2618+
# NOTE(arnaudmorin) to avoid nova destroying the instance without
2619+
# unplugging the interface, refresh network_info if it is empty.
2620+
if not network_info:
2621+
network_info = self.network_api.get_instance_nw_info(
2622+
context, instance)
2623+
26182624
# NOTE(vish) get bdms before destroying the instance
26192625
vol_bdms = [bdm for bdm in bdms if bdm.is_volume]
26202626
block_device_info = self._get_instance_block_device_info(

nova/tests/unit/compute/test_compute_mgr.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4860,6 +4860,39 @@ def test_terminate_instance_no_bdm_volume_id(self, mock_delete_instance,
48604860
mock_delete_instance.assert_called_once_with(
48614861
self.context, instance, bdms)
48624862

4863+
@mock.patch('nova.context.RequestContext.elevated')
4864+
def test_terminate_instance_no_network_info(self, mock_elevated):
4865+
# Tests that we refresh the network info if it was empty
4866+
instance = fake_instance.fake_instance_obj(
4867+
self.context, vm_state=vm_states.ACTIVE)
4868+
empty_nw_info = network_model.NetworkInfo()
4869+
instance.info_cache = objects.InstanceInfoCache(
4870+
network_info=empty_nw_info)
4871+
vif = fake_network_cache_model.new_vif()
4872+
nw_info = network_model.NetworkInfo([vif])
4873+
bdms = objects.BlockDeviceMappingList()
4874+
elevated = context.get_admin_context()
4875+
mock_elevated.return_value = elevated
4876+
4877+
# Call shutdown instance
4878+
with test.nested(
4879+
mock.patch.object(self.compute.network_api, 'get_instance_nw_info',
4880+
return_value=nw_info),
4881+
mock.patch.object(self.compute, '_get_instance_block_device_info'),
4882+
mock.patch.object(self.compute.driver, 'destroy')
4883+
) as (
4884+
mock_nw_api_info, mock_get_bdi, mock_destroy
4885+
):
4886+
self.compute._shutdown_instance(self.context, instance, bdms,
4887+
notify=False, try_deallocate_networks=False)
4888+
4889+
# Verify
4890+
mock_nw_api_info.assert_called_once_with(elevated, instance)
4891+
mock_get_bdi.assert_called_once_with(elevated, instance, bdms=bdms)
4892+
# destroy should have been called with the refresh network_info
4893+
mock_destroy.assert_called_once_with(
4894+
elevated, instance, nw_info, mock_get_bdi.return_value)
4895+
48634896
@mock.patch('nova.compute.utils.notify_about_instance_action')
48644897
@mock.patch.object(nova.compute.manager.ComputeManager,
48654898
'_notify_about_instance_usage')

nova/tests/unit/compute/test_compute_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
def create_instance(context, user_id='fake', project_id='fake', params=None):
6262
"""Create a test instance."""
6363
flavor = flavors.get_flavor_by_name('m1.tiny')
64-
net_info = model.NetworkInfo([])
64+
net_info = model.NetworkInfo([model.VIF(id=uuids.port_id)])
6565
info_cache = objects.InstanceInfoCache(network_info=net_info)
6666
inst = objects.Instance(context=context,
6767
image_ref=uuids.fake_image_ref,

0 commit comments

Comments
 (0)