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 commit8cc2765b5f
) (cherry picked from commitafd6b2f5ae
)
This commit is contained in:
parent
2bcbd947b3
commit
fa3fa17ef0
|
@ -601,6 +601,10 @@ class IpLinkCommand(IpDeviceCommandBase):
|
||||||
return privileged.get_link_attributes(self.name,
|
return privileged.get_link_attributes(self.name,
|
||||||
self._parent.namespace)
|
self._parent.namespace)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def exists(self):
|
||||||
|
return privileged.interface_exists(self.name, self._parent.namespace)
|
||||||
|
|
||||||
|
|
||||||
class IpAddrCommand(IpDeviceCommandBase):
|
class IpAddrCommand(IpDeviceCommandBase):
|
||||||
COMMAND = 'addr'
|
COMMAND = 'addr'
|
||||||
|
@ -1147,8 +1151,8 @@ def ensure_device_is_ready(device_name, namespace=None):
|
||||||
dev = IPDevice(device_name, namespace=namespace)
|
dev = IPDevice(device_name, namespace=namespace)
|
||||||
try:
|
try:
|
||||||
# Ensure the device has a MAC address and is up, even if it is already
|
# 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.
|
# up.
|
||||||
if not dev.link.address:
|
if not dev.link.exists or not dev.link.address:
|
||||||
LOG.error("Device %s cannot be used as it has no MAC "
|
LOG.error("Device %s cannot be used as it has no MAC "
|
||||||
"address", device_name)
|
"address", device_name)
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -14,6 +14,7 @@ import errno
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
from neutron_lib import constants
|
from neutron_lib import constants
|
||||||
|
from oslo_log import log as logging
|
||||||
import pyroute2
|
import pyroute2
|
||||||
from pyroute2.netlink import rtnl
|
from pyroute2.netlink import rtnl
|
||||||
from pyroute2.netlink.rtnl import ifinfmsg
|
from pyroute2.netlink.rtnl import ifinfmsg
|
||||||
|
@ -25,6 +26,8 @@ from neutron._i18n import _
|
||||||
from neutron import privileged
|
from neutron import privileged
|
||||||
|
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
_IP_VERSION_FAMILY_MAP = {4: socket.AF_INET, 6: socket.AF_INET6}
|
_IP_VERSION_FAMILY_MAP = {4: socket.AF_INET, 6: socket.AF_INET6}
|
||||||
|
|
||||||
|
|
||||||
|
@ -146,12 +149,17 @@ def _translate_ip_device_exception(e, device=None, namespace=None):
|
||||||
namespace=namespace)
|
namespace=namespace)
|
||||||
|
|
||||||
|
|
||||||
def _get_link_id(device, namespace):
|
def _get_link_id(device, namespace, raise_exception=True):
|
||||||
try:
|
with _get_iproute(namespace) as ip:
|
||||||
with _get_iproute(namespace) as ip:
|
link_id = ip.link_lookup(ifname=device)
|
||||||
return ip.link_lookup(ifname=device)[0]
|
if not link_id or len(link_id) < 1:
|
||||||
except IndexError:
|
if raise_exception:
|
||||||
raise NetworkInterfaceNotFound(device=device, namespace=namespace)
|
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):
|
def _run_iproute_link(command, device, namespace=None, **kwargs):
|
||||||
|
@ -272,10 +280,8 @@ def delete_interface(ifname, namespace, **kwargs):
|
||||||
@privileged.default.entrypoint
|
@privileged.default.entrypoint
|
||||||
def interface_exists(ifname, namespace):
|
def interface_exists(ifname, namespace):
|
||||||
try:
|
try:
|
||||||
idx = _get_link_id(ifname, namespace)
|
idx = _get_link_id(ifname, namespace, raise_exception=False)
|
||||||
return bool(idx)
|
return bool(idx)
|
||||||
except NetworkInterfaceNotFound:
|
|
||||||
return False
|
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
if e.errno == errno.ENOENT:
|
if e.errno == errno.ENOENT:
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -1336,15 +1336,21 @@ class TestDeviceExists(base.BaseTestCase):
|
||||||
|
|
||||||
def test_ensure_device_is_ready_no_link_address(self):
|
def test_ensure_device_is_ready_no_link_address(self):
|
||||||
with mock.patch.object(
|
with mock.patch.object(
|
||||||
priv_lib, 'get_link_attributes'
|
priv_lib, 'get_link_attributes') as get_link_attributes, \
|
||||||
) as get_link_attributes, mock.patch.object(
|
mock.patch.object(priv_lib, 'set_link_attribute') as \
|
||||||
priv_lib, 'set_link_attribute'
|
set_link_attribute, \
|
||||||
) as set_link_attribute:
|
mock.patch.object(priv_lib, 'interface_exists',
|
||||||
|
return_value=True):
|
||||||
get_link_attributes.return_value = {}
|
get_link_attributes.return_value = {}
|
||||||
self.assertFalse(ip_lib.ensure_device_is_ready("lo"))
|
self.assertFalse(ip_lib.ensure_device_is_ready("lo"))
|
||||||
get_link_attributes.assert_called_once_with("lo", None)
|
get_link_attributes.assert_called_once_with("lo", None)
|
||||||
set_link_attribute.assert_not_called()
|
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):
|
class TestGetRoutingTable(base.BaseTestCase):
|
||||||
ip_db_interfaces = {
|
ip_db_interfaces = {
|
||||||
|
|
Loading…
Reference in New Issue