Merge "Delete ovs port if namespace is corrupted"
This commit is contained in:
commit
5a71695d93
|
@ -19,6 +19,7 @@ import time
|
|||
import netaddr
|
||||
from neutron_lib import constants
|
||||
from oslo_log import log as logging
|
||||
from oslo_utils import excutils
|
||||
import six
|
||||
|
||||
from neutron.agent.common import ovs_lib
|
||||
|
@ -377,8 +378,21 @@ class OVSInterfaceDriver(LinuxInterfaceDriver):
|
|||
|
||||
# Add an interface created by ovs to the namespace.
|
||||
if not self.conf.ovs_use_veth and namespace:
|
||||
namespace_obj = ip.ensure_namespace(namespace)
|
||||
namespace_obj.add_device_to_namespace(ns_dev)
|
||||
try:
|
||||
namespace_obj = ip.ensure_namespace(namespace)
|
||||
namespace_obj.add_device_to_namespace(ns_dev)
|
||||
except exceptions.ProcessExecutionError:
|
||||
# To prevent the namespace failure from blasting
|
||||
# ovs, the ovs port created should be reverted
|
||||
# When the namespace is corrupted, the ProcessExecutionError
|
||||
# has execption message as:
|
||||
# Exit code: 2; Stdin: ; Stdout: ; Stderr: RTNETLINK
|
||||
# answers: Invalid argument
|
||||
LOG.warning("Failed to plug interface %s into bridge %s, "
|
||||
"cleaning up", device_name, bridge)
|
||||
with excutils.save_and_reraise_exception():
|
||||
ovs = ovs_lib.OVSBridge(bridge)
|
||||
ovs.delete_port(tap_name)
|
||||
|
||||
# NOTE(ihrachys): the order here is significant: we must set MTU after
|
||||
# the device is moved into a namespace, otherwise OVS bridge does not
|
||||
|
|
|
@ -15,10 +15,12 @@
|
|||
|
||||
import mock
|
||||
from neutron_lib import constants
|
||||
from oslo_utils import excutils
|
||||
|
||||
from neutron.agent.common import ovs_lib
|
||||
from neutron.agent.linux import interface
|
||||
from neutron.agent.linux import ip_lib
|
||||
from neutron.common import exceptions
|
||||
from neutron.conf.agent import common as config
|
||||
from neutron.tests import base
|
||||
|
||||
|
@ -458,6 +460,32 @@ class TestOVSInterfaceDriver(TestBase):
|
|||
|
||||
self.ip.assert_has_calls(expected)
|
||||
|
||||
def test_plug_new(self):
|
||||
with mock.patch('neutron.agent.ovsdb.impl_idl._connection'):
|
||||
bridge = 'br-int'
|
||||
namespace = '01234567-1234-1234-99'
|
||||
with mock.patch.object(ovs_lib.OVSBridge,
|
||||
'delete_port') as delete_port:
|
||||
with mock.patch.object(ovs_lib.OVSBridge, 'replace_port'):
|
||||
ovs = interface.OVSInterfaceDriver(self.conf)
|
||||
reraise = mock.patch.object(
|
||||
excutils, 'save_and_reraise_exception')
|
||||
reraise.start()
|
||||
proEr = exceptions.ProcessExecutionError('', 2)
|
||||
processExecutionError = mock.Mock(side_effect=proEr)
|
||||
ip = self.ip.return_value
|
||||
ip.ensure_namespace.side_effect = processExecutionError
|
||||
ovs.plug_new(
|
||||
'01234567-1234-1234-99',
|
||||
'port-1234',
|
||||
'tap0',
|
||||
'aa:bb:cc:dd:ee:ff',
|
||||
bridge=bridge,
|
||||
namespace=namespace,
|
||||
prefix='veth',
|
||||
mtu=9000)
|
||||
delete_port.assert_called_once_with('tap0')
|
||||
|
||||
def test_unplug(self, bridge=None):
|
||||
if not bridge:
|
||||
bridge = 'br-int'
|
||||
|
@ -534,6 +562,12 @@ class TestOVSInterfaceDriverWithVeth(TestOVSInterfaceDriver):
|
|||
root_dev.assert_has_calls([mock.call.link.set_up()])
|
||||
ns_dev.assert_has_calls([mock.call.link.set_up()])
|
||||
|
||||
def test_plug_new(self, bridge=None, namespace=None):
|
||||
# The purpose of test_plug_new in parent class(TestOVSInterfaceDriver)
|
||||
# is to test exception(exceptions.ProcessExecutionError), method here
|
||||
# would not go through that code, So just pass
|
||||
pass
|
||||
|
||||
def test_unplug(self, bridge=None):
|
||||
if not bridge:
|
||||
bridge = 'br-int'
|
||||
|
|
Loading…
Reference in New Issue