OVSInterfaceDriver.plug_new should catch correct exceptions

Now that "IPWrapper.add_device_to_namespace" is implemented with
Pyroute2, the function should catch the correct exceptions:
- NetlinkError in case of duplicated interface
- OSError in case of corrupted namespace

Change-Id: I12b5710dc3bfdcc4c6b1e96bbfbfab9e59684065
Closes-Bug: #1856853
This commit is contained in:
Rodolfo Alonso Hernandez 2019-12-18 15:10:23 +00:00
parent 33919fbd50
commit e54b64f725
2 changed files with 23 additions and 22 deletions

View File

@ -21,6 +21,7 @@ from neutron_lib import constants
from neutron_lib import exceptions from neutron_lib import exceptions
from oslo_log import log as logging from oslo_log import log as logging
from oslo_utils import excutils from oslo_utils import excutils
from pyroute2.netlink import exceptions as pyroute2_exc
import six import six
from neutron.agent.common import ovs_lib from neutron.agent.common import ovs_lib
@ -379,13 +380,11 @@ class OVSInterfaceDriver(LinuxInterfaceDriver):
try: try:
namespace_obj = ip.ensure_namespace(namespace) namespace_obj = ip.ensure_namespace(namespace)
namespace_obj.add_device_to_namespace(ns_dev) namespace_obj.add_device_to_namespace(ns_dev)
except exceptions.ProcessExecutionError: except (pyroute2_exc.NetlinkError, OSError):
# To prevent the namespace failure from blasting # To prevent the namespace failure from blasting OVS, the OVS
# ovs, the ovs port created should be reverted # port creation should be reverted. Possible exceptions:
# When the namespace is corrupted, the ProcessExecutionError # - NetlinkError in case of duplicated interface
# has execption message as: # - OSError in case of corrupted namespace
# Exit code: 2; Stdin: ; Stdout: ; Stderr: RTNETLINK
# answers: Invalid argument
LOG.warning("Failed to plug interface %s into bridge %s, " LOG.warning("Failed to plug interface %s into bridge %s, "
"cleaning up", device_name, bridge) "cleaning up", device_name, bridge)
with excutils.save_and_reraise_exception(): with excutils.save_and_reraise_exception():

View File

@ -15,8 +15,8 @@
import mock import mock
from neutron_lib import constants from neutron_lib import constants
from neutron_lib import exceptions
from oslo_utils import excutils from oslo_utils import excutils
from pyroute2.netlink import exceptions as pyroute2_exc
from neutron.agent.common import ovs_lib from neutron.agent.common import ovs_lib
from neutron.agent.linux import interface from neutron.agent.linux import interface
@ -476,20 +476,22 @@ class TestOVSInterfaceDriver(TestBase):
reraise = mock.patch.object( reraise = mock.patch.object(
excutils, 'save_and_reraise_exception') excutils, 'save_and_reraise_exception')
reraise.start() reraise.start()
proEr = exceptions.ProcessExecutionError('', 2) ip_wrapper = mock.Mock()
processExecutionError = mock.Mock(side_effect=proEr) for exception in (OSError(),
ip = self.ip.return_value pyroute2_exc.NetlinkError(22)):
ip.ensure_namespace.side_effect = processExecutionError ip_wrapper.ensure_namespace.side_effect = exception
ovs.plug_new( self.ip.return_value = ip_wrapper
'01234567-1234-1234-99', delete_port.reset_mock()
'port-1234', ovs.plug_new(
'tap0', '01234567-1234-1234-99',
'aa:bb:cc:dd:ee:ff', 'port-1234',
bridge=bridge, 'tap0',
namespace=namespace, 'aa:bb:cc:dd:ee:ff',
prefix='veth', bridge=bridge,
mtu=9000) namespace=namespace,
delete_port.assert_called_once_with('tap0') prefix='veth',
mtu=9000)
delete_port.assert_called_once_with('tap0')
def test_unplug(self): def test_unplug(self):
with mock.patch('neutron.agent.common.ovs_lib.OVSBridge') as ovs_br: with mock.patch('neutron.agent.common.ovs_lib.OVSBridge') as ovs_br: