]>
git.proxmox.com Git - mirror_ifupdown2.git/blob - pkg/ifupdownmain.py
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
32 # priv flags to mark iface objects
36 scripts_dir
='/etc/network'
37 addon_modules_dir
='/usr/share/ifupdownaddons'
38 addon_modules_configfile
='/etc/network/.addons.conf'
40 # iface dictionary in the below format:
41 # { '<ifacename>' : [<ifaceobject1>, <ifaceobject2> ..] }
43 # { 'swp1' : [<ifaceobject1>, <ifaceobject2> ..] }
45 # Each ifaceobject corresponds to a configuration block for
47 ifaceobjdict
= OrderedDict()
50 # iface dictionary representing the curr running state of an iface
51 # in the below format:
52 # {'<ifacename>' : <ifaceobject>}
53 ifaceobjcurrdict
= OrderedDict()
55 # Dictionary representing operation, sub operation and modules
56 # for every sub operation
57 operations
= OrderedDict([('pre-up', []),
60 ('query-checkcurr', []),
61 ('query-running', []),
62 ('query-dependency', []),
69 # For old style /etc/network/ bash scripts
70 operations_compat
= OrderedDict([('pre-up', []),
78 def __init__(self
, force
=False, dryrun
=False, nowait
=False,
79 perfmode
=False, withdepends
=False, njobs
=1,
81 self
.logger
= logging
.getLogger('ifupdown')
86 self
.PERFMODE
= perfmode
87 self
.WITH_DEPENDS
= withdepends
89 self
._DELETE
_DEPENDENT
_IFACES
_WITH
_NOCONFIG
= False
91 self
.ifaces
= OrderedDict()
93 self
.pp
= pprint
.PrettyPrinter(indent
=4)
94 self
.modules
= OrderedDict({})
95 self
.module_attrs
= {}
96 self
.load_addon_modules(self
.addon_modules_dir
)
97 self
.load_scripts(self
.scripts_dir
)
98 self
.dependency_graph
= OrderedDict({})
101 self
.statemanager
= stateManager()
102 self
.statemanager
.read_saved_state()
104 # XXX Maybe we should continue by ignoring old state
105 self
.logger
.warning('error reading state (%s)' %str
(e
))
108 def get_subops(self
, op
):
109 """ Returns sub-operation list """
110 return self
.operations
.get(op
).keys()
112 def compat_conv_op_to_mode(self
, op
):
113 """ Returns old op name to work with existing scripts """
116 elif op
== 'pre-down':
121 def set_force(self
, force
):
122 """ Set force flag. """
126 """ return force flag. """
129 def set_dryrun(self
, dryrun
):
132 def get_dryrun(self
):
138 def get_ifaceobjdict(self
):
139 return self
.ifaceobjdict
141 def set_ifaceobjdict(self
, ifaceobjdict
):
142 del self
.ifaceobjdict
143 self
.ifaceobjdict
= ifaceobjdict
145 def set_dependency_graph(self
, dependency_graph
):
146 self
.dependency_graph
= dependency_graph
148 def get_dependency_graph(self
):
149 return self
.dependency_graph
151 def set_perfmode(self
, perfmode
):
152 self
.PERFMODE
= perfmode
154 def get_perfmode(self
):
157 def set_nowait(self
, nowait
):
160 def get_nowait(self
):
163 def set_njobs(self
, njobs
):
164 self
.logger
.debug('setting njobs to %d' %njobs
)
170 def get_withdepends(self
):
171 return self
.WITH_DEPENDS
173 def set_withdepends(self
, withdepends
):
174 self
.logger
.debug('setting withdepends to true')
175 self
.WITH_DEPENDS
= withdepends
177 def set_iface_state(self
, ifaceobj
, state
, status
):
178 ifaceobj
.set_state(state
)
179 ifaceobj
.set_status(status
)
180 self
.statemanager
.update_iface_state(ifaceobj
)
182 def get_iface_objs(self
, ifacename
):
183 return self
.ifaceobjdict
.get(ifacename
)
185 def get_iface_obj_first(self
, ifacename
):
186 ifaceobjs
= self
.get_iface_objs(ifacename
)
187 if ifaceobjs
is not None:
191 def get_iface_obj_last(self
, ifacename
):
192 return self
.ifaceobjdict
.get(ifacename
)[-1]
194 def create_n_save_ifaceobjcurr(self
, ifaceobj
):
195 ifacename
= ifaceobj
.get_name()
196 ifaceobjcurr
= self
.get_ifaceobjcurr(ifacename
)
197 if ifaceobjcurr
is not None:
200 ifaceobjcurr
= iface()
201 ifaceobjcurr
.set_name(ifacename
)
202 ifaceobjcurr
.set_dependents(ifaceobj
.get_dependents())
203 self
.ifaceobjcurrdict
[ifacename
] = ifaceobjcurr
207 def get_ifaceobjcurr(self
, ifacename
):
208 return self
.ifaceobjcurrdict
.get(ifacename
)
210 def get_ifaceobjrunning(self
, ifacename
):
211 return self
.ifaceobjrunningdict
.get(ifacename
)
213 def get_iface_status(self
, ifacename
):
214 ifaceobjs
= self
.get_iface_objs(ifacename
)
216 if i
.get_status() != ifaceStatus
.SUCCESS
:
217 return i
.get_status()
219 return ifaceStatus
.SUCCESS
221 def get_iface_refcnt(self
, ifacename
):
223 ifaceobjs
= self
.get_iface_objs(ifacename
)
225 if i
.get_refcnt() > max:
229 def create_n_save_ifaceobj(self
, ifacename
, priv_flags
=None,
231 """ creates and returns a fake vlan iface object.
232 This was added to support creation of simple vlan
233 devices without any user specified configuration.
236 ifaceobj
.set_name(ifacename
)
237 ifaceobj
.priv_flags
= priv_flags
240 ifaceobj
.inc_refcnt()
241 self
.ifaceobjdict
[ifacename
] = [ifaceobj
]
243 def is_iface_builtin_byname(self
, ifacename
):
244 """ Returns true if iface name is a builtin interface.
246 A builtin interface is an interface which ifupdown understands.
247 The following are currently considered builtin ifaces:
248 - vlan interfaces in the format <ifacename>.<vlanid>
250 return '.' in ifacename
252 def is_ifaceobj_builtin(self
, ifaceobj
):
253 """ Returns true if iface name is a builtin interface.
255 A builtin interface is an interface which ifupdown understands.
256 The following are currently considered builtin ifaces:
257 - vlan interfaces in the format <ifacename>.<vlanid>
259 return (ifaceobj
.priv_flags
& self
.BUILTIN
)
261 def is_ifaceobj_noconfig(self
, ifaceobj
):
262 """ Returns true if iface name did not have a user defined config.
264 These interfaces appear only when they are dependents of interfaces
265 which have user defined config
267 return (ifaceobj
.priv_flags
& self
.NOCONFIG
)
269 def is_iface_noconfig(self
, ifacename
):
270 """ Returns true if iface has no config """
272 ifaceobj
= self
.get_iface_obj_first(ifacename
)
273 if not ifaceobj
: return True
275 return self
.is_ifaceobj_noconfig(ifaceobj
)
277 def preprocess_dependency_list(self
, dlist
, ops
):
278 """ We go through the dependency list and
279 delete or add interfaces from the interfaces dict by
280 applying the following rules:
281 if flag _DELETE_DEPENDENT_IFACES_WITH_NOCONFIG is True:
282 we only consider devices whose configuration was
283 specified in the network interfaces file. We delete
284 any interface whose config was not specified except
285 for vlan devices. vlan devices get special treatment.
286 Even if they are not present they are created and added
288 elif flag _DELETE_DEPENDENT_IFACES_WITH_NOCONFIG is False:
289 we create objects for all dependent devices that are not
290 present in the ifacesdict
295 dilist
= self
.get_iface_objs(d
)
297 if self
.is_iface_builtin_byname(d
):
298 self
.create_n_save_ifaceobj(d
,
299 self
.BUILTIN | self
.NOCONFIG
, True),
300 elif self
._DELETE
_DEPENDENT
_IFACES
_WITH
_NOCONFIG
== False:
301 # create fake devices to all dependents that dont
303 self
.create_n_save_ifaceobj(d
, self
.NOCONFIG
, True),
313 def query_dependents(self
, ifaceobj
, ops
):
314 """ Gets iface dependents by calling into respective modules """
317 # Get dependents for interface by querying respective modules
319 for mname
in self
.operations
.get(op
):
320 module
= self
.modules
.get(mname
)
321 if op
== 'query-running':
323 'get_dependent_ifacenames_running') == False):
325 dlist
= module
.get_dependent_ifacenames_running(ifaceobj
)
327 if (hasattr(module
, 'get_dependent_ifacenames') == False):
329 dlist
= module
.get_dependent_ifacenames(ifaceobj
,
330 self
.ifaceobjdict
.keys())
331 if dlist
and len(dlist
):
332 ifaceobj
.set_realdev_dependents(dlist
[:])
333 self
.logger
.debug('%s: ' %ifaceobj
.get_name() +
334 'got dependency list: %s' %str
(dlist
))
338 def populate_dependency_info(self
, ifacenames
, ops
):
339 """ recursive function to generate iface dependency info """
341 if ifacenames
is None:
342 ifacenames
= self
.ifaceobjdict
.keys()
344 self
.logger
.debug('populating dependency info for %s' %str
(ifacenames
))
346 iqueue
= deque(ifacenames
)
350 # Go through all modules and find dependent ifaces
352 ifaceobj
= self
.get_iface_obj_first(i
)
356 dlist
= ifaceobj
.get_dependents()
358 dlist
= self
.query_dependents(ifaceobj
, ops
)
362 if dlist
is not None:
363 self
.preprocess_dependency_list(dlist
, ops
)
364 self
.logger
.debug('%s: dependency list after processing: %s'
366 ifaceobj
.set_dependents(dlist
)
367 [iqueue
.append(d
) for d
in dlist
]
369 if self
.dependency_graph
.get(i
) is None:
370 self
.dependency_graph
[i
] = dlist
372 def _save_iface(self
, ifaceobj
):
373 if not self
.ifaceobjdict
.get(ifaceobj
.get_name()):
374 self
.ifaceobjdict
[ifaceobj
.get_name()] = [ifaceobj
]
376 self
.ifaceobjdict
[ifaceobj
.get_name()].append(ifaceobj
)
378 def _module_syntax_checker(self
, attrname
, attrval
):
379 for m
, mdict
in self
.module_attrs
.items():
380 attrsdict
= mdict
.get('attrs')
381 if attrsdict
and attrname
in attrsdict
.keys(): return True
384 def read_default_iface_config(self
):
385 """ Reads default network interface config /etc/network/interfaces. """
386 nifaces
= networkInterfaces()
387 nifaces
.subscribe('iface_found', self
._save
_iface
)
388 nifaces
.subscribe('validate', self
._module
_syntax
_checker
)
391 def read_iface_config(self
):
392 return self
.read_default_iface_config()
394 def read_old_iface_config(self
):
395 """ Reads the saved iface config instead of default iface config. """
397 # Read it from the statemanager
398 self
.ifaceobjdict
= self
.statemanager
.get_ifaceobjdict()
400 def load_addon_modules_config(self
):
401 with
open(self
.addon_modules_configfile
, 'r') as f
:
402 lines
= f
.readlines()
404 litems
= l
.rstrip(' \n').split(',')
405 operation
= litems
[0]
407 self
.operations
[operation
].append(mname
)
409 def load_addon_modules(self
, modules_dir
):
410 """ load python modules from modules_dir
412 Default modules_dir is /usr/share/ifupdownmodules
415 self
.logger
.info('loading builtin modules from %s' %modules_dir
)
416 self
.load_addon_modules_config()
417 if not modules_dir
in sys
.path
:
418 sys
.path
.append(modules_dir
)
420 for op
, mlist
in self
.operations
.items():
422 if self
.modules
.get(mname
) is not None:
424 mpath
= modules_dir
+ '/' + mname
+ '.py'
425 if os
.path
.exists(mpath
):
427 m
= __import__(mname
)
428 mclass
= getattr(m
, mname
)
431 minstance
= mclass(force
=self
.FORCE
,
434 perfmode
=self
.PERFMODE
,
436 self
.modules
[mname
] = minstance
437 if hasattr(minstance
, 'get_modinfo'):
438 self
.module_attrs
[mname
] = minstance
.get_modinfo()
442 # Assign all modules to query operations
443 self
.operations
['query-checkcurr'] = self
.modules
.keys()
444 self
.operations
['query-running'] = self
.modules
.keys()
445 self
.operations
['query-dependency'] = self
.modules
.keys()
446 self
.operations
['query'] = self
.modules
.keys()
447 self
.operations
['query-raw'] = self
.modules
.keys()
449 def modules_help(self
):
451 for m
, mdict
in self
.module_attrs
.items():
454 print('%s: %s' %(m
, mdict
.get('mhelp')))
455 attrdict
= mdict
.get('attrs')
459 for attrname
, attrvaldict
in attrdict
.items():
460 if attrvaldict
.get('compat', False):
462 print('%s%s' %(indent
, attrname
))
463 print('%shelp: %s' %(indent
+ ' ',
464 attrvaldict
.get('help', '')))
465 print ('%srequired: %s' %(indent
+ ' ',
466 attrvaldict
.get('required', False)))
467 default
= attrvaldict
.get('default')
469 print('%sdefault: %s' %(indent
+ ' ', default
))
471 validrange
= attrvaldict
.get('validrange')
473 print('%svalidrange: %s'
474 %(indent
+ ' ', '-'.join(validrange
)))
476 validvals
= attrvaldict
.get('validvals')
478 print('%svalidvals: %s'
479 %(indent
+ ' ', ','.join(validvals
)))
481 examples
= attrvaldict
.get('example')
485 print '%sexample:' %(indent
+ ' ')
487 print '%s%s' %(indent
+ ' ', e
)
492 def load_scripts(self
, modules_dir
):
493 """ loading user modules from /etc/network/.
495 Note that previously loaded python modules override modules found
496 under /etc/network if any
500 self
.logger
.info('looking for user scripts under %s' %modules_dir
)
501 for op
, mlist
in self
.operations_compat
.items():
502 msubdir
= modules_dir
+ '/if-%s.d' %op
503 self
.logger
.info('loading scripts under %s ...' %msubdir
)
505 module_list
= os
.listdir(msubdir
)
506 for module
in module_list
:
507 if self
.modules
.get(module
) is not None:
509 self
.operations_compat
[op
].append(
510 msubdir
+ '/' + module
)
514 def conv_iface_namelist_to_objlist(self
, intf_list
):
515 for intf
in intf_list
:
516 iface_obj
= self
.get_iface(intf
)
518 raise ifupdownInvalidValue('no iface %s', intf
)
519 iface_objs
.append(iface_obj
)
523 def run_without_dependents(self
, ops
, ifacenames
):
524 """ Run interface list without their dependents """
526 raise ifupdownInvalidValue('no interfaces found')
528 self
.logger
.debug('run_without_dependents for ops %s for %s'
529 %(str(ops
), str(ifacenames
)))
531 ifaceSched
= ifaceScheduler(force
=self
.FORCE
)
532 ifaceSched
.run_iface_list(self
, ifacenames
, ops
,
533 order
=ifaceSchedulerFlags
.INORDER
535 else ifaceSchedulerFlags
.POSTORDER
,
536 followdependents
=False)
538 def run_with_dependents(self
, ops
, ifacenames
):
540 self
.logger
.debug('running \'%s\' with dependents for %s'
541 %(str(ops
), str(ifacenames
)))
543 ifaceSched
= ifaceScheduler()
544 if ifacenames
is None:
545 ifacenames
= self
.ifaceobjdict
.keys()
547 if self
.logger
.isEnabledFor(logging
.DEBUG
):
548 self
.logger
.debug('dependency graph:')
549 self
.logger
.debug(self
.pp
.pformat(self
.dependency_graph
))
552 ret
= ifaceSched
.run_iface_dependency_graph_parallel(self
,
553 self
.dependency_graph
, ops
)
555 ret
= ifaceSched
.run_iface_dependency_graphs(self
,
556 self
.dependency_graph
, ops
,
557 order
=ifaceSchedulerFlags
.INORDER
559 else ifaceSchedulerFlags
.POSTORDER
)
562 def print_dependency(self
, ifacenames
, format
):
563 if ifacenames
is None:
564 ifacenames
= self
.ifaceobjdict
.keys()
567 for k
,v
in self
.dependency_graph
.items():
568 print '%s : %s' %(k
, str(v
))
569 elif format
== 'dot':
571 map(lambda i
: indegrees
.update({i
:
572 self
.get_iface_refcnt(i
)}),
573 self
.dependency_graph
.keys())
574 graph
.generate_dots(self
.dependency_graph
, indegrees
)
576 def validate_ifaces(self
, ifacenames
):
577 """ validates interface list for config existance.
579 returns -1 if one or more interface not found. else, returns 0
585 ifaceobjs
= self
.get_iface_objs(i
)
586 if ifaceobjs
is None:
590 self
.logger
.error('could not find interfaces: %s' %err_iface
)
596 def iface_whitelisted(self
, auto
, allow_classes
, excludepats
, ifacename
):
597 """ Checks if interface is whitelisted depending on set of parameters.
600 interfaces are checked against the allow_classes and auto lists.
603 # If the interface matches
604 if excludepats
and len(excludepats
):
605 for e
in excludepats
:
606 if re
.search(e
, ifacename
):
609 ifaceobjs
= self
.get_iface_objs(ifacename
)
610 if ifaceobjs
is None:
611 self
.logger
.debug('iface %s' %ifacename
+ ' not found')
614 # We check classes first
615 if allow_classes
and len(allow_classes
):
617 if len(i
.get_classes()):
618 common
= Set([allow_classes
]).intersection(
619 Set(i
.get_classes()))
632 def generate_running_env(self
, ifaceobj
, op
):
633 """ Generates a dictionary with env variables required for
634 an interface. Used to support script execution for interfaces.
638 iface_env
= ifaceobj
.get_env()
639 if iface_env
is not None:
642 cenv
.update(iface_env
)
646 cenv
['MODE'] = self
.compat_conv_op_to_mode(op
)
650 def up(self
, ops
, auto
=False, allow_classes
=None, ifacenames
=None,
651 excludepats
=None, printdependency
=None):
654 self
.WITH_DEPENDS
= True
657 self
.read_iface_config()
661 if ifacenames
is not None:
662 # If iface list is given by the caller, always check if iface
664 if self
.validate_ifaces(ifacenames
) != 0:
665 raise Exception('all or some interfaces not found')
667 # if iface list not given by user, assume all from config file
668 if ifacenames
is None: ifacenames
= self
.ifaceobjdict
.keys()
670 # filter interfaces based on auto and allow classes
671 filtered_ifacenames
= [i
for i
in ifacenames
672 if self
.iface_whitelisted(auto
, allow_classes
,
674 if not len(filtered_ifacenames
):
675 raise Exception('no ifaces found matching given allow lists')
677 self
.populate_dependency_info(filtered_ifacenames
, ops
)
679 if printdependency
is not None:
680 self
.print_dependency(filtered_ifacenames
, printdependency
)
683 if self
.WITH_DEPENDS
:
684 self
.run_with_dependents(ops
, filtered_ifacenames
)
686 self
.run_without_dependents(ops
, filtered_ifacenames
)
688 # Update persistant iface states
691 self
.statemanager
.flush_state(self
.ifaceobjdict
)
693 self
.statemanager
.flush_state()
695 if self
.logger
.isEnabledFor(logging
.DEBUG
):
696 t
= sys
.exc_info()[2]
697 traceback
.print_tb(t
)
698 self
.logger
.warning('error saving state (%s)' %str
(e
))
700 def down(self
, ops
, auto
=False, allow_classes
=None, ifacenames
=None,
701 excludepats
=None, printdependency
=None):
702 loaded_newconfig
= False
705 self
.WITH_DEPENDS
= True
707 # for down we need to look at old state
708 self
.logger
.debug('Looking at old state ..')
710 if len(self
.statemanager
.get_ifaceobjdict()):
711 self
.read_old_iface_config()
713 # If no old state available
714 self
.logger
.info('old state not available. ' +
715 'Force option set. Loading new iface config file')
717 self
.read_iface_config()
719 raise Exception('error reading iface config (%s)' %str
(e
))
720 loaded_newconfig
= True
722 raise Exception('old state not available...aborting.' +
723 ' try running with --force option')
726 # If iface list is given by the caller, always check if iface
728 if self
.validate_ifaces(ifacenames
) != 0:
729 raise Exception('all or some interfaces not found')
731 # if iface list not given by user, assume all from config file
732 if ifacenames
is None: ifacenames
= self
.ifaceobjdict
.keys()
734 # filter interfaces based on auto and allow classes
735 filtered_ifacenames
= [i
for i
in ifacenames
736 if self
.iface_whitelisted(auto
, allow_classes
,
738 if not len(filtered_ifacenames
):
739 raise Exception('no ifaces found matching given allow lists')
741 self
.populate_dependency_info(filtered_ifacenames
, ops
)
743 self
.print_dependency(filtered_ifacenames
, printdependency
)
746 if self
.WITH_DEPENDS
:
747 self
.run_with_dependents(ops
, filtered_ifacenames
)
749 self
.run_without_dependents(ops
, filtered_ifacenames
)
752 # Update persistant iface states
755 self
.statemanager
.flush_state(self
.ifaceobjdict
)
757 self
.statemanager
.flush_state()
759 if self
.logger
.isEnabledFor(logging
.DEBUG
):
760 t
= sys
.exc_info()[2]
761 traceback
.print_tb(t
)
762 self
.logger
.warning('error saving state (%s)' %str
(e
))
764 def query(self
, ops
, auto
=False, allow_classes
=None, ifacenames
=None,
765 excludepats
=None, printdependency
=None,
768 self
.logger
.debug('setting flag ALL')
770 self
.WITH_DEPENDS
= True
772 if ops
[0] == 'query-syntax':
775 elif ops
[0] == 'query-running':
776 # create fake devices to all dependents that dont have config
777 map(lambda i
: self
.create_n_save_ifaceobj(i
, self
.NOCONFIG
),
781 self
.read_iface_config()
785 if ifacenames
is not None and ops
[0] != 'query-running':
786 # If iface list is given, always check if iface is present
787 if self
.validate_ifaces(ifacenames
) != 0:
788 raise Exception('all or some interfaces not found')
790 # if iface list not given by user, assume all from config file
791 if ifacenames
is None: ifacenames
= self
.ifaceobjdict
.keys()
793 # filter interfaces based on auto and allow classes
794 if ops
[0] == 'query-running':
795 filtered_ifacenames
= ifacenames
797 filtered_ifacenames
= [i
for i
in ifacenames
798 if self
.iface_whitelisted(auto
, allow_classes
,
800 if len(filtered_ifacenames
) == 0:
801 raise Exception('no ifaces found matching ' +
804 self
.populate_dependency_info(filtered_ifacenames
, ops
)
805 if ops
[0] == 'query-dependency' and printdependency
:
806 self
.print_dependency(filtered_ifacenames
, printdependency
)
809 if ops
[0] == 'query':
810 return self
.print_ifaceobjs_pretty(filtered_ifacenames
, format
)
811 elif ops
[0] == 'query-raw':
812 return self
.print_ifaceobjs_raw(filtered_ifacenames
)
814 if self
.WITH_DEPENDS
:
815 self
.run_with_dependents(ops
, filtered_ifacenames
)
817 self
.run_without_dependents(ops
, filtered_ifacenames
)
819 if ops
[0] == 'query-checkcurr':
820 ret
= self
.print_ifaceobjscurr_pretty(filtered_ifacenames
, format
)
822 # if any of the object has an error, signal that silently
824 elif ops
[0] == 'query-running':
825 self
.print_ifaceobjsrunning_pretty(filtered_ifacenames
, format
)
828 def reload(self
, auto
=False, allow
=None,
829 ifacenames
=None, excludepats
=None, downchangediface
=False):
830 """ main ifupdown run method """
832 upops
= ['pre-up', 'up', 'post-up']
833 downops
= ['pre-down', 'down', 'post-down']
835 self
.logger
.debug('reloading interface config ..')
839 self
.WITH_DEPENDS
= True
842 # Read the current interface config
843 self
.read_iface_config()
847 # generate dependency graph of interfaces
848 self
.populate_dependency_info(ifacenames
, upops
)
850 # Save a copy of new iface objects and dependency_graph
851 new_ifaceobjdict
= dict(self
.get_ifaceobjdict())
852 new_dependency_graph
= dict(self
.get_dependency_graph())
854 if len(self
.statemanager
.get_ifaceobjdict()) > 0:
855 # if old state is present, read old state and mark op for 'down'
856 # followed by 'up' aka: reload
857 # old interface config is read into self.ifaceobjdict
859 self
.read_old_iface_config()
862 # oldconfig not available, continue with 'up' with new config
865 if ifacenames
is None: ifacenames
= self
.ifaceobjdict
.keys()
867 if (op
== 'reload' and ifacenames
is not None and
868 len(ifacenames
) != 0):
869 filtered_ifacenames
= [i
for i
in ifacenames
870 if self
.iface_whitelisted(auto
, allow_classes
,
873 # Generate the interface down list
874 # Interfaces that go into the down list:
875 # - interfaces that were present in last config and are not
876 # present in the new config
877 # - interfaces that were changed between the last and current
881 for ifname
, lastifobjlist
in self
.ifaceobjdict
.items():
884 # If interface is not present in the new file
885 # append it to the down list
886 newifobjlist
= new_ifaceobjdict
.get(ifname
)
887 if newifobjlist
== None:
888 ifacedownlist
.append(ifname
)
891 if downchangediface
== False:
894 # If interface has changed between the current file
895 # and the last installed append it to the down list
896 if len(newifobjlist
) != len(lastifobjlist
):
897 ifacedownlist
.append(ifname
)
900 # compare object list
901 for objidx
in range(0, len(lastifobjlist
)):
902 oldobj
= lastifobjlist
[objidx
]
903 newobj
= newifobjlist
[objidx
]
904 if newobj
.is_different(oldobj
):
905 ifacedownlist
.append(ifname
)
909 if ifacedownlist
is not None and len(ifacedownlist
) > 0:
910 self
.logger
.info('Executing down on interfaces: %s'
912 # Generate dependency info for old config
913 self
.populate_dependency_info(ifacedownlist
, downops
)
914 if len(ifacedownlist
) == len(self
.ifaceobjdict
):
915 # if you are downing all interfaces, its better run
917 self
.run_with_dependents(downops
, ifacedownlist
)
919 # if not, down only the interfaces that we have in the
921 self
.run_without_dependents(downops
, ifacedownlist
)
922 # Update persistant iface states
925 self
.statemanager
.flush_state(self
.ifaceobjdict
)
927 self
.statemanager
.flush_state()
929 if self
.logger
.isEnabledFor(logging
.DEBUG
):
930 t
= sys
.exc_info()[2]
931 traceback
.print_tb(t
)
932 self
.logger
.warning('error saving state (%s)' %str
(e
))
934 self
.logger
.debug('no interfaces to down ..')
936 # Now, run up with new config dict
937 self
.set_ifaceobjdict(new_ifaceobjdict
)
938 self
.set_dependency_graph(new_dependency_graph
)
940 ifacenames
= self
.ifaceobjdict
.keys()
941 filtered_ifacenames
= [i
for i
in ifacenames
942 if self
.iface_whitelisted(auto
, allow_classes
,
945 self
.logger
.info('Executing up on interfaces: %s'
946 %str
(filtered_ifacenames
))
947 if self
.WITH_DEPENDS
:
948 self
.run_with_dependents(upops
, filtered_ifacenames
)
950 self
.run_without_dependents(upops
, filtered_ifacenames
)
952 # Update persistant iface states
955 self
.statemanager
.flush_state(self
.get_ifaceobjdict())
957 self
.statemanager
.flush_state()
959 if self
.logger
.isEnabledFor(logging
.DEBUG
):
960 t
= sys
.exc_info()[2]
961 traceback
.print_tb(t
)
962 self
.logger
.warning('error saving state (%s)' %str
(e
))
965 """ all state dump """
967 print 'ifupdown object dump'
968 print self
.pp
.pprint(self
.modules
)
969 print self
.pp
.pprint(self
.ifaces
)
970 self
.state_manager
.dump()
972 def print_state(self
, ifacenames
=None):
973 self
.statemanager
.dump(ifacenames
)
975 def print_ifaceobjs_raw(self
, ifacenames
):
977 for ifaceobj
in self
.get_iface_objs(i
):
978 if (self
.is_ifaceobj_builtin(ifaceobj
) or
979 not ifaceobj
.is_config_present()):
981 ifaceobj
.dump_raw(self
.logger
)
983 if self
.WITH_DEPENDS
:
984 dlist
= ifaceobj
.get_dependents()
985 if not dlist
or not len(dlist
): continue
986 self
.print_ifaceobjs_pretty(dlist
, format
)
988 def print_ifaceobjs_pretty(self
, ifacenames
, format
='native'):
990 for ifaceobj
in self
.get_iface_objs(i
):
991 if (self
.is_ifaceobj_builtin(ifaceobj
) or
992 not ifaceobj
.is_config_present()):
997 ifaceobj
.dump_pretty()
999 if self
.WITH_DEPENDS
:
1000 dlist
= ifaceobj
.get_dependents()
1001 if not dlist
or not len(dlist
): continue
1002 self
.print_ifaceobjs_pretty(dlist
, format
)
1004 def dump_ifaceobjs(self
, ifacenames
):
1005 for i
in ifacenames
:
1006 ifaceobjs
= self
.get_iface_objs(i
)
1011 def print_ifaceobjscurr_pretty(self
, ifacenames
, format
='native'):
1012 """ Dumps current running state of interfaces.
1014 returns 1 if any of the interface has an error,
1018 for i
in ifacenames
:
1019 ifaceobj
= self
.get_ifaceobjcurr(i
)
1020 if not ifaceobj
: continue
1021 if ifaceobj
.get_status() == ifaceStatus
.NOTFOUND
:
1022 print 'iface %s' %ifaceobj
.get_name() + ' (not found)\n'
1025 elif ifaceobj
.get_status() == ifaceStatus
.ERROR
:
1028 if (self
.is_ifaceobj_builtin(ifaceobj
) or
1029 ifaceobj
.is_config_present() == False):
1032 if format
== 'json':
1033 ifaceobj
.dump_json()
1035 ifaceobj
.dump_pretty()
1037 if self
.WITH_DEPENDS
:
1038 dlist
= ifaceobj
.get_dependents()
1039 if not dlist
or not len(dlist
): continue
1040 self
.print_ifaceobjscurr_pretty(dlist
, format
)
1044 def print_ifaceobjsrunning_pretty(self
, ifacenames
, format
='native'):
1045 for i
in ifacenames
:
1046 ifaceobj
= self
.get_iface_obj_first(i
)
1047 if ifaceobj
.get_status() == ifaceStatus
.NOTFOUND
:
1048 print 'iface %s' %ifaceobj
.get_name() + ' (not found)\n'
1051 if ifaceobj
.is_config_present() == False:
1054 if format
== 'json':
1055 ifaceobj
.dump_json()
1057 ifaceobj
.dump_pretty()
1059 if self
.WITH_DEPENDS
:
1060 dlist
= ifaceobj
.get_dependents()
1061 if dlist
is None or len(dlist
) == 0: continue
1062 self
.print_ifaceobjsrunning_pretty(dlist
, format
)
1065 def print_ifaceobjs_saved_state_pretty(self
, ifacenames
):
1066 self
.statemanager
.print_state_pretty(ifacenames
, self
.logger
)
1068 def print_ifaceobjs_saved_state_detailed_pretty(self
, ifacenames
):
1069 self
.statemanager
.print_state_detailed_pretty(ifacenames
, self
.logger
)