def delNetwork(network, force=False, configWriter=None, **options): _netinfo = NetInfo() validateBridgeName(network) if network not in networks().keys(): raise ConfigNetworkError(ne.ERR_BAD_BRIDGE, "Cannot delete network %r: It doesn't exist" % network) nics, vlan, bonding = _netinfo.getNicsVlanAndBondingForNetwork(network) bridged = networks()[network]['bridged'] logging.info("Removing network %s with vlan=%s, bonding=%s, nics=%s. options=%s"%(network, vlan, bonding, nics, options)) if not utils.tobool(force): if bonding: validateBondingName(bonding) if set(nics) != set(_netinfo.bondings[bonding]["slaves"]): raise ConfigNetworkError(ne.ERR_BAD_NIC, 'delNetwork: %s are not all nics enslaved to %s' % (nics, bonding)) if vlan: #assertVlan(vlan) validateVlanId(vlan) if bridged: assertBridgeClean(network, vlan, bonding, nics) if configWriter is None: configWriter = ConfigWriter() if not utils.tobool(options.get('skipLibvirt', False)): removeLibvirtNetwork(network) if bridged: configWriter.setNewMtu(network) if network and bridged: ifdown(network) subprocess.call([constants.EXT_BRCTL, 'delbr', network]) configWriter.removeBridge(network) if vlan: vlandev = (bonding or nics[0]) + '.' + vlan ifdown(vlandev) subprocess.call([constants.EXT_VCONFIG, 'rem', vlandev], stderr=subprocess.PIPE) configWriter.removeVlan(vlan, bonding or nics[0]) if bonding: if not bridged or not bondingOtherUsers(network, vlan, bonding): ifdown(bonding) if not bridged or not bondingOtherUsers(network, vlan, bonding): configWriter.removeBonding(bonding) for nic in nics: if not bridged or not nicOtherUsers(network, vlan, bonding, nic): ifdown(nic) if bridged and nicOtherUsers(network, vlan, bonding, nic): continue configWriter.removeNic(nic)
def _getNetworkIp(network): try: nets = netinfo.networks() device = nets[network].get('iface', network) ip, _, _, _ = netinfo.addresses.getIpInfo(device) except (libvirt.libvirtError, KeyError, IndexError): ip = config.get('addresses', 'guests_gateway_ip') if ip == '': ip = '0' logging.info('network %s: using %s', network, ip) return ip
def _getNetworkIp(network): try: nets = netinfo.networks() device = nets[network].get('iface', network) ip, _, _, _ = netinfo.getIpInfo(device) except (libvirt.libvirtError, KeyError, IndexError): ip = config.get('addresses', 'guests_gateway_ip') if ip == '': ip = '0' logging.info('network %s: using %s', network, ip) return ip
def upgrade_networks(*args): """ Since ovirt-3.0, Vdsm uses libvirt networks (with names vdsm-*) to store its own networks. Older Vdsms did not have those defined, and used only linux bridges. This command is kept as an upgrade tool for the (very few) people who still have such old setups running. """ networks = netinfo.networks() bridges = netinfo.bridges() if isNeeded(networks, bridges): run(networks, bridges)
def _isLibvirtInterface(self): try: networks = netinfo.networks() except libvirtError: # libvirt might not be started or it just fails logging.error('Libvirt failed to answer. It might be the case that' ' this script is being run before libvirt startup. ' ' Thus, check if vdsm owns %s an alternative way' % self.device) return self._isLibvirtInterfaceFallback() trackedInterfaces = [network.get('bridge') or network.get('iface') for network in networks.itervalues()] return self.device in trackedInterfaces
def _isLibvirtInterface(device): try: networks = netinfo.networks() except libvirtError: # libvirt might not be started or it just fails logging.error( "Libvirt failed to answer. It might be the case that" " this script is being run before libvirt startup. " " Thus, check if vdsm owns %s an alternative way" % device ) return DynamicSourceRoute._isLibvirtInterfaceFallback(device) trackedInterfaces = [network.get("bridge") or network.get("iface") for network in networks.itervalues()] return device in trackedInterfaces
def upgrade_networks(*args): """ upgrade-3.0.0-networks [upgrade-options] Since ovirt-3.0, Vdsm uses libvirt networks (with names vdsm-*) to store its own networks. Older Vdsms did not have those defined, and used only linux bridges. This command is kept as an upgrade tool for the (very few) people who still have such old setups running. """ networks = netinfo.networks() bridges = netinfo.bridges() if isNeeded(networks, bridges): run(networks, bridges)
def ifaceUsed(iface): """Lightweight implementation of bool(Netinfo.ifaceUsers()) that does not require a NetInfo object.""" if os.path.exists(os.path.join(netinfo.NET_PATH, iface, 'brport')): return True # Is it a port 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 _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() routes = get_routes() if vdsmnets is None: libvirt_nets = netinfo.networks() networking['networks'] = libvirtNets2vdsm(libvirt_nets, routes, ipaddrs) 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) devinfo.update(bonding.get_bond_slave_agg_info(dev.name)) elif dev.isBOND(): devinfo = networking['bondings'][dev.name] = bonding.info(dev) devinfo.update(bonding.get_bond_agg_info(dev.name)) elif dev.isVLAN(): devinfo = networking['vlans'][dev.name] = vlans.info(dev) else: continue devinfo.update(_devinfo(dev, routes, ipaddrs)) 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 _syncLibvirtNetworks(self): """ function is mostly for upgrade from versions that did not have a libvirt network per vdsm network """ # add libvirt networks nets = netinfo.networks() bridges = netinfo.bridges() for bridge in bridges: if not bridge in nets: configNetwork.createLibvirtNetwork(network=bridge, bridged=True) # remove bridged networks that their bridge not exists #TODO: # this should probably go into vdsm-restore-net script for network in nets: if nets[network]['bridged'] and network not in bridges: configNetwork.removeLibvirtNetwork(network)
def _syncLibvirtNetworks(self): """ function is mostly for upgrade from versions that did not have a libvirt network per vdsm network """ # add libvirt networks nets = netinfo.networks() bridges = netinfo.bridges() configWriter = ifcfg.ConfigWriter() for bridge in bridges: if not bridge in nets: configWriter.createLibvirtNetwork(network=bridge, bridged=True, skipBackup=True) # remove bridged networks that their bridge not exists #TODO: # this should probably go into vdsm-restore-net script for network in nets: if nets[network]['bridged'] and network not in bridges: configWriter.removeLibvirtNetwork(network, skipBackup=True)
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="<ip>" netmask="<ip>" gateway="<ip>" bootproto="..." delay="..." onboot="yes"|"no" (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: force=0|1 connectivityCheck=0|1 connectivityTimeout=<int> 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") _netinfo = netinfo.NetInfo() configurator = Ifcfg() networksAdded = set() logger.debug("Setting up network according to configuration: " "networks:%r, bondings:%r, options:%r" % (networks, bondings, options)) force = options.get('force', False) if not utils.tobool(force): logging.debug("Validating configuration") _validateNetworkSetup(dict(networks), dict(bondings)) logger.debug("Applying...") try: libvirt_nets = netinfo.networks() # Remove edited networks and networks with 'remove' attribute for network, networkAttrs in networks.items(): if network in _netinfo.networks: logger.debug("Removing network %r" % network) delNetwork(network, configurator=configurator, force=force, implicitBonding=False) if 'remove' in networkAttrs: del networks[network] del libvirt_nets[network] 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) if 'remove' in networkAttrs: del networks[network] del libvirt_nets[network] elif 'remove' in networkAttrs: raise ConfigNetworkError( ne.ERR_BAD_BRIDGE, "Cannot delete " "network %r: It doesn't exist in the " "system" % network) else: networksAdded.add(network) _handleBondings(bondings, configurator) # We need to use the newest host info _ni = netinfo.NetInfo() for network, networkAttrs in networks.iteritems(): d = dict(networkAttrs) if 'bonding' in d: d.update(_buildBondOptions(d['bonding'], bondings, _ni)) else: d['nics'] = [d.pop('nic')] d['force'] = force logger.debug("Adding network %r" % network) addNetwork(network, configurator=configurator, implicitBonding=True, **d) if utils.tobool(options.get('connectivityCheck', True)): logger.debug('Checking connectivity...') if not clientSeen( int( options.get('connectivityTimeout', CONNECTIVITY_TIMEOUT_DEFAULT))): logger.info('Connectivity check failed, rolling back') for network in networksAdded: # If the new added network was created on top of # existing bond, we need to keep the bond on rollback # flow, else we will break the new created bond. delNetwork(network, force=True, implicitBonding=networks[network].get('bonding') in bondings) raise ConfigNetworkError(ne.ERR_LOST_CONNECTION, 'connectivity check failed') except: configurator.rollback() raise
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: force=0|1 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") libvirt_nets = netinfo.networks() _netinfo = netinfo.NetInfo(_netinfo=netinfo.get( netinfo._libvirtNets2vdsm(libvirt_nets))) networksAdded = set() logger.debug("Setting up network according to configuration: " "networks:%r, bondings:%r, options:%r" % (networks, bondings, options)) force = options.get('force', False) if not utils.tobool(force): logging.debug("Validating configuration") _validateNetworkSetup(dict(networks), dict(bondings)) results = hooks.before_network_setup(_buildSetupHookDict(networks, bondings, options)) # gather any changes that could have been done by the hook scripts networks = results['request']['networks'] bondings = results['request']['bondings'] options = results['request']['options'] logger.debug("Applying...") with ConfiguratorClass(options.get('_inRollback', False)) as configurator: # Remove edited networks and networks with 'remove' attribute for network, networkAttrs in networks.items(): if network in _netinfo.networks: logger.debug("Removing network %r", network) delNetwork(network, configurator=configurator, force=force, implicitBonding=False, _netinfo=_netinfo) if 'remove' in networkAttrs: del networks[network] del libvirt_nets[network] _netinfo.updateDevices() del _netinfo.networks[network] 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) if 'remove' in networkAttrs: del networks[network] del libvirt_nets[network] _netinfo.updateDevices() elif 'remove' in networkAttrs: raise ConfigNetworkError(ne.ERR_BAD_BRIDGE, "Cannot delete " "network %r: It doesn't exist in the " "system" % network) else: networksAdded.add(network) _handleBondings(bondings, configurator) # We need to use the newest host info _netinfo.updateDevices() for network, networkAttrs in networks.iteritems(): d = dict(networkAttrs) if 'bonding' in d: d.update(_buildBondOptions(d['bonding'], bondings, _netinfo)) else: d['nics'] = [d.pop('nic')] if 'nic' in d else [] d['force'] = force 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, networkAttrs, configurator) raise _netinfo.updateDevices() # Things like a bond mtu can change if utils.tobool(options.get('connectivityCheck', True)): logger.debug('Checking connectivity...') if not clientSeen(int(options.get('connectivityTimeout', CONNECTIVITY_TIMEOUT_DEFAULT))): logger.info('Connectivity check failed, rolling back') for network in networksAdded: # If the new added network was created on top of # existing bond, we need to keep the bond on rollback # flow, else we will break the new created bond. delNetwork(network, force=True, implicitBonding=networks[network]. get('bonding') in bondings) raise ConfigNetworkError(ne.ERR_LOST_CONNECTION, 'connectivity check failed') hooks.after_network_setup(_buildSetupHookDict(networks, bondings, options))
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: force=0|1 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") libvirt_nets = netinfo.networks() _netinfo = netinfo.NetInfo(_netinfo=netinfo.get( netinfo._libvirtNets2vdsm(libvirt_nets))) networksAdded = set() logger.debug("Setting up network according to configuration: " "networks:%r, bondings:%r, options:%r" % (networks, bondings, options)) force = options.get('force', False) if not utils.tobool(force): logging.debug("Validating configuration") _validateNetworkSetup(dict(networks), dict(bondings)) results = hooks.before_network_setup(_buildSetupHookDict(networks, bondings, options)) # gather any changes that could have been done by the hook scripts networks = results['request']['networks'] bondings = results['request']['bondings'] options = results['request']['options'] logger.debug("Applying...") with ConfiguratorClass(options.get('_inRollback', False)) as configurator: # Remove edited networks and networks with 'remove' attribute for network, networkAttrs in networks.items(): if network in _netinfo.networks: logger.debug("Removing network %r" % network) delNetwork(network, configurator=configurator, force=force, implicitBonding=False, _netinfo=_netinfo) if 'remove' in networkAttrs: del networks[network] del libvirt_nets[network] _netinfo.updateDevices() del _netinfo.networks[network] 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) if 'remove' in networkAttrs: del networks[network] del libvirt_nets[network] _netinfo.updateDevices() elif 'remove' in networkAttrs: raise ConfigNetworkError(ne.ERR_BAD_BRIDGE, "Cannot delete " "network %r: It doesn't exist in the " "system" % network) else: networksAdded.add(network) _handleBondings(bondings, configurator) # We need to use the newest host info _netinfo.updateDevices() for network, networkAttrs in networks.iteritems(): d = dict(networkAttrs) if 'bonding' in d: d.update(_buildBondOptions(d['bonding'], bondings, _netinfo)) else: d['nics'] = [d.pop('nic')] if 'nic' in d else [] d['force'] = force logger.debug("Adding network %r" % network) addNetwork(network, configurator=configurator, implicitBonding=True, _netinfo=_netinfo, **d) _netinfo.updateDevices() # Things like a bond mtu can change if utils.tobool(options.get('connectivityCheck', True)): logger.debug('Checking connectivity...') if not clientSeen(int(options.get('connectivityTimeout', CONNECTIVITY_TIMEOUT_DEFAULT))): logger.info('Connectivity check failed, rolling back') for network in networksAdded: # If the new added network was created on top of # existing bond, we need to keep the bond on rollback # flow, else we will break the new created bond. delNetwork(network, force=True, implicitBonding=networks[network]. get('bonding') in bondings) raise ConfigNetworkError(ne.ERR_LOST_CONNECTION, 'connectivity check failed') hooks.after_network_setup(_buildSetupHookDict(networks, bondings, options))
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="<ip>" netmask="<ip>" gateway="<ip>" bootproto="..." delay="..." onboot="yes"|"no" (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: force=0|1 connectivityCheck=0|1 connectivityTimeout=<int> 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") _netinfo = netinfo.NetInfo() configurator = Ifcfg() networksAdded = set() logger.debug("Setting up network according to configuration: " "networks:%r, bondings:%r, options:%r" % (networks, bondings, options)) force = options.get('force', False) if not utils.tobool(force): logging.debug("Validating configuration") _validateNetworkSetup(dict(networks), dict(bondings)) logger.debug("Applying...") try: libvirt_nets = netinfo.networks() # Remove edited networks and networks with 'remove' attribute for network, networkAttrs in networks.items(): if network in _netinfo.networks: logger.debug("Removing network %r" % network) delNetwork(network, configurator=configurator, force=force, implicitBonding=False) if 'remove' in networkAttrs: del networks[network] del libvirt_nets[network] 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) if 'remove' in networkAttrs: del networks[network] del libvirt_nets[network] elif 'remove' in networkAttrs: raise ConfigNetworkError(ne.ERR_BAD_BRIDGE, "Cannot delete " "network %r: It doesn't exist in the " "system" % network) else: networksAdded.add(network) _handleBondings(bondings, configurator) # We need to use the newest host info _ni = netinfo.NetInfo() for network, networkAttrs in networks.iteritems(): d = dict(networkAttrs) if 'bonding' in d: d.update(_buildBondOptions(d['bonding'], bondings, _ni)) else: d['nics'] = [d.pop('nic')] d['force'] = force logger.debug("Adding network %r" % network) addNetwork(network, configurator=configurator, implicitBonding=True, **d) if utils.tobool(options.get('connectivityCheck', True)): logger.debug('Checking connectivity...') if not clientSeen(int(options.get('connectivityTimeout', CONNECTIVITY_TIMEOUT_DEFAULT))): logger.info('Connectivity check failed, rolling back') for network in networksAdded: # If the new added network was created on top of # existing bond, we need to keep the bond on rollback # flow, else we will break the new created bond. delNetwork(network, force=True, implicitBonding=networks[network]. get('bonding') in bondings) raise ConfigNetworkError(ne.ERR_LOST_CONNECTION, 'connectivity check failed') except: configurator.rollback() raise
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: force=0|1 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)) force = options.get('force', False) if not utils.tobool(force): logging.debug("Validating configuration") _validateNetworkSetup(networks, bondings) bondings, networks, options = _apply_hook(bondings, networks, options) libvirt_nets = netinfo.networks() _netinfo = netinfo.NetInfo(_netinfo=netinfo.get( netinfo.libvirtNets2vdsm(libvirt_nets))) connectivity_check_networks = set() logger.debug("Applying...") in_rollback = options.get('_inRollback', False) 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) running_conf = configurator.runningConfig.networks.get(network) keep_bridge = _should_keep_bridge( network_attrs=attrs, currently_bridged=_netinfo.networks[network]['bridged'], network_running_config=running_conf ) _delNetwork(network, configurator=configurator, force=force, implicitBonding=False, _netinfo=_netinfo, keep_bridge=keep_bridge) _netinfo.updateDevices() del _netinfo.networks[network] 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, force, logger, _netinfo) _check_connectivity(connectivity_check_networks, networks, bondings, options, logger) hooks.after_network_setup(_buildSetupHookDict(networks, bondings, options))
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: force=0|1 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)) force = options.get('force', False) if not utils.tobool(force): logging.debug("Validating configuration") _validateNetworkSetup(networks, bondings) bondings, networks, options = _apply_hook(bondings, networks, options) libvirt_nets = netinfo.networks() _netinfo = netinfo.NetInfo( _netinfo=netinfo.get(netinfo.libvirtNets2vdsm(libvirt_nets))) connectivity_check_networks = set() logger.debug("Applying...") in_rollback = options.get('_inRollback', False) kernel_config = netconfpersistence.KernelConfig(_netinfo) normalized_config = kernel_config.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, force=force, implicitBonding=False, _netinfo=_netinfo, keep_bridge=keep_bridge) del _netinfo.networks[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, force, logger, _netinfo) _check_connectivity(connectivity_check_networks, networks, bondings, options, logger) hooks.after_network_setup(_buildSetupHookDict(networks, bondings, options))