Example #1
0
File: api.py Project: fancyKai/vdsm
def _add_missing_networks(configurator, networks, bondings, logger,
                          _netinfo=None):
    # We need to use the newest host info
    if _netinfo is None:
        _netinfo = CachingNetInfo()
    else:
        _netinfo.updateDevices()

    for network, attrs in networks.iteritems():
        if 'remove' in attrs:
            continue

        d = dict(attrs)
        if 'bonding' in d:
            d.update(_buildBondOptions(d['bonding'], bondings, _netinfo))
        else:
            d['nics'] = [d.pop('nic')] if 'nic' in d else []

        logger.debug("Adding network %r", network)
        try:
            _addNetwork(network, configurator=configurator,
                        implicitBonding=True, _netinfo=_netinfo, **d)
        except ConfigNetworkError as cne:
            if cne.errCode == ne.ERR_FAILED_IFUP:
                logger.debug("Adding network %r failed. Running "
                             "orphan-devices cleanup", network)
                _emergencyNetworkCleanup(network, attrs,
                                         configurator)
            raise

        _netinfo.updateDevices()  # Things like a bond mtu can change
Example #2
0
File: api.py Project: fancyKai/vdsm
def setupNetworks(networks, bondings, **options):
    """Add/Edit/Remove configuration for networks and bondings.

    Params:
        networks - dict of key=network, value=attributes
            where 'attributes' is a dict with the following optional items:
                        vlan=<id>
                        bonding="<name>" | nic="<name>"
                        (bonding and nics are mutually exclusive)
                        ipaddr="<ipv4>"
                        netmask="<ipv4>"
                        gateway="<ipv4>"
                        bootproto="..."
                        ipv6addr="<ipv6>[/<prefixlen>]"
                        ipv6gateway="<ipv6>"
                        ipv6autoconf="0|1"
                        dhcpv6="0|1"
                        defaultRoute=True|False
                        (other options will be passed to the config file AS-IS)
                        -- OR --
                        remove=True (other attributes can't be specified)

        bondings - dict of key=bonding, value=attributes
            where 'attributes' is a dict with the following optional items:
                        nics=["<nic1>" , "<nic2>", ...]
                        options="<bonding-options>"
                        -- OR --
                        remove=True (other attributes can't be specified)

        options - dict of options, such as:
                        connectivityCheck=0|1
                        connectivityTimeout=<int>
                        _inRollback=True|False

    Notes:
        When you edit a network that is attached to a bonding, it's not
        necessary to re-specify the bonding (you need only to note
        the attachment in the network's attributes). Similarly, if you edit
        a bonding, it's not necessary to specify its networks.
    """
    logger = logging.getLogger("setupNetworks")

    logger.debug("Setting up network according to configuration: "
                 "networks:%r, bondings:%r, options:%r" % (networks,
                                                           bondings, options))

    _canonize_networks(networks)
    # TODO: Add _canonize_bondings(bondings)

    logging.debug("Validating configuration")
    _validateNetworkSetup(networks, bondings)

    bondings, networks, options = _apply_hook(bondings, networks, options)

    libvirt_nets = netinfo_networks()
    _netinfo = CachingNetInfo(_netinfo=netinfo_get(
        libvirtNets2vdsm(libvirt_nets)))
    connectivity_check_networks = set()

    logger.debug("Applying...")
    in_rollback = options.get('_inRollback', False)
    kernel_config = kernelconfig.KernelConfig(_netinfo)
    normalized_config = kernelconfig.normalize(
        netconfpersistence.BaseConfig(networks, bondings))
    with ConfiguratorClass(in_rollback) as configurator:
        # Remove edited networks and networks with 'remove' attribute
        for network, attrs in networks.items():
            if network in _netinfo.networks:
                logger.debug("Removing network %r", network)
                keep_bridge = _should_keep_bridge(
                    network_attrs=normalized_config.networks[network],
                    currently_bridged=_netinfo.networks[network]['bridged'],
                    net_kernel_config=kernel_config.networks[network]
                )

                _delNetwork(network, configurator=configurator,
                            implicitBonding=False, _netinfo=_netinfo,
                            keep_bridge=keep_bridge)
                _netinfo.del_network(network)
                _netinfo.updateDevices()
            elif network in libvirt_nets:
                # If the network was not in _netinfo but is in the networks
                # returned by libvirt, it means that we are dealing with
                # a broken network.
                logger.debug('Removing broken network %r', network)
                _delBrokenNetwork(network, libvirt_nets[network],
                                  configurator=configurator)
                _netinfo.updateDevices()
            elif 'remove' in attrs:
                raise ConfigNetworkError(ne.ERR_BAD_BRIDGE, "Cannot delete "
                                         "network %r: It doesn't exist in the "
                                         "system" % network)
            else:
                connectivity_check_networks.add(network)

        _handleBondings(bondings, configurator, in_rollback)

        _add_missing_networks(configurator, networks, bondings,
                              logger, _netinfo)

        _check_connectivity(connectivity_check_networks, networks, bondings,
                            options, logger)

    hooks.after_network_setup(_buildSetupHookDict(networks, bondings, options))