3 # Copyright 2013. Cumulus Networks, Inc.
4 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
18 from statemanager
import *
19 from networkinterfaces
import *
21 from scheduler
import *
22 from collections
import deque
23 from collections
import OrderedDict
28 _crossmark
= u
'\u2717'
29 _success_sym
= _tickmark
30 _error_sym
= _crossmark
32 class ifupdownMain(ifupdownBase
):
33 """ ifupdown2 main class """
38 COMPAT_EXEC_SCRIPTS
= False
39 STATEMANAGER_ENABLE
= True
40 STATEMANAGER_UPDATE
= True
43 # priv flags to mark iface objects
47 scripts_dir
='/etc/network'
48 addon_modules_dir
='/usr/share/ifupdownaddons'
49 addon_modules_configfile
='/var/lib/ifupdownaddons/addons.conf'
51 # iface dictionary in the below format:
52 # { '<ifacename>' : [<ifaceobject1>, <ifaceobject2> ..] }
54 # { 'swp1' : [<iface swp1>, <iface swp2> ..] }
56 # Each ifaceobject corresponds to a configuration block for
58 # The value in the dictionary is a list because the network
59 # interface configuration file supports more than one iface section
60 # in the interfaces file
61 ifaceobjdict
= OrderedDict()
63 # iface dictionary representing the curr running state of an iface
64 # in the below format:
65 # {'<ifacename>' : <ifaceobject>}
66 ifaceobjcurrdict
= OrderedDict()
68 # Dictionary representing operation and modules
70 module_ops
= OrderedDict([('pre-up', []),
73 ('query-checkcurr', []),
74 ('query-running', []),
75 ('query-dependency', []),
82 # For old style /etc/network/ bash scripts
83 script_ops
= OrderedDict([('pre-up', []),
90 # Handlers for ops that ifupdown2 owns
91 def run_up(self
, ifaceobj
):
92 ifacename
= ifaceobj
.name
93 if self
.link_exists(ifacename
):
94 self
.link_up(ifacename
)
96 def run_down(self
, ifaceobj
):
97 ifacename
= ifaceobj
.name
98 if self
.link_exists(ifacename
):
99 self
.link_down(ifacename
)
101 # ifupdown object interface operation handlers
102 ops_handlers
= OrderedDict([('up', run_up
),
105 def run_sched_ifaceobj_posthook(self
, ifaceobj
, op
):
106 if ((ifaceobj
.priv_flags
& self
.BUILTIN
) or
107 (ifaceobj
.priv_flags
& self
.NOCONFIG
)):
109 if self
.STATEMANAGER_UPDATE
:
110 self
.statemanager
.ifaceobj_sync(ifaceobj
, op
)
112 # ifupdown object interface scheduler pre and posthooks
113 sched_hooks
= {'posthook' : run_sched_ifaceobj_posthook
}
115 def __init__(self
, config
={},
116 force
=False, dryrun
=False, nowait
=False,
117 perfmode
=False, withdepends
=False, njobs
=1,
118 cache
=False, addons_enable
=True, statemanager_enable
=True,
119 interfacesfile
='/etc/network/interfaces',
120 interfacesfileiobuf
=None,
121 interfacesfileformat
='native'):
122 self
.logger
= logging
.getLogger('ifupdown')
126 self
.PERFMODE
= perfmode
127 self
.WITH_DEPENDS
= withdepends
128 self
.STATEMANAGER_ENABLE
= statemanager_enable
130 self
.interfacesfile
= interfacesfile
131 self
.interfacesfileiobuf
= interfacesfileiobuf
132 self
.interfacesfileformat
= interfacesfileformat
134 self
.logger
.debug(self
.config
)
136 # Can be used to provide hints for caching
137 self
.CACHE_FLAGS
= 0x0
138 self
._DELETE
_DEPENDENT
_IFACES
_WITH
_NOCONFIG
= False
139 self
.ADDONS_ENABLE
= addons_enable
141 self
.ifaces
= OrderedDict()
143 self
.pp
= pprint
.PrettyPrinter(indent
=4)
144 self
.modules
= OrderedDict({})
145 self
.module_attrs
= {}
147 self
.load_addon_modules(self
.addon_modules_dir
)
148 if self
.COMPAT_EXEC_SCRIPTS
:
149 self
.load_scripts(self
.scripts_dir
)
150 self
.dependency_graph
= OrderedDict({})
152 if self
.STATEMANAGER_ENABLE
:
154 self
.statemanager
= stateManager()
155 self
.statemanager
.read_saved_state()
157 # XXX Maybe we should continue by ignoring old state
158 self
.logger
.warning('error reading state (%s)' %str
(e
))
161 self
.STATEMANAGER_UPDATE
= False
163 def get_ifaceobjs(self
, ifacename
):
164 return self
.ifaceobjdict
.get(ifacename
)
166 def get_ifaceobj_first(self
, ifacename
):
167 ifaceobjs
= self
.get_ifaceobjs(ifacename
)
172 def get_ifacenames(self
):
173 return self
.ifaceobjdict
.keys()
175 def get_iface_obj_last(self
, ifacename
):
176 return self
.ifaceobjdict
.get(ifacename
)[-1]
178 def create_n_save_ifaceobj(self
, ifacename
, priv_flags
=None,
180 """ creates a iface object and adds it to the iface dictionary """
182 ifaceobj
.name
= ifacename
183 ifaceobj
.priv_flags
= priv_flags
186 ifaceobj
.inc_refcnt()
187 self
.ifaceobjdict
[ifacename
] = [ifaceobj
]
190 def create_n_save_ifaceobjcurr(self
, ifaceobj
):
191 """ creates a copy of iface object and adds it to the iface
192 dict containing current iface objects
194 ifaceobjcurr
= iface()
195 ifaceobjcurr
.name
= ifaceobj
.name
196 ifaceobjcurr
.lowerifaces
= ifaceobj
.lowerifaces
197 ifaceobjcurr
.priv_flags
= ifaceobj
.priv_flags
198 ifaceobjcurr
.auto
= ifaceobj
.auto
199 self
.ifaceobjcurrdict
.setdefault(ifaceobj
.name
,
200 []).append(ifaceobjcurr
)
203 def get_ifaceobjcurr(self
, ifacename
, idx
=0):
204 ifaceobjlist
= self
.ifaceobjcurrdict
.get(ifacename
)
210 return ifaceobjlist
[idx
]
212 def get_ifaceobjrunning(self
, ifacename
):
213 return self
.ifaceobjrunningdict
.get(ifacename
)
215 def get_iface_refcnt(self
, ifacename
):
216 """ Return iface ref count """
218 ifaceobjs
= self
.get_ifaceobjs(ifacename
)
226 def is_iface_builtin_byname(self
, ifacename
):
227 """ Returns true if iface name is a builtin interface.
229 A builtin interface is an interface which ifupdown understands.
230 The following are currently considered builtin ifaces:
231 - vlan interfaces in the format <ifacename>.<vlanid>
233 return '.' in ifacename
235 def is_ifaceobj_builtin(self
, ifaceobj
):
236 """ Returns true if iface name is a builtin interface.
238 A builtin interface is an interface which ifupdown understands.
239 The following are currently considered builtin ifaces:
240 - vlan interfaces in the format <ifacename>.<vlanid>
242 return (ifaceobj
.priv_flags
& self
.BUILTIN
)
244 def is_ifaceobj_noconfig(self
, ifaceobj
):
245 """ Returns true if iface object did not have a user defined config.
247 These interfaces appear only when they are dependents of interfaces
248 which have user defined config
250 return (ifaceobj
.priv_flags
& self
.NOCONFIG
)
252 def is_iface_noconfig(self
, ifacename
):
253 """ Returns true if iface has no config """
255 ifaceobj
= self
.get_ifaceobj_first(ifacename
)
256 if not ifaceobj
: return True
257 return self
.is_ifaceobj_noconfig(ifaceobj
)
259 def preprocess_dependency_list(self
, upperifacename
, dlist
, ops
):
260 """ We go through the dependency list and
261 delete or add interfaces from the interfaces dict by
262 applying the following rules:
263 if flag _DELETE_DEPENDENT_IFACES_WITH_NOCONFIG is True:
264 we only consider devices whose configuration was
265 specified in the network interfaces file. We delete
266 any interface whose config was not specified except
267 for vlan devices. vlan devices get special treatment.
268 Even if they are not present they are created and added
270 elif flag _DELETE_DEPENDENT_IFACES_WITH_NOCONFIG is False:
271 we create objects for all dependent devices that are not
272 present in the ifacesdict
277 dilist
= self
.get_ifaceobjs(d
)
279 if self
.is_iface_builtin_byname(d
):
280 self
.create_n_save_ifaceobj(d
, self
.BUILTIN | self
.NOCONFIG
,
281 True).add_to_upperifaces(upperifacename
)
282 elif not self
._DELETE
_DEPENDENT
_IFACES
_WITH
_NOCONFIG
:
283 self
.create_n_save_ifaceobj(d
, self
.NOCONFIG
,
284 True).add_to_upperifaces(upperifacename
)
290 di
.add_to_upperifaces(upperifacename
)
295 def query_dependents(self
, ifaceobj
, ops
):
296 """ Gets iface dependents by calling into respective modules """
299 # Get dependents for interface by querying respective modules
300 for mname
, module
in self
.modules
.items():
301 module
= self
.modules
.get(mname
)
303 if ops
[0] == 'query-running':
304 if (not hasattr(module
,
305 'get_dependent_ifacenames_running')):
307 dlist
= module
.get_dependent_ifacenames_running(ifaceobj
)
309 if (not hasattr(module
, 'get_dependent_ifacenames')):
311 dlist
= module
.get_dependent_ifacenames(ifaceobj
,
312 self
.ifaceobjdict
.keys())
314 self
.logger
.warn('%s: error getting dependent interfaces (%s)'
315 %(ifaceobj
.name
, str(e
)))
322 def populate_dependency_info(self
, ops
, ifacenames
=None):
323 """ recursive function to generate iface dependency info """
326 ifacenames
= self
.ifaceobjdict
.keys()
328 iqueue
= deque(ifacenames
)
331 # Go through all modules and find dependent ifaces
333 ifaceobj
= self
.get_ifaceobj_first(i
)
336 dlist
= ifaceobj
.lowerifaces
338 dlist
= self
.query_dependents(ifaceobj
, ops
)
342 self
.preprocess_dependency_list(ifaceobj
.name
,
344 ifaceobj
.lowerifaces
= dlist
345 [iqueue
.append(d
) for d
in dlist
]
346 if not self
.dependency_graph
.get(i
):
347 self
.dependency_graph
[i
] = dlist
349 def _save_iface(self
, ifaceobj
):
350 currentifaceobjlist
= self
.ifaceobjdict
.get(ifaceobj
.name
)
351 if not currentifaceobjlist
:
352 self
.ifaceobjdict
[ifaceobj
.name
]= [ifaceobj
]
354 if ifaceobj
.compare(currentifaceobjlist
[0]):
355 self
.logger
.warn('duplicate interface %s found' %ifaceobj
.name
)
357 currentifaceobjlist
[0].flags |
= iface
.HAS_SIBLINGS
358 ifaceobj
.flags |
= iface
.HAS_SIBLINGS
359 self
.ifaceobjdict
[ifaceobj
.name
].append(ifaceobj
)
361 def _iface_configattr_syntax_checker(self
, attrname
, attrval
):
362 for m
, mdict
in self
.module_attrs
.items():
365 attrsdict
= mdict
.get('attrs')
367 if attrsdict
.get(attrname
):
369 except AttributeError:
373 def _ifaceobj_syntax_checker(self
, ifaceobj
):
375 for attrname
in ifaceobj
.config
:
377 for k
, v
in self
.module_attrs
.items():
378 if v
and v
.get('attrs', {}).get(attrname
):
383 self
.logger
.warn('%s: unsupported attribute \'%s\'' %attrname
)
387 def read_iface_config(self
):
388 """ Reads default network interface config /etc/network/interfaces. """
389 nifaces
= networkInterfaces(self
.interfacesfile
,
390 self
.interfacesfileiobuf
,
391 self
.interfacesfileformat
,
392 template_engine
=self
.config
.get('template_engine'),
393 template_lookuppath
=self
.config
.get('template_lookuppath'))
394 nifaces
.subscribe('iface_found', self
._save
_iface
)
395 nifaces
.subscribe('validateifaceattr',
396 self
._iface
_configattr
_syntax
_checker
)
397 nifaces
.subscribe('validateifaceobj', self
._ifaceobj
_syntax
_checker
)
400 def read_old_iface_config(self
):
401 """ Reads the saved iface config instead of default iface config.
402 And saved iface config is already read by the statemanager """
403 self
.ifaceobjdict
= copy
.deepcopy(self
.statemanager
.ifaceobjdict
)
405 def _load_addon_modules_config(self
):
406 """ Load addon modules config file """
408 with
open(self
.addon_modules_configfile
, 'r') as f
:
409 lines
= f
.readlines()
411 litems
= l
.rstrip(' \n').split(',')
412 operation
= litems
[0]
414 self
.module_ops
[operation
].append(mname
)
416 def load_addon_modules(self
, modules_dir
):
417 """ load python modules from modules_dir
419 Default modules_dir is /usr/share/ifupdownmodules
422 self
.logger
.info('loading builtin modules from %s' %modules_dir
)
423 self
._load
_addon
_modules
_config
()
424 if not modules_dir
in sys
.path
:
425 sys
.path
.append(modules_dir
)
427 for op
, mlist
in self
.module_ops
.items():
429 if self
.modules
.get(mname
):
431 mpath
= modules_dir
+ '/' + mname
+ '.py'
432 if os
.path
.exists(mpath
):
434 m
= __import__(mname
)
435 mclass
= getattr(m
, mname
)
438 minstance
= mclass(force
=self
.FORCE
,
441 perfmode
=self
.PERFMODE
,
443 cacheflags
=self
.CACHE_FLAGS
)
444 self
.modules
[mname
] = minstance
446 self
.module_attrs
[mname
] = minstance
.get_modinfo()
452 # Assign all modules to query operations
453 self
.module_ops
['query-checkcurr'] = self
.modules
.keys()
454 self
.module_ops
['query-running'] = self
.modules
.keys()
455 self
.module_ops
['query-dependency'] = self
.modules
.keys()
456 self
.module_ops
['query'] = self
.modules
.keys()
457 self
.module_ops
['query-raw'] = self
.modules
.keys()
460 def _modules_help(self
):
461 """ Prints addon modules supported syntax """
464 for m
, mdict
in self
.module_attrs
.items():
467 print('%s: %s' %(m
, mdict
.get('mhelp')))
468 attrdict
= mdict
.get('attrs')
472 for attrname
, attrvaldict
in attrdict
.items():
473 if attrvaldict
.get('compat', False):
475 print('%s%s' %(indent
, attrname
))
476 print('%shelp: %s' %(indent
+ ' ',
477 attrvaldict
.get('help', '')))
478 print ('%srequired: %s' %(indent
+ ' ',
479 attrvaldict
.get('required', False)))
480 default
= attrvaldict
.get('default')
482 print('%sdefault: %s' %(indent
+ ' ', default
))
484 validrange
= attrvaldict
.get('validrange')
486 print('%svalidrange: %s-%s'
487 %(indent
+ ' ', validrange
[0], validrange
[1]))
489 validvals
= attrvaldict
.get('validvals')
491 print('%svalidvals: %s'
492 %(indent
+ ' ', ','.join(validvals
)))
494 examples
= attrvaldict
.get('example')
498 print '%sexample:' %(indent
+ ' ')
500 print '%s%s' %(indent
+ ' ', e
)
505 def load_scripts(self
, modules_dir
):
506 """ loading user modules from /etc/network/.
508 Note that previously loaded python modules override modules found
509 under /etc/network if any
513 self
.logger
.info('looking for user scripts under %s' %modules_dir
)
514 for op
, mlist
in self
.script_ops
.items():
515 msubdir
= modules_dir
+ '/if-%s.d' %op
516 self
.logger
.info('loading scripts under %s ...' %msubdir
)
518 module_list
= os
.listdir(msubdir
)
519 for module
in module_list
:
520 if self
.modules
.get(module
) is not None:
522 self
.script_ops
[op
].append(
523 msubdir
+ '/' + module
)
528 def _sched_ifaces(self
, ifacenames
, ops
):
529 self
.logger
.debug('scheduling \'%s\' for %s'
530 %(str(ops
), str(ifacenames
)))
532 self
._pretty
_print
_ordered
_dict
('dependency graph',
533 self
.dependency_graph
)
534 return ifaceScheduler
.sched_ifaces(self
, ifacenames
, ops
,
535 dependency_graph
=self
.dependency_graph
,
536 order
=ifaceSchedulerFlags
.INORDER
538 else ifaceSchedulerFlags
.POSTORDER
,
539 followdependents
=True if self
.WITH_DEPENDS
else False)
541 def _validate_ifaces(self
, ifacenames
):
542 """ validates interface list for config existance.
544 returns -1 if one or more interface not found. else, returns 0
549 ifaceobjs
= self
.get_ifaceobjs(i
)
553 raise Exception('cannot find interfaces:%s' %err_iface
)
556 def _iface_whitelisted(self
, auto
, allow_classes
, excludepats
, ifacename
):
557 """ Checks if interface is whitelisted depending on set of parameters.
559 interfaces are checked against the allow_classes and auto lists.
564 for e
in excludepats
:
565 if re
.search(e
, ifacename
):
567 ifaceobjs
= self
.get_ifaceobjs(ifacename
)
569 self
.logger
.debug('iface %s' %ifacename
+ ' not found')
571 # We check classes first
575 common
= Set([allow_classes
]).intersection(
587 def _compat_conv_op_to_mode(self
, op
):
588 """ Returns old op name to work with existing scripts """
591 elif op
== 'pre-down':
596 def generate_running_env(self
, ifaceobj
, op
):
597 """ Generates a dictionary with env variables required for
598 an interface. Used to support script execution for interfaces.
602 iface_env
= ifaceobj
.env
606 cenv
.update(iface_env
)
609 cenv
['MODE'] = self
._compat
_conv
_op
_to
_mode
(op
)
612 def _save_state(self
):
613 if not self
.STATEMANAGER_ENABLE
or not self
.STATEMANAGER_UPDATE
:
616 # Update persistant iface states
617 self
.statemanager
.save_state()
619 if self
.logger
.isEnabledFor(logging
.DEBUG
):
620 t
= sys
.exc_info()[2]
621 traceback
.print_tb(t
)
622 self
.logger
.warning('error saving state (%s)' %str
(e
))
624 def up(self
, ops
, auto
=False, allow_classes
=None, ifacenames
=None,
625 excludepats
=None, printdependency
=None, syntaxcheck
=False):
626 """ up an interface """
628 if not self
.ADDONS_ENABLE
: self
.STATEMANAGER_UPDATE
= False
631 self
.WITH_DEPENDS
= True
633 self
.read_iface_config()
637 # If only syntax check was requested, return here
642 # If iface list is given by the caller, always check if iface
644 self
._validate
_ifaces
(ifacenames
)
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
)
664 self
._sched
_ifaces
(filtered_ifacenames
, ops
)
666 if not self
.DRYRUN
and self
.ADDONS_ENABLE
:
669 def down(self
, ops
, auto
=False, allow_classes
=None, ifacenames
=None,
670 excludepats
=None, printdependency
=None, usecurrentconfig
=False):
671 """ down an interface """
673 if not self
.ADDONS_ENABLE
: self
.STATEMANAGER_UPDATE
= False
676 self
.WITH_DEPENDS
= True
677 # For down we need to look at old state, unless usecurrentconfig
679 if (not usecurrentconfig
and self
.STATEMANAGER_ENABLE
and
680 self
.statemanager
.ifaceobjdict
):
681 # Since we are using state manager objects,
682 # skip the updating of state manager objects
683 self
.logger
.debug('Looking at old state ..')
684 self
.read_old_iface_config()
686 # If no old state available
688 self
.read_iface_config()
690 raise Exception('error reading iface config (%s)' %str
(e
))
692 # If iface list is given by the caller, always check if iface
695 self
._validate
_ifaces
(ifacenames
)
697 raise Exception('%s' %str
(e
) +
698 ' (interface was probably never up ?)')
700 # if iface list not given by user, assume all from config file
701 if not ifacenames
: ifacenames
= self
.ifaceobjdict
.keys()
703 # filter interfaces based on auto and allow classes
704 filtered_ifacenames
= [i
for i
in ifacenames
705 if self
._iface
_whitelisted
(auto
, allow_classes
,
707 if not filtered_ifacenames
:
708 raise Exception('no ifaces found matching given allow lists')
711 self
.populate_dependency_info(ops
, filtered_ifacenames
)
712 self
.print_dependency(filtered_ifacenames
, printdependency
)
715 self
.populate_dependency_info(ops
)
718 self
._sched
_ifaces
(filtered_ifacenames
, ops
)
720 if not self
.DRYRUN
and self
.ADDONS_ENABLE
:
723 def query(self
, ops
, auto
=False, allow_classes
=None, ifacenames
=None,
724 excludepats
=None, printdependency
=None,
726 """ query an interface """
728 if self
.STATEMANAGER_ENABLE
and ops
[0] == 'query-savedstate':
729 return self
.statemanager
.dump_pretty(ifacenames
)
731 self
.STATEMANAGER_UPDATE
= False
733 self
.logger
.debug('setting flag ALL')
735 self
.WITH_DEPENDS
= True
737 if ops
[0] == 'query-syntax':
740 elif ops
[0] == 'query-running':
741 # create fake devices to all dependents that dont have config
742 map(lambda i
: self
.create_n_save_ifaceobj(i
, self
.NOCONFIG
),
746 self
.read_iface_config()
750 if ifacenames
and ops
[0] != 'query-running':
751 # If iface list is given, always check if iface is present
752 self
._validate
_ifaces
(ifacenames
)
754 # if iface list not given by user, assume all from config file
755 if not ifacenames
: ifacenames
= self
.ifaceobjdict
.keys()
757 # filter interfaces based on auto and allow classes
758 if ops
[0] == 'query-running':
759 filtered_ifacenames
= ifacenames
761 filtered_ifacenames
= [i
for i
in ifacenames
762 if self
._iface
_whitelisted
(auto
, allow_classes
,
764 if not filtered_ifacenames
:
765 raise Exception('no ifaces found matching ' +
768 self
.populate_dependency_info(ops
, filtered_ifacenames
)
769 if ops
[0] == 'query-dependency' and printdependency
:
770 self
.print_dependency(filtered_ifacenames
, printdependency
)
773 if ops
[0] == 'query':
774 return self
.print_ifaceobjs_pretty(filtered_ifacenames
, format
)
775 elif ops
[0] == 'query-raw':
776 return self
.print_ifaceobjs_raw(filtered_ifacenames
)
778 self
._sched
_ifaces
(filtered_ifacenames
, ops
)
780 if ops
[0] == 'query-checkcurr':
781 ret
= self
.print_ifaceobjscurr_pretty(filtered_ifacenames
, format
)
783 # if any of the object has an error, signal that silently
785 elif ops
[0] == 'query-running':
786 self
.print_ifaceobjsrunning_pretty(filtered_ifacenames
, format
)
789 def reload(self
, upops
, downops
, auto
=False, allow
=None,
790 ifacenames
=None, excludepats
=None, usecurrentconfig
=False):
791 """ reload interface config """
795 self
.logger
.debug('reloading interface config ..')
798 self
.WITH_DEPENDS
= True
801 self
.read_iface_config()
805 # generate dependency graph of interfaces
806 self
.populate_dependency_info(upops
)
807 if (not usecurrentconfig
and self
.STATEMANAGER_ENABLE
808 and self
.statemanager
.ifaceobjdict
):
809 # Save a copy of new iface objects and dependency_graph
810 new_ifaceobjdict
= dict(self
.ifaceobjdict
)
811 new_dependency_graph
= dict(self
.dependency_graph
)
813 # if old state is present, read old state and mark op for 'down'
814 # followed by 'up' aka: reload
815 # old interface config is read into self.ifaceobjdict
816 self
.read_old_iface_config()
819 # oldconfig not available, continue with 'up' with new config
822 if not ifacenames
: ifacenames
= self
.ifaceobjdict
.keys()
823 if op
== 'reload' and ifacenames
:
824 filtered_ifacenames
= [i
for i
in ifacenames
825 if self
._iface
_whitelisted
(auto
, allow_classes
,
827 # Generate the interface down list
828 # Interfaces that go into the down list:
829 # - interfaces that were present in last config and are not
830 # present in the new config
831 # - interfaces that were changed between the last and current
835 for ifname
, lastifaceobjlist
in self
.ifaceobjdict
.items():
837 # If interface is not present in the new file
838 # append it to the down list
839 newifaceobjlist
= new_ifaceobjdict
.get(ifname
)
840 if not newifaceobjlist
:
841 ifacedownlist
.append(ifname
)
843 # If interface has changed between the current file
844 # and the last installed append it to the down list
845 if len(newifaceobjlist
) != len(lastifaceobjlist
):
846 ifacedownlist
.append(ifname
)
848 # compare object list
849 for objidx
in range(0, len(lastifaceobjlist
)):
850 oldobj
= lastifaceobjlist
[objidx
]
851 newobj
= newifaceobjlist
[objidx
]
852 if not newobj
.compare(oldobj
):
853 ifacedownlist
.append(ifname
)
857 self
.logger
.info('Executing down on interfaces: %s'
859 # reinitialize dependency graph
860 self
.dependency_graph
= OrderedDict({})
861 # Generate dependency info for old config
862 self
.populate_dependency_info(downops
, ifacedownlist
)
863 self
._sched
_ifaces
(ifacedownlist
, downops
)
865 self
.logger
.debug('no interfaces to down ..')
867 # Now, run 'up' with new config dict
868 # reset statemanager update flag to default
869 self
.ifaceobjdict
= new_ifaceobjdict
870 self
.dependency_graph
= new_dependency_graph
871 ifacenames
= self
.ifaceobjdict
.keys()
872 filtered_ifacenames
= [i
for i
in ifacenames
873 if self
._iface
_whitelisted
(auto
, allow_classes
,
876 self
.logger
.info('Scheduling up on interfaces: %s'
877 %str
(filtered_ifacenames
))
878 self
._sched
_ifaces
(filtered_ifacenames
, upops
)
883 def _pretty_print_ordered_dict(self
, prefix
, argdict
):
884 outbuf
= prefix
+ ' {\n'
885 for k
, vlist
in argdict
.items():
886 outbuf
+= '\t%s : %s\n' %(k
, str(vlist
))
887 self
.logger
.debug(outbuf
+ '}')
889 def print_dependency(self
, ifacenames
, format
):
890 """ prints iface dependency information """
893 ifacenames
= self
.ifaceobjdict
.keys()
895 for k
,v
in self
.dependency_graph
.items():
896 print '%s : %s' %(k
, str(v
))
897 elif format
== 'dot':
899 map(lambda i
: indegrees
.update({i
:
900 self
.get_iface_refcnt(i
)}),
901 self
.dependency_graph
.keys())
902 graph
.generate_dots(self
.dependency_graph
, indegrees
)
904 def print_ifaceobjs_raw(self
, ifacenames
):
905 """ prints raw lines for ifaces from config file """
908 for ifaceobj
in self
.get_ifaceobjs(i
):
909 if (self
.is_ifaceobj_builtin(ifaceobj
) or
910 not ifaceobj
.is_config_present()):
912 ifaceobj
.dump_raw(self
.logger
)
914 if self
.WITH_DEPENDS
and not self
.ALL
:
915 dlist
= ifaceobj
.lowerifaces
916 if not dlist
: continue
917 self
.print_ifaceobjs_raw(dlist
)
919 def _get_ifaceobjs_pretty(self
, ifacenames
, ifaceobjs
, running
=False):
920 """ returns iface obj list """
923 for ifaceobj
in self
.get_ifaceobjs(i
):
924 if ((not running
and self
.is_ifaceobj_noconfig(ifaceobj
)) or
925 (running
and not ifaceobj
.is_config_present())):
927 ifaceobjs
.append(ifaceobj
)
928 if self
.WITH_DEPENDS
and not self
.ALL
:
929 dlist
= ifaceobj
.lowerifaces
930 if not dlist
: continue
931 self
._get
_ifaceobjs
_pretty
(dlist
, ifaceobjs
, running
)
933 def print_ifaceobjs_pretty(self
, ifacenames
, format
='native'):
934 """ pretty prints iface in format given by keyword arg format """
937 self
._get
_ifaceobjs
_pretty
(ifacenames
, ifaceobjs
)
938 if not ifaceobjs
: return
940 print json
.dumps(ifaceobjs
, cls
=ifaceJsonEncoder
,
941 indent
=4, separators
=(',', ': '))
943 map(lambda i
: i
.dump_pretty(), ifaceobjs
)
945 def _get_ifaceobjscurr_pretty(self
, ifacenames
, ifaceobjs
):
948 ifaceobjscurr
= self
.get_ifaceobjcurr(i
)
949 if not ifaceobjscurr
: continue
950 for ifaceobj
in ifaceobjscurr
:
951 if (ifaceobj
.status
== ifaceStatus
.NOTFOUND
or
952 ifaceobj
.status
== ifaceStatus
.ERROR
):
954 if self
.is_ifaceobj_noconfig(ifaceobj
):
956 ifaceobjs
.append(ifaceobj
)
957 if self
.WITH_DEPENDS
and not self
.ALL
:
958 dlist
= ifaceobj
.lowerifaces
959 if not dlist
: continue
960 dret
= self
._get
_ifaceobjscurr
_pretty
(dlist
, ifaceobjs
)
964 def print_ifaceobjscurr_pretty(self
, ifacenames
, format
='native'):
965 """ pretty prints current running state of interfaces with status.
967 returns 1 if any of the interface has an error,
972 ret
= self
._get
_ifaceobjscurr
_pretty
(ifacenames
, ifaceobjs
)
973 if not ifaceobjs
: return
974 self
.logger
.debug(ifaceobjs
)
976 print json
.dumps(ifaceobjs
, cls
=ifaceJsonEncoder
, indent
=2,
977 separators
=(',', ': '))
979 map(lambda i
: i
.dump_pretty(with_status
=True,
980 successstr
=self
.config
.get('check_success_str',
982 errorstr
=self
.config
.get('check_error_str', _error_sym
)),
986 def print_ifaceobjsrunning_pretty(self
, ifacenames
, format
='native'):
987 """ pretty prints iface running state """
990 self
._get
_ifaceobjs
_pretty
(ifacenames
, ifaceobjs
, running
=True)
991 if not ifaceobjs
: return
993 print json
.dumps(ifaceobjs
, cls
=ifaceJsonEncoder
, indent
=2,
994 separators
=(',', ': '))
996 map(lambda i
: i
.dump_pretty(), ifaceobjs
)
999 print 'ifupdown main object dump'
1000 print self
.pp
.pprint(self
.modules
)
1001 print self
.pp
.pprint(self
.ifaceobjdict
)
1003 def _dump_ifaceobjs(self
, ifacenames
):
1004 for i
in ifacenames
:
1005 ifaceobjs
= self
.get_ifaceobjs(i
)