Mark Wu has uploaded a new change for review. Change subject: Refactor configNetwork.py: add a new class NativeConfigurator ......................................................................
Refactor configNetwork.py: add a new class NativeConfigurator Basically, this patch just adds a new class NativeConfigurator and moves the functions of add, delete, edit and setup network into that class. The purpose of this patch is to make it easy to integrate netcf support by adding a wrapper to the actual network configurator. Change-Id: I052955a8e2b7b92b123a5179afd15b79798e6c50 Signed-off-by: Mark Wu <[email protected]> --- M vdsm/configNetwork.py 1 file changed, 440 insertions(+), 414 deletions(-) git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/15/7915/1 diff --git a/vdsm/configNetwork.py b/vdsm/configNetwork.py index 12e5e5b..803ba3c 100755 --- a/vdsm/configNetwork.py +++ b/vdsm/configNetwork.py @@ -855,293 +855,6 @@ _validateInterNetworkCompatibility(_netinfo, vlan, nic, bridged) -def addNetwork(network, vlan=None, bonding=None, nics=None, ipaddr=None, - netmask=None, mtu=None, gateway=None, force=False, - configWriter=None, bondingOptions=None, bridged=True, - **options): - nics = nics or () - _netinfo = netinfo.NetInfo() - bridged = utils.tobool(bridged) - - if mtu: - mtu = int(mtu) - - # Validation - if not utils.tobool(force): - logging.debug('validating network...') - _addNetworkValidation(_netinfo, network=network, - vlan=vlan, bonding=bonding, nics=nics, ipaddr=ipaddr, - netmask=netmask, gateway=gateway, bondingOptions=bondingOptions, - bridged=bridged, **options) - - logging.info("Adding network %s with vlan=%s, bonding=%s, nics=%s," - " bondingOptions=%s, mtu=%s, bridged=%s, options=%s", - network, vlan, bonding, nics, bondingOptions, - mtu, bridged, options) - - if configWriter is None: - configWriter = ConfigWriter() - - prevmtu = None - if mtu: - prevmtu = configWriter.getMaxMtu(nics, mtu) - - nic = nics[0] if nics else None - iface = bonding or nic - - # take down nics that need to be changed - vlanedIfaces = [v['iface'] for v in _netinfo.vlans.values()] - if bonding not in vlanedIfaces: - for nic in nics: - if nic not in vlanedIfaces: - ifdown(nic) - - if bridged: - configWriter.addBridge(network, ipaddr=ipaddr, netmask=netmask, - mtu=mtu, gateway=gateway, **options) - ifdown(network) - # We need to define (if requested) ip, mask & gateway on ifcfg-* - # only on most top device according to following order: - # bridge -> vlan -> bond -> nic - # For lower level devices we should ignore it. - # reset ip, netmask, gateway for lower level devices - ipaddr = netmask = gateway = None - - # For VLAN we should attach bridge only to the VLAN device - # rather than to underlying NICs or bond - brName = network if bridged else None - bridgeForNic = None if vlan else brName - - # We want to create config files (ifcfg-*) in top-down order - # (bridge->vlan->bond->nic) to be able to handle IP/NETMASK - # correctly for bridgeless networks - if vlan: - # don't ifup VLAN interface here, it should be done last, - # after the bond and nic up - configWriter.addVlan(vlan, iface, network=brName, - mtu=mtu, bridged=bridged, - ipaddr=ipaddr, netmask=netmask, - gateway=gateway, **options) - iface += '.' + vlan - # reset ip, netmask, gateway for lower level devices - ipaddr = netmask = gateway = None - - # First we need to prepare all conf files - if bonding: - configWriter.addBonding(bonding, bridge=bridgeForNic, - bondingOptions=bondingOptions, - mtu=max(prevmtu, mtu), - ipaddr=ipaddr, netmask=netmask, - gateway=gateway, **options) - # reset ip, netmask, gateway for lower level devices - ipaddr = netmask = gateway = None - - for nic in nics: - configWriter.addNic(nic, bonding=bonding, - bridge=bridgeForNic if not bonding else None, - mtu=max(prevmtu, mtu), - ipaddr=ipaddr, netmask=netmask, - gateway=gateway, **options) - - # Now we can run ifup for all interfaces - if bonding: - ifup(bonding) - - # NICs must be activated in the same order of boot time - # to expose the correct MAC address. - for nic in nicSort(nics): - ifup(nic) - - # Now we can ifup VLAN interface, because bond and nic already up - if vlan: - ifup(iface) - - if bridged: - if options.get('bootproto') == 'dhcp' and \ - not utils.tobool(options.get('blockingdhcp')): - # wait for dhcp in another thread, - # so vdsm won't get stuck (BZ#498940) - t = threading.Thread(target=ifup, name='ifup-waiting-on-dhcp', - args=(network,)) - t.daemon = True - t.start() - else: - ifup(network) - - # add libvirt network - configWriter.createLibvirtNetwork(network, bridged, iface) - - -def assertBridgeClean(bridge, vlan, bonding, nics): - brifs = os.listdir('/sys/class/net/%s/brif/' % bridge) - for nic in nics: - try: - brifs.remove(nic) - except: - pass - if vlan: - brif = (bonding or nics[0]) + '.' + vlan - else: - brif = bonding - try: - brifs.remove(brif) - except: - pass - - if brifs: - raise ConfigNetworkError(ne.ERR_USED_BRIDGE, - 'bridge %s has interfaces %s connected' % (bridge, brifs)) - - -def showNetwork(network): - _netinfo = netinfo.NetInfo() - if network not in _netinfo.networks: - print "Network %r doesn't exist" % network - return - - bridged = _netinfo.networks[network]['bridged'] - print "Network %s(Bridged: %s):" % (network, bridged) - - nics, vlan, bonding = _netinfo.getNicsVlanAndBondingForNetwork(network) - - if bridged: - ipaddr = _netinfo.networks[network]['addr'] - netmask = _netinfo.networks[network]['netmask'] - gateway = _netinfo.networks[network]['gateway'] - print "ipaddr=%s, netmask=%s, gateway=%s" % (ipaddr, netmask, gateway) - else: - iface = _netinfo.networks[network]['iface'] - ipaddr = _netinfo.nics[iface]['addr'] - netmask = _netinfo.nics[iface]['netmask'] - print "ipaddr=%s, netmask=%s" % (ipaddr, netmask) - - print "vlan=%s, bonding=%s, nics=%s" % (vlan, bonding, nics) - - -def listNetworks(): - _netinfo = netinfo.NetInfo() - print "Networks:", _netinfo.networks.keys() - print "Vlans:", _netinfo.vlans.keys() - print "Nics:", _netinfo.nics.keys() - print "Bondings:", _netinfo.bondings.keys() - - -def delNetwork(network, vlan=None, bonding=None, nics=None, force=False, - configWriter=None, implicitBonding=True, **options): - _netinfo = netinfo.NetInfo() - - if configWriter is None: - configWriter = ConfigWriter() - - if network not in _netinfo.networks: - logging.info("Network %r: doesn't exist in libvirt database", network) - if network in netinfo.bridges(): - configWriter.removeBridge(network) - else: - raise ConfigNetworkError(ne.ERR_BAD_BRIDGE, - "Cannot delete network %r: It doesn't exist " - "in the system" % network) - - if vlan: - configWriter.removeVlan(vlan, bonding or nics[0]) - - return - - nics, vlan, bonding = _netinfo.getNicsVlanAndBondingForNetwork(network) - bridged = _netinfo.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: - validateVlanId(vlan) - if bridged: - assertBridgeClean(network, vlan, bonding, nics) - - configWriter.setNewMtu(network=network, bridged=bridged) - configWriter.removeLibvirtNetwork(network) - - # We need to gather NetInfo again to refresh networks info from libvirt. - # The deleted bridge should never be up at this stage. - if network in netinfo.NetInfo().networks: - raise ConfigNetworkError(ne.ERR_USED_BRIDGE, - "delNetwork: bridge %s still exists" % network) - - if network and bridged: - configWriter.removeBridge(network) - - nic = nics[0] if nics else None - iface = bonding if bonding else nic - if iface: - if vlan: - configWriter.removeVlan(vlan, iface) - else: - cf = configWriter.NET_CONF_PREF + iface - if not bridged: - # When removing bridgeless non-VLANed network - # we need to remove IP/NETMASK from the cfg file - for key in ('IPADDR', 'NETMASK', 'GATEWAY', 'BOOTPROTO'): - configWriter._updateConfigValue(cf, key, '', True) - else: - # When removing bridged non-VLANed network - # we need to remove BRIDGE from the cfg file - configWriter._updateConfigValue(cf, 'BRIDGE', '', True) - - # The (relatively) new setupNetwork verb allows to remove a network - # defined on top of an bonding device without break the bond itself. - if implicitBonding: - if bonding and not bondingOtherUsers(network, vlan, bonding): - ifdown(bonding) - configWriter.removeBonding(bonding) - iface = None if bonding == iface else iface - - for nic in nics: - if not nicOtherUsers(network, vlan, bonding, nic): - ifdown(nic) - configWriter.removeNic(nic) - iface = None if nic == iface else iface - - # Now we can restart changed interface - if iface: - ifdown(iface) - ifup(iface) - - -def clientSeen(timeout): - start = time.time() - while timeout >= 0: - if os.stat(constants.P_VDSM_CLIENT_LOG).st_mtime > start: - return True - time.sleep(1) - timeout -= 1 - return False - - -def editNetwork(oldBridge, newBridge, vlan=None, bonding=None, nics=None, - **options): - configWriter = ConfigWriter() - try: - delNetwork(oldBridge, configWriter=configWriter, **options) - addNetwork(newBridge, vlan=vlan, bonding=bonding, nics=nics, - configWriter=configWriter, **options) - except: - configWriter.restoreBackups() - raise - if utils.tobool(options.get('connectivityCheck', False)): - if not clientSeen(int(options.get('connectivityTimeout', - CONNECTIVITY_TIMEOUT_DEFAULT))): - delNetwork(newBridge, force=True) - configWriter.restoreBackups() - return define.errCode['noConPeer']['status']['code'] - - def _validateNetworkSetup(networks={}, bondings={}): _netinfo = netinfo.NetInfo() @@ -1171,73 +884,441 @@ "Unknown nics in: %r" % list(nics)) -def _editBondings(bondings, configWriter): - """ Add/Edit bond interface """ - logger = logging.getLogger("_editBondings") +def assertBridgeClean(bridge, vlan, bonding, nics): + brifs = os.listdir('/sys/class/net/%s/brif/' % bridge) + for nic in nics: + try: + brifs.remove(nic) + except: + pass + if vlan: + brif = (bonding or nics[0]) + '.' + vlan + else: + brif = bonding + try: + brifs.remove(brif) + except: + pass - _netinfo = netinfo.NetInfo() + if brifs: + raise ConfigNetworkError(ne.ERR_USED_BRIDGE, + 'bridge %s has interfaces %s connected' % (bridge, brifs)) - for bond, bondAttrs in bondings.iteritems(): - logger.debug("Creating/Editing bond %s with attributes %s", - bond, bondAttrs) - brNets = list(_netinfo.getBridgedNetworksForIface(bond)) - # Only one bridged-non-VLANed network allowed on same nic/bond - bridge = brNets[0] if brNets else None +def clientSeen(timeout): + start = time.time() + while timeout >= 0: + if os.stat(constants.P_VDSM_CLIENT_LOG).st_mtime > start: + return True + time.sleep(1) + timeout -= 1 + return False - mtu = None - if bond in _netinfo.bondings: - # Save MTU for future set on NICs - confParams = netinfo.getIfaceCfg(bond) - mtu = confParams.get('MTU', None) - if mtu: - mtu = int(mtu) - ifdown(bond) - # Take down all bond's NICs. - for nic in _netinfo.getNicsForBonding(bond): - ifdown(nic) - configWriter.removeNic(nic) +class NativeConfigurator(): - # Note! In case we have bridge up and connected to the bond - # we will get error in log: - # (ifdown) bridge XXX is still up; can't delete it - # But, we prefer this behaviour instead of taking bridge down - # Anyway, we will not be able to take it down with connected VMs + def addNetwork(self, network, vlan=None, bonding=None, nics=None, + ipaddr=None, netmask=None, mtu=None, gateway=None, + force=False, configWriter=None, bondingOptions=None, + bridged=True, **options): + nics = nics or () + _netinfo = netinfo.NetInfo() + bridged = utils.tobool(bridged) + + if mtu: + mtu = int(mtu) + + # Validation + if not utils.tobool(force): + logging.debug('validating network...') + _addNetworkValidation(_netinfo, network=network, + vlan=vlan, bonding=bonding, nics=nics, ipaddr=ipaddr, + netmask=netmask, gateway=gateway, + bondingOptions=bondingOptions, bridged=bridged, **options) + + logging.info("Adding network %s with vlan=%s, bonding=%s, nics=%s," + " bondingOptions=%s, mtu=%s, bridged=%s, options=%s", + network, vlan, bonding, nics, bondingOptions, + mtu, bridged, options) + + if configWriter is None: + configWriter = ConfigWriter() + + prevmtu = None + if mtu: + prevmtu = configWriter.getMaxMtu(nics, mtu) + + nic = nics[0] if nics else None + iface = bonding or nic + + # take down nics that need to be changed + vlanedIfaces = [v['iface'] for v in _netinfo.vlans.values()] + if bonding not in vlanedIfaces: + for nic in nics: + if nic not in vlanedIfaces: + ifdown(nic) + + if bridged: + configWriter.addBridge(network, ipaddr=ipaddr, netmask=netmask, + mtu=mtu, gateway=gateway, **options) + ifdown(network) + # We need to define (if requested) ip, mask & gateway on ifcfg-* + # only on most top device according to following order: + # bridge -> vlan -> bond -> nic + # For lower level devices we should ignore it. + # reset ip, netmask, gateway for lower level devices + ipaddr = netmask = gateway = None + + # For VLAN we should attach bridge only to the VLAN device + # rather than to underlying NICs or bond + brName = network if bridged else None + bridgeForNic = None if vlan else brName + + # We want to create config files (ifcfg-*) in top-down order + # (bridge->vlan->bond->nic) to be able to handle IP/NETMASK + # correctly for bridgeless networks + if vlan: + # don't ifup VLAN interface here, it should be done last, + # after the bond and nic up + configWriter.addVlan(vlan, iface, network=brName, + mtu=mtu, bridged=bridged, + ipaddr=ipaddr, netmask=netmask, + gateway=gateway, **options) + iface += '.' + vlan + # reset ip, netmask, gateway for lower level devices + ipaddr = netmask = gateway = None # First we need to prepare all conf files - configWriter.addBonding(bond, bridge=bridge, mtu=mtu, - bondingOptions=bondAttrs.get('options', None)) + if bonding: + configWriter.addBonding(bonding, bridge=bridgeForNic, + bondingOptions=bondingOptions, + mtu=max(prevmtu, mtu), + ipaddr=ipaddr, netmask=netmask, + gateway=gateway, **options) + # reset ip, netmask, gateway for lower level devices + ipaddr = netmask = gateway = None - for nic in bondAttrs['nics']: - configWriter.addNic(nic, bonding=bond, mtu=mtu) + for nic in nics: + configWriter.addNic(nic, bonding=bonding, + bridge=bridgeForNic if not bonding else None, + mtu=max(prevmtu, mtu), + ipaddr=ipaddr, netmask=netmask, + gateway=gateway, **options) # Now we can run ifup for all interfaces - ifup(bond) + if bonding: + ifup(bonding) + # NICs must be activated in the same order of boot time # to expose the correct MAC address. - for nic in nicSort(bondAttrs['nics']): + for nic in nicSort(nics): ifup(nic) + # Now we can ifup VLAN interface, because bond and nic already up + if vlan: + ifup(iface) -def _removeBondings(bondings, configWriter): - """ Remove bond interface """ - logger = logging.getLogger("_removeBondings") + if bridged: + if options.get('bootproto') == 'dhcp' and \ + not utils.tobool(options.get('blockingdhcp')): + # wait for dhcp in another thread, + # so vdsm won't get stuck (BZ#498940) + t = threading.Thread(target=ifup, name='ifup-waiting-on-dhcp', + args=(network,)) + t.daemon = True + t.start() + else: + ifup(network) - _netinfo = netinfo.NetInfo() + # add libvirt network + configWriter.createLibvirtNetwork(network, bridged, iface) - for bond, bondAttrs in bondings.items(): - if 'remove' in bondAttrs: - nics = _netinfo.getNicsForBonding(bond) - logger.debug("Removing bond %r with nics = %s", bond, nics) - ifdown(bond) - configWriter.removeBonding(bond) + def delNetwork(self, network, vlan=None, bonding=None, nics=None, + force=False, configWriter=None, implicitBonding=True, + **options): + _netinfo = netinfo.NetInfo() + + if configWriter is None: + configWriter = ConfigWriter() + + if network not in _netinfo.networks: + logging.info("Network %r: doesn't exist in libvirt database", + network) + if network in netinfo.bridges(): + configWriter.removeBridge(network) + else: + raise ConfigNetworkError(ne.ERR_BAD_BRIDGE, + "Cannot delete network %r: It doesn't exist " + "in the system" % network) + + if vlan: + configWriter.removeVlan(vlan, bonding or nics[0]) + + return + + nics, vlan, bonding = _netinfo.getNicsVlanAndBondingForNetwork(network) + bridged = _netinfo.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: + validateVlanId(vlan) + if bridged: + assertBridgeClean(network, vlan, bonding, nics) + + configWriter.setNewMtu(network=network, bridged=bridged) + configWriter.removeLibvirtNetwork(network) + + # We need to gather NetInfo again to refresh networks info from + # libvirt. The deleted bridge should never be up at this stage. + if network in netinfo.NetInfo().networks: + raise ConfigNetworkError(ne.ERR_USED_BRIDGE, + "delNetwork: bridge %s still exists" % network) + + if network and bridged: + configWriter.removeBridge(network) + + nic = nics[0] if nics else None + iface = bonding if bonding else nic + if iface: + if vlan: + configWriter.removeVlan(vlan, iface) + else: + cf = configWriter.NET_CONF_PREF + iface + if not bridged: + # When removing bridgeless non-VLANed network + # we need to remove IP/NETMASK from the cfg file + for key in ('IPADDR', 'NETMASK', 'GATEWAY', 'BOOTPROTO'): + configWriter._updateConfigValue(cf, key, '', True) + else: + # When removing bridged non-VLANed network + # we need to remove BRIDGE from the cfg file + configWriter._updateConfigValue(cf, 'BRIDGE', '', True) + + # The (relatively) new setupNetwork verb allows to remove a network + # defined on top of an bonding device without break the bond itself. + if implicitBonding: + if bonding and not bondingOtherUsers(network, vlan, bonding): + ifdown(bonding) + configWriter.removeBonding(bonding) + iface = None if bonding == iface else iface for nic in nics: - ifdown(nic) - configWriter.removeNic(nic) + if not nicOtherUsers(network, vlan, bonding, nic): + ifdown(nic) + configWriter.removeNic(nic) + iface = None if nic == iface else iface - del bondings[bond] + # Now we can restart changed interface + if iface: + ifdown(iface) + ifup(iface) + + def editNetwork(self, oldBridge, newBridge, vlan=None, bonding=None, + nics=None, **options): + configWriter = ConfigWriter() + try: + self.delNetwork(oldBridge, configWriter=configWriter, **options) + self.addNetwork(newBridge, vlan=vlan, bonding=bonding, nics=nics, + configWriter=configWriter, **options) + except: + configWriter.restoreBackups() + raise + if utils.tobool(options.get('connectivityCheck', False)): + if not clientSeen(int(options.get('connectivityTimeout', + CONNECTIVITY_TIMEOUT_DEFAULT))): + delNetwork(newBridge, force=True) + configWriter.restoreBackups() + return define.errCode['noConPeer']['status']['code'] + + def _editBondings(self, bondings, configWriter): + """ Add/Edit bond interface """ + logger = logging.getLogger("_editBondings") + + _netinfo = netinfo.NetInfo() + + for bond, bondAttrs in bondings.iteritems(): + logger.debug("Creating/Editing bond %s with attributes %s", + bond, bondAttrs) + + brNets = list(_netinfo.getBridgedNetworksForIface(bond)) + # Only one bridged-non-VLANed network allowed on same nic/bond + bridge = brNets[0] if brNets else None + + mtu = None + if bond in _netinfo.bondings: + # Save MTU for future set on NICs + confParams = netinfo.getIfaceCfg(bond) + mtu = confParams.get('MTU', None) + if mtu: + mtu = int(mtu) + + ifdown(bond) + # Take down all bond's NICs. + for nic in _netinfo.getNicsForBonding(bond): + ifdown(nic) + configWriter.removeNic(nic) + + # Note! In case we have bridge up and connected to the bond + # we will get error in log: + # (ifdown) bridge XXX is still up; can't delete it + # But, we prefer this behaviour instead of taking bridge down + # Anyway, we will not be able to take it down with connected VMs + + # First we need to prepare all conf files + configWriter.addBonding(bond, bridge=bridge, mtu=mtu, + bondingOptions=bondAttrs.get('options', None)) + + for nic in bondAttrs['nics']: + configWriter.addNic(nic, bonding=bond, mtu=mtu) + + # Now we can run ifup for all interfaces + ifup(bond) + # NICs must be activated in the same order of boot time + # to expose the correct MAC address. + for nic in nicSort(bondAttrs['nics']): + ifup(nic) + + def _removeBondings(self, bondings, configWriter): + """ Remove bond interface """ + logger = logging.getLogger("_removeBondings") + + _netinfo = netinfo.NetInfo() + + for bond, bondAttrs in bondings.items(): + if 'remove' in bondAttrs: + nics = _netinfo.getNicsForBonding(bond) + logger.debug("Removing bond %r with nics = %s", bond, nics) + ifdown(bond) + configWriter.removeBonding(bond) + + for nic in nics: + ifdown(nic) + configWriter.removeNic(nic) + + del bondings[bond] + + def setupNetworks(self, networks={}, bondings={}, **options): + + logger = logging.getLogger("setupNetworks") + + try: + _netinfo = netinfo.NetInfo() + configWriter = ConfigWriter() + networksAdded = set() + # keep set netsWithNewBonds to be able remove + # a new added network if connectivity check fail. + # If a new network needs to be created on top of existing bond, + # we will need to keep the bond on rollback flow, + # else we will break the new created bond. + netsWithNewBonds = 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: + # 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) + self.delNetwork(network, configWriter=configWriter, + force=force, implicitBonding=False) + if 'remove' in networkAttrs: + del networks[network] + else: + networksAdded.add(network) + + # Remove bonds with 'remove' attribute + self._removeBondings(bondings, configWriter) + + # Check whether bonds should be resized + self._editBondings(bondings, configWriter) + + # We need to use the newest host info + _ni = netinfo.NetInfo() + for network, networkAttrs in networks.iteritems(): + d = dict(networkAttrs) + if 'bonding' in d: + # we may not receive any information + # about the bonding device if it is unchanged + # In this case check whether this bond exists + # on host and take its parameters + if bondings.get(d['bonding']): + d['nics'] = bondings[d['bonding']]['nics'] + d['bondingOptions'] = \ + bondings[d['bonding']].get('options', None) + # we create a new bond + if network in networksAdded: + netsWithNewBonds.add(network) + elif d['bonding'] in _ni.bondings: + logger.debug("Updating bond %r info", d['bonding']) + d['nics'] = _ni.bondings[d['bonding']]['slaves'] + d['bondingOptions'] = \ + _ni.bondings[d['bonding']]['cfg'].get( + 'BONDING_OPTS', None) + else: + d['nics'] = [d.pop('nic')] + d['force'] = force + + logger.debug("Adding network %r" % network) + self.addNetwork(network, configWriter=configWriter, + 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: + self.delNetwork(network, force=True, + implicitBonding=network in netsWithNewBonds) + raise ConfigNetworkError(ne.ERR_LOST_CONNECTION, + 'connectivity check failed') + except: + configWriter.restoreBackups() + raise + + except Exception, e: + # SuperVdsm eats the error, so let's print it ourselves + logger.error(e, exc_info=True) + raise + + +configurator = NativeConfigurator() + + +def addNetwork(network, vlan=None, bonding=None, nics=None, ipaddr=None, + netmask=None, mtu=None, gateway=None, force=False, + bondingOptions=None, bridged=True, **options): + configurator.addNetwork(network, vlan, bonding, nics, ipaddr, netmask, mtu, + gateway, force, bondingOptions, bridged, **options) + + +def delNetwork(network, vlan=None, bonding=None, nics=None, force=False, + implicitBonding=True, **options): + configurator.delNetwork(network, vlan, bonding, nics, force, + implicitBonding, **options) + + +def editNetwork(oldBridge, newBridge, vlan=None, bonding=None, nics=None, + **options): + configurator.editNetwork(oldBridge, newBridge, vlan, bonding, nics, + **options) def setupNetworks(networks={}, bondings={}, **options): @@ -1277,95 +1358,40 @@ 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") + configurator.setupNetworks(networks, bondings, **options) - try: - _netinfo = netinfo.NetInfo() - configWriter = ConfigWriter() - networksAdded = set() - # keep set netsWithNewBonds to be able remove - # a new added network if connectivity check fail. - # If a new network needs to be created on top of existing bond, - # we will need to keep the bond on rollback flow, - # else we will break the new created bond. - netsWithNewBonds = set() - logger.debug("Setting up network according to configuration: " - "networks:%r, bondings:%r, options:%r" % (networks, - bondings, options)) +def showNetwork(network): + _netinfo = netinfo.NetInfo() + if network not in _netinfo.networks: + print "Network %r doesn't exist" % network + return - force = options.get('force', False) - if not utils.tobool(force): - logging.debug("Validating configuration") - _validateNetworkSetup(dict(networks), dict(bondings)) + bridged = _netinfo.networks[network]['bridged'] + print "Network %s(Bridged: %s):" % (network, bridged) - logger.debug("Applying...") - try: - # 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, configWriter=configWriter, force=force, - implicitBonding=False) - if 'remove' in networkAttrs: - del networks[network] - else: - networksAdded.add(network) + nics, vlan, bonding = _netinfo.getNicsVlanAndBondingForNetwork(network) - # Remove bonds with 'remove' attribute - _removeBondings(bondings, configWriter) + if bridged: + ipaddr = _netinfo.networks[network]['addr'] + netmask = _netinfo.networks[network]['netmask'] + gateway = _netinfo.networks[network]['gateway'] + print "ipaddr=%s, netmask=%s, gateway=%s" % (ipaddr, netmask, gateway) + else: + iface = _netinfo.networks[network]['iface'] + ipaddr = _netinfo.nics[iface]['addr'] + netmask = _netinfo.nics[iface]['netmask'] + print "ipaddr=%s, netmask=%s" % (ipaddr, netmask) - # Check whether bonds should be resized - _editBondings(bondings, configWriter) + print "vlan=%s, bonding=%s, nics=%s" % (vlan, bonding, nics) - # We need to use the newest host info - _ni = netinfo.NetInfo() - for network, networkAttrs in networks.iteritems(): - d = dict(networkAttrs) - if 'bonding' in d: - # we may not receive any information - # about the bonding device if it is unchanged - # In this case check whether this bond exists - # on host and take its parameters - if bondings.get(d['bonding']): - d['nics'] = bondings[d['bonding']]['nics'] - d['bondingOptions'] = \ - bondings[d['bonding']].get('options', None) - # we create a new bond - if network in networksAdded: - netsWithNewBonds.add(network) - elif d['bonding'] in _ni.bondings: - logger.debug("Updating bond %r info", d['bonding']) - d['nics'] = _ni.bondings[d['bonding']]['slaves'] - d['bondingOptions'] = \ - _ni.bondings[d['bonding']]['cfg'].get( - 'BONDING_OPTS', None) - else: - d['nics'] = [d.pop('nic')] - d['force'] = force - logger.debug("Adding network %r" % network) - addNetwork(network, configWriter=configWriter, - 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: - delNetwork(network, force=True, - implicitBonding=network in netsWithNewBonds) - raise ConfigNetworkError(ne.ERR_LOST_CONNECTION, - 'connectivity check failed') - except: - configWriter.restoreBackups() - raise - - except Exception, e: - # SuperVdsm eats the error, so let's print it ourselves - logger.error(e, exc_info=True) - raise +def listNetworks(): + _netinfo = netinfo.NetInfo() + print "Networks:", _netinfo.networks.keys() + print "Vlans:", _netinfo.vlans.keys() + print "Nics:", _netinfo.nics.keys() + print "Bondings:", _netinfo.bondings.keys() def setSafeNetworkConfig(): -- To view, visit http://gerrit.ovirt.org/7915 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I052955a8e2b7b92b123a5179afd15b79798e6c50 Gerrit-PatchSet: 1 Gerrit-Project: vdsm Gerrit-Branch: master Gerrit-Owner: Mark Wu <[email protected]> _______________________________________________ vdsm-patches mailing list [email protected] https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches
