github.com/noxiouz/docker@v0.7.3-0.20160629055221-3d231c78e8c5/daemon/links.go (about) 1 package daemon 2 3 import ( 4 "strings" 5 "sync" 6 7 "github.com/Sirupsen/logrus" 8 "github.com/docker/docker/container" 9 "github.com/docker/docker/pkg/graphdb" 10 ) 11 12 // linkIndex stores link relationships between containers, including their specified alias 13 // The alias is the name the parent uses to reference the child 14 type linkIndex struct { 15 // idx maps a parent->alias->child relationship 16 idx map[*container.Container]map[string]*container.Container 17 // childIdx maps child->parent->aliases 18 childIdx map[*container.Container]map[*container.Container]map[string]struct{} 19 mu sync.Mutex 20 } 21 22 func newLinkIndex() *linkIndex { 23 return &linkIndex{ 24 idx: make(map[*container.Container]map[string]*container.Container), 25 childIdx: make(map[*container.Container]map[*container.Container]map[string]struct{}), 26 } 27 } 28 29 // link adds indexes for the passed in parent/child/alias relationships 30 func (l *linkIndex) link(parent, child *container.Container, alias string) { 31 l.mu.Lock() 32 33 if l.idx[parent] == nil { 34 l.idx[parent] = make(map[string]*container.Container) 35 } 36 l.idx[parent][alias] = child 37 if l.childIdx[child] == nil { 38 l.childIdx[child] = make(map[*container.Container]map[string]struct{}) 39 } 40 if l.childIdx[child][parent] == nil { 41 l.childIdx[child][parent] = make(map[string]struct{}) 42 } 43 l.childIdx[child][parent][alias] = struct{}{} 44 45 l.mu.Unlock() 46 } 47 48 // unlink removes the requested alias for the given parent/child 49 func (l *linkIndex) unlink(alias string, child, parent *container.Container) { 50 l.mu.Lock() 51 delete(l.idx[parent], alias) 52 delete(l.childIdx[child], parent) 53 l.mu.Unlock() 54 } 55 56 // children maps all the aliases-> children for the passed in parent 57 // aliases here are the aliases the parent uses to refer to the child 58 func (l *linkIndex) children(parent *container.Container) map[string]*container.Container { 59 l.mu.Lock() 60 children := l.idx[parent] 61 l.mu.Unlock() 62 return children 63 } 64 65 // parents maps all the aliases->parent for the passed in child 66 // aliases here are the aliases the parents use to refer to the child 67 func (l *linkIndex) parents(child *container.Container) map[string]*container.Container { 68 l.mu.Lock() 69 70 parents := make(map[string]*container.Container) 71 for parent, aliases := range l.childIdx[child] { 72 for alias := range aliases { 73 parents[alias] = parent 74 } 75 } 76 77 l.mu.Unlock() 78 return parents 79 } 80 81 // delete deletes all link relationships referencing this container 82 func (l *linkIndex) delete(container *container.Container) { 83 l.mu.Lock() 84 for _, child := range l.idx[container] { 85 delete(l.childIdx[child], container) 86 } 87 delete(l.idx, container) 88 delete(l.childIdx, container) 89 l.mu.Unlock() 90 } 91 92 // migrateLegacySqliteLinks migrates sqlite links to use links from HostConfig 93 // when sqlite links were used, hostConfig.Links was set to nil 94 func (daemon *Daemon) migrateLegacySqliteLinks(db *graphdb.Database, container *container.Container) error { 95 // if links is populated (or an empty slice), then this isn't using sqlite links and can be skipped 96 if container.HostConfig == nil || container.HostConfig.Links != nil { 97 return nil 98 } 99 100 logrus.Debugf("migrating legacy sqlite link info for container: %s", container.ID) 101 102 fullName := container.Name 103 if fullName[0] != '/' { 104 fullName = "/" + fullName 105 } 106 107 // don't use a nil slice, this ensures that the check above will skip once the migration has completed 108 links := []string{} 109 children, err := db.Children(fullName, 0) 110 if err != nil { 111 if !strings.Contains(err.Error(), "Cannot find child for") { 112 return err 113 } 114 // else continue... it's ok if we didn't find any children, it'll just be nil and we can continue the migration 115 } 116 117 for _, child := range children { 118 c, err := daemon.GetContainer(child.Entity.ID()) 119 if err != nil { 120 return err 121 } 122 123 links = append(links, c.Name+":"+child.Edge.Name) 124 } 125 126 container.HostConfig.Links = links 127 return container.WriteHostConfig() 128 }