3 # Copyright 2013. Cumulus Networks, Inc.
4 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
16 from statemanager
import *
17 from networkinterfaces
import *
19 from scheduler
import *
20 from collections
import deque
21 from collections
import OrderedDict
25 class ifupdownMain(ifupdownBase
):
31 COMPAT_EXEC_SCRIPTS
= False
32 UPDATE_STATEMANAGER
= True
34 # priv flags to mark iface objects
38 scripts_dir
='/etc/network'
39 addon_modules_dir
='/usr/share/ifupdownaddons'
40 addon_modules_configfile
='/etc/network/.addons.conf'
42 # iface dictionary in the below format:
43 # { '<ifacename>' : [<ifaceobject1>, <ifaceobject2> ..] }
45 # { 'swp1' : [<ifaceobject1>, <ifaceobject2> ..] }
47 # Each ifaceobject corresponds to a configuration block for
49 ifaceobjdict
= OrderedDict()
52 # iface dictionary representing the curr running state of an iface
53 # in the below format:
54 # {'<ifacename>' : <ifaceobject>}
55 ifaceobjcurrdict
= OrderedDict()
57 # Dictionary representing operation and modules
59 module_ops
= OrderedDict([('pre-up', []),
62 ('query-checkcurr', []),
63 ('query-running', []),
64 ('query-dependency', []),
71 # For old style /etc/network/ bash scripts
72 script_ops
= OrderedDict([('pre-up', []),
79 # Handlers for ops that ifupdown2 owns
80 def run_up(self
, ifaceobj
):
81 ifacename
= ifaceobj
.get_name()
82 if self
.link_exists(ifacename
):
83 self
.link_up(ifacename
)
85 def run_down(self
, ifaceobj
):
86 ifacename
= ifaceobj
.get_name()
87 if self
.link_exists(ifacename
):
88 self
.link_down(ifacename
)
90 # ifupdown object interface operation handlers
91 ops_handlers
= OrderedDict([('up', run_up
),
95 def run_sched_ifaceobj_posthook(self
, ifaceobj
):
96 if self
.UPDATE_STATEMANAGER
:
97 self
.statemanager
.ifaceobj_sync(ifaceobj
)
99 # ifupdown object interface scheduler pre and posthooks
100 sched_hooks
= {'posthook' : run_sched_ifaceobj_posthook
}
102 def __init__(self
, force
=False, dryrun
=False, nowait
=False,
103 perfmode
=False, withdepends
=False, njobs
=1,
105 self
.logger
= logging
.getLogger('ifupdown')
110 self
.PERFMODE
= perfmode
111 self
.WITH_DEPENDS
= withdepends
113 self
._DELETE
_DEPENDENT
_IFACES
_WITH
_NOCONFIG
= False
115 self
.ifaces
= OrderedDict()
117 self
.pp
= pprint
.PrettyPrinter(indent
=4)
118 self
.modules
= OrderedDict({})
119 self
.module_attrs
= {}
120 self
.load_addon_modules(self
.addon_modules_dir
)
121 if self
.COMPAT_EXEC_SCRIPTS
:
122 self
.load_scripts(self
.scripts_dir
)
123 self
.dependency_graph
= OrderedDict({})
126 self
.statemanager
= stateManager()
127 self
.statemanager
.read_saved_state()
129 # XXX Maybe we should continue by ignoring old state
130 self
.logger
.warning('error reading state (%s)' %str
(e
))
133 def get_subops(self
, op
):
134 """ Returns sub-operation list """
135 return self
.module_ops
.get(op
).keys()
137 def compat_conv_op_to_mode(self
, op
):
138 """ Returns old op name to work with existing scripts """
141 elif op
== 'pre-down':
146 def set_force(self
, force
):
147 """ Set force flag. """
151 """ return force flag. """
154 def set_dryrun(self
, dryrun
):
157 def get_dryrun(self
):
163 def get_ifaceobjdict(self
):
164 return self
.ifaceobjdict
166 def set_ifaceobjdict(self
, ifaceobjdict
):
167 self
.ifaceobjdict
= ifaceobjdict
169 def set_dependency_graph(self
, dependency_graph
):
170 self
.dependency_graph
= dependency_graph
172 def get_dependency_graph(self
):
173 return self
.dependency_graph
175 def set_perfmode(self
, perfmode
):
176 self
.PERFMODE
= perfmode
178 def get_perfmode(self
):
181 def set_nowait(self
, nowait
):
184 def get_nowait(self
):
187 def set_njobs(self
, njobs
):
188 self
.logger
.debug('setting njobs to %d' %njobs
)
194 def get_withdepends(self
):
195 return self
.WITH_DEPENDS
197 def set_withdepends(self
, withdepends
):
198 self
.logger
.debug('setting withdepends to true')
199 self
.WITH_DEPENDS
= withdepends
201 def get_ifaceobjs(self
, ifacename
):
202 return self
.ifaceobjdict
.get(ifacename
)
204 def get_ifaceobj_first(self
, ifacename
):
205 ifaceobjs
= self
.get_ifaceobjs(ifacename
)
210 def get_iface_obj_last(self
, ifacename
):
211 return self
.ifaceobjdict
.get(ifacename
)[-1]
213 def create_n_save_ifaceobjcurr(self
, ifaceobj
):
214 ifacename
= ifaceobj
.get_name()
215 ifaceobjcurr
= self
.get_ifaceobjcurr(ifacename
)
219 ifaceobjcurr
= iface()
220 ifaceobjcurr
.set_name(ifacename
)
221 ifaceobjcurr
.set_lowerifaces(ifaceobj
.get_lowerifaces())
222 ifaceobjcurr
.set_priv_flags(ifaceobj
.get_priv_flags())
223 self
.ifaceobjcurrdict
[ifacename
] = ifaceobjcurr
227 def get_ifaceobjcurr(self
, ifacename
):
228 return self
.ifaceobjcurrdict
.get(ifacename
)
230 def get_ifaceobjrunning(self
, ifacename
):
231 return self
.ifaceobjrunningdict
.get(ifacename
)
233 def get_iface_status(self
, ifacename
):
234 ifaceobjs
= self
.get_ifaceobjs(ifacename
)
236 if i
.get_status() != ifaceStatus
.SUCCESS
:
237 return i
.get_status()
238 return ifaceStatus
.SUCCESS
240 def get_iface_refcnt(self
, ifacename
):
242 ifaceobjs
= self
.get_ifaceobjs(ifacename
)
244 if i
.get_refcnt() > max:
248 def create_n_save_ifaceobj(self
, ifacename
, priv_flags
=None,
250 """ creates and returns a fake vlan iface object.
251 This was added to support creation of simple vlan
252 devices without any user specified configuration.
255 ifaceobj
.set_name(ifacename
)
256 ifaceobj
.priv_flags
= priv_flags
259 ifaceobj
.inc_refcnt()
260 self
.ifaceobjdict
[ifacename
] = [ifaceobj
]
264 def is_iface_builtin_byname(self
, ifacename
):
265 """ Returns true if iface name is a builtin interface.
267 A builtin interface is an interface which ifupdown understands.
268 The following are currently considered builtin ifaces:
269 - vlan interfaces in the format <ifacename>.<vlanid>
271 return '.' in ifacename
273 def is_ifaceobj_builtin(self
, ifaceobj
):
274 """ Returns true if iface name is a builtin interface.
276 A builtin interface is an interface which ifupdown understands.
277 The following are currently considered builtin ifaces:
278 - vlan interfaces in the format <ifacename>.<vlanid>
280 return (ifaceobj
.priv_flags
& self
.BUILTIN
)
282 def is_ifaceobj_noconfig(self
, ifaceobj
):
283 """ Returns true if iface name did not have a user defined config.
285 These interfaces appear only when they are dependents of interfaces
286 which have user defined config
288 return (ifaceobj
.priv_flags
& self
.NOCONFIG
)
290 def is_iface_noconfig(self
, ifacename
):
291 """ Returns true if iface has no config """
293 ifaceobj
= self
.get_ifaceobj_first(ifacename
)
294 if not ifaceobj
: return True
296 return self
.is_ifaceobj_noconfig(ifaceobj
)
298 def preprocess_dependency_list(self
, upperifacename
, dlist
, ops
):
299 """ We go through the dependency list and
300 delete or add interfaces from the interfaces dict by
301 applying the following rules:
302 if flag _DELETE_DEPENDENT_IFACES_WITH_NOCONFIG is True:
303 we only consider devices whose configuration was
304 specified in the network interfaces file. We delete
305 any interface whose config was not specified except
306 for vlan devices. vlan devices get special treatment.
307 Even if they are not present they are created and added
309 elif flag _DELETE_DEPENDENT_IFACES_WITH_NOCONFIG is False:
310 we create objects for all dependent devices that are not
311 present in the ifacesdict
316 dilist
= self
.get_ifaceobjs(d
)
318 if self
.is_iface_builtin_byname(d
):
319 self
.create_n_save_ifaceobj(d
, self
.BUILTIN | self
.NOCONFIG
,
320 True).add_to_upperifaces(upperifacename
)
321 elif not self
._DELETE
_DEPENDENT
_IFACES
_WITH
_NOCONFIG
:
322 self
.create_n_save_ifaceobj(d
, self
.NOCONFIG
,
323 True).add_to_upperifaces(upperifacename
)
329 di
.add_to_upperifaces(upperifacename
)
334 def query_dependents(self
, ifaceobj
, ops
):
335 """ Gets iface dependents by calling into respective modules """
338 # Get dependents for interface by querying respective modules
340 for mname
in self
.module_ops
.get(op
):
341 module
= self
.modules
.get(mname
)
342 if op
== 'query-running':
344 'get_dependent_ifacenames_running') == False):
346 dlist
= module
.get_dependent_ifacenames_running(ifaceobj
)
348 if (hasattr(module
, 'get_dependent_ifacenames') == False):
350 dlist
= module
.get_dependent_ifacenames(ifaceobj
,
351 self
.ifaceobjdict
.keys())
353 self
.logger
.debug('%s: ' %ifaceobj
.get_name() +
354 'got lowerifaces/dependents: %s' %str
(dlist
))
358 def populate_dependency_info(self
, ifacenames
, ops
):
359 """ recursive function to generate iface dependency info """
361 ifacenames
= self
.ifaceobjdict
.keys()
362 self
.logger
.debug('populating dependency info for %s' %str
(ifacenames
))
363 iqueue
= deque(ifacenames
)
366 # Go through all modules and find dependent ifaces
368 ifaceobj
= self
.get_ifaceobj_first(i
)
371 dlist
= ifaceobj
.get_lowerifaces()
373 dlist
= self
.query_dependents(ifaceobj
, ops
)
377 self
.preprocess_dependency_list(ifaceobj
.get_name(),
379 self
.logger
.debug('%s: lowerifaces/dependents after processing: %s'
381 ifaceobj
.set_lowerifaces(dlist
)
382 [iqueue
.append(d
) for d
in dlist
]
383 if not self
.dependency_graph
.get(i
):
384 self
.dependency_graph
[i
] = dlist
386 def _save_iface(self
, ifaceobj
):
387 if not self
.ifaceobjdict
.get(ifaceobj
.get_name()):
388 self
.ifaceobjdict
[ifaceobj
.get_name()] = [ifaceobj
]
390 self
.ifaceobjdict
[ifaceobj
.get_name()].append(ifaceobj
)
392 def _module_syntax_checker(self
, attrname
, attrval
):
393 for m
, mdict
in self
.module_attrs
.items():
394 attrsdict
= mdict
.get('attrs')
395 if attrsdict
and attrname
in attrsdict
.keys(): return True
398 def read_default_iface_config(self
):
399 """ Reads default network interface config /etc/network/interfaces. """
400 nifaces
= networkInterfaces()
401 nifaces
.subscribe('iface_found', self
._save
_iface
)
402 nifaces
.subscribe('validate', self
._module
_syntax
_checker
)
405 def read_iface_config(self
):
406 return self
.read_default_iface_config()
408 def read_old_iface_config(self
):
409 """ Reads the saved iface config instead of default iface config. """
411 # Read it from the statemanager
412 self
.ifaceobjdict
= self
.statemanager
.get_ifaceobjdict()
414 def load_addon_modules_config(self
):
415 with
open(self
.addon_modules_configfile
, 'r') as f
:
416 lines
= f
.readlines()
418 litems
= l
.rstrip(' \n').split(',')
419 operation
= litems
[0]
421 self
.module_ops
[operation
].append(mname
)
423 def load_addon_modules(self
, modules_dir
):
424 """ load python modules from modules_dir
426 Default modules_dir is /usr/share/ifupdownmodules
429 self
.logger
.info('loading builtin modules from %s' %modules_dir
)
430 self
.load_addon_modules_config()
431 if not modules_dir
in sys
.path
:
432 sys
.path
.append(modules_dir
)
434 for op
, mlist
in self
.module_ops
.items():
436 if self
.modules
.get(mname
) is not None:
438 mpath
= modules_dir
+ '/' + mname
+ '.py'
439 if os
.path
.exists(mpath
):
441 m
= __import__(mname
)
442 mclass
= getattr(m
, mname
)
445 minstance
= mclass(force
=self
.FORCE
,
448 perfmode
=self
.PERFMODE
,
450 self
.modules
[mname
] = minstance
451 if hasattr(minstance
, 'get_modinfo'):
452 self
.module_attrs
[mname
] = minstance
.get_modinfo()
456 # Assign all modules to query operations
457 self
.module_ops
['query-checkcurr'] = self
.modules
.keys()
458 self
.module_ops
['query-running'] = self
.modules
.keys()
459 self
.module_ops
['query-dependency'] = self
.modules
.keys()
460 self
.module_ops
['query'] = self
.modules
.keys()
461 self
.module_ops
['query-raw'] = self
.modules
.keys()
463 def modules_help(self
):
465 for m
, mdict
in self
.module_attrs
.items():
468 print('%s: %s' %(m
, mdict
.get('mhelp')))
469 attrdict
= mdict
.get('attrs')
473 for attrname
, attrvaldict
in attrdict
.items():
474 if attrvaldict
.get('compat', False):
476 print('%s%s' %(indent
, attrname
))
477 print('%shelp: %s' %(indent
+ ' ',
478 attrvaldict
.get('help', '')))
479 print ('%srequired: %s' %(indent
+ ' ',
480 attrvaldict
.get('required', False)))
481 default
= attrvaldict
.get('default')
483 print('%sdefault: %s' %(indent
+ ' ', default
))
485 validrange
= attrvaldict
.get('validrange')
487 print('%svalidrange: %s'
488 %(indent
+ ' ', '-'.join(validrange
)))
490 validvals
= attrvaldict
.get('validvals')
492 print('%svalidvals: %s'
493 %(indent
+ ' ', ','.join(validvals
)))
495 examples
= attrvaldict
.get('example')
499 print '%sexample:' %(indent
+ ' ')
501 print '%s%s' %(indent
+ ' ', e
)
506 def load_scripts(self
, modules_dir
):
507 """ loading user modules from /etc/network/.
509 Note that previously loaded python modules override modules found
510 under /etc/network if any
514 self
.logger
.info('looking for user scripts under %s' %modules_dir
)
515 for op
, mlist
in self
.script_ops
.items():
516 msubdir
= modules_dir
+ '/if-%s.d' %op
517 self
.logger
.info('loading scripts under %s ...' %msubdir
)
519 module_list
= os
.listdir(msubdir
)
520 for module
in module_list
:
521 if self
.modules
.get(module
) is not None:
523 self
.script_ops
[op
].append(
524 msubdir
+ '/' + module
)
529 def conv_iface_namelist_to_objlist(self
, intf_list
):
530 for intf
in intf_list
:
531 iface_obj
= self
.get_iface(intf
)
533 raise ifupdownInvalidValue('no iface %s', intf
)
534 iface_objs
.append(iface_obj
)
538 def run_without_dependents(self
, ops
, ifacenames
):
539 """ Run interface list without their dependents """
541 raise ifupdownInvalidValue('no interfaces found')
543 self
.logger
.debug('run_without_dependents for ops %s for %s'
544 %(str(ops
), str(ifacenames
)))
546 ifaceScheduler
.run_iface_list(self
, ifacenames
, ops
, parent
=None,
547 order
=ifaceSchedulerFlags
.INORDER
549 else ifaceSchedulerFlags
.POSTORDER
,
550 followdependents
=False)
552 def run_with_dependents(self
, ops
, ifacenames
):
554 self
.logger
.debug('running \'%s\' with dependents for %s'
555 %(str(ops
), str(ifacenames
)))
557 if ifacenames
is None:
558 ifacenames
= self
.ifaceobjdict
.keys()
560 self
.logger
.info('dependency graph:')
561 self
.logger
.info(self
.pp
.pformat(self
.dependency_graph
))
564 ret
= ifaceScheduler
.run_iface_dependency_graph_parallel(self
,
565 self
.dependency_graph
, ops
)
567 ret
= ifaceScheduler
.run_iface_dependency_graphs(self
,
568 self
.dependency_graph
, ops
,
569 order
=ifaceSchedulerFlags
.INORDER
571 else ifaceSchedulerFlags
.POSTORDER
)
574 def print_dependency(self
, ifacenames
, format
):
575 if ifacenames
is None:
576 ifacenames
= self
.ifaceobjdict
.keys()
579 for k
,v
in self
.dependency_graph
.items():
580 print '%s : %s' %(k
, str(v
))
581 elif format
== 'dot':
583 map(lambda i
: indegrees
.update({i
:
584 self
.get_iface_refcnt(i
)}),
585 self
.dependency_graph
.keys())
586 graph
.generate_dots(self
.dependency_graph
, indegrees
)
588 def validate_ifaces(self
, ifacenames
):
589 """ validates interface list for config existance.
591 returns -1 if one or more interface not found. else, returns 0
596 ifaceobjs
= self
.get_ifaceobjs(i
)
600 self
.logger
.error('could not find interfaces: %s' %err_iface
)
604 def iface_whitelisted(self
, auto
, allow_classes
, excludepats
, ifacename
):
605 """ Checks if interface is whitelisted depending on set of parameters.
607 interfaces are checked against the allow_classes and auto lists.
610 # If the interface matches
612 for e
in excludepats
:
613 if re
.search(e
, ifacename
):
615 ifaceobjs
= self
.get_ifaceobjs(ifacename
)
617 self
.logger
.debug('iface %s' %ifacename
+ ' not found')
619 # We check classes first
623 common
= Set([allow_classes
]).intersection(
624 Set(i
.get_classes()))
635 def generate_running_env(self
, ifaceobj
, op
):
636 """ Generates a dictionary with env variables required for
637 an interface. Used to support script execution for interfaces.
641 iface_env
= ifaceobj
.get_env()
642 if iface_env
is not None:
645 cenv
.update(iface_env
)
649 cenv
['MODE'] = self
.compat_conv_op_to_mode(op
)
653 def up(self
, ops
, auto
=False, allow_classes
=None, ifacenames
=None,
654 excludepats
=None, printdependency
=None):
657 self
.WITH_DEPENDS
= True
660 self
.read_iface_config()
665 # If iface list is given by the caller, always check if iface
667 if self
.validate_ifaces(ifacenames
) != 0:
668 raise Exception('all or some interfaces not found')
670 # if iface list not given by user, assume all from config file
671 if not ifacenames
: ifacenames
= self
.ifaceobjdict
.keys()
673 # filter interfaces based on auto and allow classes
674 filtered_ifacenames
= [i
for i
in ifacenames
675 if self
.iface_whitelisted(auto
, allow_classes
,
677 if not filtered_ifacenames
:
678 raise Exception('no ifaces found matching given allow lists')
680 self
.populate_dependency_info(filtered_ifacenames
, ops
)
682 if printdependency
is not None:
683 self
.print_dependency(filtered_ifacenames
, printdependency
)
686 if self
.WITH_DEPENDS
:
687 self
.run_with_dependents(ops
, filtered_ifacenames
)
689 self
.run_without_dependents(ops
, filtered_ifacenames
)
694 # Update persistant iface states
696 self
.statemanager
.save_state()
698 if self
.logger
.isEnabledFor(logging
.DEBUG
):
699 t
= sys
.exc_info()[2]
700 traceback
.print_tb(t
)
701 self
.logger
.warning('error saving state (%s)' %str
(e
))
703 def down(self
, ops
, auto
=False, allow_classes
=None, ifacenames
=None,
704 excludepats
=None, printdependency
=None):
707 self
.WITH_DEPENDS
= True
708 # for down we need to look at old state
709 self
.logger
.debug('Looking at old state ..')
710 if self
.statemanager
.get_ifaceobjdict():
711 # Since we are using state manager objects,
712 # skip the updating of state manager objects
713 self
.UPDATE_STATEMANAGER
= False
714 self
.read_old_iface_config()
716 # If no old state available
717 self
.logger
.info('old state not available. ' +
718 'Loading current iface config file')
720 self
.read_iface_config()
722 raise Exception('error reading iface config (%s)' %str
(e
))
724 # If iface list is given by the caller, always check if iface
726 if self
.validate_ifaces(ifacenames
) != 0:
727 raise Exception('all or some interfaces not found')
728 # if iface list not given by user, assume all from config file
729 if not ifacenames
: ifacenames
= self
.ifaceobjdict
.keys()
730 # filter interfaces based on auto and allow classes
731 filtered_ifacenames
= [i
for i
in ifacenames
732 if self
.iface_whitelisted(auto
, allow_classes
,
734 if not filtered_ifacenames
:
735 raise Exception('no ifaces found matching given allow lists')
737 self
.populate_dependency_info(filtered_ifacenames
, ops
)
739 self
.print_dependency(filtered_ifacenames
, printdependency
)
742 if self
.WITH_DEPENDS
:
743 self
.run_with_dependents(ops
, filtered_ifacenames
)
745 self
.run_without_dependents(ops
, filtered_ifacenames
)
749 # Update persistant iface states
751 self
.statemanager
.save_state()
753 if self
.logger
.isEnabledFor(logging
.DEBUG
):
754 t
= sys
.exc_info()[2]
755 traceback
.print_tb(t
)
756 self
.logger
.warning('error saving state (%s)' %str
(e
))
758 def query(self
, ops
, auto
=False, allow_classes
=None, ifacenames
=None,
759 excludepats
=None, printdependency
=None,
762 self
.UPDATE_STATEMANAGER
= False
764 self
.logger
.debug('setting flag ALL')
766 self
.WITH_DEPENDS
= True
768 if ops
[0] == 'query-syntax':
771 elif ops
[0] == 'query-running':
772 # create fake devices to all dependents that dont have config
773 map(lambda i
: self
.create_n_save_ifaceobj(i
, self
.NOCONFIG
),
777 self
.read_iface_config()
781 if ifacenames
is not None and ops
[0] != 'query-running':
782 # If iface list is given, always check if iface is present
783 if self
.validate_ifaces(ifacenames
) != 0:
784 raise Exception('all or some interfaces not found')
786 # if iface list not given by user, assume all from config file
787 if not ifacenames
: ifacenames
= self
.ifaceobjdict
.keys()
789 # filter interfaces based on auto and allow classes
790 if ops
[0] == 'query-running':
791 filtered_ifacenames
= ifacenames
793 filtered_ifacenames
= [i
for i
in ifacenames
794 if self
.iface_whitelisted(auto
, allow_classes
,
796 if not filtered_ifacenames
:
797 raise Exception('no ifaces found matching ' +
800 self
.populate_dependency_info(filtered_ifacenames
, ops
)
801 if ops
[0] == 'query-dependency' and printdependency
:
802 self
.print_dependency(filtered_ifacenames
, printdependency
)
805 if ops
[0] == 'query':
806 return self
.print_ifaceobjs_pretty(filtered_ifacenames
, format
)
807 elif ops
[0] == 'query-raw':
808 return self
.print_ifaceobjs_raw(filtered_ifacenames
)
810 if self
.WITH_DEPENDS
:
811 self
.run_with_dependents(ops
, filtered_ifacenames
)
813 self
.run_without_dependents(ops
, filtered_ifacenames
)
815 if ops
[0] == 'query-checkcurr':
816 ret
= self
.print_ifaceobjscurr_pretty(filtered_ifacenames
, format
)
818 # if any of the object has an error, signal that silently
820 elif ops
[0] == 'query-running':
821 self
.print_ifaceobjsrunning_pretty(filtered_ifacenames
, format
)
824 def reload(self
, auto
=False, allow
=None,
825 ifacenames
=None, excludepats
=None, downchangediface
=False):
826 """ main ifupdown run method """
828 upops
= ['pre-up', 'up', 'post-up']
829 downops
= ['pre-down', 'down', 'post-down']
831 self
.logger
.debug('reloading interface config ..')
835 self
.WITH_DEPENDS
= True
838 # Read the current interface config
839 self
.read_iface_config()
843 # generate dependency graph of interfaces
844 self
.populate_dependency_info(ifacenames
, upops
)
846 # Save a copy of new iface objects and dependency_graph
847 new_ifaceobjdict
= dict(self
.get_ifaceobjdict())
848 new_dependency_graph
= dict(self
.get_dependency_graph())
850 if self
.statemanager
.get_ifaceobjdict():
851 # if old state is present, read old state and mark op for 'down'
852 # followed by 'up' aka: reload
853 # old interface config is read into self.ifaceobjdict
855 self
.UPDATE_STATEMANAGER
= False
856 self
.read_old_iface_config()
859 # oldconfig not available, continue with 'up' with new config
862 if ifacenames
is None: ifacenames
= self
.ifaceobjdict
.keys()
864 if op
== 'reload' and ifacenames
:
865 filtered_ifacenames
= [i
for i
in ifacenames
866 if self
.iface_whitelisted(auto
, allow_classes
,
869 # Generate the interface down list
870 # Interfaces that go into the down list:
871 # - interfaces that were present in last config and are not
872 # present in the new config
873 # - interfaces that were changed between the last and current
877 for ifname
, lastifobjlist
in self
.ifaceobjdict
.items():
880 # If interface is not present in the new file
881 # append it to the down list
882 newifobjlist
= new_ifaceobjdict
.get(ifname
)
883 if newifobjlist
== None:
884 ifacedownlist
.append(ifname
)
887 if downchangediface
== False:
890 # If interface has changed between the current file
891 # and the last installed append it to the down list
892 if len(newifobjlist
) != len(lastifobjlist
):
893 ifacedownlist
.append(ifname
)
896 # compare object list
897 for objidx
in range(0, len(lastifobjlist
)):
898 oldobj
= lastifobjlist
[objidx
]
899 newobj
= newifobjlist
[objidx
]
900 if newobj
.is_different(oldobj
):
901 ifacedownlist
.append(ifname
)
906 self
.logger
.info('Executing down on interfaces: %s'
908 # Generate dependency info for old config
909 self
.populate_dependency_info(ifacedownlist
, downops
)
910 self
.run_with_dependents(downops
, ifacedownlist
)
912 # Update persistant iface states
915 self
.statemanager
.flush_state(self
.ifaceobjdict
)
917 self
.statemanager
.flush_state()
919 if self
.logger
.isEnabledFor(logging
.DEBUG
):
920 t
= sys
.exc_info()[2]
921 traceback
.print_tb(t
)
922 self
.logger
.warning('error saving state (%s)' %str
(e
))
924 self
.logger
.debug('no interfaces to down ..')
926 # Now, run up with new config dict
927 self
.set_ifaceobjdict(new_ifaceobjdict
)
928 self
.set_dependency_graph(new_dependency_graph
)
930 ifacenames
= self
.ifaceobjdict
.keys()
931 filtered_ifacenames
= [i
for i
in ifacenames
932 if self
.iface_whitelisted(auto
, allow_classes
,
935 self
.logger
.info('Executing up on interfaces: %s'
936 %str
(filtered_ifacenames
))
937 if self
.WITH_DEPENDS
:
938 self
.run_with_dependents(upops
, filtered_ifacenames
)
940 self
.run_without_dependents(upops
, filtered_ifacenames
)
943 # Update persistant iface states
946 self
.statemanager
.flush_state(self
.get_ifaceobjdict())
948 self
.statemanager
.flush_state()
950 if self
.logger
.isEnabledFor(logging
.DEBUG
):
951 t
= sys
.exc_info()[2]
952 traceback
.print_tb(t
)
953 self
.logger
.warning('error saving state (%s)' %str
(e
))
956 """ all state dump """
958 print 'ifupdown object dump'
959 print self
.pp
.pprint(self
.modules
)
960 print self
.pp
.pprint(self
.ifaces
)
961 self
.state_manager
.dump()
963 def print_state(self
, ifacenames
=None):
964 self
.statemanager
.dump(ifacenames
)
966 def print_ifaceobjs_raw(self
, ifacenames
):
968 for ifaceobj
in self
.get_ifaceobjs(i
):
969 if (self
.is_ifaceobj_builtin(ifaceobj
) or
970 not ifaceobj
.is_config_present()):
972 ifaceobj
.dump_raw(self
.logger
)
974 if self
.WITH_DEPENDS
:
975 dlist
= ifaceobj
.get_lowerifaces()
976 if not dlist
: continue
977 self
.print_ifaceobjs_pretty(dlist
, format
)
979 def print_ifaceobjs_pretty(self
, ifacenames
, format
='native'):
981 for ifaceobj
in self
.get_ifaceobjs(i
):
982 if (self
.is_ifaceobj_noconfig(ifaceobj
)):
987 ifaceobj
.dump_pretty()
988 if self
.WITH_DEPENDS
:
989 dlist
= ifaceobj
.get_lowerifaces()
990 if not dlist
: continue
991 self
.print_ifaceobjs_pretty(dlist
, format
)
993 def dump_ifaceobjs(self
, ifacenames
):
995 ifaceobjs
= self
.get_ifaceobjs(i
)
1000 def print_ifaceobjscurr_pretty(self
, ifacenames
, format
='native'):
1001 """ Dumps current running state of interfaces.
1003 returns 1 if any of the interface has an error,
1007 for i
in ifacenames
:
1008 ifaceobj
= self
.get_ifaceobjcurr(i
)
1009 if not ifaceobj
: continue
1010 if ifaceobj
.get_status() == ifaceStatus
.NOTFOUND
:
1011 print 'iface %s %s\n' %(ifaceobj
.get_name(),
1012 ifaceStatus
.to_str(ifaceStatus
.NOTFOUND
))
1015 elif ifaceobj
.get_status() == ifaceStatus
.ERROR
:
1018 if (self
.is_ifaceobj_noconfig(ifaceobj
)):
1021 if format
== 'json':
1022 ifaceobj
.dump_json(with_status
=True)
1024 ifaceobj
.dump_pretty(with_status
=True)
1026 if self
.WITH_DEPENDS
:
1027 dlist
= ifaceobj
.get_lowerifaces()
1028 if not dlist
: continue
1029 self
.print_ifaceobjscurr_pretty(dlist
, format
)
1032 def print_ifaceobjsrunning_pretty(self
, ifacenames
, format
='native'):
1033 for i
in ifacenames
:
1034 ifaceobj
= self
.get_ifaceobj_first(i
)
1035 if ifaceobj
.get_status() == ifaceStatus
.NOTFOUND
:
1036 print 'iface %s' %ifaceobj
.get_name() + ' (not found)\n'
1038 if not ifaceobj
.is_config_present():
1040 if format
== 'json':
1041 ifaceobj
.dump_json()
1043 ifaceobj
.dump_pretty()
1044 if self
.WITH_DEPENDS
:
1045 dlist
= ifaceobj
.get_lowerifaces()
1046 if not dlist
: continue
1047 self
.print_ifaceobjsrunning_pretty(dlist
, format
)