mirror of
https://github.com/containers/podman.git
synced 2025-12-03 19:59:39 +08:00
Merge pull request #3800 from vrothberg/generate-pod
generate systemd pod
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user