mirror of
				https://github.com/CumulusNetworks/ifupdown2.git
				synced 2024-05-06 15:54:50 +00:00 
			
		
		
		
	the tree)
Ticket: CM-7765
Reviewed By: CCR-3621
Testing Done: tested interface dependencies with auto and non-auto
interfaces
This commit fixes a change in behaviour introduced by "460906d0552d" ("skip adding
filtered or blacklisted interfaces in the dependency graph") that
skipped non-auto (or blacklisted) interfaces.
Turns out we have files out there that do have non-auto
dependents. This patch makes sure blacklisted interfaces who are
dependents of other interfaces are always picked up.
		
	
		
			
				
	
	
		
			95 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			95 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
#!/usr/bin/python
 | 
						|
#
 | 
						|
# Copyright 2014 Cumulus Networks, Inc. All rights reserved.
 | 
						|
# Author: Roopa Prabhu, roopa@cumulusnetworks.com
 | 
						|
#
 | 
						|
# graph --
 | 
						|
#    graph helper module for ifupdown
 | 
						|
#
 | 
						|
 | 
						|
import logging
 | 
						|
import copy
 | 
						|
from collections import deque
 | 
						|
try:
 | 
						|
    from gvgen import *
 | 
						|
except ImportError, e:
 | 
						|
    pass
 | 
						|
 | 
						|
class graph():
 | 
						|
    """ graph functions to sort and print interface graph """
 | 
						|
 | 
						|
    def __init__(self):
 | 
						|
        self.logger = logging.getLogger('ifupdown.' +
 | 
						|
                    self.__class__.__name__)
 | 
						|
 | 
						|
    @classmethod
 | 
						|
    def topological_sort_graphs_all(cls, dependency_graphs, indegrees_arg):
 | 
						|
        """ runs topological sort on interface list passed as dependency graph
 | 
						|
 | 
						|
        Args:
 | 
						|
            **dependency_graphs** (dict): dependency graph with dependency
 | 
						|
                                          lists for interfaces 
 | 
						|
 | 
						|
            **indegrees_arg** (dict): indegrees array for all interfaces
 | 
						|
        """
 | 
						|
        S = []
 | 
						|
        Q = deque()
 | 
						|
 | 
						|
        indegrees = copy.deepcopy(indegrees_arg)
 | 
						|
        for ifname,indegree in indegrees.items():
 | 
						|
            if indegree == 0:
 | 
						|
                Q.append(ifname)
 | 
						|
 | 
						|
        while len(Q):
 | 
						|
            # initialize queue
 | 
						|
            x = Q.popleft()
 | 
						|
 | 
						|
            # Get dependents of x
 | 
						|
            dlist = dependency_graphs.get(x)
 | 
						|
            if not dlist:
 | 
						|
                S.append(x)
 | 
						|
                continue
 | 
						|
 | 
						|
            for y in dlist:
 | 
						|
                try:
 | 
						|
                    indegrees[y] = indegrees.get(y) - 1
 | 
						|
                except:
 | 
						|
                    self.logger.debug('topological_sort_graphs_all: did not find %s' %y)
 | 
						|
                    indegrees[y] = 0
 | 
						|
                    pass
 | 
						|
                if indegrees.get(y) == 0:
 | 
						|
                    Q.append(y)
 | 
						|
 | 
						|
            S.append(x)
 | 
						|
 | 
						|
        for ifname,indegree in indegrees.items():
 | 
						|
            if indegree != 0:
 | 
						|
                raise Exception('cycle found involving iface %s' %ifname +
 | 
						|
                                ' (indegree %d)' %indegree)
 | 
						|
 | 
						|
        return S
 | 
						|
 | 
						|
    @classmethod
 | 
						|
    def generate_dots(cls, dependency_graph, indegrees):
 | 
						|
        """ spits out interface dependency graph in dot format
 | 
						|
 | 
						|
        Args:
 | 
						|
            **dependency_graphs** (dict): dependency graph with dependency
 | 
						|
                                          lists for interfaces 
 | 
						|
 | 
						|
            **indegrees_arg** (dict): indegrees array for all interfaces
 | 
						|
        """
 | 
						|
 | 
						|
        gvgraph = GvGen()
 | 
						|
        graphnodes = {}
 | 
						|
        for v in dependency_graph.keys():
 | 
						|
            graphnodes[v] = gvgraph.newItem(v)
 | 
						|
 | 
						|
        for i, v in graphnodes.items():
 | 
						|
            dlist = dependency_graph.get(i, [])
 | 
						|
            if not dlist:
 | 
						|
                continue
 | 
						|
            for d in dlist:
 | 
						|
                gvgraph.newLink(v, graphnodes.get(d))
 | 
						|
        gvgraph.dot()
 |