diff options
Diffstat (limited to 'libpod')
-rw-r--r-- | libpod/container_graph.go | 24 | ||||
-rw-r--r-- | libpod/container_graph_test.go | 26 | ||||
-rw-r--r-- | libpod/container_internal.go | 2 | ||||
-rw-r--r-- | libpod/pod_api.go | 4 |
4 files changed, 36 insertions, 20 deletions
diff --git a/libpod/container_graph.go b/libpod/container_graph.go index 5aa51bc2f..f6988e1ac 100644 --- a/libpod/container_graph.go +++ b/libpod/container_graph.go @@ -16,14 +16,30 @@ type containerNode struct { dependedOn []*containerNode } -type containerGraph struct { +// ContainerGraph is a dependency graph based on a set of containers. +type ContainerGraph struct { nodes map[string]*containerNode noDepNodes []*containerNode notDependedOnNodes map[string]*containerNode } -func buildContainerGraph(ctrs []*Container) (*containerGraph, error) { - graph := new(containerGraph) +// DependencyMap returns the dependency graph as map with the key being a +// container and the value being the containers the key depends on. +func (cg *ContainerGraph) DependencyMap() (dependencies map[*Container][]*Container) { + dependencies = make(map[*Container][]*Container) + for _, node := range cg.nodes { + dependsOn := make([]*Container, len(node.dependsOn)) + for i, d := range node.dependsOn { + dependsOn[i] = d.container + } + dependencies[node.container] = dependsOn + } + return dependencies +} + +// BuildContainerGraph builds a dependency graph based on the container slice. +func BuildContainerGraph(ctrs []*Container) (*ContainerGraph, error) { + graph := new(ContainerGraph) graph.nodes = make(map[string]*containerNode) graph.notDependedOnNodes = make(map[string]*containerNode) @@ -78,7 +94,7 @@ func buildContainerGraph(ctrs []*Container) (*containerGraph, error) { // Detect cycles in a container graph using Tarjan's strongly connected // components algorithm // Return true if a cycle is found, false otherwise -func detectCycles(graph *containerGraph) (bool, error) { +func detectCycles(graph *ContainerGraph) (bool, error) { type nodeInfo struct { index int lowLink int diff --git a/libpod/container_graph_test.go b/libpod/container_graph_test.go index d1a52658d..38f03c59c 100644 --- a/libpod/container_graph_test.go +++ b/libpod/container_graph_test.go @@ -8,7 +8,7 @@ import ( ) func TestBuildContainerGraphNoCtrsIsEmpty(t *testing.T) { - graph, err := buildContainerGraph([]*Container{}) + graph, err := BuildContainerGraph([]*Container{}) assert.NoError(t, err) assert.Equal(t, 0, len(graph.nodes)) assert.Equal(t, 0, len(graph.noDepNodes)) @@ -24,7 +24,7 @@ func TestBuildContainerGraphOneCtr(t *testing.T) { ctr1, err := getTestCtr1(manager) assert.NoError(t, err) - graph, err := buildContainerGraph([]*Container{ctr1}) + graph, err := BuildContainerGraph([]*Container{ctr1}) assert.NoError(t, err) assert.Equal(t, 1, len(graph.nodes)) assert.Equal(t, 1, len(graph.noDepNodes)) @@ -49,7 +49,7 @@ func TestBuildContainerGraphTwoCtrNoEdge(t *testing.T) { ctr2, err := getTestCtr2(manager) assert.NoError(t, err) - graph, err := buildContainerGraph([]*Container{ctr1, ctr2}) + graph, err := BuildContainerGraph([]*Container{ctr1, ctr2}) assert.NoError(t, err) assert.Equal(t, 2, len(graph.nodes)) assert.Equal(t, 2, len(graph.noDepNodes)) @@ -76,7 +76,7 @@ func TestBuildContainerGraphTwoCtrOneEdge(t *testing.T) { assert.NoError(t, err) ctr2.config.UserNsCtr = ctr1.config.ID - graph, err := buildContainerGraph([]*Container{ctr1, ctr2}) + graph, err := BuildContainerGraph([]*Container{ctr1, ctr2}) assert.NoError(t, err) assert.Equal(t, 2, len(graph.nodes)) assert.Equal(t, 1, len(graph.noDepNodes)) @@ -99,7 +99,7 @@ func TestBuildContainerGraphTwoCtrCycle(t *testing.T) { ctr2.config.UserNsCtr = ctr1.config.ID ctr1.config.NetNsCtr = ctr2.config.ID - _, err = buildContainerGraph([]*Container{ctr1, ctr2}) + _, err = BuildContainerGraph([]*Container{ctr1, ctr2}) assert.Error(t, err) } @@ -116,7 +116,7 @@ func TestBuildContainerGraphThreeCtrNoEdges(t *testing.T) { ctr3, err := getTestCtrN("3", manager) assert.NoError(t, err) - graph, err := buildContainerGraph([]*Container{ctr1, ctr2, ctr3}) + graph, err := BuildContainerGraph([]*Container{ctr1, ctr2, ctr3}) assert.NoError(t, err) assert.Equal(t, 3, len(graph.nodes)) assert.Equal(t, 3, len(graph.noDepNodes)) @@ -150,7 +150,7 @@ func TestBuildContainerGraphThreeContainersTwoInCycle(t *testing.T) { ctr1.config.UserNsCtr = ctr2.config.ID ctr2.config.IPCNsCtr = ctr1.config.ID - _, err = buildContainerGraph([]*Container{ctr1, ctr2, ctr3}) + _, err = BuildContainerGraph([]*Container{ctr1, ctr2, ctr3}) assert.Error(t, err) } @@ -170,7 +170,7 @@ func TestBuildContainerGraphThreeContainersCycle(t *testing.T) { ctr2.config.IPCNsCtr = ctr3.config.ID ctr3.config.NetNsCtr = ctr1.config.ID - _, err = buildContainerGraph([]*Container{ctr1, ctr2, ctr3}) + _, err = BuildContainerGraph([]*Container{ctr1, ctr2, ctr3}) assert.Error(t, err) } @@ -190,7 +190,7 @@ func TestBuildContainerGraphThreeContainersNoCycle(t *testing.T) { ctr1.config.NetNsCtr = ctr3.config.ID ctr2.config.IPCNsCtr = ctr3.config.ID - graph, err := buildContainerGraph([]*Container{ctr1, ctr2, ctr3}) + graph, err := BuildContainerGraph([]*Container{ctr1, ctr2, ctr3}) assert.NoError(t, err) assert.Equal(t, 3, len(graph.nodes)) assert.Equal(t, 1, len(graph.noDepNodes)) @@ -215,7 +215,7 @@ func TestBuildContainerGraphFourContainersNoEdges(t *testing.T) { ctr4, err := getTestCtrN("4", manager) assert.NoError(t, err) - graph, err := buildContainerGraph([]*Container{ctr1, ctr2, ctr3, ctr4}) + graph, err := BuildContainerGraph([]*Container{ctr1, ctr2, ctr3, ctr4}) assert.NoError(t, err) assert.Equal(t, 4, len(graph.nodes)) assert.Equal(t, 4, len(graph.noDepNodes)) @@ -256,7 +256,7 @@ func TestBuildContainerGraphFourContainersTwoInCycle(t *testing.T) { ctr1.config.IPCNsCtr = ctr2.config.ID ctr2.config.UserNsCtr = ctr1.config.ID - _, err = buildContainerGraph([]*Container{ctr1, ctr2, ctr3, ctr4}) + _, err = BuildContainerGraph([]*Container{ctr1, ctr2, ctr3, ctr4}) assert.Error(t, err) } @@ -280,7 +280,7 @@ func TestBuildContainerGraphFourContainersAllInCycle(t *testing.T) { ctr3.config.NetNsCtr = ctr4.config.ID ctr4.config.UTSNsCtr = ctr1.config.ID - _, err = buildContainerGraph([]*Container{ctr1, ctr2, ctr3, ctr4}) + _, err = BuildContainerGraph([]*Container{ctr1, ctr2, ctr3, ctr4}) assert.Error(t, err) } @@ -303,7 +303,7 @@ func TestBuildContainerGraphFourContainersNoneInCycle(t *testing.T) { ctr1.config.NetNsCtr = ctr3.config.ID ctr2.config.UserNsCtr = ctr3.config.ID - graph, err := buildContainerGraph([]*Container{ctr1, ctr2, ctr3, ctr4}) + graph, err := BuildContainerGraph([]*Container{ctr1, ctr2, ctr3, ctr4}) assert.NoError(t, err) assert.Equal(t, 4, len(graph.nodes)) assert.Equal(t, 2, len(graph.noDepNodes)) diff --git a/libpod/container_internal.go b/libpod/container_internal.go index 313f67963..f51b53e85 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -788,7 +788,7 @@ func (c *Container) startDependencies(ctx context.Context) error { } // Build a dependency graph of containers - graph, err := buildContainerGraph(depCtrs) + graph, err := BuildContainerGraph(depCtrs) if err != nil { return errors.Wrapf(err, "error generating dependency graph for container %s", c.ID()) } diff --git a/libpod/pod_api.go b/libpod/pod_api.go index c7b0353bd..e2448e92a 100644 --- a/libpod/pod_api.go +++ b/libpod/pod_api.go @@ -37,7 +37,7 @@ func (p *Pod) Start(ctx context.Context) (map[string]error, error) { } // Build a dependency graph of containers in the pod - graph, err := buildContainerGraph(allCtrs) + graph, err := BuildContainerGraph(allCtrs) if err != nil { return nil, errors.Wrapf(err, "error generating dependency graph for pod %s", p.ID()) } @@ -289,7 +289,7 @@ func (p *Pod) Restart(ctx context.Context) (map[string]error, error) { } // Build a dependency graph of containers in the pod - graph, err := buildContainerGraph(allCtrs) + graph, err := BuildContainerGraph(allCtrs) if err != nil { return nil, errors.Wrapf(err, "error generating dependency graph for pod %s", p.ID()) } |