Exemple #1
0
 def __init__(self, inRollback=False):
     self.unifiedPersistence = \
         config.get('vars', 'net_persistence') == 'unified'
     super(Ifcfg, self).__init__(ConfigWriter(self.unifiedPersistence),
                                 inRollback)
     if self.unifiedPersistence:
         self.runningConfig = RunningConfig()
Exemple #2
0
class PyrouteTwo(Iproute2):
    def __init__(self, inRollback=False):
        super(Iproute2, self).__init__(ConfigApplier(), inRollback)
        self.runningConfig = RunningConfig()

    def commit(self):
        self.configApplier.releaseSocket()
        self.configApplier = None
        self.runningConfig.save()
        self.runningConfig = None
Exemple #3
0
class PyrouteTwo(Iproute2):
    def __init__(self, inRollback=False):
        super(Iproute2, self).__init__(ConfigApplier(), inRollback)
        self.runningConfig = RunningConfig()

    def commit(self):
        self.configApplier.releaseSocket()
        self.configApplier = None
        self.runningConfig.save()
        self.runningConfig = None
Exemple #4
0
class Ifcfg(Configurator):
    # TODO: Do all the configApplier interaction from here.
    def __init__(self, inRollback=False):
        self.unifiedPersistence = \
            config.get('vars', 'net_persistence') == 'unified'
        super(Ifcfg, self).__init__(ConfigWriter(self.unifiedPersistence),
                                    inRollback)
        if self.unifiedPersistence:
            self.runningConfig = RunningConfig()

    def begin(self):
        if self.configApplier is None:
            self.configApplier = ConfigWriter(self.unifiedPersistence)
        if self.unifiedPersistence and self.runningConfig is None:
            self.runningConfig = RunningConfig()

    def rollback(self):
        self.configApplier.restoreBackups()
        self.configApplier = None
        if self.unifiedPersistence:
            self.runningConfig = None

    def commit(self):
        self.configApplier = None
        if self.unifiedPersistence:
            self.runningConfig.save()
            self.runningConfig = None

    def configureBridge(self, bridge, **opts):
        self.configApplier.addBridge(bridge, **opts)
        ifdown(bridge.name)
        if bridge.port:
            bridge.port.configure(**opts)
        self._addSourceRoute(bridge)
        ifup(bridge.name, bridge.ipConfig.async)

    def configureVlan(self, vlan, **opts):
        self.configApplier.addVlan(vlan, **opts)
        vlan.device.configure(**opts)
        self._addSourceRoute(vlan)
        ifup(vlan.name, vlan.ipConfig.async)

    def configureBond(self, bond, **opts):
        self.configApplier.addBonding(bond, **opts)
        if not netinfo.isVlanned(bond.name):
            for slave in bond.slaves:
                ifdown(slave.name)
        for slave in bond.slaves:
            slave.configure(**opts)
        self._addSourceRoute(bond)
        ifup(bond.name, bond.ipConfig.async)
def main():
    setup_nets_config = hooking.read_json()
    log('Hook started, handling: %s' % setup_nets_config)

    running_config = RunningConfig()
    networks = setup_nets_config['request']['networks']
    bondings = setup_nets_config['request']['bondings']

    in_ovs_rollback = setup_nets_config['request']['options'].get(
        '_inOVSRollback')

    if in_ovs_rollback:
        log('OVS rollback is to be done.')
        _rollback(running_config)
        _set_nets_bonds(setup_nets_config['request'], {}, {})
        log('OVS rollback finished, returning empty networks and bondings '
            'configuration back to VDSM.')
    else:
        ovs_nets, non_ovs_nets, ovs_bonds, non_ovs_bonds = \
            _separate_ovs_nets_bonds(networks, bondings, running_config)
        if ovs_nets or ovs_bonds:
            _configure(ovs_nets, ovs_bonds, running_config)
            _set_nets_bonds(setup_nets_config['request'], non_ovs_nets,
                            non_ovs_bonds)
        log('Hook finished, returning non-OVS networks and bondings back to '
            'VDSM: %s' % setup_nets_config)

    hooking.write_json(setup_nets_config)
Exemple #6
0
def ovs_networks_stats(stats):
    """Get OVS networks from RunningConfig and assign them network stats
    dictionaries from underlying devices. Fake bridges and bonds already have
    stats with their names.

    Note, that it takes some time for a new device to appear in stats, so we
    first check if the device we got from running_config is already reported.
    """
    ovs_networks_stats = {}
    running_config = RunningConfig()

    for network, attrs in six.iteritems(running_config.networks):
        if is_ovs_network(attrs):
            vlan = attrs.get('vlan')
            iface = attrs.get('nic') or attrs.get('bonding')
            if vlan is None and iface in stats:
                # Untagged networks use OVS bridge as their bridge, but Engine
                # expects a bridge with 'network-name' name.  create a copy of
                # top underlying device stats and save it as bridge's stats.
                # NOTE: copy stats of ovsbr0? (now we repots iface's stats)
                ovs_networks_stats[network] = stats[iface]
                ovs_networks_stats[network]['name'] = network
            elif network in stats:
                # Engine expects stats entries for vlans named 'iface.id'
                vlan_name = '%s.%s' % (iface, vlan)
                ovs_networks_stats[vlan_name] = stats[network]
                ovs_networks_stats[vlan_name]['name'] = vlan_name

    log('Updating network stats with OVS networks: %s' % ovs_networks_stats)
    return ovs_networks_stats
Exemple #7
0
 def call_and_update(self, *args, **kwargs):
     ret = func(self, *args, **kwargs)
     self.netinfo = \
         netinfo.NetInfo(self.vdscli.getVdsCapabilities()['info'])
     if self.config is not None:
         self.config = RunningConfig()
     return ret
Exemple #8
0
 def __init__(self, inRollback=False):
     self.unifiedPersistence = \
         config.get('vars', 'net_persistence') == 'unified'
     super(Ifcfg, self).__init__(ConfigWriter(self.unifiedPersistence),
                                 inRollback)
     if self.unifiedPersistence:
         self.runningConfig = RunningConfig()
Exemple #9
0
 def start(self):
     self.vdscli = vdscli.connect()
     self.netinfo = self._get_netinfo()
     if config.get('vars', 'net_persistence') == 'unified':
         self.config = RunningConfig()
     else:
         self.config = None
Exemple #10
0
 def start(self):
     self.vdscli = vdscli.connect()
     self.netinfo = \
         netinfo.NetInfo(self.vdscli.getVdsCapabilities()['info'])
     if config.get('vars', 'net_persistence') == 'unified':
         self.config = RunningConfig()
     else:
         self.config = None
Exemple #11
0
def main():
    running_config = RunningConfig()
    caps = hooking.read_json()
    caps['networks'].update(networks_caps(running_config))
    caps['bridges'].update(bridges_caps(running_config))
    caps['vlans'].update(vlans_caps(running_config))
    caps['bondings'].update(bondings_caps(running_config))
    hooking.write_json(caps)
Exemple #12
0
 def rollback(self):
     """
     returns None when all the nets were successfully rolled back, a
     vdsm.netoconfpersistence.Config object with the not yet rolled back
     networks and bonds.
     """
     # self.runningConfig will have all the changes that were applied before
     # we needed to rollback.
     return RunningConfig().diffFrom(self.runningConfig)
Exemple #13
0
 def start(self):
     if _JSONRPC_ENABLED:
         requestQueues = config.get('addresses', 'request_queues')
         requestQueue = requestQueues.split(",")[0]
         self.vdscli = jsonrpcvdscli.connect(requestQueue, xml_compat=False)
     else:
         self.vdscli = vdscli.connect()
     self.netinfo = self._get_netinfo()
     if config.get('vars', 'net_persistence') == 'unified':
         self.config = RunningConfig()
     else:
         self.config = None
Exemple #14
0
def _all_configured_fcoe_networks():
    """
    Return a mapping of configured fcoe networks in format
    (network_name, nic_name)
    """
    existing_fcoe_networks = {}
    config = RunningConfig()
    for net, net_attr in six.iteritems(config.networks):
        if _has_fcoe(net_attr):
            nic = net_attr.get('nic')
            if nic:
                existing_fcoe_networks[net] = nic
            else:
                hooking.log("WARNING: Invalid FCoE configuration of %s "
                            "detected. Please check documentation" % (net))

    return existing_fcoe_networks
Exemple #15
0
def ovs_device(domxml):
    """ Modify interface XML in Libvirt to proper OVS configuration if OVS
    network is set as a source.
    """
    running_config = RunningConfig()

    iface = domxml.getElementsByTagName('interface')[0]
    source = iface.getElementsByTagName('source')[0]
    source_bridge = source.getAttribute('bridge')

    network = running_config.networks.get(source_bridge)
    if network is None:
        hooking.exit_hook('Network %s does not exist' % source_bridge)

    if is_ovs_network(network):
        virtualport = domxml.createElement('virtualport')
        virtualport.setAttribute('type', 'openvswitch')
        iface.appendChild(virtualport)
        if network.get('vlan') is None:
            source.setAttribute('bridge', BRIDGE_NAME)
Exemple #16
0
 def __init__(self, inRollback=False):
     super(Iproute2, self).__init__(ConfigApplier(), inRollback)
     self.runningConfig = RunningConfig()
Exemple #17
0
class Iproute2(Configurator):
    def __init__(self, inRollback=False):
        super(Iproute2, self).__init__(ConfigApplier(), inRollback)
        self.runningConfig = RunningConfig()

    def begin(self):
        if self.configApplier is None:
            self.configApplier = ConfigApplier()
        if self.runningConfig is None:
            self.runningConfig = RunningConfig()

    def commit(self):
        self.configApplier = None
        self.runningConfig.save()
        self.runningConfig = None

    def configureBridge(self, bridge, **opts):
        self.configApplier.addBridge(bridge)
        if bridge.port:
            bridge.port.configure(**opts)
            self.configApplier.addBridgePort(bridge)
        DynamicSourceRoute.addInterfaceTracking(bridge)
        self.configApplier.setIfaceConfigAndUp(bridge)
        self._addSourceRoute(bridge)
        if 'custom' in opts and 'bridge_opts' in opts['custom']:
            self.configApplier._setBridgeOpts(bridge,
                                              opts['custom']['bridge_opts'])

    def configureVlan(self, vlan, **opts):
        vlan.device.configure(**opts)
        self.configApplier.addVlan(vlan)
        DynamicSourceRoute.addInterfaceTracking(vlan)
        self.configApplier.setIfaceConfigAndUp(vlan)
        self._addSourceRoute(vlan)

    def configureBond(self, bond, **opts):
        self.configApplier.addBond(bond)
        if not bond.areOptionsApplied():
            self.configApplier.ifdown(bond)
            self.configApplier.addBondOptions(bond)
        for slave in bond.slaves:
            if slave.name not in netinfo.slaves(bond.name):
                self.configApplier.addBondSlave(bond, slave)
                slave.configure(**opts)
        DynamicSourceRoute.addInterfaceTracking(bond)
        self.configApplier.setIfaceConfigAndUp(bond)
        self._addSourceRoute(bond)
        self.runningConfig.setBonding(
            bond.name, {'options': bond.options,
                        'nics': [slave.name for slave in bond.slaves]})

    def editBonding(self, bond, _netinfo):
        """
        Modifies the bond so that the bond in the system ends up with the
        same slave and options configuration that are requested. Makes a
        best effort not to interrupt connectivity.
        """
        nicsToSet = frozenset(nic.name for nic in bond.slaves)
        currentNics = frozenset(_netinfo.getNicsForBonding(bond.name))
        nicsToAdd = nicsToSet
        nicsToRemove = currentNics

        if bond.areOptionsApplied():
            nicsToAdd -= currentNics
            nicsToRemove -= nicsToSet

        for nic in nicsToRemove:
            slave = Nic(nic, self, _netinfo=_netinfo)
            self.configApplier.removeBondSlave(bond, slave)
            slave.remove()

        if not bond.areOptionsApplied():
            self.configApplier.ifdown(bond)
            self.configApplier.addBondOptions(bond)

        for slave in bond.slaves:
            if slave.name in nicsToAdd:
                self.configApplier.addBondSlave(bond, slave)

        self.configApplier.ifup(bond)
        self.runningConfig.setBonding(
            bond.name, {'options': bond.options,
                        'nics': [slave.name for slave in bond.slaves]})

    def configureNic(self, nic, **opts):
        DynamicSourceRoute.addInterfaceTracking(nic)
        self.configApplier.setIfaceConfigAndUp(nic)
        self._addSourceRoute(nic)

        ethtool_opts = getEthtoolOpts(nic.name)
        if ethtool_opts:
            # We ignore ethtool's return code to maintain initscripts'
            # behaviour.
            execCmd(
                [_ETHTOOL_BINARY.cmd, '-K', nic.name] + ethtool_opts.split())

    def removeBridge(self, bridge):
        DynamicSourceRoute.addInterfaceTracking(bridge)
        self.configApplier.ifdown(bridge)
        self._removeSourceRoute(bridge, DynamicSourceRoute)
        self.configApplier.removeBridge(bridge)
        if bridge.port:
            bridge.port.remove()

    def removeVlan(self, vlan):
        DynamicSourceRoute.addInterfaceTracking(vlan)
        self.configApplier.ifdown(vlan)
        self._removeSourceRoute(vlan, DynamicSourceRoute)
        self.configApplier.removeVlan(vlan)
        vlan.device.remove()

    def _destroyBond(self, bonding):
        for slave in bonding.slaves:
            self.configApplier.removeBondSlave(bonding, slave)
            slave.remove()
        self.configApplier.removeBond(bonding)

    def removeBond(self, bonding):
        toBeRemoved = not netinfo.ifaceUsed(bonding.name)

        if toBeRemoved:
            if bonding.master is None:
                self.configApplier.removeIpConfig(bonding)
                DynamicSourceRoute.addInterfaceTracking(bonding)
                self._removeSourceRoute(bonding, DynamicSourceRoute)

            if bonding.destroyOnMasterRemoval:
                self._destroyBond(bonding)
                self.runningConfig.removeBonding(bonding.name)
            else:
                self.configApplier.setIfaceMtu(bonding.name,
                                               netinfo.DEFAULT_MTU)
                self.configApplier.ifdown(bonding)
        else:
            self._setNewMtu(bonding, netinfo.vlanDevsForIface(bonding.name))

    def removeNic(self, nic):
        toBeRemoved = not netinfo.ifaceUsed(nic.name)

        if toBeRemoved:
            if nic.master is None:
                self.configApplier.removeIpConfig(nic)
                DynamicSourceRoute.addInterfaceTracking(nic)
                self._removeSourceRoute(nic, DynamicSourceRoute)
            else:
                self.configApplier.setIfaceMtu(nic.name,
                                               netinfo.DEFAULT_MTU)
                self.configApplier.ifdown(nic)
        else:
            self._setNewMtu(nic, netinfo.vlanDevsForIface(nic.name))

    @staticmethod
    def configureSourceRoute(routes, rules, device):
        for route in routes:
            routeAdd(route)

        for rule in rules:
            ruleAdd(rule)

    @staticmethod
    def removeSourceRoute(routes, rules, device):
        for route in routes:
            routeDel(route)

        for rule in rules:
            ruleDel(rule)
Exemple #18
0
 def begin(self):
     if self.configApplier is None:
         self.configApplier = ConfigApplier()
     if self.runningConfig is None:
         self.runningConfig = RunningConfig()
Exemple #19
0
 def __init__(self, inRollback=False):
     super(Iproute2, self).__init__(ConfigApplier(), inRollback)
     self.runningConfig = RunningConfig()
Exemple #20
0
class Iproute2(Configurator):
    def __init__(self, inRollback=False):
        super(Iproute2, self).__init__(ConfigApplier(), inRollback)
        self.runningConfig = RunningConfig()

    def begin(self):
        if self.configApplier is None:
            self.configApplier = ConfigApplier()
        if self.runningConfig is None:
            self.runningConfig = RunningConfig()

    def commit(self):
        self.configApplier = None
        self.runningConfig.save()
        self.runningConfig = None

    def configureBridge(self, bridge, **opts):
        self.configApplier.addBridge(bridge)
        if bridge.port:
            bridge.port.configure(**opts)
            self.configApplier.addBridgePort(bridge)
        DynamicSourceRoute.addInterfaceTracking(bridge)
        self.configApplier.setIfaceConfigAndUp(bridge)
        if not bridge.ipv6.address and not bridge.ipv6.ipv6autoconf and (
                not bridge.ipv6.dhcpv6 and netinfo.ipv6_supported()):
            wait_for_device(bridge.name)
            sysctl.disable_ipv6(bridge.name)
        self._addSourceRoute(bridge)
        if 'custom' in opts and 'bridge_opts' in opts['custom']:
            self.configApplier._setBridgeOpts(bridge,
                                              opts['custom']['bridge_opts'])

    def configureVlan(self, vlan, **opts):
        vlan.device.configure(**opts)
        self.configApplier.addVlan(vlan)
        DynamicSourceRoute.addInterfaceTracking(vlan)
        self.configApplier.setIfaceConfigAndUp(vlan)
        self._addSourceRoute(vlan)

    def configureBond(self, bond, **opts):
        self.configApplier.addBond(bond)
        if not bond.areOptionsApplied():
            self.configApplier.ifdown(bond)
            self.configApplier.addBondOptions(bond)
        for slave in bond.slaves:
            if slave.name not in netinfo.slaves(bond.name):
                self.configApplier.addBondSlave(bond, slave)
                slave.configure(**opts)
        DynamicSourceRoute.addInterfaceTracking(bond)
        self.configApplier.setIfaceConfigAndUp(bond)
        self._addSourceRoute(bond)
        self.runningConfig.setBonding(
            bond.name, {
                'options': bond.options,
                'nics': [slave.name for slave in bond.slaves]
            })

    def editBonding(self, bond, _netinfo):
        """
        Modifies the bond so that the bond in the system ends up with the
        same slave and options configuration that are requested. Makes a
        best effort not to interrupt connectivity.
        """
        nicsToSet = frozenset(nic.name for nic in bond.slaves)
        currentNics = frozenset(_netinfo.getNicsForBonding(bond.name))
        nicsToAdd = nicsToSet
        nicsToRemove = currentNics

        if bond.areOptionsApplied():
            nicsToAdd -= currentNics
            nicsToRemove -= nicsToSet

        for nic in nicsToRemove:
            slave = Nic(nic, self, _netinfo=_netinfo)
            self.configApplier.removeBondSlave(bond, slave)
            slave.remove()

        if not bond.areOptionsApplied():
            self.configApplier.ifdown(bond)
            self.configApplier.addBondOptions(bond)

        for slave in bond.slaves:
            if slave.name in nicsToAdd:
                self.configApplier.addBondSlave(bond, slave)

        self.configApplier.ifup(bond)
        self.runningConfig.setBonding(
            bond.name, {
                'options': bond.options,
                'nics': [slave.name for slave in bond.slaves]
            })

    def configureNic(self, nic, **opts):
        DynamicSourceRoute.addInterfaceTracking(nic)
        self.configApplier.setIfaceConfigAndUp(nic)
        self._addSourceRoute(nic)

        ethtool_opts = getEthtoolOpts(nic.name)
        if ethtool_opts:
            # We ignore ethtool's return code to maintain initscripts'
            # behaviour.
            execCmd([_ETHTOOL_BINARY.cmd, '-K', nic.name] +
                    ethtool_opts.split())

    def removeBridge(self, bridge):
        DynamicSourceRoute.addInterfaceTracking(bridge)
        self.configApplier.ifdown(bridge)
        self._removeSourceRoute(bridge, DynamicSourceRoute)
        self.configApplier.removeBridge(bridge)
        if bridge.port:
            bridge.port.remove()

    def removeVlan(self, vlan):
        DynamicSourceRoute.addInterfaceTracking(vlan)
        self.configApplier.ifdown(vlan)
        self._removeSourceRoute(vlan, DynamicSourceRoute)
        self.configApplier.removeVlan(vlan)
        vlan.device.remove()

    def _destroyBond(self, bonding):
        for slave in bonding.slaves:
            self.configApplier.removeBondSlave(bonding, slave)
            slave.remove()
        self.configApplier.removeBond(bonding)

    def removeBond(self, bonding):
        toBeRemoved = not netinfo.ifaceUsed(bonding.name)

        if toBeRemoved:
            if bonding.master is None:
                self.configApplier.removeIpConfig(bonding)
                DynamicSourceRoute.addInterfaceTracking(bonding)
                self._removeSourceRoute(bonding, DynamicSourceRoute)

            if bonding.destroyOnMasterRemoval:
                self._destroyBond(bonding)
                self.runningConfig.removeBonding(bonding.name)
            else:
                self.configApplier.setIfaceMtu(bonding.name,
                                               netinfo.DEFAULT_MTU)
                self.configApplier.ifdown(bonding)
        else:
            self._setNewMtu(bonding, netinfo.vlanDevsForIface(bonding.name))

    def removeNic(self, nic):
        toBeRemoved = not netinfo.ifaceUsed(nic.name)

        if toBeRemoved:
            if nic.master is None:
                self.configApplier.removeIpConfig(nic)
                DynamicSourceRoute.addInterfaceTracking(nic)
                self._removeSourceRoute(nic, DynamicSourceRoute)
            else:
                self.configApplier.setIfaceMtu(nic.name, netinfo.DEFAULT_MTU)
                self.configApplier.ifdown(nic)
        else:
            self._setNewMtu(nic, netinfo.vlanDevsForIface(nic.name))

    @staticmethod
    def configureSourceRoute(routes, rules, device):
        for route in routes:
            routeAdd(route)

        for rule in rules:
            ruleAdd(rule)

    @staticmethod
    def removeSourceRoute(routes, rules, device):
        for route in routes:
            try:
                routeDel(route)
            except IPRoute2Error as e:
                if 'No such process' in e.message[0]:
                    # The kernel or dhclient has won the race and removed the
                    # route already. We have yet to remove routing rules.
                    pass
                else:
                    raise

        for rule in rules:
            ruleDel(rule)
Exemple #21
0
 def call_and_update(self, *args, **kwargs):
     ret = func(self, *args, **kwargs)
     self.netinfo = self._get_netinfo()
     if self.config is not None:
         self.config = RunningConfig()
     return ret
Exemple #22
0
 def begin(self):
     if self.configApplier is None:
         self.configApplier = ConfigApplier()
     if self.runningConfig is None:
         self.runningConfig = RunningConfig()
Exemple #23
0
 def __init__(self, inRollback=False):
     self.unifiedPersistence = config.get("vars", "net_persistence") == "unified"
     super(Ifcfg, self).__init__(ConfigWriter(self.unifiedPersistence), inRollback)
     if self.unifiedPersistence:
         self.runningConfig = RunningConfig()
Exemple #24
0
class Iproute2(Configurator):
    def __init__(self, inRollback=False):
        self.unifiedPersistence = True
        super(Iproute2, self).__init__(ConfigApplier(), inRollback)
        self.runningConfig = RunningConfig()

    def begin(self):
        if self.configApplier is None:
            self.configApplier = ConfigApplier()
        if self.runningConfig is None:
            self.runningConfig = RunningConfig()

    def commit(self):
        self.configApplier = None
        self.runningConfig.save()
        self.runningConfig = None

    def configureBridge(self, bridge, **opts):
        self.configApplier.addBridge(bridge)
        if bridge.port:
            bridge.port.configure(**opts)
            self.configApplier.addBridgePort(bridge)
        DynamicSourceRoute.addInterfaceTracking(bridge)
        self.configApplier.setIfaceConfigAndUp(bridge)
        if not bridge.ipv6.address and not bridge.ipv6.ipv6autoconf and (not bridge.ipv6.dhcpv6):
            wait_for_device(bridge.name)
            sysctl.disable_ipv6(bridge.name)
        self._addSourceRoute(bridge)
        if "custom" in opts and "bridge_opts" in opts["custom"]:
            self.configApplier._setBridgeOpts(bridge, opts["custom"]["bridge_opts"])

    def configureVlan(self, vlan, **opts):
        vlan.device.configure(**opts)
        self.configApplier.addVlan(vlan)
        DynamicSourceRoute.addInterfaceTracking(vlan)
        self.configApplier.setIfaceConfigAndUp(vlan)
        self._addSourceRoute(vlan)

    def configureBond(self, bond, **opts):
        self.configApplier.addBond(bond)
        if not bond.areOptionsApplied():
            self.configApplier.ifdown(bond)
            self.configApplier.addBondOptions(bond)
        for slave in bond.slaves:
            if slave.name not in netinfo.slaves(bond.name):
                self.configApplier.addBondSlave(bond, slave)
                slave.configure(**opts)
        DynamicSourceRoute.addInterfaceTracking(bond)
        self.configApplier.setIfaceConfigAndUp(bond)
        self._addSourceRoute(bond)
        self.runningConfig.setBonding(
            bond.name, {"options": bond.options, "nics": [slave.name for slave in bond.slaves]}
        )

    def editBonding(self, bond, _netinfo):
        """
        Modifies the bond so that the bond in the system ends up with the
        same slave and options configuration that are requested. Makes a
        best effort not to interrupt connectivity.
        """
        nicsToSet = frozenset(nic.name for nic in bond.slaves)
        currentNics = frozenset(_netinfo.getNicsForBonding(bond.name))
        nicsToAdd = nicsToSet
        nicsToRemove = currentNics

        if bond.areOptionsApplied():
            nicsToAdd -= currentNics
            nicsToRemove -= nicsToSet

        for nic in nicsToRemove:
            slave = Nic(nic, self, _netinfo=_netinfo)
            self.configApplier.removeBondSlave(bond, slave)
            slave.remove()

        if not bond.areOptionsApplied():
            self.configApplier.ifdown(bond)
            self.configApplier.addBondOptions(bond)

        for slave in bond.slaves:
            if slave.name in nicsToAdd:
                self.configApplier.addBondSlave(bond, slave)

        self.configApplier.ifup(bond)
        self.runningConfig.setBonding(
            bond.name, {"options": bond.options, "nics": [slave.name for slave in bond.slaves]}
        )

    def configureNic(self, nic, **opts):
        DynamicSourceRoute.addInterfaceTracking(nic)
        self.configApplier.setIfaceConfigAndUp(nic)
        self._addSourceRoute(nic)

        ethtool_opts = getEthtoolOpts(nic.name)
        if ethtool_opts:
            # We ignore ethtool's return code to maintain initscripts'
            # behaviour.
            execCmd([_ETHTOOL_BINARY.cmd, "-K", nic.name] + ethtool_opts.split())

    def removeBridge(self, bridge):
        DynamicSourceRoute.addInterfaceTracking(bridge)
        self.configApplier.ifdown(bridge)
        self._removeSourceRoute(bridge, DynamicSourceRoute)
        self.configApplier.removeBridge(bridge)
        if bridge.port:
            bridge.port.remove()

    def removeVlan(self, vlan):
        DynamicSourceRoute.addInterfaceTracking(vlan)
        self.configApplier.ifdown(vlan)
        self._removeSourceRoute(vlan, DynamicSourceRoute)
        self.configApplier.removeVlan(vlan)
        vlan.device.remove()

    def _destroyBond(self, bonding):
        for slave in bonding.slaves:
            self.configApplier.removeBondSlave(bonding, slave)
            slave.remove()
        self.configApplier.removeBond(bonding)

    def removeBond(self, bonding):
        toBeRemoved = not netinfo.ifaceUsed(bonding.name)

        if toBeRemoved:
            if bonding.master is None:
                self.configApplier.removeIpConfig(bonding)
                DynamicSourceRoute.addInterfaceTracking(bonding)
                self._removeSourceRoute(bonding, DynamicSourceRoute)

            if bonding.destroyOnMasterRemoval:
                self._destroyBond(bonding)
                self.runningConfig.removeBonding(bonding.name)
            else:
                self.configApplier.setIfaceMtu(bonding.name, netinfo.DEFAULT_MTU)
                self.configApplier.ifdown(bonding)
        else:
            self._setNewMtu(bonding, netinfo.vlanDevsForIface(bonding.name))

    def removeNic(self, nic):
        toBeRemoved = not netinfo.ifaceUsed(nic.name)

        if toBeRemoved:
            if nic.master is None:
                self.configApplier.removeIpConfig(nic)
                DynamicSourceRoute.addInterfaceTracking(nic)
                self._removeSourceRoute(nic, DynamicSourceRoute)
            else:
                self.configApplier.setIfaceMtu(nic.name, netinfo.DEFAULT_MTU)
                self.configApplier.ifdown(nic)
        else:
            self._setNewMtu(nic, netinfo.vlanDevsForIface(nic.name))

    @staticmethod
    def configureSourceRoute(routes, rules, device):
        for route in routes:
            routeAdd(route)

        for rule in rules:
            ruleAdd(rule)

    @staticmethod
    def removeSourceRoute(routes, rules, device):
        for route in routes:
            try:
                routeDel(route)
            except IPRoute2Error as e:
                if "No such process" in e.message[0]:
                    # The kernel or dhclient has won the race and removed the
                    # route already. We have yet to remove routing rules.
                    pass
                else:
                    raise

        for rule in rules:
            ruleDel(rule)
Exemple #25
0
class Ifcfg(Configurator):
    # TODO: Do all the configApplier interaction from here.
    def __init__(self, inRollback=False):
        self.unifiedPersistence = \
            config.get('vars', 'net_persistence') == 'unified'
        super(Ifcfg, self).__init__(ConfigWriter(self.unifiedPersistence),
                                    inRollback)
        if self.unifiedPersistence:
            self.runningConfig = RunningConfig()

    def begin(self):
        if self.configApplier is None:
            self.configApplier = ConfigWriter(self.unifiedPersistence)
        if self.unifiedPersistence and self.runningConfig is None:
            self.runningConfig = RunningConfig()

    def rollback(self):
        self.configApplier.restoreBackups()
        self.configApplier = None
        if self.unifiedPersistence:
            self.runningConfig = None

    def commit(self):
        self.configApplier = None
        if self.unifiedPersistence:
            self.runningConfig.save()
            self.runningConfig = None

    def configureBridge(self, bridge, **opts):
        self.configApplier.addBridge(bridge, **opts)
        ifdown(bridge.name)
        if bridge.port:
            bridge.port.configure(**opts)
        self._addSourceRoute(bridge)
        ifup(bridge.name, bridge.ipConfig. async)

    def configureVlan(self, vlan, **opts):
        self.configApplier.addVlan(vlan, **opts)
        vlan.device.configure(**opts)
        self._addSourceRoute(vlan)
        ifup(vlan.name, vlan.ipConfig. async)

    def configureBond(self, bond, **opts):
        self.configApplier.addBonding(bond, **opts)
        if not netinfo.isVlanned(bond.name):
            for slave in bond.slaves:
                ifdown(slave.name)
        for slave in bond.slaves:
            slave.configure(**opts)
        self._addSourceRoute(bond)
        ifup(bond.name, bond.ipConfig. async)
        if self.unifiedPersistence:
            self.runningConfig.setBonding(
                bond.name, {
                    'options': bond.options,
                    'nics': [slave.name for slave in bond.slaves]
                })

    def editBonding(self, bond, _netinfo):
        """
        Modifies the bond so that the bond in the system ends up with the
        same slave and options configuration that are requested. Makes a
        best effort not to interrupt connectivity.
        """
        nicsToSet = frozenset(nic.name for nic in bond.slaves)
        currentNics = frozenset(_netinfo.getNicsForBonding(bond.name))
        nicsToAdd = nicsToSet - currentNics

        # Create bond configuration in case it was a non ifcfg controlled bond.
        # Needed to be before slave configuration for initscripts to add slave
        # to bond.
        bondIfcfgWritten = False
        isIfcfgControlled = os.path.isfile(netinfo.NET_CONF_PREF + bond.name)
        areOptionsApplied = bond.areOptionsApplied()
        if not isIfcfgControlled or not areOptionsApplied:
            bridgeName = _netinfo.getBridgedNetworkForIface(bond.name)
            if isIfcfgControlled and bridgeName:
                bond.master = Bridge(bridgeName, self, port=bond)
            self.configApplier.addBonding(bond)
            bondIfcfgWritten = True

        for nic in currentNics - nicsToSet:
            ifdown(nic)  # So that no users will be detected for it.
            Nic(nic, self, _netinfo=_netinfo).remove()

        for slave in bond.slaves:
            if slave.name in nicsToAdd:
                ifdown(slave.name)  # nics must be down to join a bond
                self.configApplier.addNic(slave)
                ifup(slave.name)

        if bondIfcfgWritten:
            ifdown(bond.name)
            ifup(bond.name)
        if self.unifiedPersistence:
            self.runningConfig.setBonding(
                bond.name, {
                    'options': bond.options,
                    'nics': [slave.name for slave in bond.slaves]
                })

    def configureNic(self, nic, **opts):
        self.configApplier.addNic(nic, **opts)
        self._addSourceRoute(nic)
        if nic.bond is None:
            if not netinfo.isVlanned(nic.name):
                ifdown(nic.name)
            ifup(nic.name, nic.ipConfig. async)

    def removeBridge(self, bridge):
        DynamicSourceRoute.addInterfaceTracking(bridge)
        ifdown(bridge.name)
        self._removeSourceRoute(bridge, StaticSourceRoute)
        utils.execCmd([constants.EXT_BRCTL, 'delbr', bridge.name])
        self.configApplier.removeBridge(bridge.name)
        if bridge.port:
            bridge.port.remove()

    def removeVlan(self, vlan):
        DynamicSourceRoute.addInterfaceTracking(vlan)
        ifdown(vlan.name)
        self._removeSourceRoute(vlan, StaticSourceRoute)
        self.configApplier.removeVlan(vlan.name)
        vlan.device.remove()

    def _ifaceDownAndCleanup(self, iface):
        """Returns True iff the iface is to be removed."""
        DynamicSourceRoute.addInterfaceTracking(iface)
        to_be_removed = not netinfo.ifaceUsed(iface.name)
        if to_be_removed:
            ifdown(iface.name)
        self._removeSourceRoute(iface, StaticSourceRoute)
        return to_be_removed

    def _addSourceRoute(self, netEnt):
        """For ifcfg tracking can be done together with route/rule addition"""
        super(Ifcfg, self)._addSourceRoute(netEnt)
        DynamicSourceRoute.addInterfaceTracking(netEnt)

    def removeBond(self, bonding):
        to_be_removed = self._ifaceDownAndCleanup(bonding)
        if to_be_removed:
            self.configApplier.removeBonding(bonding.name)
            if bonding.destroyOnMasterRemoval:
                for slave in bonding.slaves:
                    slave.remove()
                if self.unifiedPersistence:
                    self.runningConfig.removeBonding(bonding.name)
            else:  # Recreate the bond with ip and master info cleared
                bonding.ip = bonding.master = None
                bonding.configure()
        else:
            set_mtu = self._setNewMtu(bonding,
                                      netinfo.vlanDevsForIface(bonding.name))
            # Since we are not taking the device up again, ifcfg will not be
            # read at this point and we need to set the live mtu value.
            # Note that ip link set dev bondX mtu Y sets Y on all its links
            if set_mtu is not None:
                ipwrapper.linkSet(bonding.name, ['mtu', str(set_mtu)])

    def removeNic(self, nic):
        to_be_removed = self._ifaceDownAndCleanup(nic)
        if to_be_removed:
            self.configApplier.removeNic(nic.name)
            if nic.name in netinfo.nics():
                ifup(nic.name)
            else:
                logging.warning('host interface %s missing', nic.name)
        else:
            set_mtu = self._setNewMtu(nic, netinfo.vlanDevsForIface(nic.name))
            # Since we are not taking the device up again, ifcfg will not be
            # read at this point and we need to set the live mtu value
            if set_mtu is not None:
                ipwrapper.linkSet(nic.name, ['mtu', str(set_mtu)])

    def _getFilePath(self, fileType, device):
        return os.path.join(netinfo.NET_CONF_DIR, '%s-%s' % (fileType, device))

    def _removeSourceRouteFile(self, fileType, device):
        filePath = self._getFilePath(fileType, device)
        self.configApplier._backup(filePath)
        self.configApplier._removeFile(filePath)

    def _writeConfFile(self, contents, fileType, device):
        filePath = self._getFilePath(fileType, device)

        configuration = ''
        for entry in contents:
            configuration += str(entry) + '\n'

        self.configApplier.writeConfFile(filePath, configuration)

    def configureSourceRoute(self, routes, rules, device):
        self._writeConfFile(routes, 'route', device)
        self._writeConfFile(rules, 'rule', device)

    def removeSourceRoute(self, routes, rules, device):
        self._removeSourceRouteFile('rule', device)
        self._removeSourceRouteFile('route', device)

    def flush(self):
        super(Ifcfg, self).flush()
        self.configApplier.flush()
Exemple #26
0
 def __init__(self, inRollback=False):
     self.unifiedPersistence = True
     super(Iproute2, self).__init__(ConfigApplier(), inRollback)
     self.runningConfig = RunningConfig()
Exemple #27
0
class Ifcfg(Configurator):
    # TODO: Do all the configApplier interaction from here.
    def __init__(self, inRollback=False):
        self.unifiedPersistence = \
            config.get('vars', 'net_persistence') == 'unified'
        super(Ifcfg, self).__init__(ConfigWriter(self.unifiedPersistence),
                                    inRollback)
        if self.unifiedPersistence:
            self.runningConfig = RunningConfig()

    def begin(self):
        if self.configApplier is None:
            self.configApplier = ConfigWriter(self.unifiedPersistence)
        if self.unifiedPersistence and self.runningConfig is None:
            self.runningConfig = RunningConfig()

    def rollback(self):
        """This reimplementation always returns None since Ifcfg can rollback
        on its own via restoreBackups(). This makes the general mechanism of
        API.Global._rollback redundant in this case."""
        self.configApplier.restoreBackups()
        self.configApplier = None
        if self.unifiedPersistence:
            self.runningConfig = None

    def commit(self):
        self.configApplier = None
        if self.unifiedPersistence:
            self.runningConfig.save()
            self.runningConfig = None

    def configureBridge(self, bridge, **opts):
        self.configApplier.addBridge(bridge, **opts)
        ifdown(bridge.name)
        if bridge.port:
            bridge.port.configure(**opts)
        self._addSourceRoute(bridge)
        _ifup(bridge)
        if not bridge.ipv6.address and not bridge.ipv6.ipv6autoconf and (
                not bridge.ipv6.dhcpv6 and misc.ipv6_supported()):
            wait_for_device(bridge.name)
            sysctl.disable_ipv6(bridge.name)

    def configureVlan(self, vlan, **opts):
        self.configApplier.addVlan(vlan, **opts)
        vlan.device.configure(**opts)
        self._addSourceRoute(vlan)
        _ifup(vlan)

    def configureBond(self, bond, **opts):
        self.configApplier.addBonding(bond, **opts)
        if not vlans.is_vlanned(bond.name):
            for slave in bond.slaves:
                ifdown(slave.name)
        for slave in bond.slaves:
            slave.configure(**opts)
        self._addSourceRoute(bond)
        _ifup(bond)
        if self.unifiedPersistence:
            self.runningConfig.setBonding(
                bond.name, {'options': bond.options,
                            'nics': [slave.name for slave in bond.slaves]})

    def editBonding(self, bond, _netinfo):
        """
        Modifies the bond so that the bond in the system ends up with the
        same slave and options configuration that are requested. Makes a
        best effort not to interrupt connectivity.
        """
        nicsToSet = frozenset(nic.name for nic in bond.slaves)
        currentNics = frozenset(_netinfo.getNicsForBonding(bond.name))
        nicsToAdd = nicsToSet - currentNics

        # Create bond configuration in case it was a non ifcfg controlled bond.
        # Needed to be before slave configuration for initscripts to add slave
        # to bond.
        bondIfcfgWritten = False
        isIfcfgControlled = os.path.isfile(NET_CONF_PREF + bond.name)
        areOptionsApplied = bond.areOptionsApplied()
        if not isIfcfgControlled or not areOptionsApplied:
            bridgeName = _netinfo.getBridgedNetworkForIface(bond.name)
            if isIfcfgControlled and bridgeName:
                bond.master = Bridge(bridgeName, self, port=bond)
            self.configApplier.addBonding(bond)
            bondIfcfgWritten = True

        for nic in currentNics - nicsToSet:
            ifdown(nic)  # So that no users will be detected for it.
            Nic(nic, self, _netinfo=_netinfo).remove()

        for slave in bond.slaves:
            if slave.name in nicsToAdd:
                ifdown(slave.name)  # nics must be down to join a bond
                self.configApplier.addNic(slave)
                _exec_ifup(slave.name)

        if bondIfcfgWritten:
            ifdown(bond.name)
            _restore_default_bond_options(bond.name, bond.options)
            _exec_ifup(bond.name)
        if self.unifiedPersistence:
            self.runningConfig.setBonding(
                bond.name, {'options': bond.options,
                            'nics': [slave.name for slave in bond.slaves]})

    def configureNic(self, nic, **opts):
        self.configApplier.addNic(nic, **opts)
        self._addSourceRoute(nic)
        if nic.bond is None:
            if not vlans.is_vlanned(nic.name):
                ifdown(nic.name)
            _ifup(nic)

    def removeBridge(self, bridge):
        DynamicSourceRoute.addInterfaceTracking(bridge)
        ifdown(bridge.name)
        self._removeSourceRoute(bridge, StaticSourceRoute)
        commands.execCmd([constants.EXT_BRCTL, 'delbr', bridge.name])
        self.configApplier.removeBridge(bridge.name)
        if bridge.port:
            bridge.port.remove()

    def removeVlan(self, vlan):
        DynamicSourceRoute.addInterfaceTracking(vlan)
        ifdown(vlan.name)
        self._removeSourceRoute(vlan, StaticSourceRoute)
        self.configApplier.removeVlan(vlan.name)
        vlan.device.remove()

    def _ifaceDownAndCleanup(self, iface, remove_even_if_used=False):
        """Returns True iff the iface is to be removed."""
        DynamicSourceRoute.addInterfaceTracking(iface)
        to_be_removed = remove_even_if_used or not ifaceUsed(iface.name)
        if to_be_removed:
            ifdown(iface.name)
        self._removeSourceRoute(iface, StaticSourceRoute)
        return to_be_removed

    def _addSourceRoute(self, netEnt):
        """For ifcfg tracking can be done together with route/rule addition"""
        super(Ifcfg, self)._addSourceRoute(netEnt)
        DynamicSourceRoute.addInterfaceTracking(netEnt)

    def removeBond(self, bonding):
        to_be_removed = self._ifaceDownAndCleanup(bonding)
        if to_be_removed:
            self.configApplier.removeBonding(bonding.name)
            if bonding.destroyOnMasterRemoval:
                for slave in bonding.slaves:
                    slave.remove()
                if self.unifiedPersistence:
                    self.runningConfig.removeBonding(bonding.name)
            else:  # Recreate the bond with ip and master info cleared
                bonding.ipv4 = IPv4()
                bonding.ipv6 = IPv6()
                bonding.master = None
                bonding.configure()
        else:
            set_mtu = self._setNewMtu(bonding,
                                      vlans.vlan_devs_for_iface(bonding.name))
            # Since we are not taking the device up again, ifcfg will not be
            # read at this point and we need to set the live mtu value.
            # Note that ip link set dev bondX mtu Y sets Y on all its links
            if set_mtu is not None:
                ipwrapper.linkSet(bonding.name, ['mtu', str(set_mtu)])

    def removeNic(self, nic, remove_even_if_used=False):
        to_be_removed = self._ifaceDownAndCleanup(nic, remove_even_if_used)
        if to_be_removed:
            self.configApplier.removeNic(nic.name)
            if nic.name in nics.nics():
                _exec_ifup(nic.name)
            else:
                logging.warning('host interface %s missing', nic.name)
        else:
            set_mtu = self._setNewMtu(nic, vlans.vlan_devs_for_iface(nic.name))
            # Since we are not taking the device up again, ifcfg will not be
            # read at this point and we need to set the live mtu value
            if set_mtu is not None:
                ipwrapper.linkSet(nic.name, ['mtu', str(set_mtu)])

    def _getFilePath(self, fileType, device):
        return os.path.join(NET_CONF_DIR, '%s-%s' % (fileType, device))

    def _removeSourceRouteFile(self, fileType, device):
        filePath = self._getFilePath(fileType, device)
        self.configApplier._backup(filePath)
        self.configApplier._removeFile(filePath)

    def _writeConfFile(self, contents, fileType, device):
        filePath = self._getFilePath(fileType, device)

        configuration = ''
        for entry in contents:
            configuration += str(entry) + '\n'

        self.configApplier.writeConfFile(filePath, configuration)

    def configureSourceRoute(self, routes, rules, device):
        self._writeConfFile(routes, 'route', device)
        self._writeConfFile(rules, 'rule', device)

    def removeSourceRoute(self, routes, rules, device):
        self._removeSourceRouteFile('rule', device)
        self._removeSourceRouteFile('route', device)
Exemple #28
0
 def __init__(self, inRollback=False):
     self.unifiedPersistence = True
     super(Iproute2, self).__init__(ConfigApplier(), inRollback)
     self.runningConfig = RunningConfig()
Exemple #29
0
 def begin(self):
     if self.configApplier is None:
         self.configApplier = ConfigWriter(self.unifiedPersistence)
     if self.unifiedPersistence and self.runningConfig is None:
         self.runningConfig = RunningConfig()
Exemple #30
0
 def begin(self):
     if self.configApplier is None:
         self.configApplier = ConfigWriter(self.unifiedPersistence)
     if self.unifiedPersistence and self.runningConfig is None:
         self.runningConfig = RunningConfig()