mirror of
https://github.com/CumulusNetworks/ifupdown2.git
synced 2024-05-06 15:54:50 +00:00
A few state manager optimizations + and some other fixes
Ticket: CM-1438 Reviewed By: Testing Done: This also fixes a bug with address handling: - If the user changed a primary address, flush all the addresses and re-add them. Previously, if user added a new primary address, it would ust get appended to the end of the address list as a secondary address.
This commit is contained in:
23
pkg/iface.py
23
pkg/iface.py
@@ -107,7 +107,6 @@ class ifaceState():
|
|||||||
elif state_str == 'query-running':
|
elif state_str == 'query-running':
|
||||||
return cls.QUERY_RUNNING
|
return cls.QUERY_RUNNING
|
||||||
|
|
||||||
|
|
||||||
class ifaceJsonEncoder(json.JSONEncoder):
|
class ifaceJsonEncoder(json.JSONEncoder):
|
||||||
def default(self, o):
|
def default(self, o):
|
||||||
retconfig = {}
|
retconfig = {}
|
||||||
@@ -139,7 +138,6 @@ class iface():
|
|||||||
self.config_status = {}
|
self.config_status = {}
|
||||||
self.state = ifaceState.NEW
|
self.state = ifaceState.NEW
|
||||||
self.status = ifaceStatus.UNKNOWN
|
self.status = ifaceStatus.UNKNOWN
|
||||||
self.errstr = ''
|
|
||||||
self.flags = 0x0
|
self.flags = 0x0
|
||||||
self.priv_flags = 0x0
|
self.priv_flags = 0x0
|
||||||
self.refcnt = 0
|
self.refcnt = 0
|
||||||
@@ -148,7 +146,6 @@ class iface():
|
|||||||
self.auto = False
|
self.auto = False
|
||||||
self.classes = []
|
self.classes = []
|
||||||
self.env = None
|
self.env = None
|
||||||
self.config_current = {}
|
|
||||||
self.raw_lines = []
|
self.raw_lines = []
|
||||||
self.linkstate = None
|
self.linkstate = None
|
||||||
|
|
||||||
@@ -199,12 +196,6 @@ class iface():
|
|||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def set_config_current(self, config_current):
|
|
||||||
self.config_current = config_current
|
|
||||||
|
|
||||||
def get_config_current(self):
|
|
||||||
return self.config_current
|
|
||||||
|
|
||||||
def get_auto(self):
|
def get_auto(self):
|
||||||
return self.auto
|
return self.auto
|
||||||
|
|
||||||
@@ -228,7 +219,6 @@ class iface():
|
|||||||
def belongs_to_class(self, intfclass):
|
def belongs_to_class(self, intfclass):
|
||||||
if intfclass in self.classes:
|
if intfclass in self.classes:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def set_priv_flags(self, priv_flags):
|
def set_priv_flags(self, priv_flags):
|
||||||
@@ -393,15 +383,28 @@ class iface():
|
|||||||
del odict['status']
|
del odict['status']
|
||||||
del odict['lowerifaces']
|
del odict['lowerifaces']
|
||||||
del odict['refcnt']
|
del odict['refcnt']
|
||||||
|
del odict['config_status']
|
||||||
|
del odict['flags']
|
||||||
|
del odict['priv_flags']
|
||||||
|
del odict['upperifaces']
|
||||||
|
del odict['raw_lines']
|
||||||
|
del odict['linkstate']
|
||||||
|
del odict['env']
|
||||||
return odict
|
return odict
|
||||||
|
|
||||||
def __setstate__(self, dict):
|
def __setstate__(self, dict):
|
||||||
self.__dict__.update(dict)
|
self.__dict__.update(dict)
|
||||||
|
self.config_status = {}
|
||||||
self.state = ifaceState.NEW
|
self.state = ifaceState.NEW
|
||||||
self.status = ifaceStatus.UNKNOWN
|
self.status = ifaceStatus.UNKNOWN
|
||||||
self.refcnt = 0
|
self.refcnt = 0
|
||||||
|
self.flags = 0
|
||||||
self.lowerifaces = None
|
self.lowerifaces = None
|
||||||
|
self.upperifaces = None
|
||||||
self.linkstate = None
|
self.linkstate = None
|
||||||
|
self.env = None
|
||||||
|
self.priv_flags = 0
|
||||||
|
self.raw_lines = []
|
||||||
self.flags |= self.PICKLED
|
self.flags |= self.PICKLED
|
||||||
|
|
||||||
def dump_raw(self, logger):
|
def dump_raw(self, logger):
|
||||||
|
@@ -94,6 +94,9 @@ class ifupdownMain(ifupdownBase):
|
|||||||
('down', run_down)])
|
('down', run_down)])
|
||||||
|
|
||||||
def run_sched_ifaceobj_posthook(self, ifaceobj):
|
def run_sched_ifaceobj_posthook(self, ifaceobj):
|
||||||
|
if ((ifaceobj.priv_flags & self.BUILTIN) or
|
||||||
|
(ifaceobj.priv_flags & self.NOCONFIG)):
|
||||||
|
return
|
||||||
if self.STATEMANAGER_UPDATE:
|
if self.STATEMANAGER_UPDATE:
|
||||||
self.statemanager.ifaceobj_sync(ifaceobj)
|
self.statemanager.ifaceobj_sync(ifaceobj)
|
||||||
|
|
||||||
@@ -365,30 +368,6 @@ class ifupdownMain(ifupdownBase):
|
|||||||
break
|
break
|
||||||
return dlist
|
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):
|
|
||||||
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,
|
|
||||||
self.ifaceobjdict.keys())
|
|
||||||
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, ifacenames, ops):
|
||||||
""" recursive function to generate iface dependency info """
|
""" recursive function to generate iface dependency info """
|
||||||
|
|
||||||
@@ -744,22 +723,23 @@ class ifupdownMain(ifupdownBase):
|
|||||||
self.save_state()
|
self.save_state()
|
||||||
|
|
||||||
def down(self, ops, auto=False, allow_classes=None, ifacenames=None,
|
def down(self, ops, auto=False, allow_classes=None, ifacenames=None,
|
||||||
excludepats=None, printdependency=None):
|
excludepats=None, printdependency=None, usecurrentconfig=False):
|
||||||
if self.ADDONS_ENABLE: self.STATEMANAGER_UPDATE = False
|
if self.ADDONS_ENABLE: self.STATEMANAGER_UPDATE = False
|
||||||
if auto:
|
if auto:
|
||||||
self.ALL = True
|
self.ALL = True
|
||||||
self.WITH_DEPENDS = True
|
self.WITH_DEPENDS = True
|
||||||
# for down we need to look at old state
|
# For down we need to look at old state, unless usecurrentconfig
|
||||||
self.logger.debug('Looking at old state ..')
|
# is set
|
||||||
if self.STATEMANAGER_ENABLE and self.statemanager.get_ifaceobjdict():
|
if (not usecurrentconfig and self.STATEMANAGER_ENABLE and
|
||||||
|
self.statemanager.get_ifaceobjdict()):
|
||||||
# Since we are using state manager objects,
|
# Since we are using state manager objects,
|
||||||
# skip the updating of state manager objects
|
# skip the updating of state manager objects
|
||||||
self.STATEMANAGER_UPDATE = False
|
self.STATEMANAGER_UPDATE = False
|
||||||
|
self.logger.debug('Looking at old state ..')
|
||||||
self.read_old_iface_config()
|
self.read_old_iface_config()
|
||||||
else:
|
else:
|
||||||
# If no old state available
|
# If no old state available
|
||||||
self.logger.info('old state not available. ' +
|
self.logger.info('Loading current iface config file')
|
||||||
'Loading current iface config file')
|
|
||||||
try:
|
try:
|
||||||
self.read_iface_config()
|
self.read_iface_config()
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
@@ -796,6 +776,8 @@ class ifupdownMain(ifupdownBase):
|
|||||||
def query(self, ops, auto=False, allow_classes=None, ifacenames=None,
|
def query(self, ops, auto=False, allow_classes=None, ifacenames=None,
|
||||||
excludepats=None, printdependency=None,
|
excludepats=None, printdependency=None,
|
||||||
format='native'):
|
format='native'):
|
||||||
|
if self.STATEMANAGER_ENABLE and ops[0] == 'query-savedstate':
|
||||||
|
return self.statemanager.dump_pretty(ifacenames)
|
||||||
|
|
||||||
self.STATEMANAGER_UPDATE = False
|
self.STATEMANAGER_UPDATE = False
|
||||||
if auto:
|
if auto:
|
||||||
|
@@ -12,6 +12,7 @@ import logging
|
|||||||
import os
|
import os
|
||||||
from iface import *
|
from iface import *
|
||||||
import copy
|
import copy
|
||||||
|
import marshal
|
||||||
|
|
||||||
class pickling():
|
class pickling():
|
||||||
|
|
||||||
@@ -20,14 +21,14 @@ class pickling():
|
|||||||
try:
|
try:
|
||||||
with open(filename, 'w') as f:
|
with open(filename, 'w') as f:
|
||||||
for obj in list_of_objects:
|
for obj in list_of_objects:
|
||||||
cPickle.dump(obj, f)
|
cPickle.dump(obj, f, cPickle.HIGHEST_PROTOCOL)
|
||||||
except:
|
except:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def save_obj(cls, f, obj):
|
def save_obj(cls, f, obj):
|
||||||
try:
|
try:
|
||||||
cPickle.dump(obj, f)
|
cPickle.dump(obj, f, cPickle.HIGHEST_PROTOCOL)
|
||||||
except:
|
except:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
@@ -53,10 +54,8 @@ class stateManager():
|
|||||||
self.state_file = self.state_dir + self.state_filename
|
self.state_file = self.state_dir + self.state_filename
|
||||||
|
|
||||||
def save_ifaceobj(self, ifaceobj):
|
def save_ifaceobj(self, ifaceobj):
|
||||||
if self.ifaceobjdict.get(ifaceobj.get_name()) is None:
|
self.ifaceobjdict.setdefault(ifaceobj.get_name(),
|
||||||
self.ifaceobjdict[ifaceobj.get_name()] = [ifaceobj]
|
[]).append(ifaceobj)
|
||||||
else:
|
|
||||||
self.ifaceobjdict[ifaceobj.get_name()].append(ifaceobj)
|
|
||||||
|
|
||||||
def read_saved_state(self, filename=None):
|
def read_saved_state(self, filename=None):
|
||||||
pickle_filename = filename
|
pickle_filename = filename
|
||||||
@@ -75,6 +74,9 @@ class stateManager():
|
|||||||
def get_ifaceobjdict(self):
|
def get_ifaceobjdict(self):
|
||||||
return self.ifaceobjdict
|
return self.ifaceobjdict
|
||||||
|
|
||||||
|
def get_ifaceobjs(self, ifacename):
|
||||||
|
return self.ifaceobjdict.get(ifacename)
|
||||||
|
|
||||||
def compare_iface_state(ifaceobj1, ifaceobj2):
|
def compare_iface_state(ifaceobj1, ifaceobj2):
|
||||||
ifaceobj1_state = ifaceobj1.get_state()
|
ifaceobj1_state = ifaceobj1.get_state()
|
||||||
ifaceobj2_state = ifaceobj2.get_state()
|
ifaceobj2_state = ifaceobj2.get_state()
|
||||||
@@ -154,28 +156,18 @@ class stateManager():
|
|||||||
except:
|
except:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def print_state(self, ifaceobj, prefix, indent):
|
def dump_pretty(self, ifacenames, format='native'):
|
||||||
print (indent + '%s' %prefix +
|
if not ifacenames:
|
||||||
'%s' %ifaceobj.get_state_str() +
|
ifacenames = self.ifaceobjdict.keys()
|
||||||
', %s' %ifaceobj.get_status_str())
|
for i in ifacenames:
|
||||||
|
ifaceobjs = self.get_ifaceobjs(i)
|
||||||
def print_state_pretty(self, ifacenames, logger):
|
if not ifaceobjs:
|
||||||
for ifacename in ifacenames:
|
continue
|
||||||
old_ifaceobjs = self.ifaceobjdict.get(ifacename)
|
for ifaceobj in ifaceobjs:
|
||||||
if old_ifaceobjs is not None:
|
if format == 'json':
|
||||||
firstifaceobj = old_ifaceobjs[0]
|
ifaceobj.dump_json()
|
||||||
self.print_state(firstifaceobj,
|
else:
|
||||||
'%s: ' %firstifaceobj.get_name(), '')
|
ifaceobj.dump_pretty()
|
||||||
|
|
||||||
def print_state_detailed_pretty(self, ifacenames, logger):
|
|
||||||
indent = '\t'
|
|
||||||
for ifacename in ifacenames:
|
|
||||||
old_ifaceobjs = self.ifaceobjdict.get(ifacename)
|
|
||||||
if old_ifaceobjs is not None:
|
|
||||||
for i in old_ifaceobjs:
|
|
||||||
i.dump_pretty(logger)
|
|
||||||
self.print_state(i, '', indent)
|
|
||||||
print '\n'
|
|
||||||
|
|
||||||
def dump(self, ifacenames=None):
|
def dump(self, ifacenames=None):
|
||||||
self.logger.debug('statemanager iface state:')
|
self.logger.debug('statemanager iface state:')
|
||||||
|
@@ -63,7 +63,8 @@ def run_down(args):
|
|||||||
ifupdown_handle.down(['pre-down', 'down', 'post-down'],
|
ifupdown_handle.down(['pre-down', 'down', 'post-down'],
|
||||||
args.all, args.CLASS, iflist,
|
args.all, args.CLASS, iflist,
|
||||||
excludepats=args.excludepats,
|
excludepats=args.excludepats,
|
||||||
printdependency=args.printdependency)
|
printdependency=args.printdependency,
|
||||||
|
usecurrentconfig=args.usecurrentconfig)
|
||||||
except:
|
except:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
@@ -85,9 +86,10 @@ def run_query(args):
|
|||||||
qop = 'query-syntax'
|
qop = 'query-syntax'
|
||||||
elif args.printdependency:
|
elif args.printdependency:
|
||||||
qop = 'query-dependency'
|
qop = 'query-dependency'
|
||||||
|
elif args.printsavedstate:
|
||||||
|
qop = 'query-savedstate'
|
||||||
else:
|
else:
|
||||||
qop='query'
|
qop='query'
|
||||||
|
|
||||||
cachearg=(False if (iflist or args.nocache or
|
cachearg=(False if (iflist or args.nocache or
|
||||||
args.perfmode or args.syntaxhelp or
|
args.perfmode or args.syntaxhelp or
|
||||||
(qop != 'query-checkcurr' and
|
(qop != 'query-checkcurr' and
|
||||||
@@ -182,13 +184,14 @@ def update_ifupdown_argparser(argparser):
|
|||||||
argparser.add_argument('-f', '--force', dest='force',
|
argparser.add_argument('-f', '--force', dest='force',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help='force run all operations')
|
help='force run all operations')
|
||||||
argparser.add_argument('-n', '--no-act', dest='noact',
|
group = argparser.add_mutually_exclusive_group(required=False)
|
||||||
|
group.add_argument('-n', '--no-act', dest='noact',
|
||||||
action='store_true', help='print out what would happen,' +
|
action='store_true', help='print out what would happen,' +
|
||||||
'but don\'t do it')
|
'but don\'t do it')
|
||||||
argparser.add_argument('--print-dependency',
|
group.add_argument('--print-dependency',
|
||||||
dest='printdependency', choices=['list', 'dot'],
|
dest='printdependency', choices=['list', 'dot'],
|
||||||
help='print iface dependency')
|
help='print iface dependency')
|
||||||
argparser.add_argument('--no-scripts', '--no-addons',
|
group.add_argument('--no-scripts', '--no-addons',
|
||||||
dest='noaddons', action='store_true',
|
dest='noaddons', action='store_true',
|
||||||
help='dont run any addon modules or scripts. Runs only link ' +
|
help='dont run any addon modules or scripts. Runs only link ' +
|
||||||
'up/down')
|
'up/down')
|
||||||
@@ -198,6 +201,14 @@ def update_ifup_argparser(argparser):
|
|||||||
|
|
||||||
def update_ifdown_argparser(argparser):
|
def update_ifdown_argparser(argparser):
|
||||||
update_ifupdown_argparser(argparser)
|
update_ifupdown_argparser(argparser)
|
||||||
|
argparser.add_argument('--use-current-config',
|
||||||
|
dest='usecurrentconfig', action='store_true',
|
||||||
|
help=argparse.SUPPRESS)
|
||||||
|
#help='By default ifdown looks at the saved state for ' +
|
||||||
|
#'interfaces to bring down. This option allows ifdown to ' +
|
||||||
|
#'look at the current interfaces file. Useful when your ' +
|
||||||
|
#'state file is corrupted or you want down to use the latest '
|
||||||
|
#'from the interfaces file')
|
||||||
|
|
||||||
def update_ifquery_argparser(argparser):
|
def update_ifquery_argparser(argparser):
|
||||||
""" arg parser for ifquery options """
|
""" arg parser for ifquery options """
|
||||||
@@ -215,6 +226,9 @@ def update_ifquery_argparser(argparser):
|
|||||||
'running state of an interface')
|
'running state of an interface')
|
||||||
group.add_argument('--raw', action='store_true', dest='raw',
|
group.add_argument('--raw', action='store_true', dest='raw',
|
||||||
help='print raw config file entries')
|
help='print raw config file entries')
|
||||||
|
group.add_argument('--print-savedstate', action='store_true',
|
||||||
|
dest='printsavedstate',
|
||||||
|
help=argparse.SUPPRESS)
|
||||||
argparser.add_argument('--format', dest='format', default='native',
|
argparser.add_argument('--format', dest='format', default='native',
|
||||||
choices=['native', 'json'], help=argparse.SUPPRESS)
|
choices=['native', 'json'], help=argparse.SUPPRESS)
|
||||||
argparser.add_argument('--print-dependency',
|
argparser.add_argument('--print-dependency',
|
||||||
|
Reference in New Issue
Block a user