ml2: Add original port to context on _bind_port

During portbinding a new PortContext with the binding information
for the new host gets created. This patch adds the original
port to the newly created context. This has the following effects

- When the port was not bound before, context.original will be set
  set to None on portbinding.

- When the port was bound before (also if binding failed before)
  context.original is set to this port dict on portbinding. This
  happens mostly in the following scenarios:

  - Nova triggers a reschedule of an instance
    Nova reschedules an instance to another host, after spawning an
    instance on the first host failed for some reason. In this case,
    context.original is set to the port with the binding information
    as it was on the failed host.

  - Live Migration
    The port is now available on another host. context.original is
    set to the port and binding information of the source host.

Context.original can now be used in mechanism drivers that need to be
migration aware. This is the case for the macvtap mechanism driver.
The corresponding functionality will be added with patch [1].

[1] https://review.openstack.org/#/c/361301

Partial-Bug: #1550400

Change-Id: I2b60243366505f6e6e4c716d627255a56a4ba486
This commit is contained in:
Andreas Scheuring 2016-08-29 13:31:17 +02:00 committed by Gary Kotton
parent b2399d847a
commit 69d7363030
2 changed files with 16 additions and 1 deletions

View File

@ -421,7 +421,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
self._update_port_dict_binding(port, new_binding)
new_context = driver_context.PortContext(
self, orig_context._plugin_context, port,
orig_context.network.current, new_binding, None)
orig_context.network.current, new_binding, None,
original_port=orig_context.original)
# Attempt to bind the port and return the context with the
# result.

View File

@ -1707,6 +1707,20 @@ class TestMl2PortBinding(Ml2PluginV2TestCase,
self.context, 'foo_port_id', {'port': port})
self.assertFalse(mock_dist.called)
def test__bind_port_original_port_set(self):
plugin = directory.get_plugin()
plugin.mechanism_manager = mock.Mock()
mock_port = {'id': 'port_id'}
context = mock.Mock()
context.network.current = {'id': 'net_id'}
context.original = mock_port
with mock.patch.object(plugin, '_update_port_dict_binding'), \
mock.patch.object(segments_db, 'get_network_segments',
return_value=[]):
new_context = plugin._bind_port(context)
self.assertEqual(mock_port, new_context.original)
self.assertFalse(new_context == context)
class TestMl2PortBindingNoSG(TestMl2PortBinding):
HAS_PORT_FILTER = False