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) next := db.child(e, p)
if next == nil { if next == nil {
return nil, fmt.Errorf("Cannot find child") return nil, fmt.Errorf("Cannot find child for %s", name)
} }
e = next e = next
} }

View file

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

View file

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

View file

@ -230,7 +230,8 @@ func (runtime *Runtime) restore() error {
if err != nil { if err != nil {
return err return err
} }
containers := []*Container{} containers := make(map[string]*Container)
for i, v := range dir { for i, v := range dir {
id := v.Name() id := v.Name()
container, err := runtime.load(id) container, err := runtime.load(id)
@ -242,33 +243,34 @@ func (runtime *Runtime) restore() error {
continue continue
} }
utils.Debugf("Loaded container %v", container.ID) 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 { register := func(container *Container) {
return true 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 { for _, container := range containers {
// Try to set the default name for a container if it exists prior to links // 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 { if _, err := runtime.containerGraph.Set(fmt.Sprintf("/%s", container.ID), container.ID); err != nil {
utils.Debugf("Setting default id - %s", err) utils.Debugf("Setting default id - %s", err)
} }
register(container)
if err := runtime.Register(container); err != nil {
utils.Debugf("Failed to register container %s: %s", container.ID, err)
continue
}
} }
if os.Getenv("DEBUG") == "" && os.Getenv("TEST") == "" { if os.Getenv("DEBUG") == "" && os.Getenv("TEST") == "" {
fmt.Printf("\bdone.\n") fmt.Printf("\bdone.\n")
} }
@ -481,14 +483,24 @@ func (runtime *Runtime) Commit(container *Container, repository, tag, comment, a
return img, nil return img, nil
} }
func (runtime *Runtime) GetByName(name string) (*Container, error) { // Strip the leading slash from the name to look up if it
if name[0] != '/' { // is a truncated id
name = "/" + name // 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 { if id, err := runtime.idIndex.Get(name); err == nil {
name = id 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) entity := runtime.containerGraph.Get(name)
if entity == nil { 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 { func (runtime *Runtime) RenameLink(oldName, newName string) error {
if id, err := runtime.idIndex.Get(oldName); err == nil { oldName = runtime.getFullName(oldName)
oldName = id
}
entity := runtime.containerGraph.Get(oldName) entity := runtime.containerGraph.Get(oldName)
if entity == nil { if entity == nil {
return fmt.Errorf("Could not find entity for %s", oldName) 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 // This is not rename but adding a new link for the default name
// Strip the leading '/' // Strip the leading '/'
if strings.HasPrefix(entity.ID(), oldName[1:]) { if entity.ID() == oldName[1:] {
_, err := runtime.containerGraph.Set(newName, entity.ID()) _, err := runtime.containerGraph.Set(newName, entity.ID())
return err return err
} }

View file

@ -572,7 +572,7 @@ func TestReloadContainerLinks(t *testing.T) {
} }
h1 := &HostConfig{} h1 := &HostConfig{}
// Add a link to container 2 // 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 { if err := container1.Start(h1); err != nil {
t.Fatal(err) 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.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 // Verify that the link is still registered in the runtime
entity := runtime2.containerGraph.Get(fmt.Sprintf("/%s", container1.ID)) entity := runtime2.containerGraph.Get(fmt.Sprintf("/%s", container1.ID))
if entity == nil { if entity == nil {