DEVICE_NAME_PATTERN = re.compile(r"(\d+?): (\S+?):.*")
+def remove_interface_suffix(interface):
+ """Remove a possible "<if>@<endpoint>" suffix from an interface' name.
+
+ This suffix can appear in some kernel versions, and intends on specifying,
+ for example, a veth's pair. However, this interface name is useless to us
+ as further 'ip' commands require that the suffix be removed.
+ """
+ # If '@' is not present, this will do nothing.
+ return interface.partition("@")[0]
+
+
class AddressNotReady(exceptions.NeutronException):
message = _("Failure waiting for address %(address)s to "
"become ready: %(reason)s")
if match:
# Found a match for a device name, but its' addresses will
# only appear in following lines, so we may as well continue.
- device_name = match.group(2)
+ device_name = remove_interface_suffix(match.group(2))
continue
elif not line.startswith('inet'):
continue
from neutron._i18n import _LE
from neutron.agent.linux import async_process
+from neutron.agent.linux import ip_lib
LOG = logging.getLogger(__name__)
route = route[1:]
try:
- interface = route[1]
+ interface = ip_lib.remove_interface_suffix(route[1])
cidr = route[3]
except IndexError:
with excutils.save_and_reraise_exception():
valid_lft forever preferred_lft forever
""")
+
+ADDR_SAMPLE3 = ("""
+2: eth0@NONE: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP
+ link/ether dd:cc:aa:b9:76:ce brd ff:ff:ff:ff:ff:ff
+ inet 172.16.77.240/24 brd 172.16.77.255 scope global eth0
+""")
+
GATEWAY_SAMPLE1 = ("""
default via 10.35.19.254 metric 100
10.35.16.0/22 proto kernel scope link src 10.35.17.97
self._assert_call([], ('show', 'tap0', 'permanent', 'scope',
'global'))
+ def test_get_devices_with_ip(self):
+ self.parent._run.return_value = ADDR_SAMPLE3
+ devices = self.addr_cmd.get_devices_with_ip('172.16.77.240/24')
+ self.assertEqual(1, len(devices))
+ self.assertEqual('eth0', devices[0]['name'])
+
class TestIpRouteCommand(TestIPCmdBase):
def setUp(self):