Best Python code snippet using lisa_python
configNetwork.py
Source:configNetwork.py
1#!/usr/bin/python2#3# Copyright 2011 Red Hat, Inc.4#5# This program is free software; you can redistribute it and/or modify6# it under the terms of the GNU General Public License as published by7# the Free Software Foundation; either version 2 of the License, or8# (at your option) any later version.9#10# This program is distributed in the hope that it will be useful,11# but WITHOUT ANY WARRANTY; without even the implied warranty of12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13# GNU General Public License for more details.14#15# You should have received a copy of the GNU General Public License16# along with this program; if not, write to the Free Software17# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA18#19# Refer to the README and COPYING files for full details of the license20#21import sys, subprocess, os, re, traceback22import shutil23import pipes24import pwd25import time26import logging27from collections import defaultdict28import threading29import constants30import utils31import neterrors as ne32import define33from netinfo import NetInfo, getIpAddresses, NET_CONF_DIR, NET_CONF_BACK_DIR34CONNECTIVITY_TIMEOUT_DEFAULT = 435MAX_VLAN_ID = 409536MAX_BRIDGE_NAME_LEN = 1537ILLEGAL_BRIDGE_CHARS = ':. \t'38class ConfigNetworkError(Exception):39 def __init__(self, errCode, message):40 self.errCode = errCode41 self.message = message42 Exception.__init__(self, self.errCode, self.message)43def _isTrue(b):44 "Check all kinds of boolean input"45 if b in ('true', 'True'):46 return True47 elif b in ('false', 'False'):48 return False49 return bool(b)50def ipcalc(checkopt, s):51 "Validate an ip address (or netmask) using ipcalc"52 if not isinstance(s, basestring):53 return 054 p = subprocess.Popen([constants.EXT_IPCALC, '-c', checkopt, s],55 close_fds=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)56 out, err = p.communicate()57 if err:58 logging.warn(err)59 return not p.returncode60def ifdown(iface):61 "Bring down an interface"62 p = subprocess.Popen([constants.EXT_IFDOWN, iface], stdout=subprocess.PIPE,63 stderr=subprocess.PIPE, close_fds=True)64 out, err = p.communicate()65 if out.strip():66 logging.info(out)67 if err.strip():68 logging.warn('\n'.join([line for line in err.splitlines()69 if not line.endswith(' does not exist!')]))70 return p.returncode71def ifup(iface):72 "Bring up an interface"73 p = subprocess.Popen([constants.EXT_IFUP, iface], stdout=subprocess.PIPE,74 stderr=subprocess.PIPE, close_fds=True)75 out, err = p.communicate()76 if out.strip():77 logging.info(out)78 if err.strip():79 logging.warn(err)80def ifaceUsers(iface):81 "Returns a list of entities using the interface"82 _netinfo = NetInfo()83 users = set()84 for b, bdict in _netinfo.networks.iteritems():85 if iface in bdict['ports']:86 users.add(b)87 for b, bdict in _netinfo.bondings.iteritems():88 if iface in bdict['slaves']:89 users.add(b)90 for v, vdict in _netinfo.vlans.iteritems():91 if iface == vdict['iface']:92 users.add(v)93 return users94def nicOtherUsers(bridge, vlan, bonding, nic):95 "Returns a list of interfaces using a nic, other than the specified one (used for validation)"96 if bonding:97 owner = bonding98 elif vlan:99 owner = nic + '.' + vlan100 else:101 owner = bridge102 users = ifaceUsers(nic)103 if bonding:104 users.update(bondingOtherUsers(bridge, vlan, bonding))105 users.discard(owner)106 return users107def bondingOtherUsers(bridge, vlan, bonding):108 "Return a list of nics/interfaces using a bonding, other than the specified one (used for validation)"109 if vlan:110 owner = bonding + '.' + vlan111 else:112 owner = bridge113 users = ifaceUsers(bonding)114 users.discard(owner)115 return users116def nicSort(nics):117 "Return a list of nics/interfaces ordered by name"118 nics_list = []119 nics_rexp = re.compile("([A-Za-z]+)([0-9]+)")120 for nic_name in nics:121 nic_sre = nics_rexp.match(nic_name)122 if nic_sre:123 nics_list.append((nic_sre.group(1), int(nic_sre.group(2))))124 else:125 nics_list.append((nic_name, ''))126 return [x + str(y) for x, y in sorted(nics_list)]127class ConfigWriter(object):128 NET_CONF_PREF = NET_CONF_DIR + 'ifcfg-'129 CONFFILE_HEADER = '# automatically generated by vdsm'130 DELETED_HEADER = '# original file did not exist'131 def __init__(self):132 self._backups = {}133 def _backup(self, filename):134 self._atomicBackup(filename)135 self._persistentBackup(filename)136 def _atomicBackup(self, filename):137 """Backs up configuration to memory, for a later rollback in case of error."""138 confFile = os.path.join(NET_CONF_DIR, filename)139 if confFile not in self._backups:140 try:141 self._backups[confFile] = open(confFile).read()142 logging.debug("Backed up %s" % confFile)143 except IOError:144 pass145 def restoreAtomicBackup(self):146 logging.info("Rolling back configuration (restoring atomic backup)")147 if not self._backups:148 return149 for confFile, content in self._backups.iteritems():150 open(confFile, 'w').write(content)151 logging.debug('Restored %s', confFile)152 subprocess.Popen(['/etc/init.d/network', 'start'])153 @staticmethod154 def _removeFile(filename):155 """Remove file, umounting ovirt config files if needed."""156 mounts = open('/proc/mounts').read()157 if ' /config ext3' in mounts and ' %s ext3' % filename in mounts:158 subprocess.call([constants.EXT_UMOUNT, '-n', filename])159 utils.rmFile(filename)160 @classmethod161 def _persistentBackup(cls, filename):162 if os.path.exists('/usr/libexec/ovirt-functions'):163 subprocess.call([constants.EXT_SH, '/usr/libexec/ovirt-functions', 'unmount_config', filename])164 logging.debug("unmounted %s using ovirt" % filename)165 (dummy, basename) = os.path.split(filename)166 backup = os.path.join(NET_CONF_BACK_DIR, basename)167 if os.path.exists(backup):168 # original copy already backed up169 return170 vdsm_uid = pwd.getpwnam('vdsm').pw_uid171 # make directory (if it doesn't exist) and assign it to vdsm172 if not os.path.exists(NET_CONF_BACK_DIR):173 os.mkdir(NET_CONF_BACK_DIR)174 os.chown(NET_CONF_BACK_DIR, vdsm_uid, 0)175 if os.path.exists(filename):176 shutil.copy2(filename, backup)177 else:178 open(backup, 'w').write(cls.DELETED_HEADER + '\n')179 os.chown(backup, vdsm_uid, 0)180 logging.debug("Persistently backed up %s (until next 'set safe config')" % filename)181 def addBridge(self, name, ipaddr=None, netmask=None, gateway=None,182 bootproto=None, delay='0', onboot='yes', **kwargs):183 "Based on addNetwork"184 s = """DEVICE=%s\nTYPE=Bridge\nONBOOT=%s\n""" % (pipes.quote(name), pipes.quote(onboot))185 if ipaddr:186 s = s + 'IPADDR=%s\nNETMASK=%s\n' % (pipes.quote(ipaddr), pipes.quote(netmask))187 if gateway:188 s = s + 'GATEWAY=%s\n' % pipes.quote(gateway)189 else:190 if bootproto:191 s = s + 'BOOTPROTO=%s\n' % pipes.quote(bootproto)192 s += 'DELAY=%s\n' % pipes.quote(delay)193 BLACKLIST = ['TYPE', 'NAME', 'DEVICE', 'bondingOptions',194 'force', 'blockingdhcp',195 'connectivityCheck', 'connectivityTimeout']196 for k in set(kwargs.keys()).difference(set(BLACKLIST)):197 if re.match('^[a-zA-Z_]\w*$', k):198 s += '%s=%s\n' % (k.upper(), pipes.quote(kwargs[k]))199 else:200 logging.debug('ignoring variable %s' % k)201 conffile = self.NET_CONF_PREF + name202 self._backup(conffile)203 open(conffile, 'w').write(s)204 os.chmod(conffile, 0664)205 def addVlan(self, vlanId, iface, bridge):206 "Based on addNetwork"207 conffile = self.NET_CONF_PREF + iface + '.' + vlanId208 self._backup(conffile)209 open(conffile, 'w').write("""DEVICE=%s.%s\nONBOOT=yes\nVLAN=yes\nBOOTPROTO=none\nBRIDGE=%s\n""" % (pipes.quote(iface), vlanId, pipes.quote(bridge)))210 os.chmod(conffile, 0664)211 def addBonding(self, bonding, bridge=None, bondingOptions=None):212 "Based on addNetwork"213 conffile = self.NET_CONF_PREF + bonding214 self._backup(conffile)215 with open(conffile, 'w') as f:216 f.write("""DEVICE=%s\nONBOOT=yes\nBOOTPROTO=none\n""" % (bonding))217 if bridge:218 f.write('BRIDGE=%s\n' % pipes.quote(bridge))219 if not bondingOptions:220 bondingOptions = 'mode=802.3ad miimon=150'221 f.write('BONDING_OPTS=%s' % pipes.quote(bondingOptions or ''))222 os.chmod(conffile, 0664)223 # create the bonding device to avoid initscripts noise224 if bonding not in open('/sys/class/net/bonding_masters').read().split():225 open('/sys/class/net/bonding_masters', 'w').write('+%s\n' % bonding)226 def addNic(self, nic, bonding=None, bridge=None):227 "Based on addNetwork"228 conffile = self.NET_CONF_PREF + nic229 self._backup(conffile)230 _netinfo = NetInfo()231 hwaddr = _netinfo.nics[nic].get('permhwaddr') or \232 _netinfo.nics[nic]['hwaddr']233 with open(conffile, 'w') as f:234 f.write('DEVICE=%s\nONBOOT=yes\nBOOTPROTO=none\nHWADDR=%s\n' % (pipes.quote(nic),235 pipes.quote(hwaddr)))236 if bridge:237 f.write('BRIDGE=%s\n' % pipes.quote(bridge))238 if bonding:239 f.write('MASTER=%s\n' % pipes.quote(bonding))240 f.write('SLAVE=yes\n')241 os.chmod(conffile, 0664)242 def removeNic(self, nic):243 cf = self.NET_CONF_PREF + nic244 self._backup(cf)245 try:246 hwlines = [ line for line in open(cf).readlines()247 if line.startswith('HWADDR=') ]248 l = ['DEVICE=%s\n' % nic, 'ONBOOT=yes\n', 'BOOTPROTO=none\n'] + hwlines249 open(cf, 'w').writelines(l)250 except IOError:251 pass252 def removeVlan(self, vlanId, iface):253 self._backup(self.NET_CONF_PREF + iface + '.' + vlanId)254 self._removeFile(self.NET_CONF_PREF + iface + '.' + vlanId)255 def removeBonding(self, bonding):256 self._backup(self.NET_CONF_PREF + bonding)257 self._removeFile(self.NET_CONF_PREF + bonding)258 def removeBridge(self, bridge):259 self._backup(self.NET_CONF_PREF + bridge)260 self._removeFile(self.NET_CONF_PREF + bridge)261 # the deleted bridge should never be up at this stage.262 if bridge in NetInfo().networks:263 raise ConfigNetworkError(ne.ERR_USED_BRIDGE, 'delNetwork: bridge %s still exists' % bridge)264def isBridgeNameValid(bridgeName):265 return bridgeName and len(bridgeName) <= MAX_BRIDGE_NAME_LEN and len(set(bridgeName) & set(ILLEGAL_BRIDGE_CHARS)) == 0266def validateBridgeName(bridgeName):267 if not isBridgeNameValid(bridgeName):268 raise ConfigNetworkError(ne.ERR_BAD_BRIDGE, "Bridge name isn't valid: %r"%bridgeName)269def validateIpAddress(ipAddr):270 if not ipcalc('-4', ipAddr):271 raise ConfigNetworkError(ne.ERR_BAD_ADDR, "Bad IP address: %r"%ipAddr)272 if ipAddr in getIpAddresses():273 raise ConfigNetworkError(ne.ERR_BAD_ADDR, "IP address is already in use")274def validateNetmask(netmask):275 if not ipcalc('-m', netmask):276 raise ConfigNetworkError(ne.ERR_BAD_ADDR, "Bad netmask: %r"%netmask)277def validateGateway(gateway):278 if not ipcalc('-4', gateway):279 raise ConfigNetworkError(ne.ERR_BAD_ADDR, "Bad gateway: %r"%gateway)280def validateBondingName(bonding):281 if not re.match('^bond[0-9]+$', bonding):282 raise ConfigNetworkError(ne.ERR_BAD_BONDING, '%r is not a valid bonding device name' % bonding)283def validateBondingOptions(bonding, bondingOptions):284 'Example: BONDING_OPTS="mode=802.3ad miimon=150"'285 try:286 for option in bondingOptions.split():287 key,value = option.split('=')288 if not os.path.exists('/sys/class/net/%(bonding)s/bonding/%(key)s'289 % locals()):290 raise ConfigNetworkError(ne.ERR_BAD_BONDING,291 "%r is not a valid bonding option" % key)292 except ValueError:293 raise ConfigNetworkError(ne.ERR_BAD_BONDING,294 "Error parsing bonding options: %r" % bondingOptions)295def validateVlanId(vlan):296 try:297 if not 0 <= int(vlan) <= MAX_VLAN_ID:298 raise ConfigNetworkError(ne.ERR_BAD_VLAN, 'vlan id out of range: %r, must be 0..%s' % (vlan, MAX_VLAN_ID))299 except ValueError:300 raise ConfigNetworkError(ne.ERR_BAD_VLAN, 'vlan id must be a number')301def _addNetworkValidation(_netinfo, bridge, vlan, bonding, nics, ipaddr, netmask, gateway, bondingOptions):302 if (vlan or bonding) and not nics:303 raise ConfigNetworkError(ne.ERR_BAD_PARAMS, 'vlan/bonding definition requires nics. got: %r'%(nics,))304 # Check bridge305 validateBridgeName(bridge)306 if bridge in _netinfo.networks:307 raise ConfigNetworkError(ne.ERR_USED_BRIDGE, 'Bridge already exists')308 # vlan309 if vlan:310 validateVlanId(vlan)311 if bonding:312 validateBondingName(bonding)313 if bondingOptions:314 validateBondingOptions(bonding, bondingOptions)315 elif bondingOptions:316 raise ConfigNetworkError(ne.ERR_BAD_BONDING, 'Bonding options specified without bonding')317 # Check ip, netmask, gateway318 if ipaddr:319 if not netmask:320 raise ConfigNetworkError(ne.ERR_BAD_ADDR, "Must specify netmask to configure ip for bridge")321 validateIpAddress(ipaddr)322 validateNetmask(netmask)323 if gateway:324 validateGateway(gateway)325 else:326 if netmask or gateway:327 raise ConfigNetworkError(ne.ERR_BAD_ADDR, "Specified netmask or gateway but not ip")328 # Check nics329 for nic in nics:330 if nic not in _netinfo.nics:331 raise ConfigNetworkError(ne.ERR_BAD_NIC, "unknown nic: %r"%nic)332 bridgesForNic = list(_netinfo.getNetworksForNic(nic))333 if bridgesForNic:334 assert len(bridgesForNic) == 1335 raise ConfigNetworkError(ne.ERR_USED_NIC, "nic %r is already bound to bridge %r"%(nic, bridgesForNic[0]))336 if bonding and not vlan:337 for nic in nics:338 vlansForNic = list(_netinfo.getVlansForNic(nic))339 if len(vlansForNic):340 raise ConfigNetworkError(ne.ERR_USED_NIC, 'nic %s already used by vlans %s' % ( nics, vlansForNic))341 # Bonding342 if bonding:343 bonding_ifaces = _netinfo.getNetworksAndVlansForBonding(bonding)344 if vlan: # Make sure all connected interfaces (if any) are vlans345 for (bonding_bridge, bonding_vlan) in bonding_ifaces:346 if bonding_vlan is None:347 raise ConfigNetworkError(ne.ERR_BAD_BONDING, 'bonding %r is already member of bridge %r'%(348 bonding, bonding_bridge ))349 else:350 bonding_ifaces = list(bonding_ifaces)351 if len(bonding_ifaces):352 raise ConfigNetworkError(ne.ERR_BAD_BONDING, 'bonding %r already has members: %r'%(bonding,bonding_ifaces))353 else:354 if len(nics) > 1:355 raise ConfigNetworkError(ne.ERR_BAD_BONDING, 'multiple nics require a bonding device')356 # Make sure nics don't have a different bonding357 # still relevant if bonding is None358 for nic in nics:359 bondingForNics = _netinfo.getBondingForNic(nic)360 if bondingForNics and bondingForNics != bonding:361 raise ConfigNetworkError(ne.ERR_USED_NIC, 'nic %s already enslaved to %s' % (nic, bondingForNics))362def addNetwork(bridge, vlan=None, bonding=None, nics=None, ipaddr=None, netmask=None, gateway=None,363 force=False, configWriter=None, bondingOptions=None, **options):364 nics = nics or ()365 _netinfo = NetInfo()366 # Validation367 if not _isTrue(force):368 logging.debug('validating bridge...')369 _addNetworkValidation(_netinfo, bridge, vlan=vlan, bonding=bonding, nics=nics,370 ipaddr=ipaddr, netmask=netmask, gateway=gateway,371 bondingOptions=bondingOptions)372 logging.info("Adding bridge %s with vlan=%s, bonding=%s, nics=%s. bondingOptions=%s, options=%s"373 %(bridge, vlan, bonding, nics, bondingOptions, options))374 if configWriter is None:375 configWriter = ConfigWriter()376 configWriter.addBridge(bridge, ipaddr=ipaddr, netmask=netmask, gateway=gateway, **options)377 ifaceBridge = bridge378 if vlan:379 configWriter.addVlan(vlan, bonding or nics[0], bridge)380 # since we have vlan device, it is connected to the bridge. other381 # interfaces should be connected to the bridge through vlan, and not382 # directly.383 ifaceBridge = None384 if bonding:385 configWriter.addBonding(bonding, ifaceBridge, bondingOptions=bondingOptions)386 for nic in nics:387 configWriter.addNic(nic, bonding=bonding)388 else:389 for nic in nics:390 configWriter.addNic(nic, bridge=ifaceBridge)391 # take down nics that need to be changed392 vlanedIfaces = [v['iface'] for v in _netinfo.vlans.values()]393 if bonding not in vlanedIfaces:394 for nic in nics:395 if nic not in vlanedIfaces:396 ifdown(nic)397 ifdown(bridge)398 # nics must be activated in the same order of boot time to expose the correct399 # MAC address.400 for nic in nicSort(nics):401 ifup(nic)402 if bonding:403 ifup(bonding)404 if vlan:405 ifup((bonding or nics[0]) + '.' + vlan)406 if options.get('bootproto') == 'dhcp' and not utils.tobool(options.get('blockingdhcp')):407 # wait for dhcp in another thread, so vdsm won't get stuck (BZ#498940)408 t = threading.Thread(target=ifup, name='ifup-waiting-on-dhcp', args=(bridge,))409 t.daemon = True410 t.start()411 else:412 ifup(bridge)413def assertBridgeClean(bridge, vlan, bonding, nics):414 brifs = os.listdir('/sys/class/net/%s/brif/' % bridge)415 for nic in nics:416 try:417 brifs.remove(nic)418 except:419 pass420 if vlan:421 brif = (bonding or nics[0]) + '.' + vlan422 else:423 brif = bonding424 try:425 brifs.remove(brif)426 except:427 pass428 if brifs:429 raise ConfigNetworkError(ne.ERR_USED_BRIDGE, 'bridge %s has interfaces %s connected' % (bridge, brifs))430def showNetwork(bridge):431 _netinfo = NetInfo()432 if bridge not in _netinfo.networks:433 print "Bridge %r doesn't exist" % bridge434 return435 nics, vlan, bonding = _netinfo.getNicsVlanAndBondingForNetwork(bridge)436 print "Bridge %s: vlan=%s, bonding=%s, nics=%s" % (bridge, vlan, bonding, nics)437def listNetworks():438 _netinfo = NetInfo()439 print "Networks:", _netinfo.networks.keys()440 print "Vlans:", _netinfo.vlans.keys()441 print "Nics:", _netinfo.nics.keys()442 print "Bondings:", _netinfo.bondings.keys()443def delNetwork(bridge, force=False, configWriter=None, **options):444 _netinfo = NetInfo()445 validateBridgeName(bridge)446 if bridge not in _netinfo.networks:447 raise ConfigNetworkError(ne.ERR_BAD_BRIDGE, "Cannot delete bridge %r: It doesn't exist"%bridge)448 nics, vlan, bonding = _netinfo.getNicsVlanAndBondingForNetwork(bridge)449 logging.info("Removing bridge %s with vlan=%s, bonding=%s, nics=%s. options=%s"%(bridge, vlan, bonding, nics, options))450 if not _isTrue(force):451 if bonding:452 validateBondingName(bonding)453 if set(nics) != set(_netinfo.bondings[bonding]["slaves"]):454 raise ConfigNetworkError(ne.ERR_BAD_NIC, 'delNetwork: %s are not all nics enslaved to %s' % (nics, bonding))455 if vlan:456 #assertVlan(vlan)457 validateVlanId(vlan)458 assertBridgeClean(bridge, vlan, bonding, nics)459 if configWriter is None:460 configWriter = ConfigWriter()461 if bridge:462 ifdown(bridge)463 subprocess.call([constants.EXT_BRCTL, 'delbr', bridge])464 if vlan:465 vlandev = (bonding or nics[0]) + '.' + vlan466 ifdown(vlandev)467 subprocess.call([constants.EXT_VCONFIG, 'rem', vlandev], stderr=subprocess.PIPE)468 if bonding:469 if not bondingOtherUsers(bridge, vlan, bonding):470 ifdown(bonding)471 for nic in nics:472 if not nicOtherUsers(bridge, vlan, bonding, nic):473 ifdown(nic)474 for nic in nics:475 if nicOtherUsers(bridge, vlan, bonding, nic):476 continue477 configWriter.removeNic(nic)478 if bonding:479 if not bondingOtherUsers(bridge, vlan, bonding):480 configWriter.removeBonding(bonding)481 if vlan:482 configWriter.removeVlan(vlan, bonding or nics[0])483 if bridge:484 configWriter.removeBridge(bridge)485def clientSeen(timeout):486 start = time.time()487 while timeout >= 0:488 if os.stat(constants.P_VDSM_CLIENT_LOG).st_mtime > start:489 return True490 time.sleep(1)491 timeout -= 1492 return False493def editNetwork(oldBridge, newBridge, vlan=None, bonding=None, nics=None, **options):494 configWriter = ConfigWriter()495 try:496 delNetwork(oldBridge, configWriter=configWriter, **options)497 addNetwork(newBridge, vlan=vlan, bonding=bonding, nics=nics, configWriter=configWriter, **options)498 except:499 configWriter.restoreAtomicBackup()500 raise501 if utils.tobool(options.get('connectivityCheck', False)):502 if not clientSeen(int(options.get('connectivityTimeout', CONNECTIVITY_TIMEOUT_DEFAULT))):503 delNetwork(newBridge, force=True)504 configWriter.restoreAtomicBackup()505 return define.errCode['noConPeer']['status']['code']506def _validateNetworkSetup(networks={}, bondings={}, explicitBonding=False):507 _netinfo = NetInfo()508 # Step 1: Initial validation (validate names, existence of params, etc.)509 for network, networkAttrs in networks.iteritems():510 validateBridgeName(network)511 if networkAttrs.get('remove', False):512 if set(networkAttrs) - set(['remove']):513 raise ConfigNetworkError(ne.ERR_BAD_PARAMS, "Cannot specify any attribute when removing")514 if network not in _netinfo.networks:515 raise ConfigNetworkError(ne.ERR_BAD_BRIDGE, 'Cannot remove bridge %s: Doesn\'t exist' % network)516 continue517 vlan = networkAttrs.get('vlan', None)518 ipaddr = networkAttrs.get('ipaddr', None)519 netmask = networkAttrs.get('netmask', None)520 gateway = networkAttrs.get('gateway', None)521 if vlan:522 validateVlanId(vlan)523 # Check ip, netmask, gateway524 if ipaddr:525 if not netmask:526 raise ConfigNetworkError(ne.ERR_BAD_ADDR, "Must specify netmask to configure ip for bridge")527 validateIpAddress(ipaddr)528 validateNetmask(netmask)529 if gateway:530 validateGateway(gateway)531 else:532 if netmask or gateway:533 raise ConfigNetworkError(ne.ERR_BAD_ADDR, "Specified netmask or gateway but not ip")534 # check nic or bonding535 nic = networkAttrs.get('nic', None)536 bonding = networkAttrs.get('bonding', None)537 if nic and bonding:538 raise ConfigNetworkError(ne.ERR_BAD_PARAMS, "Don't specify both nic and bonding")539 if not nic and not bonding:540 raise ConfigNetworkError(ne.ERR_BAD_PARAMS, "Must specify either nic or bonding")541 if nic and nic not in _netinfo.nics:542 raise ConfigNetworkError(ne.ERR_BAD_NIC, "unknown nic: %r"%nic)543 for bonding, bondingAttrs in bondings.iteritems():544 validateBondingName(bonding)545 if 'options' in bondingAttrs:546 validateBondingOptions(bonding, bondingAttrs['options'])547 if bondingAttrs.get('remove', False):548 if bonding not in _netinfo.bondings:549 raise ConfigNetworkError(ne.ERR_BAD_BONDING, 'Cannot remove bonding %s: Doesn\'t exist' % bonding)550 continue551 nics = bondingAttrs.get('nics', None)552 if not nics:553 raise ConfigNetworkError(ne.ERR_BAD_PARAMS, "Must specify nics for bonding")554 if not set(nics).issubset(set(_netinfo.nics)):555 raise ConfigNetworkError(ne.ERR_BAD_NIC, "Unknown nics in: %r"%list(nics))556 # Step 2: Make sure we have complete information about the Setup, more validation557 # (if explicitBonding==False we complete the missing information ourselves, else we raise an exception)558 nics = defaultdict(lambda: {'networks':[], 'bonding':None})559 for network, networkAttrs in networks.iteritems():560 if networkAttrs.get('remove', False):561 continue562 if 'bonding' in networkAttrs:563 assert 'nic' not in networkAttrs564 bonding = networkAttrs['bonding']565 if bonding not in bondings:566 if explicitBonding:567 raise ConfigNetworkError(ne.ERR_BAD_PARAMS, "Network %s requires unspecified bonding %s"%(568 network, bonding))569 # fill in bonding info570 bondings[bonding] = {'nics':_netinfo.bondings[bonding]['slaves']}571 if '_networks' not in bondings[bonding]:572 bondings[bonding]['_networks'] = []573 bondings[bonding]['_networks'].append( network )574 else:575 assert 'nic' in networkAttrs576 nics[networkAttrs['nic']]['networks'].append( network )577 for bonding, bondingAttrs in bondings.iteritems():578 if bondingAttrs.get('remove', False):579 continue580 connectedNetworks = _netinfo.getNetworksForNic(bonding)581 for network in connectedNetworks:582 if network not in networks:583 if explicitBonding:584 raise ConfigNetworkError(ne.ERR_BAD_PARAMS, "Bonding %s is associated with unspecified network %s"%(585 bonding, network))586 # fill in network info587 _, vlan, bonding2 = _netinfo.getNicsVlanAndBondingForNetwork(network)588 assert bonding == bonding2589 networks[network] = {'bonding': bonding, 'vlan':vlan}590 for nic in bondingAttrs['nics']:591 if nics[nic]['bonding']:592 raise ConfigNetworkError(ne.ERR_BAD_BONDING, "Nic %s is attached to two different bondings in setup: %s, %s"%(593 nic, bonding, nics[nic]['bonding']))594 nics[nic]['bonding'] = bonding595 # At this point the state may be contradictory.596 # Step 3: Apply removals (We're not iterating because we change the dictionary size)597 queue = []598 for network, networkAttrs in networks.items():599 if networkAttrs.get('remove', False):600 del networks[network]601 else:602 queue.append(('network', network, networkAttrs))603 for bonding, bondingAttrs in bondings.items():604 if bondingAttrs.get('remove', False):605 del bondings[bonding]606 else:607 queue.append(('bonding', bonding, bondingAttrs))608 # Step 4: Verify Setup609 for nic, nicAttrs in nics.iteritems():610 if nicAttrs['networks'] and nicAttrs['bonding']:611 raise ConfigNetworkError(ne.ERR_USED_NIC, "Setup attached both network and bonding to nic %s"%(nic))612 if len(networks) > 1:613 for network, networkAttrs in networks.iteritems():614 if not networkAttrs.get('vlan', None):615 raise ConfigNetworkError(ne.ERR_USED_NIC,616 "Setup attached more than one network to nic %s, some of which aren't vlans"%(nic))617 for bonding, bondingAttrs in bondings.iteritems():618 networks = bondingAttrs['_networks']619 if len(networks) > 1:620 for network, networkAttrs in networks.iteritems():621 if not networkAttrs.get('vlan', None):622 raise ConfigNetworkError(ne.ERR_BAD_BONDING,623 "Setup attached more than one network to bonding %s, some of which aren't vlans"%(bonding))624def setupNetworks(networks={}, bondings={}, **options):625 """Add/Edit/Remove configuration for networks and bondings.626 Params:627 networks - dict of key=network, value=attributes628 where 'attributes' is a dict with the following optional items:629 vlan=<id>630 bonding="<name>" | nic="<name>"631 (bonding and nics are mutually exclusive)632 ipaddr="<ip>"633 netmask="<ip>"634 gateway="<ip>"635 bootproto="..."636 delay="..."637 onboot="yes"|"no"638 (other options will be passed to the config file AS-IS)639 -- OR --640 remove=True (other attributes can't be specified)641 bondings - dict of key=bonding, value=attributes642 where 'attributes' is a dict with the following optional items:643 nics=["<nic1>" , "<nic2>", ...]644 options="<bonding-options>"645 -- OR --646 remove=True (other attributes can't be specified)647 options - dict of options, such as:648 force=0|1649 connectivityCheck=0|1650 connectivityTimeout=<int>651 explicitBonding=0|1652 Notes:653 Bondings are removed when they change state from 'used' to 'unused'.654 By default, if you edit a network that is attached to a bonding, it's not655 necessary to re-specify the bonding (you need only to note the attachement656 in the network's attributes). Similarly, if you edit a bonding, it's not657 necessary to specify its networks.658 However, if you specify the 'explicitBonding' option as true, the function659 will expect you to specify all networks that are attached to a specified660 bonding, and vice-versa, the bonding attached to a specified network.661 """662 logger = logging.getLogger("setupNetworks")663 try:664 _netinfo = NetInfo()665 configWriter = ConfigWriter()666 networksAdded = []667 #bondingNetworks = {} # Reminder TODO668 logger.info("Setting up network")669 logger.debug("Setting up network according to configuration: networks:%r, bondings:%r, options:%r" % (networks, bondings, options))670 force = options.get('force', False)671 if not _isTrue(force):672 logging.debug("Validating configuration")673 _validateNetworkSetup(dict(networks), dict(bondings), explicitBonding=options.get('explicitBonding', False))674 logger.debug("Applying...")675 try:676 for network, networkAttrs in networks.items():677 if networkAttrs.pop('remove', False):678 assert not networkAttrs679 logger.debug('Removing network %r'%network)680 delNetwork(network, force=force)681 continue682 if network in _netinfo.networks:683 delNetwork(network, force=force)684 else:685 networksAdded.append(network)686 d = dict(networkAttrs)687 if 'bonding' in d:688 d['nics'] = bondings[d['bonding']]['nics']689 d['bondingOptions'] = bondings[d['bonding']].get('options', None)690 else:691 d['nics'] = [d.pop('nic')]692 d['force'] = force693 logger.debug('Adding network %r'%network)694 addNetwork(network, **d)695 except:696 configWriter.restoreAtomicBackup()697 raise698 if utils.tobool(options.get('connectivityCheck', True)):699 logger.debug('Checking connectivity...')700 if not clientSeen(int(options.get('connectivityTimeout', CONNECTIVITY_TIMEOUT_DEFAULT))):701 logger.info('Connectivity check failed, rolling back')702 for bridge in networksAdded:703 delNetwork(bridge, force=True)704 configWriter.restoreAtomicBackup()705 raise ConfigNetworkError(ne.ERR_LOST_CONNECTION, 'connectivity check failed')706 except Exception, e:707 # SuperVdsm eats the error, so let's print it ourselves708 logger.error(e, exc_info=True)709 raise710def setSafeNetworkConfig():711 """Declare current network configuration as 'safe'"""712 subprocess.Popen([constants.EXT_VDSM_STORE_NET_CONFIG])713def usage():714 print """Usage:715 ./configNetwork.py add bridge <attributes> <options>716 edit oldBridge newBridge <attributes> <options>717 del bridge <options>718 setup bridge [None|attributes] [++ bridge [None|attributes] [++ ...]] [:: <options>]719 attributes = [vlan=...] [bonding=...] [nics=<nic1>,...]720 options = [Force=<True|False>] ...721 """722def _parseKwargs(args):723 return dict(arg.split('=', 1) for arg in args)724def main():725 if len(sys.argv) <= 1:726 usage()727 raise ConfigNetworkError(ne.ERR_BAD_PARAMS, "No action specified")728 if sys.argv[1] == 'list':729 listNetworks()730 return731 if len(sys.argv) <= 2:732 usage()733 raise ConfigNetworkError(ne.ERR_BAD_PARAMS, "No action specified")734 if sys.argv[1] == 'add':735 bridge = sys.argv[2]736 kwargs = _parseKwargs(sys.argv[3:])737 if 'nics' in kwargs:738 kwargs['nics'] = kwargs['nics'].split(',')739 addNetwork(bridge, **kwargs)740 elif sys.argv[1] == 'del':741 bridge = sys.argv[2]742 kwargs = _parseKwargs(sys.argv[3:])743 if 'nics' in kwargs:744 kwargs['nics'] = kwargs['nics'].split(',')745 delNetwork(bridge, **kwargs)746 elif sys.argv[1] == 'edit':747 oldBridge = sys.argv[2]748 newBridge = sys.argv[3]749 kwargs = _parseKwargs(sys.argv[4:])750 if 'nics' in kwargs:751 kwargs['nics'] = kwargs['nics'].split(',')752 editNetwork(oldBridge, newBridge, **kwargs)753 elif sys.argv[1] == 'setup':754 batchCommands, options = utils.listSplit( sys.argv[2:], '::', 1 )755 d = {}756 for batchCommand in utils.listSplit( batchCommands, '++' ):757 d[batchCommand[0]] = _parseKwargs(batchCommand[1:]) or None758 setupNetworks(d, **_parseKwargs(options))759 elif sys.argv[1] == 'show':760 bridge = sys.argv[2]761 kwargs = _parseKwargs(sys.argv[3:])762 showNetwork(bridge, **kwargs)763 else:764 usage()765 raise ConfigNetworkError(ne.ERR_BAD_PARAMS, "Unknown action specified")766if __name__ == '__main__':767 logging.basicConfig(level=logging.INFO)768 try:769 main()770 except ConfigNetworkError, e:771 traceback.print_exc()772 print e.message773 sys.exit(e.errCode)...
guestcust_util.py
Source:guestcust_util.py
...55 nics = fp.read(NICS_SIZE)56 return nics57# This will send a RPC command to the underlying VMware Virtualization platform58# and enable nics.59def enable_nics(nics):60 if not nics:61 logger.warning("No Nics found")62 return63 enableNicsWaitRetries = 564 enableNicsWaitCount = 565 enableNicsWaitSeconds = 166 for attempt in range(0, enableNicsWaitRetries):67 logger.debug("Trying to connect interfaces, attempt %d", attempt)68 (out, _err) = set_customization_status(69 GuestCustStateEnum.GUESTCUST_STATE_RUNNING,70 GuestCustEventEnum.GUESTCUST_EVENT_ENABLE_NICS,71 nics)72 if not out:73 time.sleep(enableNicsWaitCount * enableNicsWaitSeconds)...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!