diff options
author | Matt Riedemann <mriedem@us.ibm.com> | 2016-07-12 13:17:34 -0400 |
---|---|---|
committer | Matt Riedemann <mriedem@us.ibm.com> | 2016-07-12 19:00:32 -0400 |
commit | 92a388a1e34559b2ce69d31fdef996ff029495a6 (patch) | |
tree | 4bc3f9350b806d0763cd5c3236c5d3c35d36463f | |
parent | ae9c58792c7a34f129794fa3f1928199bb859b70 (diff) | |
download | nova-92a388a1e34559b2ce69d31fdef996ff029495a6.tar.gz |
neutron: delete VIFs when deallocating networking
In e2eb6659a426bae05a54b93ebf31ff3247125258 we started creating
VirtualInterface objects for instances/ports when allocating
networking in the neutronv2 API code. This is used to support
virtual device tagging.
We need to delete the VIFs when deallocating the networking for
the instance though otherwise we can hit unique constraint failures
when trying to re-use an existing port from one instance to another
since the VIF has a unique constraint on the address which is the
port's MAC and uuid when using neutron.
Change-Id: I2254bad0df3ccc00cd5c9438fa2684e705442e2d
Closes-Bug: #1602357
-rw-r--r-- | nova/network/neutronv2/api.py | 13 | ||||
-rw-r--r-- | nova/tests/unit/network/test_neutronv2.py | 11 |
2 files changed, 23 insertions, 1 deletions
diff --git a/nova/network/neutronv2/api.py b/nova/network/neutronv2/api.py index 4acc275804..cc211e3ca1 100644 --- a/nova/network/neutronv2/api.py +++ b/nova/network/neutronv2/api.py @@ -1033,6 +1033,10 @@ class API(base_api.NetworkAPI): # Delete the rest of the ports self._delete_ports(neutron, instance, ports, raise_if_fail=True) + # deallocate vifs (mac addresses) + objects.VirtualInterface.delete_by_instance_uuid( + context, instance.uuid) + # NOTE(arosen): This clears out the network_cache only if the instance # hasn't already been deleted. This is needed when an instance fails to # launch and is rescheduled onto another compute node. If the instance @@ -1065,6 +1069,15 @@ class API(base_api.NetworkAPI): else: self._delete_ports(neutron, instance, [port_id], raise_if_fail=True) + + # Delete the VirtualInterface for the given port_id. + vif = objects.VirtualInterface.get_by_uuid(context, port_id) + if vif: + vif.destroy() + else: + LOG.debug('VirtualInterface not found for port: %s', + port_id, instance=instance) + return self.get_instance_nw_info(context, instance) def list_ports(self, context, **search_opts): diff --git a/nova/tests/unit/network/test_neutronv2.py b/nova/tests/unit/network/test_neutronv2.py index 287626f899..82b6a61e33 100644 --- a/nova/tests/unit/network/test_neutronv2.py +++ b/nova/tests/unit/network/test_neutronv2.py @@ -3737,7 +3737,9 @@ class TestNeutronv2WithMock(test.TestCase): @mock.patch('nova.network.neutronv2.api.API._unbind_ports') @mock.patch('nova.network.neutronv2.api.API._get_preexisting_port_ids') @mock.patch('nova.network.neutronv2.api.get_client') - def test_preexisting_deallocate_for_instance(self, mock_ntrn, + @mock.patch.object(objects.VirtualInterface, 'delete_by_instance_uuid') + def test_preexisting_deallocate_for_instance(self, mock_delete_vifs, + mock_ntrn, mock_gppids, mock_unbind, mock_deletep, @@ -3772,12 +3774,15 @@ class TestNeutronv2WithMock(test.TestCase): mock_inst, set([uuids.portid_2]), raise_if_fail=True) + mock_delete_vifs.assert_called_once_with(mock.sentinel.ctx, 'inst-1') @mock.patch('nova.network.neutronv2.api.API.get_instance_nw_info') @mock.patch('nova.network.neutronv2.api.API._unbind_ports') @mock.patch('nova.network.neutronv2.api.compute_utils') @mock.patch('nova.network.neutronv2.api.get_client') + @mock.patch.object(objects.VirtualInterface, 'get_by_uuid') def test_preexisting_deallocate_port_for_instance(self, + mock_get_vif_by_uuid, mock_ntrn, mock_comp_utils, mock_unbind, @@ -3791,10 +3796,14 @@ class TestNeutronv2WithMock(test.TestCase): uuid='inst-1') mock_client = mock.Mock() mock_ntrn.return_value = mock_client + mock_vif = mock.MagicMock(spec=objects.VirtualInterface) + mock_get_vif_by_uuid.return_value = mock_vif self.api.deallocate_port_for_instance(mock.sentinel.ctx, mock_inst, '2') mock_unbind.assert_called_once_with(mock.sentinel.ctx, ['2'], mock_client) + mock_get_vif_by_uuid.assert_called_once_with(mock.sentinel.ctx, '2') + mock_vif.destroy.assert_called_once_with() @mock.patch('nova.network.neutronv2.api.API.' '_check_external_network_attach') |