func (s *Service) populateAdditionalHostConfig(hostConfig *containertypes.HostConfig) error { links, err := s.getLinks() if err != nil { return err } for _, link := range s.DependentServices() { if !s.project.ServiceConfigs.Has(link.Target) { continue } service, err := s.project.CreateService(link.Target) if err != nil { return err } containers, err := service.Containers(context.Background()) if err != nil { return err } if link.Type == project.RelTypeIpcNamespace { hostConfig, err = addIpc(hostConfig, service, containers, s.serviceConfig.Ipc) } else if link.Type == project.RelTypeNetNamespace { hostConfig, err = addNetNs(hostConfig, service, containers, s.serviceConfig.NetworkMode) } if err != nil { return err } } hostConfig.Links = []string{} for k, v := range links { hostConfig.Links = append(hostConfig.Links, strings.Join([]string{v, k}, ":")) } for _, v := range s.serviceConfig.ExternalLinks { hostConfig.Links = append(hostConfig.Links, v) } return nil }
// registerLinks writes the links to a file. func (daemon *Daemon) registerLinks(container *container.Container, hostConfig *containertypes.HostConfig) error { if hostConfig == nil || hostConfig.Links == nil { return nil } for _, l := range hostConfig.Links { name, alias, err := runconfigopts.ParseLink(l) if err != nil { return err } child, err := daemon.GetContainer(name) if err != nil { //An error from daemon.GetContainer() means this name could not be found return fmt.Errorf("Could not get container for %s", name) } for child.HostConfig.NetworkMode.IsContainer() { parts := strings.SplitN(string(child.HostConfig.NetworkMode), ":", 2) child, err = daemon.GetContainer(parts[1]) if err != nil { return fmt.Errorf("Could not get container for %s", parts[1]) } } if child.HostConfig.NetworkMode.IsHost() { return runconfig.ErrConflictHostNetworkAndLinks } if err := daemon.registerLink(container, child, alias); err != nil { return err } } // After we load all the links into the daemon // set them to nil on the hostconfig hostConfig.Links = nil if err := container.WriteHostConfig(); err != nil { return err } return nil }
func (daemon *Daemon) setHostConfig(container *container.Container, hostConfig *containertypes.HostConfig) error { // Do not lock while creating volumes since this could be calling out to external plugins // Don't want to block other actions, like `docker ps` because we're waiting on an external plugin if err := daemon.registerMountPoints(container, hostConfig); err != nil { return err } container.Lock() defer container.Unlock() // Register any links from the host config before starting the container if err := daemon.registerLinks(container, hostConfig); err != nil { return err } // make sure links is not nil // this ensures that on the next daemon restart we don't try to migrate from legacy sqlite links if hostConfig.Links == nil { hostConfig.Links = []string{} } container.HostConfig = hostConfig return container.ToDisk() }