Ondřej Svoboda has uploaded a new change for review.
Change subject: netinfo: report DHCP on devices only when configured (like for networks)
......................................................................
netinfo: report DHCP on devices only when configured (like for networks)
As reporting of DHCP relies on reading of dhclient lease files, it is not
reliable when a network is reconfigured to static addressing: unused leases
indicate dhclient presence hours after it has been stopped (expiration time
is usually in hours or days).
The false indication has already been fixed for networks, now even their
respective devices adhere to configuration to stop false positives.
A year and half ago it was suggested first to rely on cmdlines on running
dhclients (where network device is the last parameter for all network
configurators). This fix is just a hacky, though little bandaid for the 3.6
release. A proper fix will be considered for the 4.0 branch.
testSetupNetworksAddDelDhcp now checks that DHCP stops being reported
on a network device, in addition to its network.
Change-Id: I2b17b0c66e3a0fc8c5ada62d166d9a2b92513033
Bug-Url:
https://bugzilla.redhat.com/1184497
Signed-off-by: Ondřej Svoboda <osvoboda(a)redhat.com>
---
M lib/vdsm/netinfo.py
M tests/functional/networkTests.py
2 files changed, 52 insertions(+), 33 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/04/45504/1
diff --git a/lib/vdsm/netinfo.py b/lib/vdsm/netinfo.py
index 9a12177..9cb39c3 100644
--- a/lib/vdsm/netinfo.py
+++ b/lib/vdsm/netinfo.py
@@ -510,6 +510,14 @@
return data
+def _netinfo_by_device(networks):
+ netinfo_by_device = {}
+ for net_attrs in networks.itervalues():
+ device = net_attrs['iface']
+ netinfo_by_device[device] = net_attrs
+ return netinfo_by_device
+
+
def _bridgeinfo(link):
return {'ports': ports(link.name),
'stp': bridge_stp_state(link.name),
@@ -548,7 +556,7 @@
return {'iface': link.device, 'vlanid': link.vlanid}
-def _devinfo(link, routes, ipaddrs, dhcpv4_ifaces, dhcpv6_ifaces):
+def _devinfo(link, routes, ipaddrs, dhcpv4_ifaces, dhcpv6_ifaces, net_attrs):
gateway = _get_gateway(routes, link.name)
ipv4addr, ipv4netmask, ipv4addrs, ipv6addrs = getIpInfo(
link.name, ipaddrs, gateway)
@@ -558,8 +566,9 @@
'ipv6addrs': ipv6addrs,
'gateway': gateway,
'ipv6gateway': _get_gateway(routes, link.name, family=6),
- 'dhcpv4': link.name in dhcpv4_ifaces,
- 'dhcpv6': link.name in dhcpv6_ifaces,
+ 'dhcpv4': _dhcp_used(link.name, dhcpv4_ifaces, net_attrs),
+ 'dhcpv6': _dhcp_used(link.name, dhcpv6_ifaces, net_attrs,
+ family=6),
'mtu': str(link.mtu),
'netmask': ipv4netmask}
if 'BOOTPROTO' not in info['cfg']:
@@ -754,6 +763,8 @@
else:
d['networks'] = vdsmnets
+ netinfo_by_device = _netinfo_by_device(d['networks'])
+
for dev in (link for link in getLinks() if not link.isHidden()):
if dev.isBRIDGE():
devinfo = d['bridges'][dev.name] = _bridgeinfo(dev)
@@ -766,7 +777,8 @@
else:
continue
devinfo.update(_devinfo(dev, routes, ipaddrs, dhcpv4_ifaces,
- dhcpv6_ifaces))
+ dhcpv6_ifaces,
+ netinfo_by_device.get(dev.name, None)))
if dev.isBOND():
_bondOptsCompat(devinfo)
_bondCustomOpts(dev, devinfo, running_config)
diff --git a/tests/functional/networkTests.py b/tests/functional/networkTests.py
index 1873222..41fd6d0 100644
--- a/tests/functional/networkTests.py
+++ b/tests/functional/networkTests.py
@@ -2043,6 +2043,37 @@
@cleanupNet
@RequireVethMod
def testSetupNetworksAddDelDhcp(self, bridged, families):
+ def _assert_applied(network_name, requested, reported):
+ self.assertNetworkExists(network_name)
+ reported_network = reported.networks[network_name]
+
+ if requested['bridged']:
+ self.assertEqual(reported_network['cfg']['BOOTPROTO'],
+ requested['bootproto'])
+ reported_devices = reported.bridges
+ device_name = network_name
+ else:
+ reported_devices = reported.nics
+ device_name = requested['nic']
+ self.assertIn(device_name, reported_devices)
+ reported_device = reported_devices[device_name]
+
+ requested_dhcpv4 = requested['bootproto'] == 'dhcp'
+ self.assertEqual(reported_network['dhcpv4'], requested_dhcpv4)
+ self.assertEqual(reported_network['dhcpv6'],
requested['dhcpv6'])
+
+ self.assertEqual(reported_device['cfg']['BOOTPROTO'],
+ requested['bootproto'])
+ self.assertEqual(reported_device['dhcpv4'], requested_dhcpv4)
+ self.assertEqual(reported_device['dhcpv6'],
requested['dhcpv6'])
+
+ if requested_dhcpv4:
+ self.assertEqual(reported_network['gateway'], IP_GATEWAY)
+ # TODO: source routing not ready for IPv6
+ ip_addr = reported_network['addr']
+ self.assertSourceRoutingConfiguration(device_name,
+ ip_addr)
+
with veth.pair() as (left, right):
veth.setIP(left, IP_ADDRESS, IP_CIDR)
veth.setIP(left, IPv6_ADDRESS, IPv6_CIDR, 6)
@@ -2058,42 +2089,18 @@
try:
status, msg = self.setupNetworks(network, {}, NOCHK)
self.assertEqual(status, SUCCESS, msg)
- self.assertNetworkExists(NETWORK_NAME)
- test_net = self.vdsm_net.netinfo.networks[NETWORK_NAME]
- self.assertEqual(test_net['dhcpv4'], dhcpv4)
- self.assertEqual(test_net['dhcpv6'], dhcpv6)
-
- if bridged:
- self.assertEqual(test_net['cfg']['BOOTPROTO'],
- bootproto)
- devs = self.vdsm_net.netinfo.bridges
- device_name = NETWORK_NAME
- else:
- devs = self.vdsm_net.netinfo.nics
- device_name = right
-
- self.assertIn(device_name, devs)
- net_attrs = devs[device_name]
- self.assertEqual(net_attrs['cfg']['BOOTPROTO'],
bootproto)
- self.assertEqual(net_attrs['dhcpv4'], dhcpv4)
- self.assertEqual(net_attrs['dhcpv6'], dhcpv6)
-
- if dhcpv4:
- self.assertEqual(test_net['gateway'], IP_GATEWAY)
- # TODO: source routing not ready for IPv6
- ip_addr = test_net['addr']
- self.assertSourceRoutingConfiguration(device_name,
- ip_addr)
+ _assert_applied(NETWORK_NAME, network,
+ self.vdsm_net.netinfo)
# Do not report DHCP from (typically still valid) leases
network[NETWORK_NAME]['bootproto'] = 'none'
network[NETWORK_NAME]['dhcpv6'] = False
status, msg = self.setupNetworks(network, {}, NOCHK)
self.assertEqual(status, SUCCESS, msg)
- test_net = self.vdsm_net.netinfo.networks[NETWORK_NAME]
- self.assertEqual(test_net['dhcpv4'], False)
- self.assertEqual(test_net['dhcpv6'], False)
+
+ _assert_applied(NETWORK_NAME, network,
+ self.vdsm_net.netinfo)
network = {NETWORK_NAME: {'remove': True}}
status, msg = self.setupNetworks(network, {}, NOCHK)
--
To view, visit
https://gerrit.ovirt.org/45504
To unsubscribe, visit
https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I2b17b0c66e3a0fc8c5ada62d166d9a2b92513033
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Ondřej Svoboda <osvoboda(a)redhat.com>