Change in vdsm[master]: wip
ibarkan at redhat.com
ibarkan at redhat.com
Thu Nov 19 13:24:04 UTC 2015
Ido Barkan has uploaded a new change for review.
Change subject: wip
......................................................................
wip
Change-Id: I8804521b42d44a699fbfa2733415c60a10015a3b
Signed-off-by: Ido Barkan <ibarkan at redhat.com>
---
M lib/vdsm/kernelconfig.py
M lib/vdsm/netinfo.py
2 files changed, 220 insertions(+), 222 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/25/48825/1
diff --git a/lib/vdsm/kernelconfig.py b/lib/vdsm/kernelconfig.py
index 50b3deb..ce47f39 100644
--- a/lib/vdsm/kernelconfig.py
+++ b/lib/vdsm/kernelconfig.py
@@ -22,6 +22,7 @@
import netaddr
import string
+from . import netinfo
from . import utils
from .netconfpersistence import BaseConfig
@@ -49,225 +50,246 @@
def _analyze_netinfo_nets(self, netinfo):
for net, net_attr in netinfo.networks.iteritems():
- yield net, self._translate_netinfo_net(net, net_attr)
+ yield net, _translate_netinfo_net(net, net_attr)
def _analyze_netinfo_bonds(self, netinfo):
for bond, bond_attr in netinfo.bondings.iteritems():
- yield bond, self._translate_netinfo_bond(bond_attr)
+ yield bond, _translate_netinfo_bond(bond_attr)
- def _translate_netinfo_net(self, net, net_attr):
- nics, _, vlan_id, bond = \
- self._netinfo.getNicsVlanAndBondingForNetwork(net)
- attributes = {}
- self._translate_bridged(attributes, net_attr)
- self._translate_mtu(attributes, net_attr)
- self._translate_vlan(attributes, vlan_id)
- if bond:
- self._translate_bonding(attributes, bond)
- elif nics:
- self._translate_nics(attributes, nics)
- self._translate_ipaddr(attributes, net_attr)
- self._translate_hostqos(attributes, net_attr)
-
- return attributes
-
- def _translate_hostqos(self, attributes, net_attr):
- if net_attr.get('hostQos'):
- attributes['hostQos'] = self._remove_zero_values_in_net_qos(
- net_attr['hostQos'])
-
- def _translate_ipaddr(self, attributes, net_attr):
- attributes['bootproto'] = 'dhcp' if net_attr['dhcpv4'] else 'none'
- attributes['dhcpv6'] = net_attr['dhcpv6']
- ifcfg = net_attr.get('cfg')
- # TODO: we must not depend on 'cfg', which is configurator-dependent.
- # TODO: Look up in the routing table instead.
- if ifcfg and ifcfg.get('DEFROUTE') == 'yes':
- attributes['defaultRoute'] = True
- else:
- attributes['defaultRoute'] = False
- # only static addresses are part of {Persistent,Running}Config.
- if attributes['bootproto'] == 'none':
- if net_attr['addr']:
- attributes['ipaddr'] = net_attr['addr']
- if net_attr['netmask']:
- attributes['netmask'] = net_attr['netmask']
- if net_attr['gateway']:
- attributes['gateway'] = net_attr['gateway']
- if not attributes['dhcpv6']:
- non_local_addresses = self._translate_ipv6_addr(
- net_attr['ipv6addrs'])
- if non_local_addresses:
- attributes['ipv6addr'] = non_local_addresses
- if net_attr['ipv6gateway'] != '::':
- attributes['ipv6gateway'] = net_attr['ipv6gateway']
-
- def _translate_ipv6_addr(self, ipv6_addrs):
- return [
- addr for addr in ipv6_addrs
- if not netaddr.IPAddress(addr.split('/')[0]).is_link_local()]
-
- def _translate_nics(self, attributes, nics):
- nic, = nics
- attributes['nic'] = nic
-
- def _translate_bonding(self, attributes, bond):
- attributes['bonding'] = bond
-
- def _translate_vlan(self, attributes, vlan):
- if vlan is not None:
- attributes['vlan'] = str(vlan)
-
- def _translate_mtu(self, attributes, net_attr):
- attributes['mtu'] = net_attr['mtu']
-
- def _translate_bridged(self, attributes, net_attr):
- attributes['bridged'] = net_attr['bridged']
- if net_attr['bridged']:
- attributes['stp'] = self._netinfo.stpBooleanize(net_attr['stp'])
-
- def _translate_netinfo_bond(self, bond_attr):
- return {
- 'nics': sorted(bond_attr['slaves']),
- 'options': self._netinfo.bondOptsForIfcfg(bond_attr['opts'])
- }
-
- def _remove_zero_values_in_net_qos(self, net_qos):
- """
- net_qos = {'out': {
- 'ul': {'m1': 0, 'd': 0, 'm2': 8000000},
- 'ls': {'m1': 4000000, 'd': 100000, 'm2': 3000000}}}
- stripped_qos = {'out': {
- 'ul': {'m2': 8000000},
- 'ls': {'m1': 4000000, 'd': 100000, 'm2': 3000000}}}"""
- stripped_qos = {}
- for part, part_config in net_qos.iteritems():
- stripped_qos[part] = dict(part_config) # copy
- for curve, curve_config in part_config.iteritems():
- stripped_qos[part][curve] = dict((k, v) for k, v
- in curve_config.iteritems()
- if v != 0)
- return stripped_qos
-
- def normalize(self, running_config):
+ @staticmethod
+ def normalize(running_config):
# TODO: normalize* methods can become class functions, as they are only
# TODO: dependent in self._netinfo, which is only needed to access
# TODO: netinfo module level functions, that cannot be imported here
# TODO: because of a circular import.
config_copy = copy.deepcopy(running_config)
- self._normalize_bridge(config_copy)
- self._normalize_vlan(config_copy)
- self._normalize_mtu(config_copy)
- self._normalize_blockingdhcp(config_copy)
- self._normalize_dhcp(config_copy)
- self._normalize_bonding_opts(config_copy)
- self._normalize_bonding_nics(config_copy)
- self._normalize_address(config_copy)
- self._normalize_ifcfg_keys(config_copy)
+ _normalize_bridge(config_copy)
+ _normalize_vlan(config_copy)
+ _normalize_mtu(config_copy)
+ _normalize_blockingdhcp(config_copy)
+ _normalize_dhcp(config_copy)
+ _normalize_bonding_opts(config_copy)
+ _normalize_bonding_nics(config_copy)
+ _normalize_address(config_copy)
+ _normalize_ifcfg_keys(config_copy)
return config_copy
- def _normalize_vlan(self, config_copy):
- for net_attr in config_copy.networks.itervalues():
- if 'vlan' in net_attr:
- net_attr['vlan'] = str(net_attr['vlan'])
- def _normalize_bridge(self, config_copy):
- for net_attr in config_copy.networks.itervalues():
- if utils.tobool(net_attr.get('bridged', True)):
- net_attr['bridged'] = True
- self._normalize_stp(net_attr)
- else:
- net_attr['bridged'] = False
+def _translate_netinfo_net(net, net_attr):
+ nics, _, vlan_id, bond = \
+ _netinfo.getNicsVlanAndBondingForNetwork(net)
+ attributes = {}
+ _translate_bridged(attributes, net_attr)
+ _translate_mtu(attributes, net_attr)
+ _translate_vlan(attributes, vlan_id)
+ if bond:
+ _translate_bonding(attributes, bond)
+ elif nics:
+ _translate_nics(attributes, nics)
+ _translate_ipaddr(attributes, net_attr)
+ _translate_hostqos(attributes, net_attr)
- def _normalize_stp(self, net_attr):
- stp = net_attr.pop('stp', net_attr.pop('STP', None))
- net_attr['stp'] = self._netinfo.stpBooleanize(
- stp)
+ return attributes
- def _normalize_mtu(self, config_copy):
- for net_attr in config_copy.networks.itervalues():
- if 'mtu' in net_attr:
- net_attr['mtu'] = str(net_attr['mtu'])
- else:
- net_attr['mtu'] = self._netinfo.getDefaultMtu()
- def _normalize_blockingdhcp(self, config_copy):
- for net_attr in config_copy.networks.itervalues():
- if 'blockingdhcp' in net_attr:
- net_attr.pop('blockingdhcp')
+def _translate_ipaddr(attributes, net_attr):
+ attributes['bootproto'] = 'dhcp' if net_attr['dhcpv4'] else 'none'
+ attributes['dhcpv6'] = net_attr['dhcpv6']
+ ifcfg = net_attr.get('cfg')
+ # TODO: we must not depend on 'cfg', which is configurator-dependent.
+ # TODO: Look up in the routing table instead.
+ if ifcfg and ifcfg.get('DEFROUTE') == 'yes':
+ attributes['defaultRoute'] = True
+ else:
+ attributes['defaultRoute'] = False
+ # only static addresses are part of {Persistent,Running}Config.
+ if attributes['bootproto'] == 'none':
+ if net_attr['addr']:
+ attributes['ipaddr'] = net_attr['addr']
+ if net_attr['netmask']:
+ attributes['netmask'] = net_attr['netmask']
+ if net_attr['gateway']:
+ attributes['gateway'] = net_attr['gateway']
+ if not attributes['dhcpv6']:
+ non_local_addresses = _translate_ipv6_addr(net_attr['ipv6addrs'])
+ if non_local_addresses:
+ attributes['ipv6addr'] = non_local_addresses
+ if net_attr['ipv6gateway'] != '::':
+ attributes['ipv6gateway'] = net_attr['ipv6gateway']
- def _normalize_dhcp(self, config_copy):
- for net_attr in config_copy.networks.itervalues():
- dhcp = net_attr.get('bootproto')
- if dhcp is None:
- net_attr['bootproto'] = 'none'
- else:
- net_attr['bootproto'] = dhcp
- net_attr['dhcpv6'] = net_attr.get('dhcpv6', False)
- return config_copy
- def _normalize_bonding_opts(self, config_copy):
- for bond, bond_attr in config_copy.bonds.iteritems():
- # TODO: globalize default bond options from Bond in models.py
- normalized_opts = self._parse_bond_options(
- bond_attr.get('options'))
- bond_attr['options'] = self._netinfo.bondOptsForIfcfg(
- normalized_opts)
- # before d18e2f10 bondingOptions were also part of networks, so in case
- # we are upgrading from an older version, they should be ignored if
- # they exist.
- # REQUIRED_FOR upgrade from vdsm<=4.16.20
- for net_attr in config_copy.networks.itervalues():
- net_attr.pop('bondingOptions', None)
+def _translate_ipv6_addr(ipv6_addrs):
+ return [
+ addr for addr in ipv6_addrs
+ if not netaddr.IPAddress(addr.split('/')[0]).is_link_local()]
- def _normalize_bonding_nics(self, config_copy):
- for bond_attr in config_copy.bonds.itervalues():
- if 'nics' in bond_attr:
- bond_attr['nics'].sort()
- def _normalize_address(self, config_copy):
- for net_attr in config_copy.networks.itervalues():
- prefix = net_attr.pop('prefix', None)
- if prefix is not None:
- net_attr['netmask'] = self._netinfo.prefix2netmask(int(prefix))
- if 'ipv6addr' in net_attr:
- net_attr['ipv6addr'] = [net_attr['ipv6addr']]
- if 'defaultRoute' not in net_attr:
- net_attr['defaultRoute'] = False
+def _translate_nics(attributes, nics):
+ nic, = nics
+ attributes['nic'] = nic
- def _normalize_ifcfg_keys(self, config_copy):
- # ignore keys in persisted networks that might originate from vdsm-reg.
- # these might be a result of calling setupNetworks with ifcfg values
- # that come from the original interface that is serving the management
- # network. for 3.5, VDSM still supports passing arbitrary values
- # directly to the ifcfg files, e.g. 'IPV6_AUTOCONF=no'. we filter them
- # out here since kernelConfig will never report them.
- # TODO: remove when 3.5 is unsupported.
- def unsupported(key):
- return set(key) <= set(
- string.ascii_uppercase + string.digits + '_')
- for net_attr in config_copy.networks.itervalues():
- for k in net_attr.keys():
- if unsupported(k):
- net_attr.pop(k)
+def _translate_bonding(attributes, bond):
+ attributes['bonding'] = bond
- def _parse_bond_options(self, opts):
- if not opts:
- return {}
- opts = dict((pair.split('=', 1) for pair in opts.split()))
+def _translate_vlan(attributes, vlan):
+ if vlan is not None:
+ attributes['vlan'] = str(vlan)
- # force a numeric bonding mode
- mode = opts.get('mode', self._netinfo.getDefaultBondingMode())
- if mode in _BONDING_MODES:
- numeric_mode = mode
+
+def _translate_mtu(attributes, net_attr):
+ attributes['mtu'] = net_attr['mtu']
+
+
+def _translate_bridged(attributes, net_attr):
+ attributes['bridged'] = net_attr['bridged']
+ if net_attr['bridged']:
+ attributes['stp'] = netinfo.stp_booleanize(net_attr['stp'])
+
+
+def _translate_netinfo_bond(bond_attr):
+ return {
+ 'nics': sorted(bond_attr['slaves']),
+ 'options': netinfo.bondOptsForIfcfg(bond_attr['opts'])
+ }
+
+
+def _translate_hostqos(attributes, net_attr):
+ if net_attr.get('hostQos'):
+ attributes['hostQos'] = _remove_zero_values_in_net_qos(
+ net_attr['hostQos'])
+
+
+def _remove_zero_values_in_net_qos( net_qos):
+ """
+ net_qos = {'out': {
+ 'ul': {'m1': 0, 'd': 0, 'm2': 8000000},
+ 'ls': {'m1': 4000000, 'd': 100000, 'm2': 3000000}}}
+ stripped_qos = {'out': {
+ 'ul': {'m2': 8000000},
+ 'ls': {'m1': 4000000, 'd': 100000, 'm2': 3000000}}}"""
+ stripped_qos = {}
+ for part, part_config in net_qos.iteritems():
+ stripped_qos[part] = dict(part_config) # copy
+ for curve, curve_config in part_config.iteritems():
+ stripped_qos[part][curve] = dict((k, v) for k, v
+ in curve_config.iteritems()
+ if v != 0)
+ return stripped_qos
+
+
+def _normalize_stp(net_attr):
+ stp = net_attr.pop('stp', net_attr.pop('STP', None))
+ net_attr['stp'] = netinfo.stp_booleanize(stp)
+
+
+def _normalize_vlan(config_copy):
+ for net_attr in config_copy.networks.itervalues():
+ if 'vlan' in net_attr:
+ net_attr['vlan'] = str(net_attr['vlan'])
+
+
+def _normalize_bridge(config_copy):
+ for net_attr in config_copy.networks.itervalues():
+ if utils.tobool(net_attr.get('bridged', True)):
+ net_attr['bridged'] = True
+ _normalize_stp(net_attr)
else:
- numeric_mode = _BONDING_MODES_REVERSED[mode]
- opts['mode'] = numeric_mode
+ net_attr['bridged'] = False
- defaults = self._netinfo.getDefaultBondingOptions(numeric_mode)
- return dict(
- (k, v) for k, v in opts.iteritems() if v != defaults.get(k))
\ No newline at end of file
+
+def _normalize_mtu(config_copy):
+ for net_attr in config_copy.networks.itervalues():
+ if 'mtu' in net_attr:
+ net_attr['mtu'] = str(net_attr['mtu'])
+ else:
+ net_attr['mtu'] = netinfo.DEFAULT_MTU
+
+
+def _normalize_blockingdhcp(config_copy):
+ for net_attr in config_copy.networks.itervalues():
+ if 'blockingdhcp' in net_attr:
+ net_attr.pop('blockingdhcp')
+
+
+def _normalize_dhcp(config_copy):
+ for net_attr in config_copy.networks.itervalues():
+ dhcp = net_attr.get('bootproto')
+ if dhcp is None:
+ net_attr['bootproto'] = 'none'
+ else:
+ net_attr['bootproto'] = dhcp
+ net_attr['dhcpv6'] = net_attr.get('dhcpv6', False)
+ return config_copy
+
+
+def _normalize_bonding_opts(config_copy):
+ for bond, bond_attr in config_copy.bonds.iteritems():
+ # TODO: globalize default bond options from Bond in models.py
+ normalized_opts = _parse_bond_options(
+ bond_attr.get('options'))
+ bond_attr['options'] = netinfo.bondOptsForIfcfg(normalized_opts)
+ # before d18e2f10 bondingOptions were also part of networks, so in case
+ # we are upgrading from an older version, they should be ignored if
+ # they exist.
+ # REQUIRED_FOR upgrade from vdsm<=4.16.20
+ for net_attr in config_copy.networks.itervalues():
+ net_attr.pop('bondingOptions', None)
+
+
+def _normalize_bonding_nics(config_copy):
+ for bond_attr in config_copy.bonds.itervalues():
+ if 'nics' in bond_attr:
+ bond_attr['nics'].sort()
+
+
+def _normalize_address(config_copy):
+ for net_attr in config_copy.networks.itervalues():
+ prefix = net_attr.pop('prefix', None)
+ if prefix is not None:
+ net_attr['netmask'] = netinfo.prefix2netmask(int(prefix))
+ if 'ipv6addr' in net_attr:
+ net_attr['ipv6addr'] = [net_attr['ipv6addr']]
+ if 'defaultRoute' not in net_attr:
+ net_attr['defaultRoute'] = False
+
+
+def _normalize_ifcfg_keys(config_copy):
+ # ignore keys in persisted networks that might originate from vdsm-reg.
+ # these might be a result of calling setupNetworks with ifcfg values
+ # that come from the original interface that is serving the management
+ # network. for 3.5, VDSM still supports passing arbitrary values
+ # directly to the ifcfg files, e.g. 'IPV6_AUTOCONF=no'. we filter them
+ # out here since kernelConfig will never report them.
+ # TODO: remove when 3.5 is unsupported.
+ def unsupported(key):
+ return set(key) <= set(
+ string.ascii_uppercase + string.digits + '_')
+
+ for net_attr in config_copy.networks.itervalues():
+ for k in net_attr.keys():
+ if unsupported(k):
+ net_attr.pop(k)
+
+
+def _parse_bond_options(opts):
+ if not opts:
+ return {}
+
+ opts = dict((pair.split('=', 1) for pair in opts.split()))
+
+ # force a numeric bonding mode
+ mode = opts.get('mode',
+ netinfo.getAllDefaultBondingOptions()['0']['mode'][-1])
+ if mode in _BONDING_MODES:
+ numeric_mode = mode
+ else:
+ numeric_mode = _BONDING_MODES_REVERSED[mode]
+ opts['mode'] = numeric_mode
+
+ defaults = netinfo.getDefaultBondingOptions(numeric_mode)
+ return dict(
+ (k, v) for k, v in opts.iteritems() if v != defaults.get(k))
\ No newline at end of file
diff --git a/lib/vdsm/netinfo.py b/lib/vdsm/netinfo.py
index cb185b9..8a36a40 100644
--- a/lib/vdsm/netinfo.py
+++ b/lib/vdsm/netinfo.py
@@ -403,7 +403,7 @@
@memoized
-def _getAllDefaultBondingOptions():
+def getAllDefaultBondingOptions():
"""
Return default options per mode, in a dictionary of dictionaries. All keys
are numeric modes stored as strings for coherence with 'mode' option value.
@@ -418,7 +418,7 @@
Return default options for the given mode. If it is None, return options
for the default mode (usually '0').
"""
- defaults = _getAllDefaultBondingOptions()
+ defaults = getAllDefaultBondingOptions()
if mode is None:
mode = defaults['0']['mode'][-1]
@@ -439,7 +439,7 @@
if val and val != defaults.get(opt)))
-def _bondOptsForIfcfg(opts):
+def bondOptsForIfcfg(opts):
"""
Options having symbolic values, e.g. 'mode', are presented by sysfs in
the order symbolic name, numeric value, e.g. 'balance-rr 0'.
@@ -521,7 +521,7 @@
def _bondOptsCompat(info):
"""Add legacy ifcfg option if missing."""
if info['opts'] and 'BONDING_OPTS' not in info['cfg']:
- info['cfg']['BONDING_OPTS'] = _bondOptsForIfcfg(info['opts'])
+ info['cfg']['BONDING_OPTS'] = bondOptsForIfcfg(info['opts'])
def _bondCustomOpts(dev, devinfo, running_config):
@@ -982,30 +982,6 @@
lnics.append(port)
return lnics, vlan, vlanid, bonding
-
- @staticmethod
- def getDefaultMtu():
- return DEFAULT_MTU
-
- @staticmethod
- def getDefaultBondingOptions(mode=None):
- return getDefaultBondingOptions(mode)
-
- @staticmethod
- def getDefaultBondingMode():
- return _getAllDefaultBondingOptions()['0']['mode'][-1]
-
- @staticmethod
- def bondOptsForIfcfg(opts):
- return _bondOptsForIfcfg(opts)
-
- @staticmethod
- def prefix2netmask(prefix):
- return prefix2netmask(prefix)
-
- @staticmethod
- def stpBooleanize(value):
- return stp_booleanize(value)
def ifaceUsers(self, iface):
"Returns a list of entities using the interface"
--
To view, visit https://gerrit.ovirt.org/48825
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I8804521b42d44a699fbfa2733415c60a10015a3b
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Ido Barkan <ibarkan at redhat.com>
More information about the vdsm-patches
mailing list