Merge "Call DVR VMARP notify outside of transaction"

This commit is contained in:
Jenkins 2014-10-15 17:09:16 +00:00 committed by Gerrit Code Review
commit 54874ed763
4 changed files with 28 additions and 7 deletions

View File

@ -538,13 +538,12 @@ class L3_NAT_with_dvr_db_mixin(l3_db.L3_NAT_db_mixin,
self._populate_subnet_for_ports(context, port_list) self._populate_subnet_for_ports(context, port_list)
return port_list return port_list
def dvr_vmarp_table_update(self, context, port_id, action): def dvr_vmarp_table_update(self, context, port_dict, action):
"""Notify the L3 agent of VM ARP table changes. """Notify the L3 agent of VM ARP table changes.
Provide the details of the VM ARP to the L3 agent when Provide the details of the VM ARP to the L3 agent when
a Nova instance gets created or deleted. a Nova instance gets created or deleted.
""" """
port_dict = self._core_plugin._get_port(context, port_id)
# Check this is a valid VM port # Check this is a valid VM port
if ("compute:" not in port_dict['device_owner'] or if ("compute:" not in port_dict['device_owner'] or
not port_dict['fixed_ips']): not port_dict['fixed_ips']):

View File

@ -1011,8 +1011,6 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
if l3plugin: if l3plugin:
router_ids = l3plugin.disassociate_floatingips( router_ids = l3plugin.disassociate_floatingips(
context, id, do_notify=False) context, id, do_notify=False)
if is_dvr_enabled:
l3plugin.dvr_vmarp_table_update(context, id, "del")
LOG.debug("Calling delete_port for %(port_id)s owned by %(owner)s" LOG.debug("Calling delete_port for %(port_id)s owned by %(owner)s"
% {"port_id": id, "owner": device_owner}) % {"port_id": id, "owner": device_owner})
@ -1020,6 +1018,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
# now that we've left db transaction, we are safe to notify # now that we've left db transaction, we are safe to notify
if l3plugin: if l3plugin:
if is_dvr_enabled:
l3plugin.dvr_vmarp_table_update(context, port, "del")
l3plugin.notify_routers_updated(context, router_ids) l3plugin.notify_routers_updated(context, router_ids)
for router in removed_routers: for router in removed_routers:
try: try:

View File

@ -165,7 +165,8 @@ class RpcCallbacks(n_rpc.RpcCallback,
utils.is_extension_supported(l3plugin, utils.is_extension_supported(l3plugin,
q_const.L3_DISTRIBUTED_EXT_ALIAS)): q_const.L3_DISTRIBUTED_EXT_ALIAS)):
try: try:
l3plugin.dvr_vmarp_table_update(rpc_context, port_id, "add") port = plugin._get_port(rpc_context, port_id)
l3plugin.dvr_vmarp_table_update(rpc_context, port, "add")
except exceptions.PortNotFound: except exceptions.PortNotFound:
LOG.debug('Port %s not found during ARP update', port_id) LOG.debug('Port %s not found during ARP update', port_id)

View File

@ -988,9 +988,9 @@ class TestFaultyMechansimDriver(Ml2PluginV2FaultyDriverTestCase):
self._delete('ports', port['port']['id']) self._delete('ports', port['port']['id'])
class TestMl2PluginCreateUpdatePort(base.BaseTestCase): class TestMl2PluginCreateUpdateDeletePort(base.BaseTestCase):
def setUp(self): def setUp(self):
super(TestMl2PluginCreateUpdatePort, self).setUp() super(TestMl2PluginCreateUpdateDeletePort, self).setUp()
self.context = mock.MagicMock() self.context = mock.MagicMock()
def _ensure_transaction_is_closed(self): def _ensure_transaction_is_closed(self):
@ -1043,3 +1043,24 @@ class TestMl2PluginCreateUpdatePort(base.BaseTestCase):
plugin._notify_l3_agent_new_port.assert_called_once_with( plugin._notify_l3_agent_new_port.assert_called_once_with(
self.context, new_host_port) self.context, new_host_port)
def test_vmarp_table_update_outside_of_delete_transaction(self):
l3plugin = mock.Mock()
l3plugin.dvr_vmarp_table_update = (
lambda *args, **kwargs: self._ensure_transaction_is_closed())
l3plugin.dvr_deletens_if_no_port.return_value = []
l3plugin.supported_extension_aliases = [
'router', constants.L3_AGENT_SCHEDULER_EXT_ALIAS,
constants.L3_DISTRIBUTED_EXT_ALIAS
]
with contextlib.nested(
mock.patch.object(ml2_plugin.Ml2Plugin, '__init__',
return_value=None),
mock.patch.object(manager.NeutronManager,
'get_service_plugins',
return_value={'L3_ROUTER_NAT': l3plugin}),
):
plugin = self._create_plugin_for_create_update_port(mock.Mock())
# deleting the port will call dvr_vmarp_table_update, which will
# run the transaction balancing function defined in this test
plugin.delete_port(self.context, 'fake_id')