summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container_graph.go24
-rw-r--r--libpod/container_graph_test.go26
-rw-r--r--libpod/container_internal.go2
-rw-r--r--libpod/pod_api.go4
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())
}