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 STATEMANAGER_ENABLE
= True
33 STATEMANAGER_UPDATE
= True
36 # priv flags to mark iface objects
40 scripts_dir
='/etc/network'
41 addon_modules_dir
='/usr/share/ifupdownaddons'
42 addon_modules_configfile
='/etc/network/.addons.conf'
44 # iface dictionary in the below format:
45 # { '<ifacename>' : [<ifaceobject1>, <ifaceobject2> ..] }
47 # { 'swp1' : [<ifaceobject1>, <ifaceobject2> ..] }
49 # Each ifaceobject corresponds to a configuration block for
51 ifaceobjdict
= OrderedDict()
54 # iface dictionary representing the curr running state of an iface
55 # in the below format:
56 # {'<ifacename>' : <ifaceobject>}
57 ifaceobjcurrdict
= OrderedDict()
59 # Dictionary representing operation and modules
61 module_ops
= OrderedDict([('pre-up', []),
64 ('query-checkcurr', []),
65 ('query-running', []),
66 ('query-dependency', []),
73 # For old style /etc/network/ bash scripts
74 script_ops
= OrderedDict([('pre-up', []),
81 # Handlers for ops that ifupdown2 owns
82 def run_up(self
, ifaceobj
):
83 ifacename
= ifaceobj
.get_name()
84 if self
.link_exists(ifacename
):
85 self
.link_up(ifacename
)
87 def run_down(self
, ifaceobj
):
88 ifacename
= ifaceobj
.get_name()
89 if self
.link_exists(ifacename
):
90 self
.link_down(ifacename
)
92 # ifupdown object interface operation handlers
93 ops_handlers
= OrderedDict([('up', run_up
),
96 def run_sched_ifaceobj_posthook(self
, ifaceobj
):
97 if ((ifaceobj
.priv_flags
& self
.BUILTIN
) or
98 (ifaceobj
.priv_flags
& self
.NOCONFIG
)):
100 if self
.STATEMANAGER_UPDATE
:
101 self
.statemanager
.ifaceobj_sync(ifaceobj
)
103 # ifupdown object interface scheduler pre and posthooks
104 sched_hooks
= {'posthook' : run_sched_ifaceobj_posthook
}
106 def __init__(self
, force
=False, dryrun
=False, nowait
=False,
107 perfmode
=False, withdepends
=False, njobs
=1,
108 cache
=False, addons_enable
=True, statemanager_enable
=True):
109 self
.logger
= logging
.getLogger('ifupdown')
113 self
.PERFMODE
= perfmode
114 self
.WITH_DEPENDS
= withdepends
115 self
.STATEMANAGER_ENABLE
= statemanager_enable
118 # Can be used to provide hints for caching
119 self
.CACHE_FLAGS
= 0x0
120 self
._DELETE
_DEPENDENT
_IFACES
_WITH
_NOCONFIG
= False
121 self
.ADDONS_ENABLE
= addons_enable
123 self
.ifaces
= OrderedDict()
125 self
.pp
= pprint
.PrettyPrinter(indent
=4)
126 self
.modules
= OrderedDict({})
127 self
.module_attrs
= {}
129 self
.load_addon_modules(self
.addon_modules_dir
)
130 if self
.COMPAT_EXEC_SCRIPTS
:
131 self
.load_scripts(self
.scripts_dir
)
132 self
.dependency_graph
= OrderedDict({})
134 if self
.STATEMANAGER_ENABLE
:
136 self
.statemanager
= stateManager()
137 self
.statemanager
.read_saved_state()
139 # XXX Maybe we should continue by ignoring old state
140 self
.logger
.warning('error reading state (%s)' %str
(e
))
143 self
.STATEMANAGER_UPDATE
= False
145 def get_subops(self
, op
):
146 """ Returns sub-operation list """
147 return self
.module_ops
.get(op
).keys()
149 def compat_conv_op_to_mode(self
, op
):
150 """ Returns old op name to work with existing scripts """
153 elif op
== 'pre-down':
158 def set_force(self
, force
):
159 """ Set force flag. """
163 """ return force flag. """
166 def set_dryrun(self
, dryrun
):
169 def get_dryrun(self
):
175 def get_ifaceobjdict(self
):
176 return self
.ifaceobjdict
178 def set_ifaceobjdict(self
, ifaceobjdict
):
179 self
.ifaceobjdict
= ifaceobjdict
181 def set_dependency_graph(self
, dependency_graph
):
182 self
.dependency_graph
= dependency_graph
184 def get_dependency_graph(self
):
185 return self
.dependency_graph
187 def set_perfmode(self
, perfmode
):
188 self
.PERFMODE
= perfmode
190 def get_perfmode(self
):
193 def set_nowait(self
, nowait
):
196 def get_nowait(self
):
199 def set_njobs(self
, njobs
):
200 self
.logger
.debug('setting njobs to %d' %njobs
)
206 def get_withdepends(self
):
207 return self
.WITH_DEPENDS
209 def set_withdepends(self
, withdepends
):
210 self
.logger
.debug('setting withdepends to true')
211 self
.WITH_DEPENDS
= withdepends
213 def get_ifaceobjs(self
, ifacename
):
214 return self
.ifaceobjdict
.get(ifacename
)
216 def get_ifaceobj_first(self
, ifacename
):
217 ifaceobjs
= self
.get_ifaceobjs(ifacename
)
222 def get_iface_obj_last(self
, ifacename
):
223 return self
.ifaceobjdict
.get(ifacename
)[-1]
225 def create_n_save_ifaceobjcurr(self
, ifaceobj
):
226 ifacename
= ifaceobj
.get_name()
227 ifaceobjcurr
= self
.get_ifaceobjcurr(ifacename
)
231 ifaceobjcurr
= iface()
232 ifaceobjcurr
.set_name(ifacename
)
233 ifaceobjcurr
.set_lowerifaces(ifaceobj
.get_lowerifaces())
234 ifaceobjcurr
.set_priv_flags(ifaceobj
.get_priv_flags())
235 self
.ifaceobjcurrdict
[ifacename
] = ifaceobjcurr
239 def get_ifaceobjcurr(self
, ifacename
):
240 return self
.ifaceobjcurrdict
.get(ifacename
)
242 def get_ifaceobjrunning(self
, ifacename
):
243 return self
.ifaceobjrunningdict
.get(ifacename
)
245 def get_iface_status(self
, ifacename
):
246 ifaceobjs
= self
.get_ifaceobjs(ifacename
)
248 if i
.get_status() != ifaceStatus
.SUCCESS
:
249 return i
.get_status()
250 return ifaceStatus
.SUCCESS
252 def get_iface_refcnt(self
, ifacename
):
254 ifaceobjs
= self
.get_ifaceobjs(ifacename
)
258 if i
.get_refcnt() > max:
262 def create_n_save_ifaceobj(self
, ifacename
, priv_flags
=None,
264 """ creates and returns a fake vlan iface object.
265 This was added to support creation of simple vlan
266 devices without any user specified configuration.
269 ifaceobj
.set_name(ifacename
)
270 ifaceobj
.priv_flags
= priv_flags
273 ifaceobj
.inc_refcnt()
274 self
.ifaceobjdict
[ifacename
] = [ifaceobj
]
278 def is_iface_builtin_byname(self
, ifacename
):
279 """ Returns true if iface name is a builtin interface.
281 A builtin interface is an interface which ifupdown understands.
282 The following are currently considered builtin ifaces:
283 - vlan interfaces in the format <ifacename>.<vlanid>
285 return '.' in ifacename
287 def is_ifaceobj_builtin(self
, ifaceobj
):
288 """ Returns true if iface name is a builtin interface.
290 A builtin interface is an interface which ifupdown understands.
291 The following are currently considered builtin ifaces:
292 - vlan interfaces in the format <ifacename>.<vlanid>
294 return (ifaceobj
.priv_flags
& self
.BUILTIN
)
296 def is_ifaceobj_noconfig(self
, ifaceobj
):
297 """ Returns true if iface name did not have a user defined config.
299 These interfaces appear only when they are dependents of interfaces
300 which have user defined config
302 return (ifaceobj
.priv_flags
& self
.NOCONFIG
)
304 def is_iface_noconfig(self
, ifacename
):
305 """ Returns true if iface has no config """
307 ifaceobj
= self
.get_ifaceobj_first(ifacename
)
308 if not ifaceobj
: return True
310 return self
.is_ifaceobj_noconfig(ifaceobj
)
312 def preprocess_dependency_list(self
, upperifacename
, dlist
, ops
):
313 """ We go through the dependency list and
314 delete or add interfaces from the interfaces dict by
315 applying the following rules:
316 if flag _DELETE_DEPENDENT_IFACES_WITH_NOCONFIG is True:
317 we only consider devices whose configuration was
318 specified in the network interfaces file. We delete
319 any interface whose config was not specified except
320 for vlan devices. vlan devices get special treatment.
321 Even if they are not present they are created and added
323 elif flag _DELETE_DEPENDENT_IFACES_WITH_NOCONFIG is False:
324 we create objects for all dependent devices that are not
325 present in the ifacesdict
330 dilist
= self
.get_ifaceobjs(d
)
332 if self
.is_iface_builtin_byname(d
):
333 self
.create_n_save_ifaceobj(d
, self
.BUILTIN | self
.NOCONFIG
,
334 True).add_to_upperifaces(upperifacename
)
335 elif not self
._DELETE
_DEPENDENT
_IFACES
_WITH
_NOCONFIG
:
336 self
.create_n_save_ifaceobj(d
, self
.NOCONFIG
,
337 True).add_to_upperifaces(upperifacename
)
343 di
.add_to_upperifaces(upperifacename
)
348 def query_dependents(self
, ifaceobj
, ops
):
349 """ Gets iface dependents by calling into respective modules """
352 # Get dependents for interface by querying respective modules
353 for mname
, module
in self
.modules
.items():
354 module
= self
.modules
.get(mname
)
355 if ops
[0] == 'query-running':
356 if (not hasattr(module
,
357 'get_dependent_ifacenames_running')):
359 dlist
= module
.get_dependent_ifacenames_running(ifaceobj
)
361 if (not hasattr(module
, 'get_dependent_ifacenames')):
363 dlist
= module
.get_dependent_ifacenames(ifaceobj
,
364 self
.ifaceobjdict
.keys())
366 self
.logger
.debug('%s: ' %ifaceobj
.get_name() +
367 'got lowerifaces/dependents: %s' %str
(dlist
))
371 def populate_dependency_info(self
, ifacenames
, ops
):
372 """ recursive function to generate iface dependency info """
375 ifacenames
= self
.ifaceobjdict
.keys()
376 self
.logger
.debug('populating dependency info for %s' %str
(ifacenames
))
377 iqueue
= deque(ifacenames
)
380 # Go through all modules and find dependent ifaces
382 ifaceobj
= self
.get_ifaceobj_first(i
)
385 dlist
= ifaceobj
.get_lowerifaces()
387 dlist
= self
.query_dependents(ifaceobj
, ops
)
391 self
.preprocess_dependency_list(ifaceobj
.get_name(),
393 self
.logger
.debug('%s: lowerifaces/dependents after processing: %s'
395 ifaceobj
.set_lowerifaces(dlist
)
396 [iqueue
.append(d
) for d
in dlist
]
397 if not self
.dependency_graph
.get(i
):
398 self
.dependency_graph
[i
] = dlist
400 def _save_iface(self
, ifaceobj
):
401 if not self
.ifaceobjdict
.get(ifaceobj
.get_name()):
402 self
.ifaceobjdict
[ifaceobj
.get_name()] = [ifaceobj
]
404 self
.ifaceobjdict
[ifaceobj
.get_name()].append(ifaceobj
)
406 def _module_syntax_checker(self
, attrname
, attrval
):
407 for m
, mdict
in self
.module_attrs
.items():
408 attrsdict
= mdict
.get('attrs')
409 if attrsdict
and attrname
in attrsdict
.keys(): return True
412 def read_default_iface_config(self
):
413 """ Reads default network interface config /etc/network/interfaces. """
414 nifaces
= networkInterfaces()
415 nifaces
.subscribe('iface_found', self
._save
_iface
)
416 nifaces
.subscribe('validate', self
._module
_syntax
_checker
)
419 def read_iface_config(self
):
420 return self
.read_default_iface_config()
422 def read_old_iface_config(self
):
423 """ Reads the saved iface config instead of default iface config. """
425 # Read it from the statemanager
426 self
.ifaceobjdict
= self
.statemanager
.get_ifaceobjdict()
428 def load_addon_modules_config(self
):
429 with
open(self
.addon_modules_configfile
, 'r') as f
:
430 lines
= f
.readlines()
432 litems
= l
.rstrip(' \n').split(',')
433 operation
= litems
[0]
435 self
.module_ops
[operation
].append(mname
)
437 def load_addon_modules(self
, modules_dir
):
438 """ load python modules from modules_dir
440 Default modules_dir is /usr/share/ifupdownmodules
443 self
.logger
.info('loading builtin modules from %s' %modules_dir
)
444 self
.load_addon_modules_config()
445 if not modules_dir
in sys
.path
:
446 sys
.path
.append(modules_dir
)
448 for op
, mlist
in self
.module_ops
.items():
450 if self
.modules
.get(mname
) is not None:
452 mpath
= modules_dir
+ '/' + mname
+ '.py'
453 if os
.path
.exists(mpath
):
455 m
= __import__(mname
)
456 mclass
= getattr(m
, mname
)
459 minstance
= mclass(force
=self
.FORCE
,
462 perfmode
=self
.PERFMODE
,
464 cacheflags
=self
.CACHE_FLAGS
)
465 self
.modules
[mname
] = minstance
466 if hasattr(minstance
, 'get_modinfo'):
467 self
.module_attrs
[mname
] = minstance
.get_modinfo()
471 # Assign all modules to query operations
472 self
.module_ops
['query-checkcurr'] = self
.modules
.keys()
473 self
.module_ops
['query-running'] = self
.modules
.keys()
474 self
.module_ops
['query-dependency'] = self
.modules
.keys()
475 self
.module_ops
['query'] = self
.modules
.keys()
476 self
.module_ops
['query-raw'] = self
.modules
.keys()
478 def modules_help(self
):
480 for m
, mdict
in self
.module_attrs
.items():
483 print('%s: %s' %(m
, mdict
.get('mhelp')))
484 attrdict
= mdict
.get('attrs')
488 for attrname
, attrvaldict
in attrdict
.items():
489 if attrvaldict
.get('compat', False):
491 print('%s%s' %(indent
, attrname
))
492 print('%shelp: %s' %(indent
+ ' ',
493 attrvaldict
.get('help', '')))
494 print ('%srequired: %s' %(indent
+ ' ',
495 attrvaldict
.get('required', False)))
496 default
= attrvaldict
.get('default')
498 print('%sdefault: %s' %(indent
+ ' ', default
))
500 validrange
= attrvaldict
.get('validrange')
502 print('%svalidrange: %s'
503 %(indent
+ ' ', '-'.join(validrange
)))
505 validvals
= attrvaldict
.get('validvals')
507 print('%svalidvals: %s'
508 %(indent
+ ' ', ','.join(validvals
)))
510 examples
= attrvaldict
.get('example')
514 print '%sexample:' %(indent
+ ' ')
516 print '%s%s' %(indent
+ ' ', e
)
521 def load_scripts(self
, modules_dir
):
522 """ loading user modules from /etc/network/.
524 Note that previously loaded python modules override modules found
525 under /etc/network if any
529 self
.logger
.info('looking for user scripts under %s' %modules_dir
)
530 for op
, mlist
in self
.script_ops
.items():
531 msubdir
= modules_dir
+ '/if-%s.d' %op
532 self
.logger
.info('loading scripts under %s ...' %msubdir
)
534 module_list
= os
.listdir(msubdir
)
535 for module
in module_list
:
536 if self
.modules
.get(module
) is not None:
538 self
.script_ops
[op
].append(
539 msubdir
+ '/' + module
)
544 def conv_iface_namelist_to_objlist(self
, intf_list
):
545 for intf
in intf_list
:
546 iface_obj
= self
.get_iface(intf
)
548 raise ifupdownInvalidValue('no iface %s', intf
)
549 iface_objs
.append(iface_obj
)
553 def run_without_dependents(self
, ops
, ifacenames
):
554 """ Run interface list without their dependents """
556 raise ifupdownInvalidValue('no interfaces found')
558 self
.logger
.debug('run_without_dependents for ops %s for %s'
559 %(str(ops
), str(ifacenames
)))
561 ifaceScheduler
.run_iface_list(self
, ifacenames
, ops
, parent
=None,
562 order
=ifaceSchedulerFlags
.INORDER
564 else ifaceSchedulerFlags
.POSTORDER
,
565 followdependents
=False)
567 def _pretty_print_ordered_dict(self
, argdict
):
568 for k
, vlist
in argdict
.items():
569 self
.logger
.info('%s : %s' %(k
, str(vlist
)))
571 def run_with_dependents(self
, ops
, ifacenames
):
573 self
.logger
.debug('running \'%s\' with dependents for %s'
574 %(str(ops
), str(ifacenames
)))
577 ifacenames
= self
.ifaceobjdict
.keys()
579 self
.logger
.info('dependency graph:')
580 self
._pretty
_print
_ordered
_dict
(self
.dependency_graph
)
583 ret
= ifaceScheduler
.run_iface_dependency_graph_parallel(self
,
584 self
.dependency_graph
, ops
)
586 ret
= ifaceScheduler
.run_iface_dependency_graphs(self
,
587 self
.dependency_graph
, ops
,
588 order
=ifaceSchedulerFlags
.INORDER
590 else ifaceSchedulerFlags
.POSTORDER
)
593 def print_dependency(self
, ifacenames
, format
):
594 if ifacenames
is None:
595 ifacenames
= self
.ifaceobjdict
.keys()
598 for k
,v
in self
.dependency_graph
.items():
599 print '%s : %s' %(k
, str(v
))
600 elif format
== 'dot':
602 map(lambda i
: indegrees
.update({i
:
603 self
.get_iface_refcnt(i
)}),
604 self
.dependency_graph
.keys())
605 graph
.generate_dots(self
.dependency_graph
, indegrees
)
607 def validate_ifaces(self
, ifacenames
):
608 """ validates interface list for config existance.
610 returns -1 if one or more interface not found. else, returns 0
615 ifaceobjs
= self
.get_ifaceobjs(i
)
619 self
.logger
.error('could not find interfaces: %s' %err_iface
)
623 def iface_whitelisted(self
, auto
, allow_classes
, excludepats
, ifacename
):
624 """ Checks if interface is whitelisted depending on set of parameters.
626 interfaces are checked against the allow_classes and auto lists.
629 # If the interface matches
631 for e
in excludepats
:
632 if re
.search(e
, ifacename
):
634 ifaceobjs
= self
.get_ifaceobjs(ifacename
)
636 self
.logger
.debug('iface %s' %ifacename
+ ' not found')
638 # We check classes first
642 common
= Set([allow_classes
]).intersection(
643 Set(i
.get_classes()))
654 def generate_running_env(self
, ifaceobj
, op
):
655 """ Generates a dictionary with env variables required for
656 an interface. Used to support script execution for interfaces.
660 iface_env
= ifaceobj
.get_env()
661 if iface_env
is not None:
664 cenv
.update(iface_env
)
667 cenv
['MODE'] = self
.compat_conv_op_to_mode(op
)
670 def save_state(self
):
671 if not self
.STATEMANAGER_ENABLE
or not self
.STATEMANAGER_UPDATE
:
674 # Update persistant iface states
675 self
.statemanager
.save_state()
677 if self
.logger
.isEnabledFor(logging
.DEBUG
):
678 t
= sys
.exc_info()[2]
679 traceback
.print_tb(t
)
680 self
.logger
.warning('error saving state (%s)' %str
(e
))
682 def up(self
, ops
, auto
=False, allow_classes
=None, ifacenames
=None,
683 excludepats
=None, printdependency
=None):
686 self
.WITH_DEPENDS
= True
689 self
.read_iface_config()
694 # If iface list is given by the caller, always check if iface
696 if self
.validate_ifaces(ifacenames
) != 0:
697 raise Exception('all or some interfaces not found')
699 # if iface list not given by user, assume all from config file
700 if not ifacenames
: ifacenames
= self
.ifaceobjdict
.keys()
702 # filter interfaces based on auto and allow classes
703 filtered_ifacenames
= [i
for i
in ifacenames
704 if self
.iface_whitelisted(auto
, allow_classes
,
706 if not filtered_ifacenames
:
707 raise Exception('no ifaces found matching given allow lists')
709 self
.populate_dependency_info(filtered_ifacenames
, ops
)
712 self
.print_dependency(filtered_ifacenames
, printdependency
)
715 if self
.WITH_DEPENDS
:
716 self
.run_with_dependents(ops
, filtered_ifacenames
)
718 self
.run_without_dependents(ops
, filtered_ifacenames
)
720 if self
.DRYRUN
and self
.ADDONS_ENABLE
:
725 def down(self
, ops
, auto
=False, allow_classes
=None, ifacenames
=None,
726 excludepats
=None, printdependency
=None, usecurrentconfig
=False):
727 if self
.ADDONS_ENABLE
: self
.STATEMANAGER_UPDATE
= False
730 self
.WITH_DEPENDS
= True
731 # For down we need to look at old state, unless usecurrentconfig
733 if (not usecurrentconfig
and self
.STATEMANAGER_ENABLE
and
734 self
.statemanager
.get_ifaceobjdict()):
735 # Since we are using state manager objects,
736 # skip the updating of state manager objects
737 self
.STATEMANAGER_UPDATE
= False
738 self
.logger
.debug('Looking at old state ..')
739 self
.read_old_iface_config()
741 # If no old state available
742 self
.logger
.info('Loading current iface config file')
744 self
.read_iface_config()
746 raise Exception('error reading iface config (%s)' %str
(e
))
748 # If iface list is given by the caller, always check if iface
750 if self
.validate_ifaces(ifacenames
) != 0:
751 raise Exception('all or some interfaces not found')
752 # if iface list not given by user, assume all from config file
753 if not ifacenames
: ifacenames
= self
.ifaceobjdict
.keys()
754 # filter interfaces based on auto and allow classes
755 filtered_ifacenames
= [i
for i
in ifacenames
756 if self
.iface_whitelisted(auto
, allow_classes
,
758 if not filtered_ifacenames
:
759 raise Exception('no ifaces found matching given allow lists')
761 self
.populate_dependency_info(filtered_ifacenames
, ops
)
763 self
.print_dependency(filtered_ifacenames
, printdependency
)
766 if self
.WITH_DEPENDS
:
767 self
.run_with_dependents(ops
, filtered_ifacenames
)
769 self
.run_without_dependents(ops
, filtered_ifacenames
)
771 if self
.DRYRUN
and self
.ADDONS_ENABLE
:
776 def query(self
, ops
, auto
=False, allow_classes
=None, ifacenames
=None,
777 excludepats
=None, printdependency
=None,
779 if self
.STATEMANAGER_ENABLE
and ops
[0] == 'query-savedstate':
780 return self
.statemanager
.dump_pretty(ifacenames
)
782 self
.STATEMANAGER_UPDATE
= False
784 self
.logger
.debug('setting flag ALL')
786 self
.WITH_DEPENDS
= True
788 if ops
[0] == 'query-syntax':
791 elif ops
[0] == 'query-running':
792 # create fake devices to all dependents that dont have config
793 map(lambda i
: self
.create_n_save_ifaceobj(i
, self
.NOCONFIG
),
797 self
.read_iface_config()
801 if ifacenames
is not None and ops
[0] != 'query-running':
802 # If iface list is given, always check if iface is present
803 if self
.validate_ifaces(ifacenames
) != 0:
804 raise Exception('all or some interfaces not found')
806 # if iface list not given by user, assume all from config file
807 if not ifacenames
: ifacenames
= self
.ifaceobjdict
.keys()
809 # filter interfaces based on auto and allow classes
810 if ops
[0] == 'query-running':
811 filtered_ifacenames
= ifacenames
813 filtered_ifacenames
= [i
for i
in ifacenames
814 if self
.iface_whitelisted(auto
, allow_classes
,
816 if not filtered_ifacenames
:
817 raise Exception('no ifaces found matching ' +
820 self
.populate_dependency_info(filtered_ifacenames
, ops
)
821 if ops
[0] == 'query-dependency' and printdependency
:
822 self
.print_dependency(filtered_ifacenames
, printdependency
)
825 if ops
[0] == 'query':
826 return self
.print_ifaceobjs_pretty(filtered_ifacenames
, format
)
827 elif ops
[0] == 'query-raw':
828 return self
.print_ifaceobjs_raw(filtered_ifacenames
)
830 if self
.WITH_DEPENDS
:
831 self
.run_with_dependents(ops
, filtered_ifacenames
)
833 self
.run_without_dependents(ops
, filtered_ifacenames
)
835 if ops
[0] == 'query-checkcurr':
836 ret
= self
.print_ifaceobjscurr_pretty(filtered_ifacenames
, format
)
838 # if any of the object has an error, signal that silently
840 elif ops
[0] == 'query-running':
841 self
.print_ifaceobjsrunning_pretty(filtered_ifacenames
, format
)
844 def reload(self
, upops
, downops
, auto
=False, allow
=None,
845 ifacenames
=None, excludepats
=None, downchangediface
=False):
846 """ main ifupdown run method """
849 self
.logger
.debug('reloading interface config ..')
852 self
.WITH_DEPENDS
= True
855 # Read the current interface config
856 self
.read_iface_config()
860 # generate dependency graph of interfaces
861 self
.populate_dependency_info(ifacenames
, upops
)
863 # Save a copy of new iface objects and dependency_graph
864 new_ifaceobjdict
= dict(self
.get_ifaceobjdict())
865 new_dependency_graph
= dict(self
.get_dependency_graph())
867 if self
.STATEMANAGER_ENABLE
and self
.statemanager
.get_ifaceobjdict():
868 # if old state is present, read old state and mark op for 'down'
869 # followed by 'up' aka: reload
870 # old interface config is read into self.ifaceobjdict
872 self
.STATEMANAGER_UPDATE
= False
873 self
.read_old_iface_config()
876 # oldconfig not available, continue with 'up' with new config
879 if not ifacenames
: ifacenames
= self
.ifaceobjdict
.keys()
880 if op
== 'reload' and ifacenames
:
881 filtered_ifacenames
= [i
for i
in ifacenames
882 if self
.iface_whitelisted(auto
, allow_classes
,
884 # Generate the interface down list
885 # Interfaces that go into the down list:
886 # - interfaces that were present in last config and are not
887 # present in the new config
888 # - interfaces that were changed between the last and current
892 for ifname
, lastifobjlist
in self
.ifaceobjdict
.items():
894 # If interface is not present in the new file
895 # append it to the down list
896 newifobjlist
= new_ifaceobjdict
.get(ifname
)
898 ifacedownlist
.append(ifname
)
900 if not downchangediface
:
902 # If interface has changed between the current file
903 # and the last installed append it to the down list
904 if len(newifobjlist
) != len(lastifobjlist
):
905 ifacedownlist
.append(ifname
)
907 # compare object list
908 for objidx
in range(0, len(lastifobjlist
)):
909 oldobj
= lastifobjlist
[objidx
]
910 newobj
= newifobjlist
[objidx
]
911 if newobj
.is_different(oldobj
):
912 ifacedownlist
.append(ifname
)
916 self
.logger
.info('Executing down on interfaces: %s'
918 # reinitialize dependency graph
919 self
.dependency_graph
= OrderedDict({})
920 # Generate dependency info for old config
921 self
.populate_dependency_info(ifacedownlist
, downops
)
922 self
.run_with_dependents(downops
, ifacedownlist
)
924 self
.logger
.debug('no interfaces to down ..')
926 # Now, run 'up' with new config dict
927 # reset statemanager update flag to default
928 self
.STATEMANAGER_UPDATE
= True
929 self
.set_ifaceobjdict(new_ifaceobjdict
)
930 self
.set_dependency_graph(new_dependency_graph
)
931 ifacenames
= self
.ifaceobjdict
.keys()
932 filtered_ifacenames
= [i
for i
in ifacenames
933 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
)
946 """ all state dump """
948 print 'ifupdown object dump'
949 print self
.pp
.pprint(self
.modules
)
950 print self
.pp
.pprint(self
.ifaces
)
951 self
.state_manager
.dump()
953 def print_state(self
, ifacenames
=None):
954 self
.statemanager
.dump(ifacenames
)
956 def print_ifaceobjs_raw(self
, ifacenames
):
958 for ifaceobj
in self
.get_ifaceobjs(i
):
959 if (self
.is_ifaceobj_builtin(ifaceobj
) or
960 not ifaceobj
.is_config_present()):
962 ifaceobj
.dump_raw(self
.logger
)
964 if self
.WITH_DEPENDS
:
965 dlist
= ifaceobj
.get_lowerifaces()
966 if not dlist
: continue
967 self
.print_ifaceobjs_pretty(dlist
, format
)
969 def print_ifaceobjs_pretty(self
, ifacenames
, format
='native'):
971 for ifaceobj
in self
.get_ifaceobjs(i
):
972 if (self
.is_ifaceobj_noconfig(ifaceobj
)):
977 ifaceobj
.dump_pretty()
978 if self
.WITH_DEPENDS
:
979 dlist
= ifaceobj
.get_lowerifaces()
980 if not dlist
: continue
981 self
.print_ifaceobjs_pretty(dlist
, format
)
983 def dump_ifaceobjs(self
, ifacenames
):
985 ifaceobjs
= self
.get_ifaceobjs(i
)
990 def print_ifaceobjscurr_pretty(self
, ifacenames
, format
='native'):
991 """ Dumps current running state of interfaces.
993 returns 1 if any of the interface has an error,
998 ifaceobj
= self
.get_ifaceobjcurr(i
)
999 if not ifaceobj
: continue
1000 if ifaceobj
.get_status() == ifaceStatus
.NOTFOUND
:
1001 print 'iface %s %s\n' %(ifaceobj
.get_name(),
1002 ifaceStatus
.to_str(ifaceStatus
.NOTFOUND
))
1005 elif ifaceobj
.get_status() == ifaceStatus
.ERROR
:
1008 if (self
.is_ifaceobj_noconfig(ifaceobj
)):
1011 if format
== 'json':
1012 ifaceobj
.dump_json(with_status
=True)
1014 ifaceobj
.dump_pretty(with_status
=True)
1016 if self
.WITH_DEPENDS
:
1017 dlist
= ifaceobj
.get_lowerifaces()
1018 if not dlist
: continue
1019 self
.print_ifaceobjscurr_pretty(dlist
, format
)
1022 def print_ifaceobjsrunning_pretty(self
, ifacenames
, format
='native'):
1023 for i
in ifacenames
:
1024 ifaceobj
= self
.get_ifaceobj_first(i
)
1025 if ifaceobj
.get_status() == ifaceStatus
.NOTFOUND
:
1026 print 'iface %s' %ifaceobj
.get_name() + ' (not found)\n'
1028 if not ifaceobj
.is_config_present():
1030 if format
== 'json':
1031 ifaceobj
.dump_json()
1033 ifaceobj
.dump_pretty()
1034 if self
.WITH_DEPENDS
:
1035 dlist
= ifaceobj
.get_lowerifaces()
1036 if not dlist
: continue
1037 self
.print_ifaceobjsrunning_pretty(dlist
, format
)