Change in vdsm[master]: net: Clean netinfo.__init__ and migrate to cache
edwardh at redhat.com
edwardh at redhat.com
Tue Feb 2 20:54:07 UTC 2016
Edward Haas has uploaded a new change for review.
Change subject: net: Clean netinfo.__init__ and migrate to cache
......................................................................
net: Clean netinfo.__init__ and migrate to cache
When stand alone modules under the netinfo package are being used by other
modules, __init__ is being processed and cause import loops.
This patch migrates most __init__ content to cache.
Change-Id: I892bb86fe9a8580d9028ca7759d27967e55d85f7
Signed-off-by: Edward Haas <edwardh at redhat.com>
---
M debian/vdsm-python.install
M lib/vdsm/netinfo/Makefile.am
M lib/vdsm/netinfo/__init__.py
A lib/vdsm/netinfo/cache.py
M lib/vdsm/network/api.py
M lib/vdsm/network/configurators/dhclient.py
M lib/vdsm/network/configurators/ifcfg.py
M lib/vdsm/network/configurators/iproute2.py
M lib/vdsm/network/configurators/qos.py
M lib/vdsm/network/models.py
M lib/vdsm/tool/unified_persistence.py
M tests/configNetworkTests.py
M tests/functional/networkTests.py
M tests/functional/utils.py
M tests/netinfoTests.py
M tests/netmodelsTests.py
M vdsm.spec.in
M vdsm/caps.py
M vdsm/vdsm-restore-net-config
M vdsm_hooks/ovs/ovs_before_network_setup_ovs.py
20 files changed, 372 insertions(+), 341 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/07/53007/1
diff --git a/debian/vdsm-python.install b/debian/vdsm-python.install
index 9650d9d..e641d84 100644
--- a/debian/vdsm-python.install
+++ b/debian/vdsm-python.install
@@ -23,6 +23,7 @@
./usr/lib/python2.7/dist-packages/vdsm/netinfo/addresses.py
./usr/lib/python2.7/dist-packages/vdsm/netinfo/bonding.py
./usr/lib/python2.7/dist-packages/vdsm/netinfo/bridges.py
+./usr/lib/python2.7/dist-packages/vdsm/netinfo/cache.py
./usr/lib/python2.7/dist-packages/vdsm/netinfo/dhcp.py
./usr/lib/python2.7/dist-packages/vdsm/netinfo/dns.py
./usr/lib/python2.7/dist-packages/vdsm/netinfo/misc.py
diff --git a/lib/vdsm/netinfo/Makefile.am b/lib/vdsm/netinfo/Makefile.am
index bac2915..f757e14 100644
--- a/lib/vdsm/netinfo/Makefile.am
+++ b/lib/vdsm/netinfo/Makefile.am
@@ -25,6 +25,7 @@
addresses.py \
bonding.py \
bridges.py \
+ cache.py \
dhcp.py \
dns.py \
misc.py \
diff --git a/lib/vdsm/netinfo/__init__.py b/lib/vdsm/netinfo/__init__.py
index b73bea6..64a7d0b 100644
--- a/lib/vdsm/netinfo/__init__.py
+++ b/lib/vdsm/netinfo/__init__.py
@@ -18,165 +18,16 @@
# Refer to the README and COPYING files for full details of the license
#
-from __future__ import absolute_import
-from itertools import chain
-import logging
-import os
-import errno
-import six
+
import xml.etree.cElementTree as etree
-from ..ipwrapper import getLinks, DUMMY_BRIDGE
+from ..ipwrapper import DUMMY_BRIDGE
from .. import libvirtconnection
-from ..netconfpersistence import RunningConfig
-from ..netlink import link as nl_link
-
-from .addresses import getIpAddrs, getIpInfo
-from . import bonding
-from . import bridges
-from .dhcp import (get_dhclient_ifaces, propose_updates_to_reported_dhcp,
- update_reported_dhcp, dhcp_used)
-from .dns import get_host_nameservers
-from .misc import getIfaceCfg, ipv6_supported
-from .mtus import getMtu
-from . import nics
-from . import vlans
-from .routes import get_routes, get_gateway
-from .qos import report_network_qos
-
-
-NET_PATH = '/sys/class/net'
-
-LIBVIRT_NET_PREFIX = 'vdsm-'
DUMMY_BRIDGE # Appease flake8 since dummy bridge should be exported from here
-
-def _get(vdsmnets=None):
- """
- Generate a networking report for all devices, including data managed by
- libvirt.
- In case vdsmnets is provided, it is used in the report instead of
- retrieving data from libvirt.
- :return: Dict of networking devices with all their details.
- """
- networking = {'bondings': {}, 'bridges': {}, 'networks': {}, 'nics': {},
- 'vlans': {}, 'dnss': get_host_nameservers()}
- paddr = bonding.permanent_address()
- ipaddrs = getIpAddrs()
- dhcpv4_ifaces, dhcpv6_ifaces = get_dhclient_ifaces()
- routes = get_routes()
- running_config = RunningConfig()
-
- if vdsmnets is None:
- libvirt_nets = networks()
- networking['networks'] = libvirtNets2vdsm(libvirt_nets, running_config,
- routes, ipaddrs,
- dhcpv4_ifaces, dhcpv6_ifaces)
- else:
- networking['networks'] = vdsmnets
-
- for dev in (link for link in getLinks() if not link.isHidden()):
- if dev.isBRIDGE():
- devinfo = networking['bridges'][dev.name] = bridges.info(dev)
- elif dev.isNICLike():
- devinfo = networking['nics'][dev.name] = nics.info(dev, paddr)
- elif dev.isBOND():
- devinfo = networking['bondings'][dev.name] = bonding.info(dev)
- elif dev.isVLAN():
- devinfo = networking['vlans'][dev.name] = vlans.info(dev)
- else:
- continue
- devinfo.update(_devinfo(dev, routes, ipaddrs, dhcpv4_ifaces,
- dhcpv6_ifaces))
- if dev.isBOND():
- bonding.bondOptsCompat(devinfo)
-
- for network_name, network_info in six.iteritems(networking['networks']):
- if network_info['bridged']:
- network_info['cfg'] = networking['bridges'][network_name]['cfg']
- updates = propose_updates_to_reported_dhcp(network_info, networking)
- update_reported_dhcp(updates, networking)
-
- report_network_qos(networking)
- networking['supportsIPv6'] = ipv6_supported()
-
- return networking
-
-
-def get(vdsmnets=None, compatibility=None):
- if compatibility is None:
- return _get(vdsmnets)
- elif compatibility < 30700:
- # REQUIRED_FOR engine < 3.7
- return _stringify_mtus(_get(vdsmnets))
-
- return _get(vdsmnets)
-
-
-def _stringify_mtus(netinfo_data):
- for devtype in ('bondings', 'bridges', 'networks', 'nics', 'vlans'):
- for dev in six.itervalues(netinfo_data[devtype]):
- dev['mtu'] = str(dev['mtu'])
- return netinfo_data
-
-
-def libvirtNets2vdsm(nets, running_config=None, routes=None, ipAddrs=None,
- dhcpv4_ifaces=None, dhcpv6_ifaces=None):
- if running_config is None:
- running_config = RunningConfig()
- if routes is None:
- routes = get_routes()
- if ipAddrs is None:
- ipAddrs = getIpAddrs()
- if dhcpv4_ifaces is None or dhcpv6_ifaces is None:
- dhcpv4_ifaces, dhcpv6_ifaces = get_dhclient_ifaces()
- d = {}
- for net, netAttr in nets.iteritems():
- try:
- # Pass the iface if the net is _not_ bridged, the bridge otherwise
- d[net] = _getNetInfo(netAttr.get('iface', net), netAttr['bridged'],
- routes, ipAddrs, dhcpv4_ifaces, dhcpv6_ifaces,
- running_config.networks.get(net, None))
- except KeyError:
- continue # Do not report missing libvirt networks.
- return d
-
-
-def _devinfo(link, routes, ipaddrs, dhcpv4_ifaces, dhcpv6_ifaces):
- gateway = get_gateway(routes, link.name)
- ipv4addr, ipv4netmask, ipv4addrs, ipv6addrs = getIpInfo(
- link.name, ipaddrs, gateway)
- info = {'addr': ipv4addr,
- 'cfg': getIfaceCfg(link.name),
- 'ipv4addrs': ipv4addrs,
- 'ipv6addrs': ipv6addrs,
- 'gateway': gateway,
- 'ipv6gateway': get_gateway(routes, link.name, family=6),
- 'dhcpv4': link.name in dhcpv4_ifaces, # to be refined if a network
- 'dhcpv6': link.name in dhcpv6_ifaces, # is not configured for DHCP
- 'mtu': link.mtu,
- 'netmask': ipv4netmask}
- if 'BOOTPROTO' not in info['cfg']:
- info['cfg']['BOOTPROTO'] = 'dhcp' if info['dhcpv4'] else 'none'
- return info
-
-
-def ifaceUsed(iface):
- """Lightweight implementation of bool(Netinfo.ifaceUsers()) that does not
- require a NetInfo object."""
- if os.path.exists(os.path.join(NET_PATH, iface, 'brport')): # Is it a port
- return True
- for linkDict in nl_link.iter_links():
- if linkDict['name'] == iface and 'master' in linkDict: # Is it a slave
- return True
- if linkDict.get('device') == iface and linkDict.get('type') == 'vlan':
- return True # it backs a VLAN
- for net_attr in six.itervalues(networks()):
- if net_attr.get('iface') == iface:
- return True
- return False
+LIBVIRT_NET_PREFIX = 'vdsm-'
def networks():
@@ -203,170 +54,4 @@
else:
nets[netname]['bridge'] = xml.find('.//bridge').get('name')
nets[netname]['bridged'] = True
- return nets
-
-
-def _getNetInfo(iface, bridged, routes, ipaddrs, dhcpv4_ifaces, dhcpv6_ifaces,
- net_attrs):
- """Returns a dictionary of properties about the network's interface status.
- Raises a KeyError if the iface does not exist."""
- data = {}
- try:
- if bridged:
- data.update({'ports': bridges.ports(iface),
- 'stp': bridges.stp_state(iface)})
- else:
- # ovirt-engine-3.1 expects to see the "interface" attribute iff the
- # network is bridgeless. Please remove the attribute and this
- # comment when the version is no longer supported.
- data['interface'] = iface
-
- gateway = get_gateway(routes, iface)
- ipv4addr, ipv4netmask, ipv4addrs, ipv6addrs = getIpInfo(
- iface, ipaddrs, gateway)
- data.update({'iface': iface, 'bridged': bridged,
- 'addr': ipv4addr, 'netmask': ipv4netmask,
- 'dhcpv4': dhcp_used(iface, dhcpv4_ifaces, net_attrs),
- 'dhcpv6': dhcp_used(iface, dhcpv6_ifaces, net_attrs,
- family=6),
- 'ipv4addrs': ipv4addrs,
- 'ipv6addrs': ipv6addrs,
- 'gateway': gateway,
- 'ipv6gateway': get_gateway(routes, iface, family=6),
- 'mtu': getMtu(iface)})
- except (IOError, OSError) as e:
- if e.errno == errno.ENOENT:
- logging.info('Obtaining info for net %s.', iface, exc_info=True)
- raise KeyError('Network %s was not found' % iface)
- else:
- raise
- return data
-
-
-class CachingNetInfo(object):
- def __init__(self, _netinfo=None):
- if _netinfo is None:
- _netinfo = get()
-
- self.networks = _netinfo['networks']
- self.vlans = _netinfo['vlans']
- self.nics = _netinfo['nics']
- self.bondings = _netinfo['bondings']
- self.bridges = _netinfo['bridges']
-
- def updateDevices(self):
- """Updates the object device information while keeping the cached
- network information."""
- _netinfo = get(vdsmnets=self.networks)
- self.networks = _netinfo['networks']
- self.vlans = _netinfo['vlans']
- self.nics = _netinfo['nics']
- self.bondings = _netinfo['bondings']
- self.bridges = _netinfo['bridges']
-
- def del_network(self, network):
- del self.networks[network]
-
- def del_bonding(self, bonding):
- del self.bondings[bonding]
-
- def getNetworksAndVlansForIface(self, iface):
- """ Returns tuples of (bridge/network, vlan) connected to nic/bond """
- return chain(self._getBridgedNetworksAndVlansForIface(iface),
- self._getBridgelessNetworksAndVlansForIface(iface))
-
- def _getBridgedNetworksAndVlansForIface(self, iface):
- """ Returns tuples of (bridge, vlan) connected to nic/bond """
- for network, netdict in self.networks.iteritems():
- if netdict['bridged']:
- for interface in netdict['ports']:
- if iface == interface:
- yield (network, None)
- elif interface.startswith(iface + '.'):
- yield (network, vlans.vlan_id(interface))
-
- def _getBridgelessNetworksAndVlansForIface(self, iface):
- """ Returns tuples of (network, vlan) connected to nic/bond """
- for network, netdict in self.networks.iteritems():
- if not netdict['bridged']:
- if iface == netdict['iface']:
- yield (network, None)
- elif netdict['iface'].startswith(iface + '.'):
- yield (network, vlans.vlan_id(netdict['iface']))
-
- def getVlansForIface(self, iface):
- for vlandict in six.itervalues(self.vlans):
- if iface == vlandict['iface']:
- yield vlandict['vlanid']
-
- def getNetworkForIface(self, iface):
- """ Return the network attached to nic/bond """
- for network, netdict in self.networks.iteritems():
- if ('ports' in netdict and iface in netdict['ports'] or
- 'iface' in netdict and iface == netdict['iface']):
- return network
-
- def getBridgedNetworkForIface(self, iface):
- """ Return all bridged networks attached to nic/bond """
- for bridge, netdict in self.networks.iteritems():
- if netdict['bridged'] and iface in netdict['ports']:
- return bridge
-
- def getNicsForBonding(self, bond):
- bondAttrs = self.bondings[bond]
- return bondAttrs['slaves']
-
- def getBondingForNic(self, nic):
- bondings = [b for (b, attrs) in self.bondings.iteritems() if
- nic in attrs['slaves']]
- if bondings:
- assert len(bondings) == 1, \
- "Unexpected configuration: More than one bonding per nic"
- return bondings[0]
- return None
-
- def getNicsVlanAndBondingForNetwork(self, network):
- vlan = None
- vlanid = None
- bonding = None
- lnics = []
-
- if self.networks[network]['bridged']:
- ports = self.networks[network]['ports']
- else:
- ports = []
- interface = self.networks[network]['iface']
- ports.append(interface)
-
- for port in ports:
- if port in self.vlans:
- assert vlan is None
- nic = vlans.vlan_device(port)
- vlanid = vlans.vlan_id(port)
- vlan = port # vlan devices can have an arbitrary name
- assert self.vlans[port]['iface'] == nic
- port = nic
- if port in self.bondings:
- assert bonding is None
- bonding = port
- lnics += self.bondings[bonding]['slaves']
- elif port in self.nics:
- lnics.append(port)
-
- return lnics, vlan, vlanid, bonding
-
- def ifaceUsers(self, iface):
- "Returns a list of entities using the interface"
- users = set()
- for n, ndict in self.networks.iteritems():
- if ndict['bridged'] and iface in ndict['ports']:
- users.add(n)
- elif not ndict['bridged'] and iface == ndict['iface']:
- users.add(n)
- for b, bdict in self.bondings.iteritems():
- if iface in bdict['slaves']:
- users.add(b)
- for v, vdict in self.vlans.iteritems():
- if iface == vdict['iface']:
- users.add(v)
- return users
+ return nets
\ No newline at end of file
diff --git a/lib/vdsm/netinfo/cache.py b/lib/vdsm/netinfo/cache.py
new file mode 100644
index 0000000..467440b
--- /dev/null
+++ b/lib/vdsm/netinfo/cache.py
@@ -0,0 +1,339 @@
+#
+# Copyright 2015 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+
+from __future__ import absolute_import
+from itertools import chain
+import logging
+import os
+import errno
+import six
+
+from ..ipwrapper import getLinks
+from ..netconfpersistence import RunningConfig
+from ..netlink import link as nl_link
+
+from vdsm import netinfo
+from .addresses import getIpAddrs, getIpInfo
+from . import bonding
+from . import bridges
+from .dhcp import (get_dhclient_ifaces, propose_updates_to_reported_dhcp,
+ update_reported_dhcp, dhcp_used)
+from .dns import get_host_nameservers
+from .misc import getIfaceCfg, ipv6_supported
+from .mtus import getMtu
+from . import nics
+from . import vlans
+from .routes import get_routes, get_gateway
+from .qos import report_network_qos
+
+
+NET_PATH = '/sys/class/net'
+
+
+def _get(vdsmnets=None):
+ """
+ Generate a networking report for all devices, including data managed by
+ libvirt.
+ In case vdsmnets is provided, it is used in the report instead of
+ retrieving data from libvirt.
+ :return: Dict of networking devices with all their details.
+ """
+ networking = {'bondings': {}, 'bridges': {}, 'networks': {}, 'nics': {},
+ 'vlans': {}, 'dnss': get_host_nameservers()}
+ paddr = bonding.permanent_address()
+ ipaddrs = getIpAddrs()
+ dhcpv4_ifaces, dhcpv6_ifaces = get_dhclient_ifaces()
+ routes = get_routes()
+ running_config = RunningConfig()
+
+ if vdsmnets is None:
+ libvirt_nets = netinfo.networks()
+ networking['networks'] = libvirtNets2vdsm(libvirt_nets, running_config,
+ routes, ipaddrs,
+ dhcpv4_ifaces, dhcpv6_ifaces)
+ else:
+ networking['networks'] = vdsmnets
+
+ for dev in (link for link in getLinks() if not link.isHidden()):
+ if dev.isBRIDGE():
+ devinfo = networking['bridges'][dev.name] = bridges.info(dev)
+ elif dev.isNICLike():
+ devinfo = networking['nics'][dev.name] = nics.info(dev, paddr)
+ elif dev.isBOND():
+ devinfo = networking['bondings'][dev.name] = bonding.info(dev)
+ elif dev.isVLAN():
+ devinfo = networking['vlans'][dev.name] = vlans.info(dev)
+ else:
+ continue
+ devinfo.update(_devinfo(dev, routes, ipaddrs, dhcpv4_ifaces,
+ dhcpv6_ifaces))
+ if dev.isBOND():
+ bonding.bondOptsCompat(devinfo)
+
+ for network_name, network_info in six.iteritems(networking['networks']):
+ if network_info['bridged']:
+ network_info['cfg'] = networking['bridges'][network_name]['cfg']
+ updates = propose_updates_to_reported_dhcp(network_info, networking)
+ update_reported_dhcp(updates, networking)
+
+ report_network_qos(networking)
+ networking['supportsIPv6'] = ipv6_supported()
+
+ return networking
+
+
+def get(vdsmnets=None, compatibility=None):
+ if compatibility is None:
+ return _get(vdsmnets)
+ elif compatibility < 30700:
+ # REQUIRED_FOR engine < 3.7
+ return _stringify_mtus(_get(vdsmnets))
+
+ return _get(vdsmnets)
+
+
+def _stringify_mtus(netinfo_data):
+ for devtype in ('bondings', 'bridges', 'networks', 'nics', 'vlans'):
+ for dev in six.itervalues(netinfo_data[devtype]):
+ dev['mtu'] = str(dev['mtu'])
+ return netinfo_data
+
+
+def libvirtNets2vdsm(nets, running_config=None, routes=None, ipAddrs=None,
+ dhcpv4_ifaces=None, dhcpv6_ifaces=None):
+ if running_config is None:
+ running_config = RunningConfig()
+ if routes is None:
+ routes = get_routes()
+ if ipAddrs is None:
+ ipAddrs = getIpAddrs()
+ if dhcpv4_ifaces is None or dhcpv6_ifaces is None:
+ dhcpv4_ifaces, dhcpv6_ifaces = get_dhclient_ifaces()
+ d = {}
+ for net, netAttr in nets.iteritems():
+ try:
+ # Pass the iface if the net is _not_ bridged, the bridge otherwise
+ d[net] = _getNetInfo(netAttr.get('iface', net), netAttr['bridged'],
+ routes, ipAddrs, dhcpv4_ifaces, dhcpv6_ifaces,
+ running_config.networks.get(net, None))
+ except KeyError:
+ continue # Do not report missing libvirt networks.
+ return d
+
+
+def _devinfo(link, routes, ipaddrs, dhcpv4_ifaces, dhcpv6_ifaces):
+ gateway = get_gateway(routes, link.name)
+ ipv4addr, ipv4netmask, ipv4addrs, ipv6addrs = getIpInfo(
+ link.name, ipaddrs, gateway)
+ info = {'addr': ipv4addr,
+ 'cfg': getIfaceCfg(link.name),
+ 'ipv4addrs': ipv4addrs,
+ 'ipv6addrs': ipv6addrs,
+ 'gateway': gateway,
+ 'ipv6gateway': get_gateway(routes, link.name, family=6),
+ 'dhcpv4': link.name in dhcpv4_ifaces, # to be refined if a network
+ 'dhcpv6': link.name in dhcpv6_ifaces, # is not configured for DHCP
+ 'mtu': link.mtu,
+ 'netmask': ipv4netmask}
+ if 'BOOTPROTO' not in info['cfg']:
+ info['cfg']['BOOTPROTO'] = 'dhcp' if info['dhcpv4'] else 'none'
+ return info
+
+
+def ifaceUsed(iface):
+ """Lightweight implementation of bool(Netinfo.ifaceUsers()) that does not
+ require a NetInfo object."""
+ if os.path.exists(os.path.join(NET_PATH, iface, 'brport')): # Is it a port
+ return True
+ for linkDict in nl_link.iter_links():
+ if linkDict['name'] == iface and 'master' in linkDict: # Is it a slave
+ return True
+ if linkDict.get('device') == iface and linkDict.get('type') == 'vlan':
+ return True # it backs a VLAN
+ for net_attr in six.itervalues(netinfo.networks()):
+ if net_attr.get('iface') == iface:
+ return True
+ return False
+
+
+def _getNetInfo(iface, bridged, routes, ipaddrs, dhcpv4_ifaces, dhcpv6_ifaces,
+ net_attrs):
+ """Returns a dictionary of properties about the network's interface status.
+ Raises a KeyError if the iface does not exist."""
+ data = {}
+ try:
+ if bridged:
+ data.update({'ports': bridges.ports(iface),
+ 'stp': bridges.stp_state(iface)})
+ else:
+ # ovirt-engine-3.1 expects to see the "interface" attribute iff the
+ # network is bridgeless. Please remove the attribute and this
+ # comment when the version is no longer supported.
+ data['interface'] = iface
+
+ gateway = get_gateway(routes, iface)
+ ipv4addr, ipv4netmask, ipv4addrs, ipv6addrs = getIpInfo(
+ iface, ipaddrs, gateway)
+ data.update({'iface': iface, 'bridged': bridged,
+ 'addr': ipv4addr, 'netmask': ipv4netmask,
+ 'dhcpv4': dhcp_used(iface, dhcpv4_ifaces, net_attrs),
+ 'dhcpv6': dhcp_used(iface, dhcpv6_ifaces, net_attrs,
+ family=6),
+ 'ipv4addrs': ipv4addrs,
+ 'ipv6addrs': ipv6addrs,
+ 'gateway': gateway,
+ 'ipv6gateway': get_gateway(routes, iface, family=6),
+ 'mtu': getMtu(iface)})
+ except (IOError, OSError) as e:
+ if e.errno == errno.ENOENT:
+ logging.info('Obtaining info for net %s.', iface, exc_info=True)
+ raise KeyError('Network %s was not found' % iface)
+ else:
+ raise
+ return data
+
+
+class CachingNetInfo(object):
+ def __init__(self, _netinfo=None):
+ if _netinfo is None:
+ _netinfo = get()
+
+ self.networks = _netinfo['networks']
+ self.vlans = _netinfo['vlans']
+ self.nics = _netinfo['nics']
+ self.bondings = _netinfo['bondings']
+ self.bridges = _netinfo['bridges']
+
+ def updateDevices(self):
+ """Updates the object device information while keeping the cached
+ network information."""
+ _netinfo = get(vdsmnets=self.networks)
+ self.networks = _netinfo['networks']
+ self.vlans = _netinfo['vlans']
+ self.nics = _netinfo['nics']
+ self.bondings = _netinfo['bondings']
+ self.bridges = _netinfo['bridges']
+
+ def del_network(self, network):
+ del self.networks[network]
+
+ def del_bonding(self, bonding):
+ del self.bondings[bonding]
+
+ def getNetworksAndVlansForIface(self, iface):
+ """ Returns tuples of (bridge/network, vlan) connected to nic/bond """
+ return chain(self._getBridgedNetworksAndVlansForIface(iface),
+ self._getBridgelessNetworksAndVlansForIface(iface))
+
+ def _getBridgedNetworksAndVlansForIface(self, iface):
+ """ Returns tuples of (bridge, vlan) connected to nic/bond """
+ for network, netdict in self.networks.iteritems():
+ if netdict['bridged']:
+ for interface in netdict['ports']:
+ if iface == interface:
+ yield (network, None)
+ elif interface.startswith(iface + '.'):
+ yield (network, vlans.vlan_id(interface))
+
+ def _getBridgelessNetworksAndVlansForIface(self, iface):
+ """ Returns tuples of (network, vlan) connected to nic/bond """
+ for network, netdict in self.networks.iteritems():
+ if not netdict['bridged']:
+ if iface == netdict['iface']:
+ yield (network, None)
+ elif netdict['iface'].startswith(iface + '.'):
+ yield (network, vlans.vlan_id(netdict['iface']))
+
+ def getVlansForIface(self, iface):
+ for vlandict in six.itervalues(self.vlans):
+ if iface == vlandict['iface']:
+ yield vlandict['vlanid']
+
+ def getNetworkForIface(self, iface):
+ """ Return the network attached to nic/bond """
+ for network, netdict in self.networks.iteritems():
+ if ('ports' in netdict and iface in netdict['ports'] or
+ 'iface' in netdict and iface == netdict['iface']):
+ return network
+
+ def getBridgedNetworkForIface(self, iface):
+ """ Return all bridged networks attached to nic/bond """
+ for bridge, netdict in self.networks.iteritems():
+ if netdict['bridged'] and iface in netdict['ports']:
+ return bridge
+
+ def getNicsForBonding(self, bond):
+ bondAttrs = self.bondings[bond]
+ return bondAttrs['slaves']
+
+ def getBondingForNic(self, nic):
+ bondings = [b for (b, attrs) in self.bondings.iteritems() if
+ nic in attrs['slaves']]
+ if bondings:
+ assert len(bondings) == 1, \
+ "Unexpected configuration: More than one bonding per nic"
+ return bondings[0]
+ return None
+
+ def getNicsVlanAndBondingForNetwork(self, network):
+ vlan = None
+ vlanid = None
+ bonding = None
+ lnics = []
+
+ if self.networks[network]['bridged']:
+ ports = self.networks[network]['ports']
+ else:
+ ports = []
+ interface = self.networks[network]['iface']
+ ports.append(interface)
+
+ for port in ports:
+ if port in self.vlans:
+ assert vlan is None
+ nic = vlans.vlan_device(port)
+ vlanid = vlans.vlan_id(port)
+ vlan = port # vlan devices can have an arbitrary name
+ assert self.vlans[port]['iface'] == nic
+ port = nic
+ if port in self.bondings:
+ assert bonding is None
+ bonding = port
+ lnics += self.bondings[bonding]['slaves']
+ elif port in self.nics:
+ lnics.append(port)
+
+ return lnics, vlan, vlanid, bonding
+
+ def ifaceUsers(self, iface):
+ "Returns a list of entities using the interface"
+ users = set()
+ for n, ndict in self.networks.iteritems():
+ if ndict['bridged'] and iface in ndict['ports']:
+ users.add(n)
+ elif not ndict['bridged'] and iface == ndict['iface']:
+ users.add(n)
+ for b, bdict in self.bondings.iteritems():
+ if iface in bdict['slaves']:
+ users.add(b)
+ for v, vdict in self.vlans.iteritems():
+ if iface == vdict['iface']:
+ users.add(v)
+ return users
diff --git a/lib/vdsm/network/api.py b/lib/vdsm/network/api.py
index 7c5d1a4..381f6a5 100755
--- a/lib/vdsm/network/api.py
+++ b/lib/vdsm/network/api.py
@@ -34,10 +34,10 @@
from vdsm import hooks
from vdsm import kernelconfig
from vdsm import netconfpersistence
-from vdsm.netinfo import (addresses, libvirtNets2vdsm, bridges,
- get as netinfo_get, CachingNetInfo, mtus,
- networks as netinfo_networks, nics as netinfo_nics,
- NET_PATH)
+from vdsm.netinfo import (addresses, bridges, mtus, nics as netinfo_nics,
+ networks as netinfo_networks)
+from vdsm.netinfo.cache import (libvirtNets2vdsm, get as netinfo_get,
+ CachingNetInfo, NET_PATH)
from vdsm import udevadm
from vdsm import utils
from vdsm import ipwrapper
diff --git a/lib/vdsm/network/configurators/dhclient.py b/lib/vdsm/network/configurators/dhclient.py
index 3e8f1fc..f74116e 100644
--- a/lib/vdsm/network/configurators/dhclient.py
+++ b/lib/vdsm/network/configurators/dhclient.py
@@ -55,7 +55,7 @@
def _dhclient(self):
# Ask dhclient to stop any dhclient running for the device
- if os.path.exists(os.path.join(netinfo.NET_PATH, self.iface)):
+ if os.path.exists(os.path.join(netinfo.cache.NET_PATH, self.iface)):
kill_dhclient(self.iface, self.family)
cmd = [self.DHCLIENT.cmd, '-%s' % self.family, '-1', '-pf',
self.pidFile, '-lf', self.leaseFile, self.iface]
diff --git a/lib/vdsm/network/configurators/ifcfg.py b/lib/vdsm/network/configurators/ifcfg.py
index 69e1d68..5c29288 100644
--- a/lib/vdsm/network/configurators/ifcfg.py
+++ b/lib/vdsm/network/configurators/ifcfg.py
@@ -41,8 +41,8 @@
from vdsm import dsaversion
from vdsm import hooks
from vdsm import ipwrapper
-from vdsm.netinfo import (bonding as netinfo_bonding, mtus, nics, vlans,
- ifaceUsed, NET_PATH, misc)
+from vdsm.netinfo import (bonding as netinfo_bonding, mtus, nics, vlans, misc)
+from vdsm.netinfo.cache import (ifaceUsed, NET_PATH)
from vdsm import sysctl
from vdsm import utils
from vdsm.netconfpersistence import RunningConfig, PersistentConfig
diff --git a/lib/vdsm/network/configurators/iproute2.py b/lib/vdsm/network/configurators/iproute2.py
index df48314..ba652bd 100644
--- a/lib/vdsm/network/configurators/iproute2.py
+++ b/lib/vdsm/network/configurators/iproute2.py
@@ -20,8 +20,8 @@
from __future__ import absolute_import
import logging
-from vdsm.netinfo import bonding, ifaceUsed, vlans, bridges, mtus
-from vdsm.netinfo import misc
+from vdsm.netinfo import bonding, vlans, bridges, mtus, misc
+from vdsm.netinfo.cache import ifaceUsed
from vdsm import ipwrapper
from vdsm.constants import EXT_BRCTL
from vdsm.ipwrapper import routeAdd, routeDel, ruleAdd, ruleDel, IPRoute2Error
diff --git a/lib/vdsm/network/configurators/qos.py b/lib/vdsm/network/configurators/qos.py
index 303aa8e..73f0e3b 100644
--- a/lib/vdsm/network/configurators/qos.py
+++ b/lib/vdsm/network/configurators/qos.py
@@ -21,7 +21,7 @@
import os
from distutils.version import StrictVersion
-from vdsm.netinfo import ifaceUsed
+from vdsm.netinfo.cache import ifaceUsed
from vdsm.netinfo import qos as netinfo_qos
from vdsm import tc
diff --git a/lib/vdsm/network/models.py b/lib/vdsm/network/models.py
index a5609fd..79c9216 100644
--- a/lib/vdsm/network/models.py
+++ b/lib/vdsm/network/models.py
@@ -22,7 +22,8 @@
import socket
import struct
-from vdsm.netinfo import bonding, ifaceUsed, mtus, nics, CachingNetInfo
+from vdsm.netinfo import bonding, mtus, nics
+from vdsm.netinfo.cache import ifaceUsed, CachingNetInfo
from .errors import ConfigNetworkError
from . import errors as ne
diff --git a/lib/vdsm/tool/unified_persistence.py b/lib/vdsm/tool/unified_persistence.py
index 1975f9c..01358ba 100644
--- a/lib/vdsm/tool/unified_persistence.py
+++ b/lib/vdsm/tool/unified_persistence.py
@@ -23,7 +23,7 @@
from .. import utils
from ..config import config
from ..netconfpersistence import RunningConfig
-from ..netinfo import CachingNetInfo
+from ..netinfo.cache import CachingNetInfo
from ..netinfo import misc, routes
from . import expose
from .upgrade import apply_upgrade
diff --git a/tests/configNetworkTests.py b/tests/configNetworkTests.py
index fb0cd6f..646efe2 100644
--- a/tests/configNetworkTests.py
+++ b/tests/configNetworkTests.py
@@ -96,7 +96,7 @@
'bondings': {'bond00': {'slaves': ['eth5', 'eth6']}}
}
- fakeInfo = netinfo.CachingNetInfo(_netinfo)
+ fakeInfo = netinfo.cache.CachingNetInfo(_netinfo)
nics = ['eth2']
# Test for already existing bridge.
@@ -165,7 +165,7 @@
api._buildBondOptions('jamesbond', {}, _netinfo=FakeNetInfo())
self.assertEquals(cne.exception.errCode, errors.ERR_BAD_PARAMS)
- @MonkeyPatch(netinfo, 'CachingNetInfo', lambda: None)
+ @MonkeyPatch(netinfo.cache, 'CachingNetInfo', lambda: None)
def testValidateNetSetupRemoveParamValidation(self):
attrs = dict(nic='dummy', remove=True,
bridged=True)
diff --git a/tests/functional/networkTests.py b/tests/functional/networkTests.py
index 3bfba16..9431eb3 100644
--- a/tests/functional/networkTests.py
+++ b/tests/functional/networkTests.py
@@ -408,7 +408,7 @@
def _assert_kernel_config_matches_running_config(self):
bare_kernel_config = kernelconfig.KernelConfig(
- vdsm.netinfo.CachingNetInfo())
+ vdsm.netinfo.cache.CachingNetInfo())
bare_running_config = self.vdsm_net.config
normalized_running_config = kernelconfig.normalize(bare_running_config)
# Unify strings to unicode instances so differences are easier to
diff --git a/tests/functional/utils.py b/tests/functional/utils.py
index 021af3a..1e13ef6 100644
--- a/tests/functional/utils.py
+++ b/tests/functional/utils.py
@@ -123,7 +123,7 @@
def _get_netinfo(self):
response = self.getVdsCapabilities()
try:
- return netinfo.CachingNetInfo(response[2])
+ return netinfo.cache.CachingNetInfo(response[2])
except IndexError:
raise Exception('VdsProxy: getVdsCapabilities failed. '
'code:%s msg:%s' % (response[0], response[1]))
diff --git a/tests/netinfoTests.py b/tests/netinfoTests.py
index c506674..46b914b 100644
--- a/tests/netinfoTests.py
+++ b/tests/netinfoTests.py
@@ -27,7 +27,8 @@
from vdsm import ipwrapper
from vdsm import netinfo
-from vdsm.netinfo import addresses, bonding, dns, dhcp, misc, nics, routes, get
+from vdsm.netinfo import addresses, bonding, dns, dhcp, misc, nics, routes
+from vdsm.netinfo.cache import get
from vdsm.netlink import addr as nl_addr
from vdsm.utils import random_iface_name
@@ -118,7 +119,7 @@
# it should.
get()
- @MonkeyPatch(netinfo, 'getLinks', lambda: [])
+ @MonkeyPatch(netinfo.cache, 'getLinks', lambda: [])
@MonkeyPatch(netinfo, 'networks', lambda: {})
def testGetEmpty(self):
result = {}
diff --git a/tests/netmodelsTests.py b/tests/netmodelsTests.py
index 00f1254..ce0b008 100644
--- a/tests/netmodelsTests.py
+++ b/tests/netmodelsTests.py
@@ -21,7 +21,8 @@
#
import os
-from vdsm.netinfo import bonding, mtus, CachingNetInfo
+from vdsm.netinfo import bonding, mtus
+from vdsm.netinfo.cache import CachingNetInfo
from vdsm.network import errors
from vdsm.network.models import Bond, Bridge, IPv4, IPv6, Nic, Vlan
from vdsm.network.models import hierarchy_backing_device, hierarchy_vlan_tag
diff --git a/vdsm.spec.in b/vdsm.spec.in
index c394d72..636585d 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -1104,6 +1104,7 @@
%{python_sitelib}/%{vdsm_name}/netinfo/addresses.py*
%{python_sitelib}/%{vdsm_name}/netinfo/bonding.py*
%{python_sitelib}/%{vdsm_name}/netinfo/bridges.py*
+%{python_sitelib}/%{vdsm_name}/netinfo/cache.py*
%{python_sitelib}/%{vdsm_name}/netinfo/dhcp.py*
%{python_sitelib}/%{vdsm_name}/netinfo/dns.py*
%{python_sitelib}/%{vdsm_name}/netinfo/misc.py*
diff --git a/vdsm/caps.py b/vdsm/caps.py
index 828d83c..de1018d 100644
--- a/vdsm/caps.py
+++ b/vdsm/caps.py
@@ -545,7 +545,7 @@
caps.update(_getVersionInfo())
# TODO: Version requests by engine to ease handling of compatibility.
- netinfo_data = netinfo.get(compatibility=30600)
+ netinfo_data = netinfo.cache.get(compatibility=30600)
caps.update(netinfo_data)
try:
diff --git a/vdsm/vdsm-restore-net-config b/vdsm/vdsm-restore-net-config
index dd230e3..858ab1c 100755
--- a/vdsm/vdsm-restore-net-config
+++ b/vdsm/vdsm-restore-net-config
@@ -30,7 +30,8 @@
from vdsm.config import config
from vdsm import ipwrapper
-from vdsm.netinfo import nics, misc, CachingNetInfo
+from vdsm.netinfo import nics, misc
+from vdsm.netinfo.cache import CachingNetInfo
from vdsm import kernelconfig
from vdsm.constants import P_VDSM_RUN
from vdsm.netconfpersistence import RunningConfig, PersistentConfig, \
diff --git a/vdsm_hooks/ovs/ovs_before_network_setup_ovs.py b/vdsm_hooks/ovs/ovs_before_network_setup_ovs.py
index c8a9238..cee8df9 100644
--- a/vdsm_hooks/ovs/ovs_before_network_setup_ovs.py
+++ b/vdsm_hooks/ovs/ovs_before_network_setup_ovs.py
@@ -21,7 +21,7 @@
import six
-from vdsm.netinfo import CachingNetInfo
+from vdsm.netinfo.cache import CachingNetInfo
from vdsm.network.configurators import libvirt
import hooking
--
To view, visit https://gerrit.ovirt.org/53007
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I892bb86fe9a8580d9028ca7759d27967e55d85f7
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Edward Haas <edwardh at redhat.com>
More information about the vdsm-patches
mailing list