# Flags
WITH_DEPENDS = False
ALL = False
- STATE_CHECK = False
COMPAT_EXEC_SCRIPTS = False
+ STATEMANAGER_ENABLE = True
+ STATEMANAGER_UPDATE = True
+ ADDONS_ENABLE = False
# priv flags to mark iface objects
BUILTIN = 0x1
if self.link_exists(ifacename):
self.link_down(ifacename)
+ # ifupdown object interface operation handlers
ops_handlers = OrderedDict([('up', run_up),
('down', run_down)])
+ def run_sched_ifaceobj_posthook(self, ifaceobj):
+ if ((ifaceobj.priv_flags & self.BUILTIN) or
+ (ifaceobj.priv_flags & self.NOCONFIG)):
+ return
+ if self.STATEMANAGER_UPDATE:
+ self.statemanager.ifaceobj_sync(ifaceobj)
+
+ # ifupdown object interface scheduler pre and posthooks
+ sched_hooks = {'posthook' : run_sched_ifaceobj_posthook}
+
def __init__(self, force=False, dryrun=False, nowait=False,
perfmode=False, withdepends=False, njobs=1,
- cache=False):
+ cache=False, addons_enable=True, statemanager_enable=True):
self.logger = logging.getLogger('ifupdown')
-
self.FORCE = force
self.DRYRUN = dryrun
self.NOWAIT = nowait
self.PERFMODE = perfmode
self.WITH_DEPENDS = withdepends
+ self.STATEMANAGER_ENABLE = statemanager_enable
self.CACHE = cache
+
+ # Can be used to provide hints for caching
+ self.CACHE_FLAGS = 0x0
self._DELETE_DEPENDENT_IFACES_WITH_NOCONFIG = False
+ self.ADDONS_ENABLE = addons_enable
self.ifaces = OrderedDict()
self.njobs = njobs
self.pp = pprint.PrettyPrinter(indent=4)
self.modules = OrderedDict({})
self.module_attrs = {}
+
self.load_addon_modules(self.addon_modules_dir)
- self.load_scripts(self.scripts_dir)
+ if self.COMPAT_EXEC_SCRIPTS:
+ self.load_scripts(self.scripts_dir)
self.dependency_graph = OrderedDict({})
- try:
- self.statemanager = stateManager()
- self.statemanager.read_saved_state()
- except Exception, e:
- # XXX Maybe we should continue by ignoring old state
- self.logger.warning('error reading state (%s)' %str(e))
- raise
+ if self.STATEMANAGER_ENABLE:
+ try:
+ self.statemanager = stateManager()
+ self.statemanager.read_saved_state()
+ except Exception, e:
+ # XXX Maybe we should continue by ignoring old state
+ self.logger.warning('error reading state (%s)' %str(e))
+ raise
+ else:
+ self.STATEMANAGER_UPDATE = False
def get_subops(self, op):
""" Returns sub-operation list """
self.logger.debug('setting withdepends to true')
self.WITH_DEPENDS = withdepends
- def set_iface_state(self, ifaceobj, state, status):
- ifaceobj.set_state(state)
- ifaceobj.set_status(status)
- self.statemanager.update_iface_state(ifaceobj)
-
- def get_iface_objs(self, ifacename):
+ def get_ifaceobjs(self, ifacename):
return self.ifaceobjdict.get(ifacename)
- def get_iface_obj_first(self, ifacename):
- ifaceobjs = self.get_iface_objs(ifacename)
- if ifaceobjs is not None:
+ def get_ifaceobj_first(self, ifacename):
+ ifaceobjs = self.get_ifaceobjs(ifacename)
+ if ifaceobjs:
return ifaceobjs[0]
return None
+ def get_ifacenames(self):
+ return self.ifaceobjdict.keys()
+
def get_iface_obj_last(self, ifacename):
return self.ifaceobjdict.get(ifacename)[-1]
return self.ifaceobjrunningdict.get(ifacename)
def get_iface_status(self, ifacename):
- ifaceobjs = self.get_iface_objs(ifacename)
+ ifaceobjs = self.get_ifaceobjs(ifacename)
for i in ifaceobjs:
if i.get_status() != ifaceStatus.SUCCESS:
return i.get_status()
-
return ifaceStatus.SUCCESS
def get_iface_refcnt(self, ifacename):
max = 0
- ifaceobjs = self.get_iface_objs(ifacename)
+ ifaceobjs = self.get_ifaceobjs(ifacename)
+ if not ifaceobjs:
+ return 0
for i in ifaceobjs:
if i.get_refcnt() > max:
max = i.get_refcnt()
def is_iface_noconfig(self, ifacename):
""" Returns true if iface has no config """
- ifaceobj = self.get_iface_obj_first(ifacename)
+ ifaceobj = self.get_ifaceobj_first(ifacename)
if not ifaceobj: return True
return self.is_ifaceobj_noconfig(ifaceobj)
del_list = []
for d in dlist:
- dilist = self.get_iface_objs(d)
+ dilist = self.get_ifaceobjs(d)
if not dilist:
if self.is_iface_builtin_byname(d):
self.create_n_save_ifaceobj(d, self.BUILTIN | self.NOCONFIG,
dlist = None
# Get dependents for interface by querying respective modules
- for op in ops:
- for mname in self.module_ops.get(op):
- module = self.modules.get(mname)
- 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,
+ for mname, module in self.modules.items():
+ module = self.modules.get(mname)
+ if ops[0] == 'query-running':
+ if (not hasattr(module,
+ 'get_dependent_ifacenames_running')):
+ continue
+ dlist = module.get_dependent_ifacenames_running(ifaceobj)
+ else:
+ if (not hasattr(module, 'get_dependent_ifacenames')):
+ continue
+ dlist = module.get_dependent_ifacenames(ifaceobj,
self.ifaceobjdict.keys())
- if dlist:
- self.logger.debug('%s: ' %ifaceobj.get_name() +
- 'got lowerifaces/dependents: %s' %str(dlist))
- break
+ if dlist:
+ self.logger.debug('%s: ' %ifaceobj.get_name() +
+ 'got lowerifaces/dependents: %s' %str(dlist))
+ break
return dlist
- def populate_dependency_info(self, ifacenames, ops):
+ def populate_dependency_info(self, ops, ifacenames=None):
""" recursive function to generate iface dependency info """
- if ifacenames is None:
+ if not ifacenames:
ifacenames = self.ifaceobjdict.keys()
self.logger.debug('populating dependency info for %s' %str(ifacenames))
-
iqueue = deque(ifacenames)
while iqueue:
i = iqueue.popleft()
-
# Go through all modules and find dependent ifaces
dlist = None
- ifaceobj = self.get_iface_obj_first(i)
- if ifaceobj is None:
+ ifaceobj = self.get_ifaceobj_first(i)
+ if not ifaceobj:
continue
-
dlist = ifaceobj.get_lowerifaces()
- if dlist is None:
+ if not dlist:
dlist = self.query_dependents(ifaceobj, ops)
else:
continue
-
- if dlist is not None:
+ if dlist:
self.preprocess_dependency_list(ifaceobj.get_name(),
dlist, ops)
self.logger.debug('%s: lowerifaces/dependents after processing: %s'
%(i, str(dlist)))
ifaceobj.set_lowerifaces(dlist)
[iqueue.append(d) for d in dlist]
-
- if self.dependency_graph.get(i) is None:
+ if not self.dependency_graph.get(i):
self.dependency_graph[i] = dlist
def _save_iface(self, ifaceobj):
dryrun=self.DRYRUN,
nowait=self.NOWAIT,
perfmode=self.PERFMODE,
- cache=self.CACHE)
+ cache=self.CACHE,
+ cacheflags=self.CACHE_FLAGS)
self.modules[mname] = minstance
if hasattr(minstance, 'get_modinfo'):
self.module_attrs[mname] = minstance.get_modinfo()
iface_objs.append(iface_obj)
return iface_objs
+ def _pretty_print_ordered_dict(self, argdict):
+ for k, vlist in argdict.items():
+ self.logger.info('%s : %s' %(k, str(vlist)))
- def run_without_dependents(self, ops, ifacenames):
- """ Run interface list without their dependents """
- if not ifacenames:
- raise ifupdownInvalidValue('no interfaces found')
-
- self.logger.debug('run_without_dependents for ops %s for %s'
- %(str(ops), str(ifacenames)))
-
- ifaceScheduler.run_iface_list(self, ifacenames, ops, parent=None,
- order=ifaceSchedulerFlags.INORDER
- if 'down' in ops[0]
- else ifaceSchedulerFlags.POSTORDER,
- followdependents=False)
-
- def run_with_dependents(self, ops, ifacenames):
- ret = 0
- self.logger.debug('running \'%s\' with dependents for %s'
+ def sched_ifaces(self, ifacenames, ops):
+ self.logger.debug('scheduling \'%s\' for %s'
%(str(ops), str(ifacenames)))
- if ifacenames is None:
- ifacenames = self.ifaceobjdict.keys()
-
self.logger.info('dependency graph:')
- self.logger.info(self.pp.pformat(self.dependency_graph))
+ self._pretty_print_ordered_dict(self.dependency_graph)
- if self.njobs > 1:
- ret = ifaceScheduler.run_iface_dependency_graph_parallel(self,
- self.dependency_graph, ops)
- else:
- ret = ifaceScheduler.run_iface_dependency_graphs(self,
- self.dependency_graph, ops,
+ return ifaceScheduler.sched_ifaces(self, ifacenames, ops,
+ dependency_graph=self.dependency_graph,
order=ifaceSchedulerFlags.INORDER
if 'down' in ops[0]
- else ifaceSchedulerFlags.POSTORDER)
- return ret
+ else ifaceSchedulerFlags.POSTORDER,
+ followdependents=True if self.WITH_DEPENDS else False)
def print_dependency(self, ifacenames, format):
- if ifacenames is None:
+ if not ifacenames:
ifacenames = self.ifaceobjdict.keys()
if format == 'list':
returns -1 if one or more interface not found. else, returns 0
"""
-
err_iface = ''
for i in ifacenames:
- ifaceobjs = self.get_iface_objs(i)
- if ifaceobjs is None:
+ ifaceobjs = self.get_ifaceobjs(i)
+ if not ifaceobjs:
err_iface += ' ' + i
-
if err_iface:
self.logger.error('could not find interfaces: %s' %err_iface)
return -1
-
return 0
-
def iface_whitelisted(self, auto, allow_classes, excludepats, ifacename):
""" Checks if interface is whitelisted depending on set of parameters.
-
interfaces are checked against the allow_classes and auto lists.
"""
for e in excludepats:
if re.search(e, ifacename):
return False
-
- ifaceobjs = self.get_iface_objs(ifacename)
- if ifaceobjs is None:
+ ifaceobjs = self.get_ifaceobjs(ifacename)
+ if not ifaceobjs:
self.logger.debug('iface %s' %ifacename + ' not found')
return False
-
# We check classes first
if allow_classes:
for i in ifaceobjs:
if common:
return True
return False
-
if auto:
for i in ifaceobjs:
if i.get_auto():
return True
return False
-
return True
def generate_running_env(self, ifaceobj, op):
cenv.update(iface_env)
else:
cenv = iface_env
-
cenv['MODE'] = self.compat_conv_op_to_mode(op)
-
return cenv
+ def save_state(self):
+ if not self.STATEMANAGER_ENABLE or not self.STATEMANAGER_UPDATE:
+ return
+ try:
+ # Update persistant iface states
+ self.statemanager.save_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 up(self, ops, auto=False, allow_classes=None, ifacenames=None,
excludepats=None, printdependency=None):
if auto:
except Exception, e:
raise
- if ifacenames is not None:
+ if ifacenames:
# If iface list is given by the caller, 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()
+ if not ifacenames: ifacenames = self.ifaceobjdict.keys()
# filter interfaces based on auto and allow classes
filtered_ifacenames = [i for i in ifacenames
if not filtered_ifacenames:
raise Exception('no ifaces found matching given allow lists')
- self.populate_dependency_info(filtered_ifacenames, ops)
-
- if printdependency is not None:
+ if printdependency:
+ self.populate_dependency_info(ops, filtered_ifacenames)
self.print_dependency(filtered_ifacenames, printdependency)
return
-
- if self.WITH_DEPENDS:
- self.run_with_dependents(ops, filtered_ifacenames)
else:
- self.run_without_dependents(ops, filtered_ifacenames)
+ self.populate_dependency_info(ops)
- if self.DRYRUN:
+ self.sched_ifaces(filtered_ifacenames, ops)
+
+ if self.DRYRUN and self.ADDONS_ENABLE:
return
- # Update persistant iface states
- try:
- if self.ALL:
- 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))
+ self.save_state()
def down(self, ops, auto=False, allow_classes=None, ifacenames=None,
- excludepats=None, printdependency=None):
- loaded_newconfig = False
+ excludepats=None, printdependency=None, usecurrentconfig=False):
+ if self.ADDONS_ENABLE: self.STATEMANAGER_UPDATE = False
if auto:
self.ALL = True
self.WITH_DEPENDS = True
-
- # for down we need to look at old state
- self.logger.debug('Looking at old state ..')
-
- if self.statemanager.get_ifaceobjdict():
+ # For down we need to look at old state, unless usecurrentconfig
+ # is set
+ if (not usecurrentconfig and self.STATEMANAGER_ENABLE and
+ self.statemanager.get_ifaceobjdict()):
+ # Since we are using state manager objects,
+ # skip the updating of state manager objects
+ self.STATEMANAGER_UPDATE = False
+ self.logger.debug('Looking at old state ..')
self.read_old_iface_config()
else:
# If no old state available
- self.logger.info('old state not available. ' +
- 'Loading new iface config file')
+ self.logger.info('Loading current iface config file')
try:
self.read_iface_config()
except Exception, e:
raise Exception('error reading iface config (%s)' %str(e))
- loaded_newconfig = True
-
if ifacenames:
# If iface list is given by the caller, 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 not ifacenames: ifacenames = self.ifaceobjdict.keys()
-
# filter interfaces based on auto and allow classes
filtered_ifacenames = [i for i in ifacenames
if self.iface_whitelisted(auto, allow_classes,
if not filtered_ifacenames:
raise Exception('no ifaces found matching given allow lists')
- self.populate_dependency_info(filtered_ifacenames, ops)
if printdependency:
+ self.populate_dependency_info(ops, filtered_ifacenames)
self.print_dependency(filtered_ifacenames, printdependency)
return
-
- if self.WITH_DEPENDS:
- self.run_with_dependents(ops, filtered_ifacenames)
else:
- self.run_without_dependents(ops, filtered_ifacenames)
+ self.populate_dependency_info(ops)
- if self.DRYRUN:
+ self.sched_ifaces(filtered_ifacenames, ops)
+ if self.DRYRUN and self.ADDONS_ENABLE:
return
- if loaded_newconfig:
- # Update persistant iface states
- try:
- if self.ALL:
- 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))
+ self.save_state()
def query(self, ops, auto=False, allow_classes=None, ifacenames=None,
excludepats=None, printdependency=None,
format='native'):
+ if self.STATEMANAGER_ENABLE and ops[0] == 'query-savedstate':
+ return self.statemanager.dump_pretty(ifacenames)
+
+ self.STATEMANAGER_UPDATE = False
if auto:
self.logger.debug('setting flag ALL')
self.ALL = True
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()
+ if not ifacenames: ifacenames = self.ifaceobjdict.keys()
# filter interfaces based on auto and allow classes
if ops[0] == 'query-running':
raise Exception('no ifaces found matching ' +
'given allow lists')
- self.populate_dependency_info(filtered_ifacenames, ops)
if ops[0] == 'query-dependency' and printdependency:
+ self.populate_dependency_info(ops, filtered_ifacenames)
self.print_dependency(filtered_ifacenames, printdependency)
return
+ else:
+ self.populate_dependency_info(ops)
if ops[0] == 'query':
return self.print_ifaceobjs_pretty(filtered_ifacenames, format)
elif ops[0] == 'query-raw':
return self.print_ifaceobjs_raw(filtered_ifacenames)
- if self.WITH_DEPENDS:
- self.run_with_dependents(ops, filtered_ifacenames)
- else:
- self.run_without_dependents(ops, filtered_ifacenames)
+ self.sched_ifaces(filtered_ifacenames, ops)
if ops[0] == 'query-checkcurr':
ret = self.print_ifaceobjscurr_pretty(filtered_ifacenames, format)
self.print_ifaceobjsrunning_pretty(filtered_ifacenames, format)
return
- def reload(self, auto=False, allow=None,
+ def reload(self, upops, downops, auto=False, allow=None,
ifacenames=None, excludepats=None, downchangediface=False):
""" main ifupdown run method """
allow_classes = []
- upops = ['pre-up', 'up', 'post-up']
- downops = ['pre-down', 'down', 'post-down']
self.logger.debug('reloading interface config ..')
-
if auto:
self.ALL = True
self.WITH_DEPENDS = True
try:
# Read the current interface config
self.read_iface_config()
- except Exception, e:
+ except:
raise
# generate dependency graph of interfaces
- self.populate_dependency_info(ifacenames, upops)
+ self.populate_dependency_info(upops)
# Save a copy of new iface objects and dependency_graph
new_ifaceobjdict = dict(self.get_ifaceobjdict())
new_dependency_graph = dict(self.get_dependency_graph())
- if self.statemanager.get_ifaceobjdict():
+ if self.STATEMANAGER_ENABLE and self.statemanager.get_ifaceobjdict():
# if old state is present, read old state and mark op for 'down'
# followed by 'up' aka: reload
# old interface config is read into self.ifaceobjdict
#
+ self.STATEMANAGER_UPDATE = False
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 not ifacenames: ifacenames = self.ifaceobjdict.keys()
if op == 'reload' and ifacenames:
filtered_ifacenames = [i for i in ifacenames
if self.iface_whitelisted(auto, allow_classes,
excludepats, i)]
-
# Generate the interface down list
# Interfaces that go into the down list:
# - interfaces that were present in last config and are not
ifacedownlist = []
for ifname, lastifobjlist in self.ifaceobjdict.items():
objidx = 0
-
# If interface is not present in the new file
# append it to the down list
newifobjlist = new_ifaceobjdict.get(ifname)
- if newifobjlist == None:
+ if not newifobjlist:
ifacedownlist.append(ifname)
continue
-
- if downchangediface == False:
+ if not downchangediface:
continue
-
# If interface has changed between the current file
# and the last installed append it to the down list
if len(newifobjlist) != len(lastifobjlist):
ifacedownlist.append(ifname)
continue
-
# compare object list
for objidx in range(0, len(lastifobjlist)):
oldobj = lastifobjlist[objidx]
ifacedownlist.append(ifname)
continue
-
if ifacedownlist:
self.logger.info('Executing down on interfaces: %s'
%str(ifacedownlist))
+ # reinitialize dependency graph
+ self.dependency_graph = OrderedDict({})
# Generate dependency info for old config
- self.populate_dependency_info(ifacedownlist, downops)
- self.run_with_dependents(downops, ifacedownlist)
-
- # Update persistant iface states
- try:
- if self.ALL:
- 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))
+ self.populate_dependency_info(downops)
+ self.sched_ifaces(ifacedownlist, downops)
else:
self.logger.debug('no interfaces to down ..')
- # Now, run up with new config dict
+ # Now, run 'up' with new config dict
+ # reset statemanager update flag to default
+ self.STATEMANAGER_UPDATE = True
self.set_ifaceobjdict(new_ifaceobjdict)
self.set_dependency_graph(new_dependency_graph)
-
ifacenames = self.ifaceobjdict.keys()
filtered_ifacenames = [i for i in ifacenames
if self.iface_whitelisted(auto, allow_classes,
excludepats, i)]
-
self.logger.info('Executing up on interfaces: %s'
%str(filtered_ifacenames))
- if self.WITH_DEPENDS:
- self.run_with_dependents(upops, filtered_ifacenames)
- else:
- self.run_without_dependents(upops, filtered_ifacenames)
+ self.sched_ifaces(filtered_ifacenames, upops)
if self.DRYRUN:
return
- # Update persistant iface states
- try:
- if self.ALL:
- 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))
+ self.save_state()
def dump(self):
""" all state dump """
print 'ifupdown object dump'
print self.pp.pprint(self.modules)
- print self.pp.pprint(self.ifaces)
- self.state_manager.dump()
+ print self.pp.pprint(self.ifaceobjdict)
+ #self.state_manager.dump()
def print_state(self, ifacenames=None):
self.statemanager.dump(ifacenames)
def print_ifaceobjs_raw(self, ifacenames):
for i in ifacenames:
- for ifaceobj in self.get_iface_objs(i):
+ for ifaceobj in self.get_ifaceobjs(i):
if (self.is_ifaceobj_builtin(ifaceobj) or
not ifaceobj.is_config_present()):
continue
def print_ifaceobjs_pretty(self, ifacenames, format='native'):
for i in ifacenames:
- for ifaceobj in self.get_iface_objs(i):
+ for ifaceobj in self.get_ifaceobjs(i):
if (self.is_ifaceobj_noconfig(ifaceobj)):
continue
if format == 'json':
ifaceobj.dump_json()
else:
ifaceobj.dump_pretty()
-
if self.WITH_DEPENDS:
dlist = ifaceobj.get_lowerifaces()
if not dlist: continue
def dump_ifaceobjs(self, ifacenames):
for i in ifacenames:
- ifaceobjs = self.get_iface_objs(i)
+ ifaceobjs = self.get_ifaceobjs(i)
for i in ifaceobjs:
i.dump(self.logger)
print '\n'
def print_ifaceobjsrunning_pretty(self, ifacenames, format='native'):
for i in ifacenames:
- ifaceobj = self.get_iface_obj_first(i)
+ ifaceobj = self.get_ifaceobj_first(i)
if ifaceobj.get_status() == ifaceStatus.NOTFOUND:
print 'iface %s' %ifaceobj.get_name() + ' (not found)\n'
continue
-
- if ifaceobj.is_config_present() == False:
+ if not ifaceobj.is_config_present():
continue
-
if format == 'json':
ifaceobj.dump_json()
else:
ifaceobj.dump_pretty()
-
if self.WITH_DEPENDS:
dlist = ifaceobj.get_lowerifaces()
if not dlist: continue