From 53b0022499ede32623a968bd82c499286830a06d Mon Sep 17 00:00:00 2001 From: roopa Date: Tue, 25 Mar 2014 15:21:19 -0700 Subject: [PATCH] cleanup + fixes Ticket: CM-1438 Reviewed By: Testing Done: Tested ifupdown sanity --- pkg/iface.py | 4 +- pkg/ifupdownmain.py | 335 ++++++++++++++++++-------------------------- pkg/scheduler.py | 247 -------------------------------- pkg/statemanager.py | 85 ++--------- 4 files changed, 148 insertions(+), 523 deletions(-) diff --git a/pkg/iface.py b/pkg/iface.py index fca097d..14eccd3 100644 --- a/pkg/iface.py +++ b/pkg/iface.py @@ -335,9 +335,11 @@ class iface(): def dump_raw(self, logger): indent = ' ' + if self.auto: + print 'auto %s' %self.name print (self.raw_config[0]) for i in range(1, len(self.raw_config)): - print (indent + self.raw_config[i]) + print(indent + self.raw_config[i]) def dump(self, logger): indent = '\t' diff --git a/pkg/ifupdownmain.py b/pkg/ifupdownmain.py index eda5de8..eb702af 100644 --- a/pkg/ifupdownmain.py +++ b/pkg/ifupdownmain.py @@ -23,6 +23,9 @@ from graph import * from sets import Set class ifupdownMain(ifupdownBase): + """ ifupdown2 main class """ + + # Flags WITH_DEPENDS = False @@ -43,13 +46,15 @@ class ifupdownMain(ifupdownBase): # iface dictionary in the below format: # { '' : [, ..] } # eg: - # { 'swp1' : [, ..] } + # { 'swp1' : [, ..] } # # Each ifaceobject corresponds to a configuration block for # that interface + # The value in the dictionary is a list because the network + # interface configuration file supports more than one iface section + # in the interfaces file ifaceobjdict = OrderedDict() - # iface dictionary representing the curr running state of an iface # in the below format: # {'' : } @@ -141,73 +146,6 @@ class ifupdownMain(ifupdownBase): else: self.STATEMANAGER_UPDATE = False - def get_subops(self, op): - """ Returns sub-operation list """ - return self.module_ops.get(op).keys() - - def compat_conv_op_to_mode(self, op): - """ Returns old op name to work with existing scripts """ - if op == 'pre-up': - return 'start' - elif op == 'pre-down': - return 'stop' - else: - return op - - def set_force(self, force): - """ Set force flag. """ - self.FORCE = force - - def get_force(self): - """ return force flag. """ - return self.FORCE - - def set_dryrun(self, dryrun): - self.DRYRUN = dryrun - - 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): - self.ifaceobjdict = ifaceobjdict - - def set_dependency_graph(self, dependency_graph): - self.dependency_graph = dependency_graph - - def get_dependency_graph(self): - return self.dependency_graph - - def set_perfmode(self, perfmode): - self.PERFMODE = perfmode - - def get_perfmode(self): - return self.PERFMODE - - def set_nowait(self, nowait): - self.NOWAIT = nowait - - def get_nowait(self): - return self.NOWAIT - - def set_njobs(self, njobs): - self.logger.debug('setting njobs to %d' %njobs) - self.njobs = njobs - - def get_njobs(self): - return self.njobs - - def get_withdepends(self): - return self.WITH_DEPENDS - - def set_withdepends(self, withdepends): - self.logger.debug('setting withdepends to true') - self.WITH_DEPENDS = withdepends def get_ifaceobjs(self, ifacename): return self.ifaceobjdict.get(ifacename) @@ -224,18 +162,29 @@ class ifupdownMain(ifupdownBase): def get_iface_obj_last(self, ifacename): return self.ifaceobjdict.get(ifacename)[-1] + def create_n_save_ifaceobj(self, ifacename, priv_flags=None, + increfcnt=False): + """ creates a iface object and adds it to the iface dictionary """ + ifaceobj = iface() + ifaceobj.name = ifacename + ifaceobj.priv_flags = priv_flags + ifaceobj.auto = True + if increfcnt: + ifaceobj.inc_refcnt() + self.ifaceobjdict[ifacename] = [ifaceobj] + return ifaceobj + def create_n_save_ifaceobjcurr(self, ifaceobj): - ifacename = ifaceobj.name - ifaceobjcurr = self.get_ifaceobjcurr(ifacename) + """ creates a copy of iface object and adds it to the iface dict containing current iface objects + """ + ifaceobjcurr = self.get_ifaceobjcurr(ifaceobj.name) if ifaceobjcurr: return ifaceobjcurr - ifaceobjcurr = iface() - ifaceobjcurr.name = ifacename + ifaceobjcurr.name = ifaceobj.name ifaceobjcurr.lowerifaces = ifaceobj.lowerifaces ifaceobjcurr.priv_flags = ifaceobj.priv_flags - self.ifaceobjcurrdict[ifacename] = ifaceobjcurr - + self.ifaceobjcurrdict[ifaceobj.name] = ifaceobjcurr return ifaceobjcurr def get_ifaceobjcurr(self, ifacename): @@ -244,14 +193,8 @@ class ifupdownMain(ifupdownBase): def get_ifaceobjrunning(self, ifacename): return self.ifaceobjrunningdict.get(ifacename) - def get_iface_status(self, ifacename): - ifaceobjs = self.get_ifaceobjs(ifacename) - for i in ifaceobjs: - if i.status != ifaceStatus.SUCCESS: - return i.status - return ifaceStatus.SUCCESS - def get_iface_refcnt(self, ifacename): + """ Return iface ref count """ max = 0 ifaceobjs = self.get_ifaceobjs(ifacename) if not ifaceobjs: @@ -261,22 +204,6 @@ class ifupdownMain(ifupdownBase): max = i.refcnt return max - def create_n_save_ifaceobj(self, ifacename, priv_flags=None, - 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. - """ - ifaceobj = iface() - ifaceobj.name = ifacename - ifaceobj.priv_flags = priv_flags - ifaceobj.auto = True - if increfcnt: - ifaceobj.inc_refcnt() - self.ifaceobjdict[ifacename] = [ifaceobj] - - return ifaceobj - def is_iface_builtin_byname(self, ifacename): """ Returns true if iface name is a builtin interface. @@ -296,7 +223,7 @@ class ifupdownMain(ifupdownBase): return (ifaceobj.priv_flags & self.BUILTIN) def is_ifaceobj_noconfig(self, ifaceobj): - """ Returns true if iface name did not have a user defined config. + """ Returns true if iface object did not have a user defined config. These interfaces appear only when they are dependents of interfaces which have user defined config @@ -308,7 +235,6 @@ class ifupdownMain(ifupdownBase): ifaceobj = self.get_ifaceobj_first(ifacename) if not ifaceobj: return True - return self.is_ifaceobj_noconfig(ifaceobj) def preprocess_dependency_list(self, upperifacename, dlist, ops): @@ -401,15 +327,14 @@ class ifupdownMain(ifupdownBase): self.dependency_graph[i] = dlist def _save_iface(self, ifaceobj): - if not self.ifaceobjdict.get(ifaceobj.name): - self.ifaceobjdict[ifaceobj.name] = [ifaceobj] - else: - self.ifaceobjdict[ifaceobj.name].append(ifaceobj) + self.ifaceobjdict.setdefault(ifaceobj.name, + []).append(ifaceobj) def _module_syntax_checker(self, attrname, attrval): for m, mdict in self.module_attrs.items(): attrsdict = mdict.get('attrs') - if attrsdict and attrname in attrsdict.keys(): return True + if attrsdict and attrname in attrsdict.keys(): + return True return False def read_default_iface_config(self): @@ -424,11 +349,11 @@ class ifupdownMain(ifupdownBase): def read_old_iface_config(self): """ Reads the saved iface config instead of default iface config. """ + self.ifaceobjdict = self.statemanager.ifaceobjdict - # Read it from the statemanager - self.ifaceobjdict = self.statemanager.get_ifaceobjdict() + def _load_addon_modules_config(self): + """ Load addon modules config file """ - def load_addon_modules_config(self): with open(self.addon_modules_configfile, 'r') as f: lines = f.readlines() for l in lines: @@ -444,13 +369,13 @@ class ifupdownMain(ifupdownBase): """ self.logger.info('loading builtin modules from %s' %modules_dir) - self.load_addon_modules_config() + self._load_addon_modules_config() if not modules_dir in sys.path: sys.path.append(modules_dir) try: for op, mlist in self.module_ops.items(): for mname in mlist: - if self.modules.get(mname) is not None: + if self.modules.get(mname): continue mpath = modules_dir + '/' + mname + '.py' if os.path.exists(mpath): @@ -466,8 +391,10 @@ class ifupdownMain(ifupdownBase): cache=self.CACHE, cacheflags=self.CACHE_FLAGS) self.modules[mname] = minstance - if hasattr(minstance, 'get_modinfo'): + try: self.module_attrs[mname] = minstance.get_modinfo() + except: + pass except: raise @@ -478,7 +405,9 @@ class ifupdownMain(ifupdownBase): self.module_ops['query'] = self.modules.keys() self.module_ops['query-raw'] = self.modules.keys() - def modules_help(self): + def _modules_help(self): + """ Prints addon modules supported syntax """ + indent = ' ' for m, mdict in self.module_attrs.items(): if not mdict: @@ -544,23 +473,11 @@ class ifupdownMain(ifupdownBase): # continue reading pass - def conv_iface_namelist_to_objlist(self, intf_list): - for intf in intf_list: - iface_obj = self.get_iface(intf) - if not iface_obj: - raise ifupdownInvalidValue('no iface %s', intf) - 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 sched_ifaces(self, ifacenames, ops): + def _sched_ifaces(self, ifacenames, ops): self.logger.debug('scheduling \'%s\' for %s' %(str(ops), str(ifacenames))) - self.logger.info('dependency graph:') + self.logger.debug('dependency graph:') self._pretty_print_ordered_dict(self.dependency_graph) return ifaceScheduler.sched_ifaces(self, ifacenames, ops, @@ -570,21 +487,7 @@ class ifupdownMain(ifupdownBase): else ifaceSchedulerFlags.POSTORDER, followdependents=True if self.WITH_DEPENDS else False) - def print_dependency(self, ifacenames, format): - if not ifacenames: - ifacenames = self.ifaceobjdict.keys() - - if format == 'list': - for k,v in self.dependency_graph.items(): - print '%s : %s' %(k, str(v)) - elif format == 'dot': - indegrees = {} - map(lambda i: indegrees.update({i : - self.get_iface_refcnt(i)}), - self.dependency_graph.keys()) - graph.generate_dots(self.dependency_graph, indegrees) - - def validate_ifaces(self, ifacenames): + def _validate_ifaces(self, ifacenames): """ validates interface list for config existance. returns -1 if one or more interface not found. else, returns 0 @@ -600,13 +503,13 @@ class ifupdownMain(ifupdownBase): return -1 return 0 - def iface_whitelisted(self, auto, allow_classes, excludepats, ifacename): + 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. """ - # If the interface matches + if excludepats: for e in excludepats: if re.search(e, ifacename): @@ -631,6 +534,15 @@ class ifupdownMain(ifupdownBase): return False return True + def _compat_conv_op_to_mode(self, op): + """ Returns old op name to work with existing scripts """ + if op == 'pre-up': + return 'start' + elif op == 'pre-down': + return 'stop' + else: + return op + def generate_running_env(self, ifaceobj, op): """ Generates a dictionary with env variables required for an interface. Used to support script execution for interfaces. @@ -644,10 +556,10 @@ class ifupdownMain(ifupdownBase): cenv.update(iface_env) else: cenv = iface_env - cenv['MODE'] = self.compat_conv_op_to_mode(op) + cenv['MODE'] = self._compat_conv_op_to_mode(op) return cenv - def save_state(self): + def _save_state(self): if not self.STATEMANAGER_ENABLE or not self.STATEMANAGER_UPDATE: return try: @@ -661,6 +573,8 @@ class ifupdownMain(ifupdownBase): def up(self, ops, auto=False, allow_classes=None, ifacenames=None, excludepats=None, printdependency=None): + """ up an interface """ + if auto: self.ALL = True self.WITH_DEPENDS = True @@ -673,7 +587,7 @@ class ifupdownMain(ifupdownBase): if ifacenames: # If iface list is given by the caller, always check if iface # is present - if self.validate_ifaces(ifacenames) != 0: + 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 @@ -681,7 +595,7 @@ class ifupdownMain(ifupdownBase): # filter interfaces based on auto and allow classes filtered_ifacenames = [i for i in ifacenames - if self.iface_whitelisted(auto, allow_classes, + if self._iface_whitelisted(auto, allow_classes, excludepats, i)] if not filtered_ifacenames: raise Exception('no ifaces found matching given allow lists') @@ -693,15 +607,17 @@ class ifupdownMain(ifupdownBase): else: self.populate_dependency_info(ops) - self.sched_ifaces(filtered_ifacenames, ops) + self._sched_ifaces(filtered_ifacenames, ops) if self.DRYRUN and self.ADDONS_ENABLE: return - self.save_state() + self._save_state() def down(self, ops, auto=False, allow_classes=None, ifacenames=None, excludepats=None, printdependency=None, usecurrentconfig=False): + """ down an interface """ + if self.ADDONS_ENABLE: self.STATEMANAGER_UPDATE = False if auto: self.ALL = True @@ -709,7 +625,7 @@ class ifupdownMain(ifupdownBase): # 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()): + self.statemanager.ifaceobjdict): # Since we are using state manager objects, # skip the updating of state manager objects self.STATEMANAGER_UPDATE = False @@ -725,13 +641,14 @@ class ifupdownMain(ifupdownBase): if ifacenames: # If iface list is given by the caller, always check if iface # is present - if self.validate_ifaces(ifacenames) != 0: + if self._validate_ifaces(ifacenames) != 0: raise Exception('all or some interfaces were never up') # 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 self._iface_whitelisted(auto, allow_classes, excludepats, i)] if not filtered_ifacenames: raise Exception('no ifaces found matching given allow lists') @@ -743,15 +660,17 @@ class ifupdownMain(ifupdownBase): else: self.populate_dependency_info(ops) - self.sched_ifaces(filtered_ifacenames, ops) + self._sched_ifaces(filtered_ifacenames, ops) if self.DRYRUN and self.ADDONS_ENABLE: return - self.save_state() + self._save_state() def query(self, ops, auto=False, allow_classes=None, ifacenames=None, excludepats=None, printdependency=None, format='native'): + """ query an interface """ + if self.STATEMANAGER_ENABLE and ops[0] == 'query-savedstate': return self.statemanager.dump_pretty(ifacenames) @@ -762,7 +681,7 @@ class ifupdownMain(ifupdownBase): self.WITH_DEPENDS = True if ops[0] == 'query-syntax': - self.modules_help() + self._modules_help() return elif ops[0] == 'query-running': # create fake devices to all dependents that dont have config @@ -774,9 +693,9 @@ class ifupdownMain(ifupdownBase): except Exception: raise - if ifacenames is not None and ops[0] != 'query-running': + if ifacenames and ops[0] != 'query-running': # If iface list is given, always check if iface is present - if self.validate_ifaces(ifacenames) != 0: + 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 @@ -787,7 +706,7 @@ class ifupdownMain(ifupdownBase): filtered_ifacenames = ifacenames else: filtered_ifacenames = [i for i in ifacenames - if self.iface_whitelisted(auto, allow_classes, + if self._iface_whitelisted(auto, allow_classes, excludepats, i)] if not filtered_ifacenames: raise Exception('no ifaces found matching ' + @@ -805,7 +724,7 @@ class ifupdownMain(ifupdownBase): elif ops[0] == 'query-raw': return self.print_ifaceobjs_raw(filtered_ifacenames) - self.sched_ifaces(filtered_ifacenames, ops) + self._sched_ifaces(filtered_ifacenames, ops) if ops[0] == 'query-checkcurr': ret = self.print_ifaceobjscurr_pretty(filtered_ifacenames, format) @@ -818,7 +737,8 @@ class ifupdownMain(ifupdownBase): def reload(self, upops, downops, auto=False, allow=None, ifacenames=None, excludepats=None, downchangediface=False): - """ main ifupdown run method """ + """ reload interface config """ + allow_classes = [] self.logger.debug('reloading interface config ..') @@ -836,10 +756,10 @@ class ifupdownMain(ifupdownBase): 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()) + new_ifaceobjdict = dict(self.ifaceobjdict) + new_dependency_graph = dict(self.dependency_graph) - if self.STATEMANAGER_ENABLE and self.statemanager.get_ifaceobjdict(): + if self.STATEMANAGER_ENABLE and self.statemanager.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 @@ -854,7 +774,7 @@ class ifupdownMain(ifupdownBase): 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, + if self._iface_whitelisted(auto, allow_classes, excludepats, i)] # Generate the interface down list # Interfaces that go into the down list: @@ -864,25 +784,25 @@ class ifupdownMain(ifupdownBase): # config # ifacedownlist = [] - for ifname, lastifobjlist in self.ifaceobjdict.items(): + for ifname, lastifaceobjlist 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 not newifobjlist: + newifaceobjlist = new_ifaceobjdict.get(ifname) + if not newifaceobjlist: ifacedownlist.append(ifname) continue 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): + if len(newifaceobjlist) != len(lastifaceobjlist): ifacedownlist.append(ifname) continue # compare object list - for objidx in range(0, len(lastifobjlist)): - oldobj = lastifobjlist[objidx] - newobj = newifobjlist[objidx] + for objidx in range(0, len(lastifaceobjlist)): + oldobj = lastifaceobjlist[objidx] + newobj = newifaceobjlist[objidx] if newobj.is_different(oldobj): ifacedownlist.append(ifname) continue @@ -894,40 +814,50 @@ class ifupdownMain(ifupdownBase): self.dependency_graph = OrderedDict({}) # Generate dependency info for old config self.populate_dependency_info(downops) - self.sched_ifaces(ifacedownlist, downops) + self._sched_ifaces(ifacedownlist, downops) else: self.logger.debug('no interfaces to down ..') # 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) + self.ifaceobjdict = new_ifaceobjdict + self.dependency_graph = new_dependency_graph ifacenames = self.ifaceobjdict.keys() filtered_ifacenames = [i for i in ifacenames - if self.iface_whitelisted(auto, allow_classes, + if self._iface_whitelisted(auto, allow_classes, excludepats, i)] - self.logger.info('Executing up on interfaces: %s' - %str(filtered_ifacenames)) - self.sched_ifaces(filtered_ifacenames, upops) + self.logger.info('Scheduling up on interfaces: %s' + %str(filtered_ifacenames)) + self._sched_ifaces(filtered_ifacenames, upops) if self.DRYRUN: return - self.save_state() + self._save_state() - def dump(self): - """ all state dump """ + def _pretty_print_ordered_dict(self, argdict): + for k, vlist in argdict.items(): + self.logger.debug('%s : %s' %(k, str(vlist))) - print 'ifupdown object dump' - print self.pp.pprint(self.modules) - print self.pp.pprint(self.ifaceobjdict) - #self.state_manager.dump() + def print_dependency(self, ifacenames, format): + """ prints iface dependency information """ - def print_state(self, ifacenames=None): - self.statemanager.dump(ifacenames) + if not ifacenames: + ifacenames = self.ifaceobjdict.keys() + if format == 'list': + for k,v in self.dependency_graph.items(): + print '%s : %s' %(k, str(v)) + elif format == 'dot': + indegrees = {} + map(lambda i: indegrees.update({i : + self.get_iface_refcnt(i)}), + self.dependency_graph.keys()) + graph.generate_dots(self.dependency_graph, indegrees) def print_ifaceobjs_raw(self, ifacenames): + """ prints raw lines for ifaces from config file """ + for i in ifacenames: for ifaceobj in self.get_ifaceobjs(i): if (self.is_ifaceobj_builtin(ifaceobj) or @@ -938,9 +868,11 @@ class ifupdownMain(ifupdownBase): if self.WITH_DEPENDS: dlist = ifaceobj.lowerifaces if not dlist: continue - self.print_ifaceobjs_pretty(dlist, format) + self.print_ifaceobjs_raw(dlist) def print_ifaceobjs_pretty(self, ifacenames, format='native'): + """ pretty prints iface in format given by keyword arg format """ + for i in ifacenames: for ifaceobj in self.get_ifaceobjs(i): if (self.is_ifaceobj_noconfig(ifaceobj)): @@ -954,19 +886,13 @@ class ifupdownMain(ifupdownBase): if not dlist: continue self.print_ifaceobjs_pretty(dlist, format) - def dump_ifaceobjs(self, ifacenames): - for i in ifacenames: - ifaceobjs = self.get_ifaceobjs(i) - for i in ifaceobjs: - i.dump(self.logger) - print '\n' - def print_ifaceobjscurr_pretty(self, ifacenames, format='native'): - """ Dumps current running state of interfaces. + """ pretty prints current running state of interfaces with status. returns 1 if any of the interface has an error, else returns 0 """ + ret = 0 for i in ifacenames: ifaceobj = self.get_ifaceobjcurr(i) @@ -978,15 +904,12 @@ class ifupdownMain(ifupdownBase): continue elif ifaceobj.status == ifaceStatus.ERROR: ret = 1 - if (self.is_ifaceobj_noconfig(ifaceobj)): continue - if format == 'json': ifaceobj.dump_json(with_status=True) else: ifaceobj.dump_pretty(with_status=True) - if self.WITH_DEPENDS: dlist = ifaceobj.lowerifaces if not dlist: continue @@ -994,6 +917,8 @@ class ifupdownMain(ifupdownBase): return ret def print_ifaceobjsrunning_pretty(self, ifacenames, format='native'): + """ pretty prints iface running state """ + for i in ifacenames: ifaceobj = self.get_ifaceobj_first(i) if ifaceobj.status == ifaceStatus.NOTFOUND: @@ -1010,3 +935,15 @@ class ifupdownMain(ifupdownBase): if not dlist: continue self.print_ifaceobjsrunning_pretty(dlist, format) return + + def _dump(self): + print 'ifupdown main object dump' + print self.pp.pprint(self.modules) + print self.pp.pprint(self.ifaceobjdict) + + def _dump_ifaceobjs(self, ifacenames): + for i in ifacenames: + ifaceobjs = self.get_ifaceobjs(i) + for i in ifaceobjs: + i.dump(self.logger) + print '\n' diff --git a/pkg/scheduler.py b/pkg/scheduler.py index 6940c9f..264a840 100644 --- a/pkg/scheduler.py +++ b/pkg/scheduler.py @@ -336,250 +336,3 @@ class ifaceScheduler(): cls.run_iface_list(ifupdownobj, run_queue, ops, parent=None,order=order, followdependents=followdependents) - - @classmethod - def run_iface(cls, ifupdownobj, ifacename, ops): - """ Runs operation on an interface """ - - ifaceobjs = ifupdownobj.get_ifaceobjs(ifacename) - for i in ifaceobjs: - cls.run_iface_ops(ifupdownobj, i, ops) - - @classmethod - def run_iface_list_op(cls, ifupdownobj, ifacenames, op, - sorted_by_dependency=False): - """ Runs interface list through sub operation handler. """ - - ifupdownobj.logger.debug('running operation %s on all given interfaces' - %op) - iface_run_queue = deque(ifacenames) - for i in range(0, len(iface_run_queue)): - if op.endswith('up'): - # XXX: simplify this - if sorted_by_dependency: - ifacename = iface_run_queue.pop() - else: - ifacename = iface_run_queue.popleft() - else: - if sorted_by_dependency: - ifacename = iface_run_queue.popleft() - else: - ifacename = iface_run_queue.pop() - - try: - ifaceobjs = ifupdownobj.get_ifaceobjs(ifacename) - for ifaceobj in ifaceobjs: - cenv = ifupdownobj.generate_running_env(ifaceobj, op) - cls.run_iface_op(ifupdownobj, ifaceobj, op, cenv) - except Exception, e: - ifupdownobj.log_error(str(e)) - - @classmethod - def run_iface_list_ops(cls, ifupdownobj, ifacenames, ops, - sorted_by_dependency=False): - """ Runs interface list through sub operations handler - - Unlike run_iface_list, this method executes a sub operation on the - entire interface list before proceeding to the next sub-operation. - ie operation 'pre-up' is run through the entire interface list before - 'up' - """ - # Each sub operation has a module list - [cls.run_iface_list_op(ifupdownobj, ifacenames, op, - sorted_by_dependency) for op in ops] - - @classmethod - def run_iface_dependency_graphs_sorted(cls, ifupdownobj, - dependency_graphs, - ops, indegrees=None, - graphsortall=False): - """ runs interface dependency graph by topologically sorting the interfaces """ - - if indegrees is None: - indegrees = OrderedDict() - for ifacename in dependency_graphs.keys(): - indegrees[ifacename] = ifupdownobj.get_iface_refcnt(ifacename) - - ifupdownobj.logger.debug('indegree array :') - ifupdownobj.logger.debug(ifupdownobj.pp.pformat(indegrees)) - - try: - ifupdownobj.logger.debug('calling topological sort on the graph ' + - '...') - if graphsortall: - sorted_ifacenames = graph.topological_sort_graphs_all( - dependency_graphs, indegrees) - else: - sorted_ifacenames = graph.topological_sort_graphs( - dependency_graphs, indegrees) - except Exception: - raise - - ifupdownobj.logger.debug('sorted iface list = %s' %sorted_ifacenames) - cls.run_iface_list_ops(ifupdownobj, sorted_ifacenames, ops, - sorted_by_dependency=True) - - - """ Methods to execute interfaces in parallel """ - @classmethod - def init_tokens(cls, count): - cls.token_pool = BoundedSemaphore(count) - - @classmethod - def accquire_token(cls, logprefix=''): - cls.token_pool.acquire() - - @classmethod - def release_token(cls, logprefix=''): - cls.token_pool.release() - - @classmethod - def run_iface_parallel(cls, ifupdownobj, ifacename, op): - """ Configures interface in parallel. - - Executes all its direct dependents in parallel - - """ - - ifupdownobj.logger.debug('%s: %s' %(ifacename, op)) - cls.accquire_token(iface) - - # Each iface can have a list of objects - ifaceobjs = ifupdownobj.get_ifaceobjs(ifacename) - if ifaceobjs is None: - ifupdownobj.logger.warning('%s: ' %ifacename + 'not found') - cls.release_token(ifacename) - return -1 - - for ifaceobj in ifaceobjs: - # Run dependents - dlist = ifaceobj.lowerifaces - if dlist: - ifupdownobj.logger.debug('%s:' %ifacename + - ' found dependents: %s' %str(dlist)) - try: - cls.release_token(ifacename) - cls.run_iface_list_parallel(ifacename, ifupdownobj, - dlist, op) - cls.accquire_token(ifacename) - except Exception, e: - if ifupdownobj.ignore_error(str(e)): - pass - else: - # Dont bring the iface up if children did not come up - ifupdownobj.logger.debug('%s:' %ifacename + - ' there was an error bringing %s' %op + - ' dependents (%s)', str(e)) - ifupdownobj.set_iface_state(ifaceobj, - ifaceState.from_str(ops[0]), - ifaceStatus.ERROR) - return -1 - - # Run all sub operations sequentially - try: - ifupdownobj.logger.debug('%s:' %ifacename + - ' running sub-operations') - cls.run_iface_ops(ifupdownobj, ifaceobj, op) - except Exception, e: - ifupdownobj.logger.error('%s:' %ifacename + - ' error running sub operations (%s)' %str(e)) - - cls.release_token(ifacename) - - @classmethod - def run_iface_list_parallel(cls, parent, ifupdownobj, ifacenames, op): - """ Runs interface list in parallel """ - - running_threads = OrderedDict() - err = 0 - - for ifacename in ifacenames: - try: - cls.accquire_token(parent) - running_threads[ifacename] = Thread(None, - cls.run_iface_parallel, ifacename, - args=(ifupdownobj, ifacename, op)) - running_threads[ifacename].start() - cls.release_token(parent) - except Exception, e: - cls.release_token(parent) - if ifupdownobj.ignore_error(str(e)): - pass - else: - raise Exception('error starting thread for iface %s' - %ifacename) - - ifupdownobj.logger.debug('%s ' %parent + - 'waiting for all the threads ...') - for ifacename, t in running_threads.items(): - t.join() - if ifupdownobj.get_iface_status(ifacename) != ifaceStatus.SUCCESS: - err += 1 - - return err - - @classmethod - def run_iface_graphs_parallel(cls, parent, ifupdownobj, ifacenames, op): - """ Runs iface graphs in parallel """ - - running_threads = OrderedDict() - err = 0 - - for ifacename in ifacenames: - try: - cls.accquire_graph_token(parent) - running_threads[ifacename] = Thread(None, - cls.run_iface_parallel, ifacename, - args=(ifupdownobj, ifacename, op)) - running_threads[ifacename].start() - cls.release_graph_token(parent) - except Exception, e: - cls.release_graph_token(parent) - if ifupdownobj.ignore_error(str(e)): - pass - else: - raise Exception('error starting thread for iface %s' - %ifacename) - - ifupdownobj.logger.info('%s ' %parent + - 'waiting for all the threads ...') - for ifacename, t in running_threads.items(): - t.join() - # Check status of thread - # XXX: Check all objs - if ifupdownobj.get_iface_status(ifacename) != ifaceStatus.SUCCESS: - err += 1 - return err - - @classmethod - def run_iface_dependency_graph_parallel(cls, ifupdownobj, dependency_graph, - operation): - """ Runs iface dependeny graph in parallel. - - arguments: - ifupdownobj -- ifupdown object (used for getting and updating iface - object state) - dependency_graph -- dependency graph with - operation -- 'up' or 'down' or 'query' - - """ - - ifupdownobj.logger.debug('running dependency graph in parallel ..') - run_queue = [] - # Build a list of ifaces that dont have any dependencies - for ifacename in dependency_graph.keys(): - if ifupdownobj.get_iface_refcnt(ifacename) == 0: - run_queue.append(ifacename) - - ifupdownobj.logger.debug('graph roots (interfaces that dont' - ' have dependents):' + ' %s' %str(run_queue)) - cls.init_tokens(ifupdownobj.get_njobs()) - return cls.run_iface_list_parallel('main', ifupdownobj, run_queue, - operation) - - # OR - # Run one graph at a time - #for iface in run_queue: - # self.run_iface_list_parallel('main', ifupdownobj, [iface], - # operation) - diff --git a/pkg/statemanager.py b/pkg/statemanager.py index db3eb3a..6a08d6f 100644 --- a/pkg/statemanager.py +++ b/pkg/statemanager.py @@ -11,10 +11,9 @@ from collections import OrderedDict import logging import os from iface import * -import copy -import marshal class pickling(): + """ class with helper methods for pickling/unpickling iface objects """ @classmethod def save(cls, filename, list_of_objects): @@ -41,6 +40,7 @@ class pickling(): except: raise class stateManager(): + """ state manager for managing ifupdown iface obj state """ state_dir = '/var/tmp/network/' state_filename = 'ifstatenew' @@ -61,98 +61,31 @@ class stateManager(): pickle_filename = filename if not pickle_filename: pickle_filename = self.state_file - if not os.path.exists(pickle_filename): return - - # Read all ifaces from file for ifaceobj in pickling.load(pickle_filename): self.save_ifaceobj(ifaceobj) - return 0 - - def get_ifaceobjdict(self): - return self.ifaceobjdict - def get_ifaceobjs(self, ifacename): return self.ifaceobjdict.get(ifacename) - def compare_iface_state(ifaceobj1, ifaceobj2): - ifaceobj1_state = ifaceobj1.state - ifaceobj2_state = ifaceobj2.state - - if ifaceobj1_state < ifaceobj2_state: - return -1 - elif ifaceobj1_state > ifaceobj2_state: - return 1 - elif ifaceobj1_state == ifaceobj2_state: - return 0 - - def cmp_old_new_state(self, ifacename, operation): - """ compares current operation with old state """ - - state_arg = ifaceState.from_str(operation) - if state_arg == ifaceState.UP: - old_ifaceobj = self.ifaceobjdict.get(ifacename) - if old_ifaceobj: - # found old state for iface - # Check its state - if (old_ifaceobj.state == state_arg and - old_ifaceobj.status == ifaceStatus.SUCCESS): - self.statemsg = 'iface already up' - return 0 - elif state_arg == ifaceState.DOWN: - old_ifaceobj = self.ifaceobjdict.get(ifname) - if old_ifaceobj: - # found old state for iface - # Check its state - if (old_ifaceobj.state == state_arg and - old_ifaceobj.status == ifaceStatus.SUCCESS): - self.statemsg = 'iface already down' - return 0 - - return 1 - - def ifaceobj_compare(self, ifaceobj_a, ifaceobj_b): - if ifaceobj_a.name != ifaceobj_b.name: - return False - - if (not ifaceobj_a.addr_family and - ifaceobj_b.addr_family): - return False - - if (ifaceobj_a.addr_family and - not ifaceobj_b.addr_family): - return False - - if (not ifaceobj_a.addr_family and - not ifaceobj_b.addr_family): - return True - - if ifaceobj_a.addr_family != ifaceobj_b.addr_family: - return False - - return True - def ifaceobj_sync(self, ifaceobj): - ifacename = ifaceobj.name - self.logger.debug('%s: statemanager sync state' %ifacename) - old_ifaceobjs = self.ifaceobjdict.get(ifacename) + self.logger.debug('%s: statemanager sync state' %ifaceobj.name) + old_ifaceobjs = self.ifaceobjdict.get(ifaceobj.name) if not old_ifaceobjs: - self.ifaceobjdict[ifacename] = [ifaceobj] + self.ifaceobjdict[ifaceobj.name] = [ifaceobj] else: if old_ifaceobjs[0].flags & iface._PICKLED: - del self.ifaceobjdict[ifacename] - self.ifaceobjdict[ifacename] = [ifaceobj] + del self.ifaceobjdict[ifaceobj.name] + self.ifaceobjdict[ifaceobj.name] = [ifaceobj] else: - self.ifaceobjdict[ifacename].append(ifaceobj) + self.ifaceobjdict[ifaceobj.name].append(ifaceobj) def save_state(self): try: with open(self.state_file, 'w') as f: for ifaceobjs in self.ifaceobjdict.values(): - for i in ifaceobjs: - pickling.save_obj(f, i) + [pickling.save_obj(f, i) for i in ifaceobjs] except: raise