1
0
mirror of https://github.com/CumulusNetworks/ifupdown2.git synced 2024-05-06 15:54:50 +00:00

A whole lot of fixes and some new code (needs some cleanup which will be

part of subsequent checkins)

Ticket: CM-1438
Reviewed By:
Testing Done: Tested ifup, ifdown and ifquery

Conflicts:
	packages/ifupdown2-addons/addons/ifenslave.py
This commit is contained in:
roopa
2014-01-16 06:46:17 -08:00
parent f407f5cfe8
commit 739f665baa
9 changed files with 498 additions and 115 deletions

9
README
View File

@ -54,3 +54,12 @@ install instructions
dpkg -i python-ifupdown2-addons-<ver>.deb
extra packages to use addional packages:
======================================
To use templates install python-mako (from wheezy):
apt-get install python-mako
To generate dot files install python-gvgen (from wheezy):
apt-get install python-gvgen

View File

@ -51,6 +51,7 @@ case "$1" in
[ -e /sbin/ifup ] || ln -s /sbin/ifupdown /sbin/ifup
[ -e /sbin/ifdown ] || ln -s /sbin/ifupdown /sbin/ifdown
[ -e /sbin/ifquery ] || ln -s /sbin/ifupdown /sbin/ifquery
[ -e /sbin/ifreload ] || ln -s /sbin/ifupdown /sbin/ifreload
;;
purge)

View File

@ -9,6 +9,10 @@
import logging
from collections import deque
try:
from gvgen import *
except ImportError, e:
pass
class graph():
@ -49,3 +53,48 @@ class graph():
' (indegree %d)' %indegree)
return S
@classmethod
def add_to_dot_old(cls, dependency_graph, gvgraph, v, parentgvitem):
dependents = dependency_graph.get(v, [])
if dependents is None:
return
if len(dependents) > 1:
# if more than one dependents .., add them to a box
box = gvgraph.newItem(v)
for d in dependents:
dnode = gvgraph.newItem(d, box)
cls.add_to_dot(dependency_graph, gvgraph, d, dnode)
if parentgvitem is not None: gvgraph.newLink(parentgvitem,
dnode)
else:
for d in dependents:
dnode = gvgraph.newItem(d)
cls.add_to_dot(dependency_graph, gvgraph, d, dnode)
if parentgvitem is not None: gvgraph.newLink(parentgvitem,
dnode)
@classmethod
def add_to_dot(cls, dependency_graph, gvgraph, v, parentgvitem):
vnode = gvgraph.newItem(v)
if parentgvitem is not None: gvgraph.newLink(parentgvitem, vnode)
dependents = dependency_graph.get(v, [])
if dependents is None:
return
for d in dependents:
cls.add_to_dot(dependency_graph, gvgraph, d, vnode)
@classmethod
def generate_dot(cls, dependency_graph, v):
gvgraph = GvGen()
cls.add_to_dot(dependency_graph, gvgraph, v, None)
gvgraph.dot(name=v)
@classmethod
def generate_dots(cls, dependency_graph, indegrees):
roots = [k for k, v in indegrees.items() if v == 0]
if roots is None:
return
print roots
map(lambda r: cls.generate_dot(dependency_graph, r), roots)

View File

@ -31,6 +31,8 @@ class ifaceStatus():
return 'success'
elif state == cls.ERROR:
return 'error'
elif state == cls.NOTFOUND:
return 'not found'
@classmethod
def from_str(cls, state_str):
@ -104,7 +106,12 @@ class iface():
self.status = ifaceStatus.UNKNOWN
self.flags = 0x0
self.refcnt = 0
# dependents that are listed as in the
# config file
self.dependents = None
# All dependents (includes dependents that
# are not listed in the config file)
self.realdev_dependents = None
self.auto = False
self.classes = []
self.env = None
@ -113,7 +120,6 @@ class iface():
self.linkstate = None
def inc_refcnt(self):
#print 'inside inc_refcnt = %d' %self.refcnt
self.refcnt += 1
def dec_refcnt(self):
@ -217,6 +223,12 @@ class iface():
def get_dependents(self):
return self.dependents
def set_realdev_dependents(self, dlist):
self.realdev_dependents = dlist
def get_realdev_dependents(self):
return self.realdev_dependents
def set_linkstate(self, l):
self.linkstate = l
@ -268,7 +280,16 @@ class iface():
if len(env) > 0:
self.set_env(env)
def update_config(self, attr_name, attr_value, attr_status=0):
def update_config(self, attr_name, attr_value):
if self.config.get(attr_name) is None:
self.config[attr_name] = [attr_value]
else:
self.config[attr_name].append(attr_value)
def update_config_dict(self, attrdict):
self.config.update(attrdict)
def update_config_with_status(self, attr_name, attr_value, attr_status=0):
if attr_value is None:
attr_value = ''
@ -314,6 +335,10 @@ class iface():
else:
logger.info(indent + 'dependents: None')
logger.info(indent + 'realdev dependents: %s'
%str(self.get_realdev_dependents()))
logger.info(indent + 'config: ')
config = self.get_config()
if config is not None:

View File

@ -56,7 +56,8 @@ class ifupdownBase(object):
def log_error(self, str):
if self.ignore_error(str) == False:
raise Exception(str)
raise
#raise Exception(str)
else:
pass

View File

@ -53,6 +53,12 @@ class ifupdownMain():
OrderedDict([('pre-up', OrderedDict({})),
('up' , OrderedDict({})),
('post-up' , OrderedDict({}))]),
'query-checkcurr' :
OrderedDict([('query-checkcurr', OrderedDict({}))]),
'query-running' :
OrderedDict([('query-running', OrderedDict({}))]),
'down' :
OrderedDict([('pre-down', OrderedDict({})),
('down' , OrderedDict({})),
@ -60,7 +66,8 @@ class ifupdownMain():
def __init__(self, force=False, dryrun=False, nowait=False,
perfmode=False, nodepends=False, njobs=1):
perfmode=False, nodepends=False, njobs=1,
format='nwifaces', cache=False):
self.logger = logging.getLogger('ifupdown')
self.FORCE = force
@ -68,6 +75,8 @@ class ifupdownMain():
self.NOWAIT = nowait
self.PERFMODE = perfmode
self.NODEPENDS = nodepends
self.CACHE = cache
self._DELETE_DEPENDENT_IFACES_WITH_NOCONFIG = True
self.ifaces = OrderedDict()
self.njobs = njobs
@ -114,6 +123,16 @@ class ifupdownMain():
def get_dryrun(self):
return self.DRYRUN
def get_cache(self):
return self.CACHE
def get_ifaceobjdict(self):
return self.ifaceobjdict
def set_ifaceobjdict(self, ifaceobjdict):
del self.ifaceobjdict
self.ifaceobjdict = ifaceobjdict
def set_perfmode(self, perfmode):
if perfmode == True:
self.logger.debug('setting perfmode to true')
@ -161,20 +180,26 @@ class ifupdownMain():
def get_iface_obj_last(self, ifacename):
return self.ifaceobjdict.get(ifacename)[-1]
def create_ifaceobjcurr(self, ifacename):
ifaceobj = self.get_ifaceobjcurr(ifacename)
if ifaceobj is not None:
return ifaceobj
def create_ifaceobjcurr(self, ifaceobj):
ifacename = ifaceobj.get_name()
ifaceobjcurr = self.get_ifaceobjcurr(ifacename)
if ifaceobjcurr is not None:
return ifaceobjcurr
ifaceobj = iface()
ifaceobj.set_name(ifacename)
self.ifaceobjcurrdict[ifacename] = ifaceobj
ifaceobjcurr = iface()
ifaceobjcurr.set_name(ifacename)
ifaceobjcurr.set_dependents(ifaceobj.get_dependents())
self.ifaceobjcurrdict[ifacename] = ifaceobjcurr
return ifaceobj
def get_ifaceobjcurr(self, ifacename):
return self.ifaceobjcurrdict.get(ifacename)
def get_ifaceobjrunning(self, ifacename):
return self.ifaceobjrunningdict.get(ifacename)
def get_iface_status(self, ifacename):
ifaceobjs = self.get_iface_objs(ifacename)
for i in ifaceobjs:
@ -191,19 +216,16 @@ class ifupdownMain():
max = i.get_refcnt()
return max
def create_fake_vlan_iface(self, vlan_ifname, op):
def create_n_save_ifaceobj(self, ifacename, increfcnt=False):
""" creates and returns a fake vlan iface object.
This was added to support creation of simple vlan devices without any
user specified configuration.
This was added to support creation of simple vlan
devices without any user specified configuration.
"""
# XXX: Ideally this should be a call-back into the vlan module.
vlan_iface_obj = iface()
vlan_iface_obj.set_name(vlan_ifname)
return vlan_iface_obj
ifaceobj = iface()
ifaceobj.set_name(ifacename)
if increfcnt == True:
ifaceobj.inc_refcnt()
self.ifaceobjdict[ifacename] = [ifaceobj]
def is_vlan_device(self, ifacename):
""" Returns true if iface name is a vlan interface.
@ -216,20 +238,31 @@ class ifupdownMain():
return False
def preprocess_dependency_list(self, dlist, op):
""" We go through the dependency list and
delete or add interfaces from the interfaces dict by
applying the following rules:
if flag _DELETE_DEPENDENT_IFACES_WITH_NOCONFIG is True:
we only consider devices whose configuration was
specified in the network interfaces file. We delete
any interface whose config was not specified except
for vlan devices. vlan devices get special treatment.
Even if they are not present they are created and added
to the ifacesdict
elif flag _DELETE_DEPENDENT_IFACES_WITH_NOCONFIG is False:
we create objects for all dependent devices that are not
present in the ifacesdict
"""
del_list = []
create_list = []
self.logger.debug('pre-processing dependency list: %s' %list(dlist))
for d in dlist:
dilist = self.get_iface_objs(d)
if dilist == None:
if self.is_vlan_device(d) == True:
vlan_iface_obj = self.create_fake_vlan_iface(d, op)
# Add face vlan device to ifaceobjdict dict
vlan_iface_obj.inc_refcnt()
self.save_iface(vlan_iface_obj)
if (self.is_vlan_device(d) == True or
self._DELETE_DEPENDENT_IFACES_WITH_NOCONFIG == False):
create_list.append(d)
else:
# Remove the device from the list
del_list.append(d)
else:
for di in dilist:
@ -238,10 +271,13 @@ class ifupdownMain():
for d in del_list:
dlist.remove(d)
# create fake devices to all dependents that dont have config
map(lambda i: self.create_n_save_ifaceobj(i, increfcnt=True),
create_list)
self.logger.debug('After Processing dependency list: %s'
%list(dlist))
def get_dependents(self, ifaceobj, op):
""" Gets iface dependents by calling into respective modules """
dlist = None
@ -254,16 +290,23 @@ class ifupdownMain():
for mname, mdata in mdict.items():
if mdata.get('ftype') == 'pmodule':
module = mdata.get('module')
if op == 'query-running':
if (hasattr(module,
'get_dependent_ifacenames_running') == False):
continue
dlist = module.get_dependent_ifacenames_running(
ifaceobj)
else:
if (hasattr(module,
'get_dependent_ifacenames') == False):
continue
dlist = module.get_dependent_ifacenames(ifaceobj,
self.ifaceobjdict.keys())
if dlist is not None:
ifaceobj.set_realdev_dependents(dlist[:])
self.logger.debug('%s: ' %ifaceobj.get_name() +
'got dependency list: %s' %str(dlist))
break
return dlist
def generate_dependency_info(self, ifacenames, dependency_graph, op):
@ -290,8 +333,7 @@ class ifupdownMain():
if dlist is not None:
self.preprocess_dependency_list(dlist, op)
ifaceobj.set_dependents(dlist)
for d in dlist:
iqueue.append(d)
[iqueue.append(d) for d in dlist]
if dependency_graph.get(i) is None:
dependency_graph[i] = dlist
@ -330,7 +372,12 @@ class ifupdownMain():
"""
try:
mmetadata = self.operations[mkind][msubkind].get(mname)
except KeyError:
self.logger.warn('unsupported module type %s' %mname)
return
if mmetadata is None or mmetadata.get('ftype') != 'pmodule':
mmetadata = {}
mmetadata['ftype'] = mftype
@ -373,15 +420,20 @@ class ifupdownMain():
minstance = mclass(force=self.get_force(),
dryrun=self.get_dryrun(),
nowait=self.get_nowait(),
perfmode=self.get_perfmode())
perfmode=self.get_perfmode(),
cache=self.get_cache())
ops = minstance.get_ops()
for op in ops:
if re.search('up', op) is not None:
if re.search('query', op) is not None:
self.save_module(op, op, mname, 'pmodule',
minstance)
elif re.search('up', op) is not None:
self.save_module('up', op, mname, 'pmodule',
minstance)
else:
self.save_module('down', op, mname, 'pmodule',
minstance)
self.save_module('down', op, mname,
'pmodule', minstance)
except:
raise
@ -396,6 +448,9 @@ class ifupdownMain():
self.logger.info('loading user modules from %s' %modules_dir)
for op, subops in self.operations.items():
if re.search('query', op) is not None:
continue
for subop in subops.keys():
msubdir = modules_dir + '/if-%s.d' %subop
self.logger.info('loading modules under %s ...' %msubdir)
@ -475,11 +530,27 @@ class ifupdownMain():
ret = ifaceSched.run_iface_dependency_graph_parallel(self,
dependency_graph, op)
else:
ret = ifaceSched.run_iface_dependency_graph(self, dependency_graph,
op)
ret = ifaceSched.run_iface_dependency_graph(self,
dependency_graph, op)
return ret
def print_dependency(self, op, ifacenames, format):
dependency_graph = {}
if ifacenames is None:
ifacenames = self.ifaceobjdict.keys()
# generate dependency graph of interfaces
self._DELETE_DEPENDENT_IFACES_WITH_NOCONFIG = False
self.generate_dependency_info(ifacenames, dependency_graph, op)
if format == 'list':
self.pp.pprint(dependency_graph)
elif format == 'dot':
indegrees = {}
map(lambda i: indegrees.update({i :
self.get_iface_refcnt(i)}),
dependency_graph.keys())
graph.generate_dots(dependency_graph, indegrees)
def validate_ifaces(self, ifacenames):
""" validates interface list for config existance.
@ -539,10 +610,8 @@ class ifupdownMain():
return True
def generate_running_env(self, ifaceobj, op):
""" Generates a dictionary with env variables required for an interface.
Used to support script execution for interfaces.
""" Generates a dictionary with env variables required for
an interface. Used to support script execution for interfaces.
"""
cenv = None
@ -560,8 +629,8 @@ class ifupdownMain():
def run(self, op, auto=False, allow_classes=None,
ifacenames=None, query_state=None, excludepats=None,
format=None):
ifacenames=None, excludepats=None,
format=None, printdependency=None):
""" main ifupdown run method """
if auto == True:
@ -571,12 +640,15 @@ class ifupdownMain():
# Only read new iface config for 'up'
# operations. For 'downs' we only rely on
# old state
if op == 'up' or op == 'query':
if op == 'query-running':
# create fake devices to all dependents that dont have config
map(lambda i: self.create_n_save_ifaceobj(i), ifacenames)
elif op == 'up' or op[:5] == 'query':
try:
self.read_iface_config()
except Exception, e:
raise
else:
elif op == 'down':
# for down we need to look at old state
self.logger.debug('down op, looking at old state ..')
@ -584,18 +656,19 @@ class ifupdownMain():
self.read_old_iface_config()
elif self.FORCE == True:
# If no old state available
self.logger.info('old state not available. Force option ' +
'set. Loading new iface config file')
self.logger.info('old state not available. ' +
'Force option set. Loading new iface config file')
try:
self.read_iface_config()
except Exception, e:
raise Exception('error reading iface config (%s)' %str(e))
raise Exception('error reading iface config (%s)'
%str(e))
else:
raise Exception('old state not available...aborting.' +
' try running with --force option')
if ifacenames is not None:
if ifacenames is not None and op != 'query-running':
# If iface list is given, always check if iface is present
if self.validate_ifaces(ifacenames) != 0:
raise Exception('all or some interfaces not found')
@ -604,36 +677,45 @@ class ifupdownMain():
if ifacenames is None: ifacenames = self.ifaceobjdict.keys()
# filter interfaces based on auto and allow classes
if op == 'query-running':
filtered_ifacenames = ifacenames
else:
filtered_ifacenames = [i for i in ifacenames
if self.iface_whitelisted(auto, allow_classes, excludepats,
i) == True]
if self.iface_whitelisted(auto, allow_classes,
excludepats, i) == True]
if len(filtered_ifacenames) == 0:
raise Exception('no ifaces found matching ' +
'given allow lists')
if op == 'query':
if query_state == None:
return self.print_ifaceobjs_pretty(filtered_ifacenames)
elif query_state == 'presumed':
return self.print_ifaceobjs_raw(filtered_ifacenames)
elif op == 'query-presumed':
return self.print_ifaceobjs_saved_state_pretty(
filtered_ifacenames)
elif query_state == 'presumeddetailed':
elif op == 'query-presumeddetailed':
return self.print_ifaceobjs_saved_state_detailed_pretty(
filtered_ifacenames)
if op == 'query' or self.NODEPENDS == True:
if printdependency is not None:
self.print_dependency(op, filtered_ifacenames, printdependency)
return
#if op.split('-')[0] == 'query' or self.NODEPENDS == True:
if op.split('-')[0] == 'query' or self.NODEPENDS == True:
self.run_without_dependents(op, filtered_ifacenames)
else:
self.run_with_dependents(op, filtered_ifacenames)
if op == 'query':
if query_state == 'curr':
if op == 'query-checkcurr':
# print curr state of all interfaces
ret = self.print_ifaceobjscurr_pretty(filtered_ifacenames)
if ret != 0:
# if any of the object has an error, signal that silently
raise Exception('')
elif op == 'query-running':
# print curr state of all interfaces
self.print_ifaceobjsrunning_pretty(filtered_ifacenames)
return
# Update persistant iface states
@ -649,17 +731,162 @@ class ifupdownMain():
self.logger.warning('error saving state (%s)' %str(e))
def up(self, auto=False, allow=None, ifacenames=None, excludepats=None):
return self.run('up', auto, allow, ifacenames, excludepats=excludepats)
def up(self, auto=False, allow=None, ifacenames=None,
excludepats=None, printdependency=None):
return self.run('up', auto, allow, ifacenames,
excludepats=excludepats,
printdependency=printdependency)
def down(self, auto=False, allow=None, ifacenames=None, excludepats=None):
return self.run('down', auto, allow, ifacenames,
excludepats=excludepats);
def query(self, auto=False, allow=None, ifacenames=None,
query_state=False, excludepats=None):
return self.run('query', auto, allow, ifacenames,
query_state=query_state, excludepats=excludepats);
def query(self, op, auto=False, allow_classes=None, ifacenames=None,
excludepats=None, printdependency=None,
format=None):
""" main ifupdown run method """
if auto == True:
self.logger.debug('setting flag ALL')
self.ALL = True
if op == 'query-running':
self._DELETE_DEPENDENT_IFACES_WITH_NOCONFIG = False
# create fake devices to all dependents that dont have config
map(lambda i: self.create_n_save_ifaceobj(i), ifacenames)
else:
try:
self.read_iface_config()
except Exception:
raise
if ifacenames is not None and op != 'query-running':
# If iface list is given, always check if iface is present
if self.validate_ifaces(ifacenames) != 0:
raise Exception('all or some interfaces not found')
# if iface list not given by user, assume all from config file
if ifacenames is None: ifacenames = self.ifaceobjdict.keys()
# filter interfaces based on auto and allow classes
if op == 'query-running':
filtered_ifacenames = ifacenames
else:
filtered_ifacenames = [i for i in ifacenames
if self.iface_whitelisted(auto, allow_classes,
excludepats, i) == True]
if len(filtered_ifacenames) == 0:
raise Exception('no ifaces found matching ' +
'given allow lists')
if op == 'query':
return self.print_ifaceobjs_raw(filtered_ifacenames)
elif op == 'query-presumed':
return self.print_ifaceobjs_saved_state_pretty(
filtered_ifacenames)
elif op == 'query-presumeddetailed':
return self.print_ifaceobjs_saved_state_detailed_pretty(
filtered_ifacenames)
if printdependency is not None:
self.print_dependency(op, filtered_ifacenames, printdependency)
return
if self.NODEPENDS == True:
self.run_without_dependents(op, filtered_ifacenames)
else:
self.run_with_dependents(op, filtered_ifacenames)
if op == 'query-checkcurr':
ret = self.print_ifaceobjscurr_pretty(filtered_ifacenames)
if ret != 0:
# if any of the object has an error, signal that silently
raise Exception('')
elif op == 'query-running':
self.print_ifaceobjsrunning_pretty(filtered_ifacenames)
return
def reload(self, auto=False, allow=None,
ifacenames=None, excludepats=None):
""" main ifupdown run method """
allow_classes = []
self.logger.debug('reloading interface config ..')
if auto == True:
self.logger.debug('setting flag ALL')
self.ALL = True
try:
self.read_iface_config()
except Exception, e:
raise
# Save a copy of new iface objects
new_ifaceobjdict = self.get_ifaceobjdict()
if len(self.statemanager.get_ifaceobjdict()) > 0:
# if old state is present, read old state and mark op for 'down'
# followed by 'up' aka: reload
self.read_old_iface_config()
op = 'reload'
else:
# oldconfig not available, continue with 'up' with new config
op = 'up'
if ifacenames is None: ifacenames = self.ifaceobjdict.keys()
if (op == 'reload' and ifacenames is not None and
len(ifacenames) != 0):
filtered_ifacenames = [i for i in ifacenames
if self.iface_whitelisted(auto, allow_classes,
excludepats, i) == True]
ifacedownlist = Set(filtered_ifacenames).difference(
Set(new_ifaceobjdict.keys()))
if ifacedownlist is not None and len(ifacedownlist) > 0:
self.logger.debug('bringing down interfaces: %s'
%str(ifacedownlist))
if self.NODEPENDS == True:
self.run_without_dependents('down', ifacedownlist)
else:
self.run_with_dependents('down', ifacedownlist)
# Update persistant iface states
try:
if self.ALL == True:
self.statemanager.flush_state(self.ifaceobjdict)
else:
self.statemanager.flush_state()
except Exception, e:
if self.logger.isEnabledFor(logging.DEBUG):
t = sys.exc_info()[2]
traceback.print_tb(t)
self.logger.warning('error saving state (%s)' %str(e))
# Now, run up with new dict
self.set_ifaceobjdict(new_ifaceobjdict)
ifacenames = self.ifaceobjdict.keys()
filtered_ifacenames = [i for i in ifacenames
if self.iface_whitelisted(auto, allow_classes,
excludepats, i) == True]
self.logger.debug('bringing up interfaces: %s'
%str(filtered_ifacenames))
if self.NODEPENDS == True:
self.run_without_dependents('up', filtered_ifacenames)
else:
self.run_with_dependents('up', filtered_ifacenames)
# Update persistant iface states
try:
if self.ALL == True:
self.statemanager.flush_state(self.get_ifaceobjdict())
else:
self.statemanager.flush_state()
except Exception, e:
if self.logger.isEnabledFor(logging.DEBUG):
t = sys.exc_info()[2]
traceback.print_tb(t)
self.logger.warning('error saving state (%s)' %str(e))
def dump(self):
""" all state dump """
@ -672,24 +899,37 @@ class ifupdownMain():
def print_state(self, ifacenames=None):
self.statemanager.dump(ifacenames)
def print_ifaceobjs_raw(self, ifacenames):
for i in ifacenames:
ifaceobjs = self.get_iface_objs(i)
for i in ifaceobjs:
i.dump_raw(self.logger)
print '\n'
def print_ifaceobjs_pretty(self, ifacenames):
for i in ifacenames:
ifaceobjs = self.get_iface_objs(i)
for io in ifaceobjs:
io.dump_raw(self.logger)
for i in ifaceobjs:
i.dump_pretty(self.logger)
print '\n'
def print_ifaceobjscurr_pretty(self, ifacenames, format):
def dump_ifaceobjs(self, ifacenames):
for i in ifacenames:
ifaceobjs = self.get_iface_objs(i)
for i in ifaceobjs:
i.dump(self.logger)
print '\n'
def print_ifaceobjscurr_pretty(self, ifacenames, format=None):
""" Dumps current running state of interfaces.
returns 1 if any of the interface has an error,
else returns 0
"""
ret = 0
for i in ifacenames:
ifaceobj = self.get_ifaceobjcurr(i)
if ifaceobj is None: continue
if ifaceobj.get_status() == ifaceStatus.NOTFOUND:
print 'iface %s' %ifaceobj.get_name() + ' (not found)'
ret = 1
@ -701,8 +941,29 @@ class ifupdownMain():
else:
ifaceobj.dump_json(self.logger)
dlist = ifaceobj.get_dependents()
if dlist is None or len(dlist) == 0: continue
self.print_ifaceobjscurr_pretty(dlist, format)
return ret
def print_ifaceobjsrunning_pretty(self, ifacenames, format=None):
for i in ifacenames:
ifaceobj = self.get_iface_obj_first(i)
if ifaceobj.get_status() == ifaceStatus.NOTFOUND:
print 'iface %s' %ifaceobj.get_name() + ' (not found)'
continue
if format is None or format == 'nwifaces':
ifaceobj.dump_pretty(self.logger)
elif format == 'json':
ifaceobj.dump_json(self.logger)
dlist = ifaceobj.get_dependents()
if dlist is None or len(dlist) == 0: continue
self.print_ifaceobjsrunning_pretty(dlist, format)
return
def print_ifaceobjs_saved_state_pretty(self, ifacenames):
self.statemanager.print_state_pretty(ifacenames, self.logger)

View File

@ -10,6 +10,7 @@
import collections
import logging
import glob
import re
from iface import *
class networkInterfaces():
@ -95,6 +96,7 @@ class networkInterfaces():
iface_line = lines[cur_idx].strip('\n ')
iface_attrs = iface_line.split()
ifacename = iface_attrs[1]
ifaceobj.raw_lines.append(iface_line)
@ -111,6 +113,9 @@ class networkInterfaces():
ifaceobj.raw_lines.append(l)
# preprocess vars (XXX: only preprocesses $IFACE for now)
l = re.sub(r'\$IFACE', ifacename, l)
attrs = l.split(' ', 1)
if len(attrs) < 2:
self.logger.warn('invalid syntax at line %d' %(line_idx + 1))
@ -124,7 +129,7 @@ class networkInterfaces():
lines_consumed = line_idx - cur_idx
# Create iface object
ifaceobj.set_name(iface_attrs[1])
ifaceobj.set_name(ifacename)
ifaceobj.set_config(iface_config)
ifaceobj.generate_env()
if len(iface_attrs) > 2:

View File

@ -50,10 +50,10 @@ class ifaceScheduler(ifupdownBase):
self.logger.debug('%s: ' %ifaceobj.get_name() +
'running module %s' %mname +
' op %s' %op + ' subop %s' %subop)
if op == 'query':
m.run(ifaceobj, subop, query=True,
if op == 'query-checkcurr':
m.run(ifaceobj, subop, query_check=True,
query_ifaceobj=ifupdownobj.create_ifaceobjcurr(
ifaceobj.get_name()))
ifaceobj))
else:
m.run(ifaceobj, subop)
else:
@ -65,7 +65,7 @@ class ifaceScheduler(ifupdownBase):
err = 1
self.log_error(str(e))
finally:
if op != 'query':
if op[:5] != 'query':
if err == 1:
ifupdownobj.set_iface_state(ifaceobj,
ifaceState.from_str(subop),
@ -135,7 +135,6 @@ class ifaceScheduler(ifupdownBase):
""" Runs interface list through sub operation handler. """
self.logger.debug('running sub operation %s on all given interfaces' %op)
iface_run_queue = deque(ifacenames)
for i in range(0, len(iface_run_queue)):
if op == 'up':

View File

@ -15,41 +15,57 @@ def run(args, op):
logger.debug('args = %s' %str(args))
try:
logger.debug('creating ifupdown object ..')
if op == 'up' or op == 'down':
ifupdown_handle = ifupdownMain(force=args.force,
nodepends=args.nodepends,
perfmode=args.perfmode,
njobs=args.jobs,
dryrun=args.noact)
elif op == 'query':
ifupdown_handle = ifupdownMain(nodepends=args.nodepends,
perfmode=args.perfmode,
njobs=args.jobs,
format=args.format)
iflist = args.iflist
if len(args.iflist) == 0:
iflist = None
cachearg=False if iflist is not None or args.nocache == True else True
logger.debug('creating ifupdown object ..')
if op == 'up' or op == 'down' or op == 'reload':
ifupdown_handle = ifupdownMain(force=args.force,
nodepends=args.nodepends,
perfmode=args.perfmode,
njobs=args.jobs,
dryrun=args.noact,
cache=cachearg)
elif op == 'query':
ifupdown_handle = ifupdownMain(nodepends=args.nodepends,
perfmode=args.perfmode,
njobs=args.jobs,
format=args.format,
cache=cachearg)
logger.debug('calling %s' %op + ' for all interfaces ..')
if op == 'up':
ifupdown_handle.up(args.all, args.CLASS, iflist,
excludepats=args.excludepats)
excludepats=args.excludepats,
printdependency=args.printdependency)
elif op == 'down':
ifupdown_handle.down(args.all, args.CLASS, iflist,
excludepats=args.excludepats)
elif op == 'query':
if args.curstate == True:
qstate='curr'
if args.checkcurstate == True:
qtype='query-checkcurr'
elif args.presumedstate == True:
qstate='presumed'
qtype='query-presumed'
elif args.presumedstatedetailed == True:
qstate='presumeddetailed'
qtype='query-presumeddetailed'
elif args.runningstate == True:
if iflist is None:
iflist = [i for i in os.listdir('/sys/class/net/')
if os.path.isdir('/sys/class/net/%s' %i) == True]
print iflist
qtype='query-running'
else:
qstate=None
ifupdown_handle.query(args.all, args.CLASS, iflist,
query_state=qstate,
qtype='query'
ifupdown_handle.query(qtype, args.all, args.CLASS, iflist,
excludepats=args.excludepats)
elif op == 'reload':
if iflist is not None:
raise Exception('iflist is currently not supported with reload')
ifupdown_handle.reload(args.all, args.CLASS, iflist,
excludepats=args.excludepats)
except:
raise
@ -77,6 +93,7 @@ def deinit():
{}
def update_argparser(argparser):
""" base parser """
argparser.add_argument('iflist', metavar='IFACE',
nargs='*', help='interfaces list')
argparser.add_argument('-v', '--verbose', dest='verbose',
@ -95,6 +112,11 @@ def update_argparser(argparser):
action='store_true', help=argparse.SUPPRESS)
argparser.add_argument('-j', '--jobs', dest='jobs', type=int,
default=-1, choices=range(1,12), help=argparse.SUPPRESS)
argparser.add_argument('--nocache', dest='nocache', action='store_true',
help=argparse.SUPPRESS)
argparser.add_argument('--print-dependency',
dest='printdependency', choices=['list', 'dot'],
help=argparse.SUPPRESS)
argparser.add_argument('-X', '--exclude', dest='excludepats',
action='append', help='exclude interfaces from the list of '
+ 'interfaces to operate on by a PATTERN '
@ -121,10 +143,14 @@ def update_ifquery_argparser(argparser):
argparser.add_argument('-l', '--list', action='store_true', dest='all',
help='process all interfaces marked \"auto\"')
group = argparser.add_mutually_exclusive_group(required=False)
group.add_argument('-r', '--running-state', dest='curstate',
group.add_argument('-r', '--running-state', dest='runningstate',
action='store_true',
help='query running state of an interface')
group.add_argument('-c', '--check-state', dest='checkcurstate',
action='store_true',
help='check running state of an interface')
# presumed-state is state maintained by ifupdown
group.add_argument('--presumed-state', dest='presumedstate',
action='store_true', help=argparse.SUPPRESS)
@ -138,6 +164,8 @@ def update_ifquery_argparser(argparser):
group.add_argument('--format', dest='format', default='nwifaces',
choices=['nwifaces', 'json'], help=argparse.SUPPRESS)
def update_ifreload_argparser(argparser):
update_ifupdown_argparser(argparser)
def parse_args(argsv, op):
descr = 'interface management'
@ -150,6 +178,8 @@ def parse_args(argsv, op):
update_ifdown_argparser(argparser)
elif op == 'query':
update_ifquery_argparser(argparser)
elif op == 'reload':
update_ifreload_argparser(argparser)
return argparser.parse_args(argsv)
@ -163,6 +193,8 @@ def main(argv):
op = 'down'
elif re.search(r'ifquery', argv[0]) != None:
op = 'query'
elif re.search(r'ifreload', argv[0]) != None:
op = 'reload'
else:
print ('Unexpected executable.' +
' Should be \'ifup\' or \'ifdown\' or \'ifquery\'')
@ -171,7 +203,7 @@ def main(argv):
# Command line arg parser
args = parse_args(argv[1:], op)
if len(args.iflist) > 0 and args.all is True:
print 'interface list and \'-a\' are mutually exclusive'
print 'interface list cannot be specified with all option'
exit(1)
init(args)
@ -184,6 +216,7 @@ def main(argv):
raise
else:
logger.error(str(e))
print '\nRerun the command with \'-d\' for a detailed errormsg'
exit(1)
finally:
deinit()