Avoid raising NetworkInterfaceNotFound exception in DHCP agent logs

In "ip_lib.ensure_device_is_ready", before retrieving the interface
attributes, a check is done to know if the interface exists. In case
it does not exist, the exception "NetworkInterfaceNotFound" will not
be raised and written in the logs.

Conflicts:
    neutron/privileged/agent/linux/ip_lib.py

Change-Id: I4b9fd0885d850601717274a5058e042871211bbb
Closes-Bug: #1854723
(cherry picked from commit 8cc2765b5f)
(cherry picked from commit afd6b2f5ae)
This commit is contained in:
Rodolfo Alonso Hernandez 2019-12-02 11:48:28 +00:00
parent fe6120f0c3
commit 3e64388bb6
3 changed files with 31 additions and 15 deletions

View File

@ -499,6 +499,10 @@ class IpLinkCommand(IpDeviceCommandBase):
return privileged.get_link_attributes(self.name,
self._parent.namespace)
@property
def exists(self):
return privileged.interface_exists(self.name, self._parent.namespace)
class IpAddrCommand(IpDeviceCommandBase):
COMMAND = 'addr'
@ -1017,8 +1021,8 @@ def ensure_device_is_ready(device_name, namespace=None):
dev = IPDevice(device_name, namespace=namespace)
try:
# Ensure the device has a MAC address and is up, even if it is already
# up. If the device doesn't exist, a RuntimeError will be raised.
if not dev.link.address:
# up.
if not dev.link.exists or not dev.link.address:
LOG.error("Device %s cannot be used as it has no MAC "
"address", device_name)
return False

View File

@ -16,6 +16,7 @@ import socket
from neutron_lib import constants
from oslo_concurrency import lockutils
from oslo_log import log as logging
import pyroute2
from pyroute2 import netlink
from pyroute2.netlink import exceptions as netlink_exceptions
@ -30,6 +31,8 @@ from neutron._i18n import _
from neutron import privileged
LOG = logging.getLogger(__name__)
_IP_VERSION_FAMILY_MAP = {4: socket.AF_INET, 6: socket.AF_INET6}
@ -210,12 +213,17 @@ def _translate_ip_device_exception(e, device=None, namespace=None):
namespace=namespace)
def get_link_id(device, namespace):
try:
with get_iproute(namespace) as ip:
return ip.link_lookup(ifname=device)[0]
except IndexError:
raise NetworkInterfaceNotFound(device=device, namespace=namespace)
def get_link_id(device, namespace, raise_exception=True):
with get_iproute(namespace) as ip:
link_id = ip.link_lookup(ifname=device)
if not link_id or len(link_id) < 1:
if raise_exception:
raise NetworkInterfaceNotFound(device=device, namespace=namespace)
else:
LOG.debug('Interface %(dev)s not found in namespace %(namespace)s',
{'dev': device, 'namespace': namespace})
return None
return link_id[0]
def _run_iproute_link(command, device, namespace=None, **kwargs):
@ -346,10 +354,8 @@ def delete_interface(ifname, namespace, **kwargs):
@privileged.default.entrypoint
def interface_exists(ifname, namespace):
try:
idx = get_link_id(ifname, namespace)
idx = get_link_id(ifname, namespace, raise_exception=False)
return bool(idx)
except NetworkInterfaceNotFound:
return False
except OSError as e:
if e.errno == errno.ENOENT:
return False

View File

@ -1212,15 +1212,21 @@ class TestDeviceExists(base.BaseTestCase):
def test_ensure_device_is_ready_no_link_address(self):
with mock.patch.object(
priv_lib, 'get_link_attributes'
) as get_link_attributes, mock.patch.object(
priv_lib, 'set_link_attribute'
) as set_link_attribute:
priv_lib, 'get_link_attributes') as get_link_attributes, \
mock.patch.object(priv_lib, 'set_link_attribute') as \
set_link_attribute, \
mock.patch.object(priv_lib, 'interface_exists',
return_value=True):
get_link_attributes.return_value = {}
self.assertFalse(ip_lib.ensure_device_is_ready("lo"))
get_link_attributes.assert_called_once_with("lo", None)
set_link_attribute.assert_not_called()
def test_ensure_device_is_ready_no_device(self):
with mock.patch.object(priv_lib, 'interface_exists',
return_value=False):
self.assertFalse(ip_lib.ensure_device_is_ready("lo"))
class TestGetRoutingTable(base.BaseTestCase):
ip_db_interfaces = {