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
):
26 """ ifupdown2 main class """
33 COMPAT_EXEC_SCRIPTS
= False
34 STATEMANAGER_ENABLE
= True
35 STATEMANAGER_UPDATE
= True
38 # priv flags to mark iface objects
42 scripts_dir
='/etc/network'
43 addon_modules_dir
='/usr/share/ifupdownaddons'
44 addon_modules_configfile
='/etc/network/.addons.conf'
46 # iface dictionary in the below format:
47 # { '<ifacename>' : [<ifaceobject1>, <ifaceobject2> ..] }
49 # { 'swp1' : [<iface swp1>, <iface swp2> ..] }
51 # Each ifaceobject corresponds to a configuration block for
53 # The value in the dictionary is a list because the network
54 # interface configuration file supports more than one iface section
55 # in the interfaces file
56 ifaceobjdict
= OrderedDict()
58 # iface dictionary representing the curr running state of an iface
59 # in the below format:
60 # {'<ifacename>' : <ifaceobject>}
61 ifaceobjcurrdict
= OrderedDict()
63 # Dictionary representing operation and modules
65 module_ops
= OrderedDict([('pre-up', []),
68 ('query-checkcurr', []),
69 ('query-running', []),
70 ('query-dependency', []),
77 # For old style /etc/network/ bash scripts
78 script_ops
= OrderedDict([('pre-up', []),
85 # Handlers for ops that ifupdown2 owns
86 def run_up(self
, ifaceobj
):
87 ifacename
= ifaceobj
.name
88 if self
.link_exists(ifacename
):
89 self
.link_up(ifacename
)
91 def run_down(self
, ifaceobj
):
92 ifacename
= ifaceobj
.name
93 if self
.link_exists(ifacename
):
94 self
.link_down(ifacename
)
96 # ifupdown object interface operation handlers
97 ops_handlers
= OrderedDict([('up', run_up
),
100 def run_sched_ifaceobj_posthook(self
, ifaceobj
):
101 if ((ifaceobj
.priv_flags
& self
.BUILTIN
) or
102 (ifaceobj
.priv_flags
& self
.NOCONFIG
)):
104 if self
.STATEMANAGER_UPDATE
:
105 self
.statemanager
.ifaceobj_sync(ifaceobj
)
107 # ifupdown object interface scheduler pre and posthooks
108 sched_hooks
= {'posthook' : run_sched_ifaceobj_posthook
}
110 def __init__(self
, force
=False, dryrun
=False, nowait
=False,
111 perfmode
=False, withdepends
=False, njobs
=1,
112 cache
=False, addons_enable
=True, statemanager_enable
=True):
113 self
.logger
= logging
.getLogger('ifupdown')
117 self
.PERFMODE
= perfmode
118 self
.WITH_DEPENDS
= withdepends
119 self
.STATEMANAGER_ENABLE
= statemanager_enable
122 # Can be used to provide hints for caching
123 self
.CACHE_FLAGS
= 0x0
124 self
._DELETE
_DEPENDENT
_IFACES
_WITH
_NOCONFIG
= False
125 self
.ADDONS_ENABLE
= addons_enable
127 self
.ifaces
= OrderedDict()
129 self
.pp
= pprint
.PrettyPrinter(indent
=4)
130 self
.modules
= OrderedDict({})
131 self
.module_attrs
= {}
133 self
.load_addon_modules(self
.addon_modules_dir
)
134 if self
.COMPAT_EXEC_SCRIPTS
:
135 self
.load_scripts(self
.scripts_dir
)
136 self
.dependency_graph
= OrderedDict({})
138 if self
.STATEMANAGER_ENABLE
:
140 self
.statemanager
= stateManager()
141 self
.statemanager
.read_saved_state()
143 # XXX Maybe we should continue by ignoring old state
144 self
.logger
.warning('error reading state (%s)' %str
(e
))
147 self
.STATEMANAGER_UPDATE
= False
150 def get_ifaceobjs(self
, ifacename
):
151 return self
.ifaceobjdict
.get(ifacename
)
153 def get_ifaceobj_first(self
, ifacename
):
154 ifaceobjs
= self
.get_ifaceobjs(ifacename
)
159 def get_ifacenames(self
):
160 return self
.ifaceobjdict
.keys()
162 def get_iface_obj_last(self
, ifacename
):
163 return self
.ifaceobjdict
.get(ifacename
)[-1]
165 def create_n_save_ifaceobj(self
, ifacename
, priv_flags
=None,
167 """ creates a iface object and adds it to the iface dictionary """
169 ifaceobj
.name
= ifacename
170 ifaceobj
.priv_flags
= priv_flags
173 ifaceobj
.inc_refcnt()
174 self
.ifaceobjdict
[ifacename
] = [ifaceobj
]
177 def create_n_save_ifaceobjcurr(self
, ifaceobj
):
178 """ creates a copy of iface object and adds it to the iface dict containing current iface objects
180 ifaceobjcurr
= self
.get_ifaceobjcurr(ifaceobj
.name
)
183 ifaceobjcurr
= iface()
184 ifaceobjcurr
.name
= ifaceobj
.name
185 ifaceobjcurr
.lowerifaces
= ifaceobj
.lowerifaces
186 ifaceobjcurr
.priv_flags
= ifaceobj
.priv_flags
187 self
.ifaceobjcurrdict
[ifaceobj
.name
] = ifaceobjcurr
190 def get_ifaceobjcurr(self
, ifacename
):
191 return self
.ifaceobjcurrdict
.get(ifacename
)
193 def get_ifaceobjrunning(self
, ifacename
):
194 return self
.ifaceobjrunningdict
.get(ifacename
)
196 def get_iface_refcnt(self
, ifacename
):
197 """ Return iface ref count """
199 ifaceobjs
= self
.get_ifaceobjs(ifacename
)
207 def is_iface_builtin_byname(self
, ifacename
):
208 """ Returns true if iface name is a builtin interface.
210 A builtin interface is an interface which ifupdown understands.
211 The following are currently considered builtin ifaces:
212 - vlan interfaces in the format <ifacename>.<vlanid>
214 return '.' in ifacename
216 def is_ifaceobj_builtin(self
, ifaceobj
):
217 """ Returns true if iface name is a builtin interface.
219 A builtin interface is an interface which ifupdown understands.
220 The following are currently considered builtin ifaces:
221 - vlan interfaces in the format <ifacename>.<vlanid>
223 return (ifaceobj
.priv_flags
& self
.BUILTIN
)
225 def is_ifaceobj_noconfig(self
, ifaceobj
):
226 """ Returns true if iface object did not have a user defined config.
228 These interfaces appear only when they are dependents of interfaces
229 which have user defined config
231 return (ifaceobj
.priv_flags
& self
.NOCONFIG
)
233 def is_iface_noconfig(self
, ifacename
):
234 """ Returns true if iface has no config """
236 ifaceobj
= self
.get_ifaceobj_first(ifacename
)
237 if not ifaceobj
: return True
238 return self
.is_ifaceobj_noconfig(ifaceobj
)
240 def preprocess_dependency_list(self
, upperifacename
, dlist
, ops
):
241 """ We go through the dependency list and
242 delete or add interfaces from the interfaces dict by
243 applying the following rules:
244 if flag _DELETE_DEPENDENT_IFACES_WITH_NOCONFIG is True:
245 we only consider devices whose configuration was
246 specified in the network interfaces file. We delete
247 any interface whose config was not specified except
248 for vlan devices. vlan devices get special treatment.
249 Even if they are not present they are created and added
251 elif flag _DELETE_DEPENDENT_IFACES_WITH_NOCONFIG is False:
252 we create objects for all dependent devices that are not
253 present in the ifacesdict
258 dilist
= self
.get_ifaceobjs(d
)
260 if self
.is_iface_builtin_byname(d
):
261 self
.create_n_save_ifaceobj(d
, self
.BUILTIN | self
.NOCONFIG
,
262 True).add_to_upperifaces(upperifacename
)
263 elif not self
._DELETE
_DEPENDENT
_IFACES
_WITH
_NOCONFIG
:
264 self
.create_n_save_ifaceobj(d
, self
.NOCONFIG
,
265 True).add_to_upperifaces(upperifacename
)
271 di
.add_to_upperifaces(upperifacename
)
276 def query_dependents(self
, ifaceobj
, ops
):
277 """ Gets iface dependents by calling into respective modules """
280 # Get dependents for interface by querying respective modules
281 for mname
, module
in self
.modules
.items():
282 module
= self
.modules
.get(mname
)
283 if ops
[0] == 'query-running':
284 if (not hasattr(module
,
285 'get_dependent_ifacenames_running')):
287 dlist
= module
.get_dependent_ifacenames_running(ifaceobj
)
289 if (not hasattr(module
, 'get_dependent_ifacenames')):
291 dlist
= module
.get_dependent_ifacenames(ifaceobj
,
292 self
.ifaceobjdict
.keys())
294 self
.logger
.debug('%s: ' %ifaceobj
.name
+
295 'got lowerifaces/dependents: %s' %str
(dlist
))
299 def populate_dependency_info(self
, ops
, ifacenames
=None):
300 """ recursive function to generate iface dependency info """
303 ifacenames
= self
.ifaceobjdict
.keys()
305 self
.logger
.debug('populating dependency info for %s' %str
(ifacenames
))
306 iqueue
= deque(ifacenames
)
309 # Go through all modules and find dependent ifaces
311 ifaceobj
= self
.get_ifaceobj_first(i
)
314 dlist
= ifaceobj
.lowerifaces
316 dlist
= self
.query_dependents(ifaceobj
, ops
)
320 self
.preprocess_dependency_list(ifaceobj
.name
,
322 self
.logger
.debug('%s: lowerifaces/dependents after processing: %s'
324 ifaceobj
.lowerifaces
= dlist
325 [iqueue
.append(d
) for d
in dlist
]
326 if not self
.dependency_graph
.get(i
):
327 self
.dependency_graph
[i
] = dlist
329 def _save_iface(self
, ifaceobj
):
330 self
.ifaceobjdict
.setdefault(ifaceobj
.name
,
333 def _module_syntax_checker(self
, attrname
, attrval
):
334 for m
, mdict
in self
.module_attrs
.items():
335 attrsdict
= mdict
.get('attrs')
336 if attrsdict
and attrname
in attrsdict
.keys():
340 def read_default_iface_config(self
):
341 """ Reads default network interface config /etc/network/interfaces. """
342 nifaces
= networkInterfaces()
343 nifaces
.subscribe('iface_found', self
._save
_iface
)
344 nifaces
.subscribe('validate', self
._module
_syntax
_checker
)
347 def read_iface_config(self
):
348 return self
.read_default_iface_config()
350 def read_old_iface_config(self
):
351 """ Reads the saved iface config instead of default iface config. """
352 self
.ifaceobjdict
= self
.statemanager
.ifaceobjdict
354 def _load_addon_modules_config(self
):
355 """ Load addon modules config file """
357 with
open(self
.addon_modules_configfile
, 'r') as f
:
358 lines
= f
.readlines()
360 litems
= l
.rstrip(' \n').split(',')
361 operation
= litems
[0]
363 self
.module_ops
[operation
].append(mname
)
365 def load_addon_modules(self
, modules_dir
):
366 """ load python modules from modules_dir
368 Default modules_dir is /usr/share/ifupdownmodules
371 self
.logger
.info('loading builtin modules from %s' %modules_dir
)
372 self
._load
_addon
_modules
_config
()
373 if not modules_dir
in sys
.path
:
374 sys
.path
.append(modules_dir
)
376 for op
, mlist
in self
.module_ops
.items():
378 if self
.modules
.get(mname
):
380 mpath
= modules_dir
+ '/' + mname
+ '.py'
381 if os
.path
.exists(mpath
):
383 m
= __import__(mname
)
384 mclass
= getattr(m
, mname
)
387 minstance
= mclass(force
=self
.FORCE
,
390 perfmode
=self
.PERFMODE
,
392 cacheflags
=self
.CACHE_FLAGS
)
393 self
.modules
[mname
] = minstance
395 self
.module_attrs
[mname
] = minstance
.get_modinfo()
401 # Assign all modules to query operations
402 self
.module_ops
['query-checkcurr'] = self
.modules
.keys()
403 self
.module_ops
['query-running'] = self
.modules
.keys()
404 self
.module_ops
['query-dependency'] = self
.modules
.keys()
405 self
.module_ops
['query'] = self
.modules
.keys()
406 self
.module_ops
['query-raw'] = self
.modules
.keys()
408 def _modules_help(self
):
409 """ Prints addon modules supported syntax """
412 for m
, mdict
in self
.module_attrs
.items():
415 print('%s: %s' %(m
, mdict
.get('mhelp')))
416 attrdict
= mdict
.get('attrs')
420 for attrname
, attrvaldict
in attrdict
.items():
421 if attrvaldict
.get('compat', False):
423 print('%s%s' %(indent
, attrname
))
424 print('%shelp: %s' %(indent
+ ' ',
425 attrvaldict
.get('help', '')))
426 print ('%srequired: %s' %(indent
+ ' ',
427 attrvaldict
.get('required', False)))
428 default
= attrvaldict
.get('default')
430 print('%sdefault: %s' %(indent
+ ' ', default
))
432 validrange
= attrvaldict
.get('validrange')
434 print('%svalidrange: %s'
435 %(indent
+ ' ', '-'.join(validrange
)))
437 validvals
= attrvaldict
.get('validvals')
439 print('%svalidvals: %s'
440 %(indent
+ ' ', ','.join(validvals
)))
442 examples
= attrvaldict
.get('example')
446 print '%sexample:' %(indent
+ ' ')
448 print '%s%s' %(indent
+ ' ', e
)
453 def load_scripts(self
, modules_dir
):
454 """ loading user modules from /etc/network/.
456 Note that previously loaded python modules override modules found
457 under /etc/network if any
461 self
.logger
.info('looking for user scripts under %s' %modules_dir
)
462 for op
, mlist
in self
.script_ops
.items():
463 msubdir
= modules_dir
+ '/if-%s.d' %op
464 self
.logger
.info('loading scripts under %s ...' %msubdir
)
466 module_list
= os
.listdir(msubdir
)
467 for module
in module_list
:
468 if self
.modules
.get(module
) is not None:
470 self
.script_ops
[op
].append(
471 msubdir
+ '/' + module
)
476 def _sched_ifaces(self
, ifacenames
, ops
):
477 self
.logger
.debug('scheduling \'%s\' for %s'
478 %(str(ops
), str(ifacenames
)))
480 self
.logger
.debug('dependency graph:')
481 self
._pretty
_print
_ordered
_dict
(self
.dependency_graph
)
483 return ifaceScheduler
.sched_ifaces(self
, ifacenames
, ops
,
484 dependency_graph
=self
.dependency_graph
,
485 order
=ifaceSchedulerFlags
.INORDER
487 else ifaceSchedulerFlags
.POSTORDER
,
488 followdependents
=True if self
.WITH_DEPENDS
else False)
490 def _validate_ifaces(self
, ifacenames
):
491 """ validates interface list for config existance.
493 returns -1 if one or more interface not found. else, returns 0
498 ifaceobjs
= self
.get_ifaceobjs(i
)
502 self
.logger
.error('could not find interfaces: %s' %err_iface
)
506 def _iface_whitelisted(self
, auto
, allow_classes
, excludepats
, ifacename
):
507 """ Checks if interface is whitelisted depending on set of parameters.
509 interfaces are checked against the allow_classes and auto lists.
514 for e
in excludepats
:
515 if re
.search(e
, ifacename
):
517 ifaceobjs
= self
.get_ifaceobjs(ifacename
)
519 self
.logger
.debug('iface %s' %ifacename
+ ' not found')
521 # We check classes first
525 common
= Set([allow_classes
]).intersection(
537 def _compat_conv_op_to_mode(self
, op
):
538 """ Returns old op name to work with existing scripts """
541 elif op
== 'pre-down':
546 def generate_running_env(self
, ifaceobj
, op
):
547 """ Generates a dictionary with env variables required for
548 an interface. Used to support script execution for interfaces.
552 iface_env
= ifaceobj
.env
556 cenv
.update(iface_env
)
559 cenv
['MODE'] = self
._compat
_conv
_op
_to
_mode
(op
)
562 def _save_state(self
):
563 if not self
.STATEMANAGER_ENABLE
or not self
.STATEMANAGER_UPDATE
:
566 # Update persistant iface states
567 self
.statemanager
.save_state()
569 if self
.logger
.isEnabledFor(logging
.DEBUG
):
570 t
= sys
.exc_info()[2]
571 traceback
.print_tb(t
)
572 self
.logger
.warning('error saving state (%s)' %str
(e
))
574 def up(self
, ops
, auto
=False, allow_classes
=None, ifacenames
=None,
575 excludepats
=None, printdependency
=None):
576 """ up an interface """
580 self
.WITH_DEPENDS
= True
583 self
.read_iface_config()
588 # If iface list is given by the caller, always check if iface
590 if self
._validate
_ifaces
(ifacenames
) != 0:
591 raise Exception('all or some interfaces not found')
593 # if iface list not given by user, assume all from config file
594 if not ifacenames
: ifacenames
= self
.ifaceobjdict
.keys()
596 # filter interfaces based on auto and allow classes
597 filtered_ifacenames
= [i
for i
in ifacenames
598 if self
._iface
_whitelisted
(auto
, allow_classes
,
600 if not filtered_ifacenames
:
601 raise Exception('no ifaces found matching given allow lists')
604 self
.populate_dependency_info(ops
, filtered_ifacenames
)
605 self
.print_dependency(filtered_ifacenames
, printdependency
)
608 self
.populate_dependency_info(ops
)
610 self
._sched
_ifaces
(filtered_ifacenames
, ops
)
612 if self
.DRYRUN
and self
.ADDONS_ENABLE
:
617 def down(self
, ops
, auto
=False, allow_classes
=None, ifacenames
=None,
618 excludepats
=None, printdependency
=None, usecurrentconfig
=False):
619 """ down an interface """
621 if self
.ADDONS_ENABLE
: self
.STATEMANAGER_UPDATE
= False
624 self
.WITH_DEPENDS
= True
625 # For down we need to look at old state, unless usecurrentconfig
627 if (not usecurrentconfig
and self
.STATEMANAGER_ENABLE
and
628 self
.statemanager
.ifaceobjdict
):
629 # Since we are using state manager objects,
630 # skip the updating of state manager objects
631 self
.STATEMANAGER_UPDATE
= False
632 self
.logger
.debug('Looking at old state ..')
633 self
.read_old_iface_config()
635 # If no old state available
636 self
.logger
.info('Loading current iface config file')
638 self
.read_iface_config()
640 raise Exception('error reading iface config (%s)' %str
(e
))
642 # If iface list is given by the caller, always check if iface
644 if self
._validate
_ifaces
(ifacenames
) != 0:
645 raise Exception('all or some interfaces were never up')
646 # if iface list not given by user, assume all from config file
647 if not ifacenames
: ifacenames
= self
.ifaceobjdict
.keys()
649 # filter interfaces based on auto and allow classes
650 filtered_ifacenames
= [i
for i
in ifacenames
651 if self
._iface
_whitelisted
(auto
, allow_classes
,
653 if not filtered_ifacenames
:
654 raise Exception('no ifaces found matching given allow lists')
657 self
.populate_dependency_info(ops
, filtered_ifacenames
)
658 self
.print_dependency(filtered_ifacenames
, printdependency
)
661 self
.populate_dependency_info(ops
)
663 self
._sched
_ifaces
(filtered_ifacenames
, ops
)
664 if self
.DRYRUN
and self
.ADDONS_ENABLE
:
669 def query(self
, ops
, auto
=False, allow_classes
=None, ifacenames
=None,
670 excludepats
=None, printdependency
=None,
672 """ query an interface """
674 if self
.STATEMANAGER_ENABLE
and ops
[0] == 'query-savedstate':
675 return self
.statemanager
.dump_pretty(ifacenames
)
677 self
.STATEMANAGER_UPDATE
= False
679 self
.logger
.debug('setting flag ALL')
681 self
.WITH_DEPENDS
= True
683 if ops
[0] == 'query-syntax':
686 elif ops
[0] == 'query-running':
687 # create fake devices to all dependents that dont have config
688 map(lambda i
: self
.create_n_save_ifaceobj(i
, self
.NOCONFIG
),
692 self
.read_iface_config()
696 if ifacenames
and ops
[0] != 'query-running':
697 # If iface list is given, always check if iface is present
698 if self
._validate
_ifaces
(ifacenames
) != 0:
699 raise Exception('all or some interfaces not found')
701 # if iface list not given by user, assume all from config file
702 if not ifacenames
: ifacenames
= self
.ifaceobjdict
.keys()
704 # filter interfaces based on auto and allow classes
705 if ops
[0] == 'query-running':
706 filtered_ifacenames
= ifacenames
708 filtered_ifacenames
= [i
for i
in ifacenames
709 if self
._iface
_whitelisted
(auto
, allow_classes
,
711 if not filtered_ifacenames
:
712 raise Exception('no ifaces found matching ' +
715 if ops
[0] == 'query-dependency' and printdependency
:
716 self
.populate_dependency_info(ops
, filtered_ifacenames
)
717 self
.print_dependency(filtered_ifacenames
, printdependency
)
720 self
.populate_dependency_info(ops
)
722 if ops
[0] == 'query':
723 return self
.print_ifaceobjs_pretty(filtered_ifacenames
, format
)
724 elif ops
[0] == 'query-raw':
725 return self
.print_ifaceobjs_raw(filtered_ifacenames
)
727 self
._sched
_ifaces
(filtered_ifacenames
, ops
)
729 if ops
[0] == 'query-checkcurr':
730 ret
= self
.print_ifaceobjscurr_pretty(filtered_ifacenames
, format
)
732 # if any of the object has an error, signal that silently
734 elif ops
[0] == 'query-running':
735 self
.print_ifaceobjsrunning_pretty(filtered_ifacenames
, format
)
738 def reload(self
, upops
, downops
, auto
=False, allow
=None,
739 ifacenames
=None, excludepats
=None, downchangediface
=False):
740 """ reload interface config """
744 self
.logger
.debug('reloading interface config ..')
747 self
.WITH_DEPENDS
= True
750 # Read the current interface config
751 self
.read_iface_config()
755 # generate dependency graph of interfaces
756 self
.populate_dependency_info(upops
)
758 # Save a copy of new iface objects and dependency_graph
759 new_ifaceobjdict
= dict(self
.ifaceobjdict
)
760 new_dependency_graph
= dict(self
.dependency_graph
)
762 if self
.STATEMANAGER_ENABLE
and self
.statemanager
.ifaceobjdict
:
763 # if old state is present, read old state and mark op for 'down'
764 # followed by 'up' aka: reload
765 # old interface config is read into self.ifaceobjdict
767 self
.STATEMANAGER_UPDATE
= False
768 self
.read_old_iface_config()
771 # oldconfig not available, continue with 'up' with new config
774 if not ifacenames
: ifacenames
= self
.ifaceobjdict
.keys()
775 if op
== 'reload' and ifacenames
:
776 filtered_ifacenames
= [i
for i
in ifacenames
777 if self
._iface
_whitelisted
(auto
, allow_classes
,
779 # Generate the interface down list
780 # Interfaces that go into the down list:
781 # - interfaces that were present in last config and are not
782 # present in the new config
783 # - interfaces that were changed between the last and current
787 for ifname
, lastifaceobjlist
in self
.ifaceobjdict
.items():
789 # If interface is not present in the new file
790 # append it to the down list
791 newifaceobjlist
= new_ifaceobjdict
.get(ifname
)
792 if not newifaceobjlist
:
793 ifacedownlist
.append(ifname
)
795 if not downchangediface
:
797 # If interface has changed between the current file
798 # and the last installed append it to the down list
799 if len(newifaceobjlist
) != len(lastifaceobjlist
):
800 ifacedownlist
.append(ifname
)
802 # compare object list
803 for objidx
in range(0, len(lastifaceobjlist
)):
804 oldobj
= lastifaceobjlist
[objidx
]
805 newobj
= newifaceobjlist
[objidx
]
806 if not newobj
.compare(oldobj
):
807 ifacedownlist
.append(ifname
)
811 self
.logger
.info('Executing down on interfaces: %s'
813 # reinitialize dependency graph
814 self
.dependency_graph
= OrderedDict({})
815 # Generate dependency info for old config
816 self
.populate_dependency_info(downops
)
817 self
._sched
_ifaces
(ifacedownlist
, downops
)
819 self
.logger
.debug('no interfaces to down ..')
821 # Now, run 'up' with new config dict
822 # reset statemanager update flag to default
823 self
.STATEMANAGER_UPDATE
= True
824 self
.ifaceobjdict
= new_ifaceobjdict
825 self
.dependency_graph
= new_dependency_graph
826 ifacenames
= self
.ifaceobjdict
.keys()
827 filtered_ifacenames
= [i
for i
in ifacenames
828 if self
._iface
_whitelisted
(auto
, allow_classes
,
831 self
.logger
.info('Scheduling up on interfaces: %s'
832 %str
(filtered_ifacenames
))
833 self
._sched
_ifaces
(filtered_ifacenames
, upops
)
839 def _pretty_print_ordered_dict(self
, argdict
):
840 for k
, vlist
in argdict
.items():
841 self
.logger
.debug('%s : %s' %(k
, str(vlist
)))
843 def print_dependency(self
, ifacenames
, format
):
844 """ prints iface dependency information """
847 ifacenames
= self
.ifaceobjdict
.keys()
849 for k
,v
in self
.dependency_graph
.items():
850 print '%s : %s' %(k
, str(v
))
851 elif format
== 'dot':
853 map(lambda i
: indegrees
.update({i
:
854 self
.get_iface_refcnt(i
)}),
855 self
.dependency_graph
.keys())
856 graph
.generate_dots(self
.dependency_graph
, indegrees
)
858 def print_ifaceobjs_raw(self
, ifacenames
):
859 """ prints raw lines for ifaces from config file """
862 for ifaceobj
in self
.get_ifaceobjs(i
):
863 if (self
.is_ifaceobj_builtin(ifaceobj
) or
864 not ifaceobj
.is_config_present()):
866 ifaceobj
.dump_raw(self
.logger
)
868 if self
.WITH_DEPENDS
:
869 dlist
= ifaceobj
.lowerifaces
870 if not dlist
: continue
871 self
.print_ifaceobjs_raw(dlist
)
873 def print_ifaceobjs_pretty(self
, ifacenames
, format
='native'):
874 """ pretty prints iface in format given by keyword arg format """
877 for ifaceobj
in self
.get_ifaceobjs(i
):
878 if (self
.is_ifaceobj_noconfig(ifaceobj
)):
883 ifaceobj
.dump_pretty()
884 if self
.WITH_DEPENDS
:
885 dlist
= ifaceobj
.lowerifaces
886 if not dlist
: continue
887 self
.print_ifaceobjs_pretty(dlist
, format
)
889 def print_ifaceobjscurr_pretty(self
, ifacenames
, format
='native'):
890 """ pretty prints current running state of interfaces with status.
892 returns 1 if any of the interface has an error,
898 ifaceobj
= self
.get_ifaceobjcurr(i
)
899 if not ifaceobj
: continue
900 if ifaceobj
.status
== ifaceStatus
.NOTFOUND
:
901 print 'iface %s (%s)\n' %(ifaceobj
.name
,
902 ifaceStatus
.to_str(ifaceStatus
.NOTFOUND
))
905 elif ifaceobj
.status
== ifaceStatus
.ERROR
:
907 if (self
.is_ifaceobj_noconfig(ifaceobj
)):
910 ifaceobj
.dump_json(with_status
=True)
912 ifaceobj
.dump_pretty(with_status
=True)
913 if self
.WITH_DEPENDS
:
914 dlist
= ifaceobj
.lowerifaces
915 if not dlist
: continue
916 self
.print_ifaceobjscurr_pretty(dlist
, format
)
919 def print_ifaceobjsrunning_pretty(self
, ifacenames
, format
='native'):
920 """ pretty prints iface running state """
923 ifaceobj
= self
.get_ifaceobj_first(i
)
924 if ifaceobj
.status
== ifaceStatus
.NOTFOUND
:
925 print 'iface %s' %ifaceobj
.name
+ ' (not found)\n'
927 if not ifaceobj
.is_config_present():
932 ifaceobj
.dump_pretty()
933 if self
.WITH_DEPENDS
:
934 dlist
= ifaceobj
.lowerifaces
935 if not dlist
: continue
936 self
.print_ifaceobjsrunning_pretty(dlist
, format
)
940 print 'ifupdown main object dump'
941 print self
.pp
.pprint(self
.modules
)
942 print self
.pp
.pprint(self
.ifaceobjdict
)
944 def _dump_ifaceobjs(self
, ifacenames
):
946 ifaceobjs
= self
.get_ifaceobjs(i
)