예제 #1
0
def _classify_nets_bonds_config(persistent_config):
    """
    Return the configuration of networks and bonds, separating the ones changed
    and the ones unchanged:
    changed_nets, changed_bonds, unchanged_nets, unchanged_bonds
    """
    net_info = NetInfo(netswitch.configurator.netinfo())
    current_config = kernelconfig.KernelConfig(net_info)
    desired_config = kernelconfig.normalize(persistent_config)

    changed_nets_names, extra_nets_names = _classify_entities_difference(
        desired_config.networks, current_config.networks
    )

    changed_bonds_names, extra_bonds_names = _classify_entities_difference(
        desired_config.bonds, current_config.bonds
    )

    changed_nets = {
        net: persistent_config.networks[net] for net in changed_nets_names
    }
    changed_bonds = {
        bond: persistent_config.bonds[bond] for bond in changed_bonds_names
    }
    extra_nets = {net: {'remove': True} for net in extra_nets_names}
    extra_bonds = {
        bond: {'remove': True}
        for bond in extra_bonds_names
        if _owned_ifcfg(bond)
    }

    return changed_nets, changed_bonds, extra_nets, extra_bonds
예제 #2
0
파일: configurator.py 프로젝트: minqf/vdsm
def _setup_nmstate(networks, bondings, options, in_rollback):
    """
    Setup the networks using nmstate as the backend provider.
    nmstate handles the rollback by itself in case of an error during the
    transaction or in case the resulted state does not include the desired one.

    In order to support the connectivity check, the "regular" rollback is
    used (the Transaction context).
    """
    logging.info('Processing setup through nmstate')
    desired_state = nmstate.generate_state(networks, bondings)
    logging.info('Desired state: %s', desired_state)
    _setup_dynamic_src_routing(networks)
    nmstate.setup(desired_state, verify_change=not in_rollback)
    net_info = NetInfo(netinfo_get())

    with Transaction(in_rollback=in_rollback, persistent=False) as config:
        _setup_qos(networks, net_info, config.networks)
        for net_name, net_attrs in six.viewitems(networks):
            if net_attrs.get('remove'):
                config.removeNetwork(net_name)
        for net_name, net_attrs in six.viewitems(networks):
            if not net_attrs.get('remove'):
                config.setNetwork(net_name, net_attrs)
        for bond_name, bond_attrs in six.viewitems(bondings):
            if bond_attrs.get('remove'):
                config.removeBonding(bond_name)
        for bond_name, bond_attrs in six.viewitems(bondings):
            if not bond_attrs.get('remove'):
                config.setBonding(bond_name, bond_attrs)
        _setup_static_src_routing(networks)
        config.save()
        link_setup.setup_custom_bridge_opts(networks)
        connectivity.check(options)
예제 #3
0
def _classify_nets_bonds_config(persistent_config):
    """
    Return the configuration of networks and bonds, separating the ones changed
    and the ones unchanged:
    changed_nets, changed_bonds, unchanged_nets, unchanged_bonds
    """
    net_info = NetInfo(netswitch.configurator.netinfo())
    current_config = kernelconfig.KernelConfig(net_info)
    desired_config = kernelconfig.normalize(persistent_config)

    changed_nets_names, extra_nets_names = _classify_entities_difference(
        desired_config.networks, current_config.networks)

    changed_bonds_names, extra_bonds_names = _classify_entities_difference(
        desired_config.bonds, current_config.bonds)

    changed_nets = {
        net: persistent_config.networks[net]
        for net in changed_nets_names
    }
    changed_bonds = {
        bond: persistent_config.bonds[bond]
        for bond in changed_bonds_names
    }
    extra_nets = {net: {'remove': True} for net in extra_nets_names}
    # We cannot ensure which bond is being owned by us, so we should not
    # remove them
    # TODO This should be removed once the cleanup is done
    extra_bonds = {}

    return changed_nets, changed_bonds, extra_nets, extra_bonds
예제 #4
0
def _create_fake_netinfo(switch):
    common_net_attrs = {
        'ipv6addrs': [],
        'gateway': '',
        'dhcpv4': False,
        'netmask': '',
        'ipv4defaultroute': False,
        'stp': 'off',
        'ipv4addrs': [],
        'mtu': 1500,
        'ipv6gateway': '::',
        'dhcpv6': False,
        'ipv6autoconf': False,
        'addr': '',
        'ports': [],
        'switch': switch
    }

    common_bond_attrs = {'opts': {'mode': '0'}, 'switch': switch}

    fake_netinfo = {
        'networks': {
            'fakebrnet1':
            dict(iface='eth0',
                 bond='',
                 bridged=False,
                 nics=['eth0'],
                 **common_net_attrs),
            'fakevlannet1':
            dict(iface='eth1.1',
                 bond='',
                 bridged=False,
                 nics=['eth1'],
                 vlanid=1,
                 **common_net_attrs),
            'fakebondnet1':
            dict(iface='bond0',
                 bond='bond0',
                 bridged=False,
                 nics=['eth2', 'eth3'],
                 **common_net_attrs)
        },
        'vlans': {
            'eth1.1': {
                'iface': 'eth1',
                'addr': '10.10.10.10',
                'netmask': '255.255.0.0',
                'mtu': 1500,
                'vlanid': 1
            }
        },
        'nics': ['eth0', 'eth1', 'eth2', 'eth3'],
        'bridges': {},
        'bondings': {
            'bond0': dict(slaves=['eth2', 'eth3'], **common_bond_attrs)
        },
        'nameservers': [],
    }
    return NetInfo(fake_netinfo)
예제 #5
0
파일: qos.py 프로젝트: rexhsu/vdsm
def _is_explicit_defined_default_class(dev):
    """
    A default class is defined explicitly when a non-vlan network has hostQos
    definitions.
    """
    netinfo = NetInfo(cache_get())
    for attrs in six.itervalues(netinfo.networks):
        if 'vlan' not in attrs and 'hostQos' in attrs and (
           attrs['iface'] == dev):
            return True

    return False
예제 #6
0
파일: qos.py 프로젝트: wuyeliang/vdsm
def _is_explicit_defined_default_class(dev):
    """
    A default class is defined explicitly when a non-vlan network has hostQos
    definitions.
    """
    netinfo = NetInfo(cache_get())
    for attrs in six.viewvalues(netinfo.networks):
        if 'vlan' not in attrs and 'hostQos' in attrs:
            ports = attrs['ports'] if attrs['bridged'] else [attrs['iface']]
            if dev in ports:
                return True

    return False
예제 #7
0
파일: configurator.py 프로젝트: kofe88/vdsm
def validate(networks, bondings, net_info):
    legacy_nets, ovs_nets, legacy_bonds, ovs_bonds = _split_switch_type(
        networks, bondings, net_info)

    use_legacy_switch = legacy_nets or legacy_bonds
    use_ovs_switch = ovs_nets or ovs_bonds
    if use_legacy_switch and use_ovs_switch:
        raise ne.ConfigNetworkError(
            ne.ERR_BAD_PARAMS,
            'Mixing of legacy and OVS networks is not supported inside one '
            'setupNetworks() call.')

    validator.validate_southbound_devices_usages(networks, NetInfo(net_info))
    validator.validate_network_setup(networks, bondings, net_info)
    if use_legacy_switch:
        legacy_switch.validate_network_setup(legacy_nets)
예제 #8
0
파일: netupgrade.py 프로젝트: asasuou/vdsm
def upgrade():
    rconfig = RunningConfig()
    pconfig = PersistentConfig()

    libvirt_networks = libvirtnetwork.networks()

    _upgrade_volatile_running_config(rconfig)

    if rconfig.config_exists() or pconfig.config_exists():
        _upgrade_unified_configuration(rconfig)
        _upgrade_unified_configuration(pconfig)
    else:
        # In case unified config has not existed before, it is assumed that
        # the networks existance have been persisted in libvirt db.
        vdsmnets = libvirt_vdsm_nets(libvirt_networks)
        _create_unified_configuration(rconfig, NetInfo(netinfo(vdsmnets)))

    _cleanup_libvirt_networks(libvirt_networks)
예제 #9
0
def _handle_setup(nets, bonds, running_config, nets_by_nic):
    commands = []
    netinfo = NetInfo(netswitch.netinfo())
    for bond, attrs in six.iteritems(bonds):
        if 'remove' not in attrs:
            _validate_bond_configuration(attrs, netinfo)
            if bond in running_config.bonds:
                commands.extend(_edit_ovs_bond(bond, attrs, running_config))
            else:
                commands.extend(_setup_ovs_bond(bond, attrs, running_config))
    for net, attrs in six.iteritems(nets):
        if 'remove' not in attrs:
            _validate_net_configuration(net, attrs, running_config, netinfo)
            if net in running_config.networks:
                commands.extend(_edit_ovs_net(net, attrs, running_config,
                                              nets_by_nic))
            else:
                commands.extend(_setup_ovs_net(net, attrs, running_config,
                                               nets_by_nic))
    return commands
예제 #10
0
 def __init__(self, nets, bonds, net_info):
     self._nets = nets
     self._bonds = bonds
     self._net_info = NetInfo(net_info)
     self._desired_config = self._create_desired_config()
     self._running_config = RunningConfig()
예제 #11
0
def _getNetInfo():
    def _processNetworks(netinfo):
        networks = {}
        defaultGateway = routes.getDefaultGateway()

        for network, netParams in netinfo.networks.iteritems():
            networks[network] = {}

            # Translate key/value pairs from netinfo to unified if key matches
            for key, value in netParams.iteritems():
                if key in NET_ATTR_WHITELIST and value != "":
                    networks[network][key] = NET_ATTR_WHITELIST[key](value)

            networks[network]['bridged'] = netParams['bridged']

            # Determine devices: nic/bond -> vlan -> bridge
            topLevelDevice = netParams['iface']
            if netParams['bridged']:
                devices = (netinfo.nics.keys() + netinfo.vlans.keys() +
                           netinfo.bondings.keys())
                nonVnicPorts = [
                    dev for dev in netParams['ports'] if dev in devices
                ]
                # A network should only ever have (at most) an underlying
                # device hierarchy
                if nonVnicPorts:
                    physicalDevice, = nonVnicPorts
                else:
                    physicalDevice = None  # vdsm allows nicless VM nets
            else:
                physicalDevice = topLevelDevice

            # Copy ip addressing information
            bootproto = str(misc.getIfaceCfg(topLevelDevice).get('BOOTPROTO'))
            if bootproto == 'dhcp':
                networks[network]['bootproto'] = bootproto
            else:
                if netParams['addr'] != '':
                    networks[network]['ipaddr'] = netParams['addr']
                if netParams['netmask'] != '':
                    networks[network]['netmask'] = netParams['netmask']
                if netParams['gateway'] != '':
                    networks[network]['gateway'] = netParams['gateway']

            if defaultGateway is not None:
                networks[network]['defaultRoute'] = (
                    defaultGateway.device == topLevelDevice)

            # What if the 'physical device' is actually a VLAN?
            if physicalDevice in netinfo.vlans:
                vlanDevice = physicalDevice
                networks[network]['vlan'] = \
                    str(netinfo.vlans[vlanDevice]['vlanid'])
                # The 'new' physical device is the VLAN's device
                physicalDevice = netinfo.vlans[vlanDevice]['iface']

            # Is the physical device a bond or a nic?
            if physicalDevice in netinfo.bondings:
                networks[network]['bonding'] = physicalDevice
            elif physicalDevice in netinfo.nics:
                networks[network]['nic'] = physicalDevice
            else:  # Nic-less networks
                pass

        return networks

    def _processBondings(netinfo):
        bondings = {}
        for bonding, bondingParams in netinfo.bondings.iteritems():
            # If the bond is unused, skip it
            if not bondingParams['slaves']:
                continue

            bondings[bonding] = {'nics': bondingParams['slaves']}
            bondingOptions = misc.getIfaceCfg(bonding). \
                get('BONDING_OPTS')
            if bondingOptions:
                bondings[bonding]['options'] = bondingOptions

        return bondings

    netinfo = NetInfo(netswitch.netinfo())
    networks = _processNetworks(netinfo)
    bonds = _processBondings(netinfo)

    used_bonds = frozenset(attr['bonding'] for attr in networks.values()
                           if 'bonding' in attr)

    # we do not want to touch bonds that are unrelated to us
    for bonding in bonds.keys():
        if not _owned(bonding) and bonding not in used_bonds:
            del bonds[bonding]

    # assert that all bonds that we depend on are persisted
    for network, attributes in networks.iteritems():
        bond = attributes.get('bonding')
        if bond is None:
            continue

        if bond not in bonds:
            raise Exception('Network %s depends on missing bond %s' %
                            (network, bond))

    return networks, bonds