1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Ensure child containers are started before parents

This commit is contained in:
Michael Crosby 2013-10-24 16:49:28 -07:00 committed by Victor Vieux
parent 2e6b241dc7
commit 356af1540f
5 changed files with 46 additions and 31 deletions

View file

@ -177,7 +177,7 @@ func (db *Database) get(name string) (*Entity, error) {
next := db.child(e, p)
if next == nil {
return nil, fmt.Errorf("Cannot find child")
return nil, fmt.Errorf("Cannot find child for %s", name)
}
e = next
}

View file

@ -9,7 +9,7 @@ type pathSorter struct {
func sortByDepth(paths []string) {
s := &pathSorter{paths, func(i, j string) bool {
return pathDepth(i) > pathDepth(j)
return PathDepth(i) > PathDepth(j)
}}
sort.Sort(s)
}

View file

@ -11,7 +11,7 @@ func split(p string) []string {
}
// Returns the depth or number of / in a given path
func pathDepth(p string) int {
func PathDepth(p string) int {
parts := split(p)
if len(parts) == 2 && parts[1] == "" {
return 1

View file

@ -230,7 +230,8 @@ func (runtime *Runtime) restore() error {
if err != nil {
return err
}
containers := []*Container{}
containers := make(map[string]*Container)
for i, v := range dir {
id := v.Name()
container, err := runtime.load(id)
@ -242,33 +243,34 @@ func (runtime *Runtime) restore() error {
continue
}
utils.Debugf("Loaded container %v", container.ID)
containers = append(containers, container)
containers[container.ID] = container
}
sortContainers(containers, func(i, j *Container) bool {
ic, _ := i.ReadHostConfig()
jc, _ := j.ReadHostConfig()
if ic == nil || ic.Links == nil {
return true
register := func(container *Container) {
if err := runtime.Register(container); err != nil {
utils.Debugf("Failed to register container %s: %s", container.ID, err)
}
if jc == nil || jc.Links == nil {
return false
}
if entities := runtime.containerGraph.List("/", -1); entities != nil {
for _, p := range entities.Paths() {
e := entities[p]
if container, ok := containers[e.ID()]; ok {
register(container)
delete(containers, e.ID())
}
}
return len(ic.Links) < len(jc.Links)
})
}
// Any containers that are left over do not exist in the graph
for _, container := range containers {
// Try to set the default name for a container if it exists prior to links
// Ignore the error because if it already exists you will get an invalid constraint
if _, err := runtime.containerGraph.Set(fmt.Sprintf("/%s", container.ID), container.ID); err != nil {
utils.Debugf("Setting default id - %s", err)
}
if err := runtime.Register(container); err != nil {
utils.Debugf("Failed to register container %s: %s", container.ID, err)
continue
}
register(container)
}
if os.Getenv("DEBUG") == "" && os.Getenv("TEST") == "" {
fmt.Printf("\bdone.\n")
}
@ -481,14 +483,24 @@ func (runtime *Runtime) Commit(container *Container, repository, tag, comment, a
return img, nil
}
func (runtime *Runtime) GetByName(name string) (*Container, error) {
if name[0] != '/' {
name = "/" + name
// Strip the leading slash from the name to look up if it
// is a truncated id
// Prepend the slash back after finding the name
func (runtime *Runtime) getFullName(name string) string {
if name[0] == '/' {
name = name[1:]
}
if id, err := runtime.idIndex.Get(name); err == nil {
name = id
}
if name[0] != '/' {
name = "/" + name
}
return name
}
func (runtime *Runtime) GetByName(name string) (*Container, error) {
name = runtime.getFullName(name)
entity := runtime.containerGraph.Get(name)
if entity == nil {
@ -520,17 +532,20 @@ func (runtime *Runtime) Children(name string) (map[string]*Container, error) {
}
func (runtime *Runtime) RenameLink(oldName, newName string) error {
if id, err := runtime.idIndex.Get(oldName); err == nil {
oldName = id
}
oldName = runtime.getFullName(oldName)
entity := runtime.containerGraph.Get(oldName)
if entity == nil {
return fmt.Errorf("Could not find entity for %s", oldName)
}
if newName[0] != '/' {
newName = "/" + newName
}
// This is not rename but adding a new link for the default name
// Strip the leading '/'
if strings.HasPrefix(entity.ID(), oldName[1:]) {
if entity.ID() == oldName[1:] {
_, err := runtime.containerGraph.Set(newName, entity.ID())
return err
}

View file

@ -572,7 +572,7 @@ func TestReloadContainerLinks(t *testing.T) {
}
h1 := &HostConfig{}
// Add a link to container 2
h1.Links = []string{utils.TruncateID(container2.ID) + ":first"}
h1.Links = []string{"/" + container2.ID + ":first"}
if err := container1.Start(h1); err != nil {
t.Fatal(err)
}
@ -618,7 +618,7 @@ func TestReloadContainerLinks(t *testing.T) {
t.Fatalf("Container 2 %s should be registered first in the runtime", container2.ID)
}
t.Logf("Number of links: %d", runtime2.containerGraph.Refs("engine"))
t.Logf("Number of links: %d", runtime2.containerGraph.Refs("0"))
// Verify that the link is still registered in the runtime
entity := runtime2.containerGraph.Get(fmt.Sprintf("/%s", container1.ID))
if entity == nil {