Merge "Delete port bindings in setup_networks_on_host if teardown=True"
This commit is contained in:
commit
89cd39e08d
@ -368,7 +368,23 @@ class API(base_api.NetworkAPI):
|
||||
|
||||
def setup_networks_on_host(self, context, instance, host=None,
|
||||
teardown=False):
|
||||
"""Setup or teardown the network structures."""
|
||||
"""Setup or teardown the network structures.
|
||||
|
||||
:param context: The user request context.
|
||||
:param instance: The instance with attached ports.
|
||||
:param host: Optional host used to control the setup. If provided and
|
||||
is not the same as the current instance.host, this method assumes
|
||||
the instance is being migrated and sets the "migrating_to"
|
||||
attribute in the binding profile for the attached ports.
|
||||
:param teardown: Whether or not network information for the ports
|
||||
should be cleaned up. If True, at a minimum the "migrating_to"
|
||||
attribute is cleared in the binding profile for the ports. If a
|
||||
host is also provided, then port bindings for that host are
|
||||
deleted when teardown is True as long as the host does not match
|
||||
the current instance.host.
|
||||
:raises: nova.exception.PortBindingDeletionFailed if host is not None,
|
||||
teardown is True, and port binding deletion fails.
|
||||
"""
|
||||
# Check if the instance is migrating to a new host.
|
||||
port_migrating = host and (instance.host != host)
|
||||
# If the port is migrating to a new host or if it is a
|
||||
@ -386,6 +402,16 @@ class API(base_api.NetworkAPI):
|
||||
# Reset the port profile
|
||||
self._clear_migration_port_profile(
|
||||
context, instance, admin_client, ports)
|
||||
# If a host was provided, delete any bindings between that
|
||||
# host and the ports as long as the host isn't the same as
|
||||
# the current instance.host.
|
||||
has_binding_ext = self.supports_port_binding_extension(context)
|
||||
if port_migrating and has_binding_ext:
|
||||
for port in ports:
|
||||
# This call is safe in that 404s for non-existing
|
||||
# bindings are ignored.
|
||||
self.delete_port_binding(
|
||||
context, port['id'], host)
|
||||
elif port_migrating:
|
||||
# Setup the port profile
|
||||
self._setup_migration_port_profile(
|
||||
|
@ -4354,7 +4354,7 @@ class TestNeutronv2WithMock(_TestNeutronv2Common):
|
||||
|
||||
instance = fake_instance.fake_instance_obj(self.context)
|
||||
self.api._has_port_binding_extension = mock.Mock(return_value=True)
|
||||
migrate_profile = {neutronapi.MIGRATING_ATTR: instance.host}
|
||||
migrate_profile = {neutronapi.MIGRATING_ATTR: 'new-host'}
|
||||
# Pass a port with an migration porfile attribute.
|
||||
port_id = uuids.port_id
|
||||
get_ports = {'ports': [
|
||||
@ -4364,12 +4364,53 @@ class TestNeutronv2WithMock(_TestNeutronv2Common):
|
||||
self.api.list_ports = mock.Mock(return_value=get_ports)
|
||||
update_port_mock = mock.Mock()
|
||||
get_client_mock.return_value.update_port = update_port_mock
|
||||
self.api.setup_networks_on_host(self.context,
|
||||
instance,
|
||||
host=instance.host,
|
||||
teardown=True)
|
||||
with mock.patch.object(self.api, 'delete_port_binding') as del_binding:
|
||||
with mock.patch.object(self.api, 'supports_port_binding_extension',
|
||||
return_value=True):
|
||||
self.api.setup_networks_on_host(self.context,
|
||||
instance,
|
||||
host='new-host',
|
||||
teardown=True)
|
||||
update_port_mock.assert_called_once_with(
|
||||
port_id, {'port': {neutronapi.BINDING_PROFILE: migrate_profile}})
|
||||
del_binding.assert_called_once_with(
|
||||
self.context, port_id, 'new-host')
|
||||
|
||||
@mock.patch.object(neutronapi, 'get_client', return_value=mock.Mock())
|
||||
def test_update_port_profile_for_migration_teardown_true_with_profile_exc(
|
||||
self, get_client_mock):
|
||||
"""Tests that delete_port_binding raises PortBindingDeletionFailed
|
||||
which is raised through to the caller.
|
||||
"""
|
||||
instance = fake_instance.fake_instance_obj(self.context)
|
||||
self.api._has_port_binding_extension = mock.Mock(return_value=True)
|
||||
migrate_profile = {neutronapi.MIGRATING_ATTR: 'new-host'}
|
||||
# Pass a port with an migration porfile attribute.
|
||||
get_ports = {
|
||||
'ports': [
|
||||
{'id': uuids.port1,
|
||||
neutronapi.BINDING_PROFILE: migrate_profile,
|
||||
neutronapi.BINDING_HOST_ID: instance.host},
|
||||
{'id': uuids.port2,
|
||||
neutronapi.BINDING_PROFILE: migrate_profile,
|
||||
neutronapi.BINDING_HOST_ID: instance.host}]}
|
||||
self.api.list_ports = mock.Mock(return_value=get_ports)
|
||||
self.api._clear_migration_port_profile = mock.Mock()
|
||||
with mock.patch.object(
|
||||
self.api, 'delete_port_binding',
|
||||
side_effect=exception.PortBindingDeletionFailed(
|
||||
port_id=uuids.port1, host='new-host')) as del_binding:
|
||||
with mock.patch.object(self.api, 'supports_port_binding_extension',
|
||||
return_value=True):
|
||||
self.assertRaises(exception.PortBindingDeletionFailed,
|
||||
self.api.setup_networks_on_host,
|
||||
self.context, instance, host='new-host',
|
||||
teardown=True)
|
||||
self.api._clear_migration_port_profile.assert_called_once_with(
|
||||
self.context, instance, get_client_mock.return_value,
|
||||
get_ports['ports'])
|
||||
del_binding.assert_called_once_with(
|
||||
self.context, uuids.port1, 'new-host')
|
||||
|
||||
@mock.patch.object(neutronapi, 'get_client', return_value=mock.Mock())
|
||||
def test_update_port_profile_for_migration_teardown_true_no_profile(
|
||||
@ -4384,10 +4425,12 @@ class TestNeutronv2WithMock(_TestNeutronv2Common):
|
||||
self.api.list_ports = mock.Mock(return_value=get_ports)
|
||||
update_port_mock = mock.Mock()
|
||||
get_client_mock.return_value.update_port = update_port_mock
|
||||
self.api.setup_networks_on_host(self.context,
|
||||
instance,
|
||||
host=instance.host,
|
||||
teardown=True)
|
||||
with mock.patch.object(self.api, 'supports_port_binding_extension',
|
||||
return_value=False):
|
||||
self.api.setup_networks_on_host(self.context,
|
||||
instance,
|
||||
host=instance.host,
|
||||
teardown=True)
|
||||
update_port_mock.assert_not_called()
|
||||
|
||||
def test__update_port_with_migration_profile_raise_exception(self):
|
||||
|
Loading…
x
Reference in New Issue
Block a user