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

ifudown --no-scripts support

Ticket: CM-1438
Reviewed By:
Testing Done:
This commit is contained in:
roopa
2014-02-26 08:09:44 -08:00
parent 03964dc48d
commit 20dd6242f6
4 changed files with 113 additions and 93 deletions

View File

@@ -24,7 +24,7 @@ class ifupdownBase(object):
cmdout = ''
try:
self.logger.debug('Executing ' + cmd)
self.logger.info('Executing ' + cmd)
ch = subprocess.Popen(cmd.split(),
stdout=subprocess.PIPE,
shell=False, env=cmdenv,
@@ -66,7 +66,7 @@ class ifupdownBase(object):
return os.path.exists('/sys/class/net/%s' %ifacename)
def link_up(self, ifacename):
self.exec_command('ip link set dev %s up' %ifacename)
self.exec_command('ifconfig %s up' %ifacename)
def link_down(self, ifacename):
self.exec_command('ip link set dev %s down' %ifacename)
self.exec_command('ifconfig %s down' %ifacename)

View File

@@ -29,7 +29,9 @@ class ifupdownMain(ifupdownBase):
ALL = False
STATE_CHECK = False
COMPAT_EXEC_SCRIPTS = False
UPDATE_STATEMANAGER = True
STATEMANAGER_ENABLE = True
STATEMANAGER_UPDATE = True
ADDONS_ENABLE = False
# priv flags to mark iface objects
BUILTIN = 0x1
@@ -91,9 +93,8 @@ class ifupdownMain(ifupdownBase):
ops_handlers = OrderedDict([('up', run_up),
('down', run_down)])
def run_sched_ifaceobj_posthook(self, ifaceobj):
if self.UPDATE_STATEMANAGER:
if self.STATEMANAGER_UPDATE:
self.statemanager.ifaceobj_sync(ifaceobj)
# ifupdown object interface scheduler pre and posthooks
@@ -101,27 +102,30 @@ class ifupdownMain(ifupdownBase):
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
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)
if self.COMPAT_EXEC_SCRIPTS:
self.load_scripts(self.scripts_dir)
self.dependency_graph = OrderedDict({})
if self.STATEMANAGER_ENABLE:
try:
self.statemanager = stateManager()
self.statemanager.read_saved_state()
@@ -129,6 +133,8 @@ class ifupdownMain(ifupdownBase):
# 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 """
@@ -240,6 +246,8 @@ class ifupdownMain(ifupdownBase):
def get_iface_refcnt(self, ifacename):
max = 0
ifaceobjs = self.get_ifaceobjs(ifacename)
if not ifaceobjs:
return 0
for i in ifaceobjs:
if i.get_refcnt() > max:
max = i.get_refcnt()
@@ -335,6 +343,29 @@ class ifupdownMain(ifupdownBase):
""" Gets iface dependents by calling into respective modules """
dlist = None
# Get dependents for interface by querying respective modules
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
return dlist
def query_dependents_old(self, ifaceobj, ops):
""" Gets iface dependents by calling into respective modules """
dlist = None
# Get dependents for interface by querying respective modules
for op in ops:
for mname in self.module_ops.get(op):
@@ -357,6 +388,7 @@ class ifupdownMain(ifupdownBase):
def populate_dependency_info(self, ifacenames, ops):
""" recursive function to generate iface dependency info """
if not ifacenames:
ifacenames = self.ifaceobjdict.keys()
self.logger.debug('populating dependency info for %s' %str(ifacenames))
@@ -549,16 +581,20 @@ class ifupdownMain(ifupdownBase):
else ifaceSchedulerFlags.POSTORDER,
followdependents=False)
def _pretty_print_ordered_dict(self, argdict):
for k, vlist in argdict.items():
self.logger.info('%s : %s' %(k, str(vlist)))
def run_with_dependents(self, ops, ifacenames):
ret = 0
self.logger.debug('running \'%s\' with dependents for %s'
%(str(ops), str(ifacenames)))
if ifacenames is None:
if not ifacenames:
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,
@@ -645,11 +681,21 @@ class ifupdownMain(ifupdownBase):
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:
@@ -679,7 +725,7 @@ class ifupdownMain(ifupdownBase):
self.populate_dependency_info(filtered_ifacenames, ops)
if printdependency is not None:
if printdependency:
self.print_dependency(filtered_ifacenames, printdependency)
return
@@ -688,29 +734,23 @@ class ifupdownMain(ifupdownBase):
else:
self.run_without_dependents(ops, filtered_ifacenames)
if self.DRYRUN:
if self.DRYRUN and self.ADDONS_ENABLE:
return
# Update persistant iface states
try:
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))
self.save_state()
def down(self, ops, auto=False, allow_classes=None, ifacenames=None,
excludepats=None, printdependency=None):
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():
if self.STATEMANAGER_ENABLE and self.statemanager.get_ifaceobjdict():
# Since we are using state manager objects,
# skip the updating of state manager objects
self.UPDATE_STATEMANAGER = False
self.STATEMANAGER_UPDATE = False
self.read_old_iface_config()
else:
# If no old state available
@@ -743,23 +783,17 @@ class ifupdownMain(ifupdownBase):
self.run_with_dependents(ops, filtered_ifacenames)
else:
self.run_without_dependents(ops, filtered_ifacenames)
if self.DRYRUN:
if self.DRYRUN and self.ADDONS_ENABLE:
return
# Update persistant iface states
try:
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))
self.save_state()
def query(self, ops, auto=False, allow_classes=None, ifacenames=None,
excludepats=None, printdependency=None,
format='native'):
self.UPDATE_STATEMANAGER = False
self.STATEMANAGER_UPDATE = False
if auto:
self.logger.debug('setting flag ALL')
self.ALL = True
@@ -821,15 +855,12 @@ class ifupdownMain(ifupdownBase):
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
@@ -837,7 +868,7 @@ class ifupdownMain(ifupdownBase):
try:
# Read the current interface config
self.read_iface_config()
except Exception, e:
except:
raise
# generate dependency graph of interfaces
@@ -847,25 +878,23 @@ class ifupdownMain(ifupdownBase):
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.UPDATE_STATEMANAGER = False
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
@@ -876,23 +905,19 @@ class ifupdownMain(ifupdownBase):
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]
@@ -901,37 +926,26 @@ class ifupdownMain(ifupdownBase):
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))
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:
@@ -940,17 +954,7 @@ class ifupdownMain(ifupdownBase):
self.run_without_dependents(upops, filtered_ifacenames)
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 """

View File

@@ -51,6 +51,8 @@ class ifaceScheduler():
if not addr_method or (addr_method and addr_method != 'manual'):
handler(ifupdownobj, ifaceobj)
if not ifupdownobj.ADDONS_ENABLE: return
for mname in ifupdownobj.module_ops.get(op):
m = ifupdownobj.modules.get(mname)
err = 0
@@ -151,7 +153,7 @@ class ifaceScheduler():
# Run lowerifaces or dependents
dlist = ifaceobj.get_lowerifaces()
if dlist:
ifupdownobj.logger.info('%s:' %ifacename +
ifupdownobj.logger.debug('%s:' %ifacename +
' found dependents: %s' %str(dlist))
try:
if not followdependents:
@@ -226,7 +228,7 @@ class ifaceScheduler():
"""
run_queue = []
if indegrees is None:
if not indegrees:
indegrees = OrderedDict()
for ifacename in dependency_graph.keys():
indegrees[ifacename] = ifupdownobj.get_iface_refcnt(ifacename)
@@ -241,7 +243,7 @@ class ifaceScheduler():
if not indegrees.get(ifacename):
run_queue.append(ifacename)
ifupdownobj.logger.info('graph roots (interfaces that dont have '
ifupdownobj.logger.debug('graph roots (interfaces that dont have '
'dependents):' + ' %s' %str(run_queue))
return cls.run_iface_list(ifupdownobj, run_queue, ops,

View File

@@ -26,8 +26,15 @@ def run_up(args):
perfmode=args.perfmode,
njobs=args.jobs,
dryrun=args.noact,
cache=cachearg)
cache=cachearg,
addons_enable=not args.noaddons,
statemanager_enable=not args.noaddons)
if args.noaddons:
ifupdown_handle.up(['up'], args.all, args.CLASS, iflist,
excludepats=args.excludepats,
printdependency=args.printdependency)
else:
ifupdown_handle.up(['pre-up', 'up', 'post-up'],
args.all, args.CLASS, iflist,
excludepats=args.excludepats,
@@ -49,7 +56,9 @@ def run_down(args):
perfmode=args.perfmode,
njobs=args.jobs,
dryrun=args.noact,
cache=cachearg)
cache=cachearg,
addons_enable=not args.noaddons,
statemanager_enable=not args.noaddons)
ifupdown_handle.down(['pre-down', 'down', 'post-down'],
args.all, args.CLASS, iflist,
@@ -96,7 +105,6 @@ def run_query(args):
except:
raise
def run_reload(args):
logger.debug('args = %s' %str(args))
@@ -108,7 +116,9 @@ def run_reload(args):
perfmode=args.perfmode,
njobs=args.jobs,
cache=cachearg)
ifupdown_handle.reload(args.all, None, None,
ifupdown_handle.reload(['pre-up', 'up', 'post-up'],
['pre-down', 'down', 'post-down'],
args.all, None, None,
excludepats=args.excludepats,
downchangediface=args.downchangediface)
except:
@@ -178,6 +188,10 @@ def update_ifupdown_argparser(argparser):
argparser.add_argument('--print-dependency',
dest='printdependency', choices=['list', 'dot'],
help='print iface dependency')
argparser.add_argument('--no-scripts', '--no-addons',
dest='noaddons', action='store_true',
help='dont run any addon modules or scripts. Runs only link ' +
'up/down')
def update_ifup_argparser(argparser):
update_ifupdown_argparser(argparser)