diff --git a/daemon/container_unix.go b/daemon/container_unix.go index 640bf5bcb2..d47647412b 100644 --- a/daemon/container_unix.go +++ b/daemon/container_unix.go @@ -77,11 +77,8 @@ func killProcessDirectly(container *Container) error { return nil } -func (container *Container) setupLinkedContainers() ([]string, error) { - var ( - env []string - daemon = container.daemon - ) +func (daemon *Daemon) setupLinkedContainers(container *Container) ([]string, error) { + var env []string children, err := daemon.children(container.Name) if err != nil { return nil, err @@ -185,17 +182,16 @@ func getDevicesFromPath(deviceMapping runconfig.DeviceMapping) (devs []*configs. return devs, derr.ErrorCodeDeviceInfo.WithArgs(deviceMapping.PathOnHost, err) } -func populateCommand(c *Container, env []string) error { +func (daemon *Daemon) populateCommand(c *Container, env []string) error { var en *execdriver.Network if !c.Config.NetworkDisabled { en = &execdriver.Network{} - if !c.daemon.execDriver.SupportsHooks() || c.hostConfig.NetworkMode.IsHost() { + if !daemon.execDriver.SupportsHooks() || c.hostConfig.NetworkMode.IsHost() { en.NamespacePath = c.NetworkSettings.SandboxKey } - parts := strings.SplitN(string(c.hostConfig.NetworkMode), ":", 2) - if parts[0] == "container" { - nc, err := c.getNetworkedContainer() + if c.hostConfig.NetworkMode.IsContainer() { + nc, err := daemon.getNetworkedContainer(c.ID, c.hostConfig.NetworkMode.ConnectedContainer()) if err != nil { return err } @@ -216,7 +212,7 @@ func populateCommand(c *Container, env []string) error { } if c.hostConfig.IpcMode.IsContainer() { - ic, err := c.getIpcContainer() + ic, err := daemon.getIpcContainer(c) if err != nil { return err } @@ -273,7 +269,7 @@ func populateCommand(c *Container, env []string) error { for _, ul := range ulimits { ulIdx[ul.Name] = ul } - for name, ul := range c.daemon.configStore.Ulimits { + for name, ul := range daemon.configStore.Ulimits { if _, exists := ulIdx[name]; !exists { ulimits = append(ulimits, ul) } @@ -321,12 +317,12 @@ func populateCommand(c *Container, env []string) error { processConfig.Env = env remappedRoot := &execdriver.User{} - rootUID, rootGID := c.daemon.GetRemappedUIDGID() + rootUID, rootGID := daemon.GetRemappedUIDGID() if rootUID != 0 { remappedRoot.UID = rootUID remappedRoot.GID = rootGID } - uidMap, gidMap := c.daemon.GetUIDGIDMaps() + uidMap, gidMap := daemon.GetUIDGIDMaps() c.command = &execdriver.Command{ CommonCommand: execdriver.CommonCommand{ @@ -442,7 +438,7 @@ func (container *Container) buildHostnameFile() error { return ioutil.WriteFile(container.HostnamePath, []byte(container.Config.Hostname+"\n"), 0644) } -func (container *Container) buildSandboxOptions(n libnetwork.Network) ([]libnetwork.SandboxOption, error) { +func (daemon *Daemon) buildSandboxOptions(container *Container, n libnetwork.Network) ([]libnetwork.SandboxOption, error) { var ( sboxOptions []libnetwork.SandboxOption err error @@ -458,7 +454,7 @@ func (container *Container) buildSandboxOptions(n libnetwork.Network) ([]libnetw sboxOptions = append(sboxOptions, libnetwork.OptionUseDefaultSandbox()) sboxOptions = append(sboxOptions, libnetwork.OptionOriginHostsPath("/etc/hosts")) sboxOptions = append(sboxOptions, libnetwork.OptionOriginResolvConfPath("/etc/resolv.conf")) - } else if container.daemon.execDriver.SupportsHooks() { + } else if daemon.execDriver.SupportsHooks() { // OptionUseExternalKey is mandatory for userns support. // But optional for non-userns support sboxOptions = append(sboxOptions, libnetwork.OptionUseExternalKey()) @@ -478,8 +474,8 @@ func (container *Container) buildSandboxOptions(n libnetwork.Network) ([]libnetw if len(container.hostConfig.DNS) > 0 { dns = container.hostConfig.DNS - } else if len(container.daemon.configStore.DNS) > 0 { - dns = container.daemon.configStore.DNS + } else if len(daemon.configStore.DNS) > 0 { + dns = daemon.configStore.DNS } for _, d := range dns { @@ -488,8 +484,8 @@ func (container *Container) buildSandboxOptions(n libnetwork.Network) ([]libnetw if len(container.hostConfig.DNSSearch) > 0 { dnsSearch = container.hostConfig.DNSSearch - } else if len(container.daemon.configStore.DNSSearch) > 0 { - dnsSearch = container.daemon.configStore.DNSSearch + } else if len(daemon.configStore.DNSSearch) > 0 { + dnsSearch = daemon.configStore.DNSSearch } for _, ds := range dnsSearch { @@ -498,8 +494,8 @@ func (container *Container) buildSandboxOptions(n libnetwork.Network) ([]libnetw if len(container.hostConfig.DNSOptions) > 0 { dnsOptions = container.hostConfig.DNSOptions - } else if len(container.daemon.configStore.DNSOptions) > 0 { - dnsOptions = container.daemon.configStore.DNSOptions + } else if len(daemon.configStore.DNSOptions) > 0 { + dnsOptions = daemon.configStore.DNSOptions } for _, ds := range dnsOptions { @@ -536,7 +532,7 @@ func (container *Container) buildSandboxOptions(n libnetwork.Network) ([]libnetw var childEndpoints, parentEndpoints []string - children, err := container.daemon.children(container.Name) + children, err := daemon.children(container.Name) if err != nil { return nil, err } @@ -560,18 +556,18 @@ func (container *Container) buildSandboxOptions(n libnetwork.Network) ([]libnetw } bridgeSettings := container.NetworkSettings.Networks["bridge"] - refs := container.daemon.containerGraph().RefPaths(container.ID) + refs := daemon.containerGraph().RefPaths(container.ID) for _, ref := range refs { if ref.ParentID == "0" { continue } - c, err := container.daemon.Get(ref.ParentID) + c, err := daemon.Get(ref.ParentID) if err != nil { logrus.Error(err) } - if c != nil && !container.daemon.configStore.DisableBridge && container.hostConfig.NetworkMode.IsPrivate() { + if c != nil && !daemon.configStore.DisableBridge && container.hostConfig.NetworkMode.IsPrivate() { logrus.Debugf("Update /etc/hosts of %s for alias %s with ip %s", c.ID, ref.Name, bridgeSettings.IPAddress) sboxOptions = append(sboxOptions, libnetwork.OptionParentUpdate(c.ID, ref.Name, bridgeSettings.IPAddress)) if ep.ID() != "" { @@ -719,13 +715,13 @@ func (container *Container) updateJoinInfo(n libnetwork.Network, ep libnetwork.E return nil } -func (container *Container) updateNetworkSettings(n libnetwork.Network) error { +func (daemon *Daemon) updateNetworkSettings(container *Container, n libnetwork.Network) error { if container.NetworkSettings == nil { container.NetworkSettings = &network.Settings{Networks: make(map[string]*network.EndpointSettings)} } for s := range container.NetworkSettings.Networks { - sn, err := container.daemon.FindNetwork(s) + sn, err := daemon.FindNetwork(s) if err != nil { continue } @@ -769,8 +765,8 @@ func (container *Container) updateSandboxNetworkSettings(sb libnetwork.Sandbox) // UpdateNetwork is used to update the container's network (e.g. when linked containers // get removed/unlinked). -func (container *Container) updateNetwork() error { - ctrl := container.daemon.netController +func (daemon *Daemon) updateNetwork(container *Container) error { + ctrl := daemon.netController sid := container.NetworkSettings.SandboxID sb, err := ctrl.SandboxByID(sid) @@ -781,7 +777,7 @@ func (container *Container) updateNetwork() error { // Find if container is connected to the default bridge network var n libnetwork.Network for name := range container.NetworkSettings.Networks { - sn, err := container.daemon.FindNetwork(name) + sn, err := daemon.FindNetwork(name) if err != nil { continue } @@ -796,7 +792,7 @@ func (container *Container) updateNetwork() error { return nil } - options, err := container.buildSandboxOptions(n) + options, err := daemon.buildSandboxOptions(container, n) if err != nil { return derr.ErrorCodeNetworkUpdate.WithArgs(err) } @@ -893,8 +889,8 @@ func (container *Container) buildCreateEndpointOptions(n libnetwork.Network) ([] return createOptions, nil } -func (container *Container) allocateNetwork() error { - controller := container.daemon.netController +func (daemon *Daemon) allocateNetwork(container *Container) error { + controller := daemon.netController // Cleanup any stale sandbox left over due to ungraceful daemon shutdown if err := controller.SandboxDestroy(container.ID); err != nil { @@ -913,7 +909,7 @@ func (container *Container) allocateNetwork() error { networkName = controller.Config().Daemon.DefaultNetwork } if mode.IsUserDefined() { - n, err := container.daemon.FindNetwork(networkName) + n, err := daemon.FindNetwork(networkName) if err != nil { return err } @@ -925,7 +921,7 @@ func (container *Container) allocateNetwork() error { } for n := range container.NetworkSettings.Networks { - if err := container.connectToNetwork(n, updateSettings); err != nil { + if err := daemon.connectToNetwork(container, n, updateSettings); err != nil { return err } } @@ -933,9 +929,9 @@ func (container *Container) allocateNetwork() error { return container.writeHostConfig() } -func (container *Container) getNetworkSandbox() libnetwork.Sandbox { +func (daemon *Daemon) getNetworkSandbox(container *Container) libnetwork.Sandbox { var sb libnetwork.Sandbox - container.daemon.netController.WalkSandboxes(func(s libnetwork.Sandbox) bool { + daemon.netController.WalkSandboxes(func(s libnetwork.Sandbox) bool { if s.ContainerID() == container.ID { sb = s return true @@ -946,11 +942,11 @@ func (container *Container) getNetworkSandbox() libnetwork.Sandbox { } // ConnectToNetwork connects a container to a netork -func (container *Container) ConnectToNetwork(idOrName string) error { +func (daemon *Daemon) ConnectToNetwork(container *Container, idOrName string) error { if !container.Running { return derr.ErrorCodeNotRunning.WithArgs(container.ID) } - if err := container.connectToNetwork(idOrName, true); err != nil { + if err := daemon.connectToNetwork(container, idOrName, true); err != nil { return err } if err := container.toDiskLocking(); err != nil { @@ -959,26 +955,26 @@ func (container *Container) ConnectToNetwork(idOrName string) error { return nil } -func (container *Container) connectToNetwork(idOrName string, updateSettings bool) (err error) { +func (daemon *Daemon) connectToNetwork(container *Container, idOrName string, updateSettings bool) (err error) { if container.hostConfig.NetworkMode.IsContainer() { return runconfig.ErrConflictSharedNetwork } if runconfig.NetworkMode(idOrName).IsBridge() && - container.daemon.configStore.DisableBridge { + daemon.configStore.DisableBridge { container.Config.NetworkDisabled = true return nil } - controller := container.daemon.netController + controller := daemon.netController - n, err := container.daemon.FindNetwork(idOrName) + n, err := daemon.FindNetwork(idOrName) if err != nil { return err } if updateSettings { - if err := container.updateNetworkSettings(n); err != nil { + if err := daemon.updateNetworkSettings(container, n); err != nil { return err } } @@ -1014,9 +1010,9 @@ func (container *Container) connectToNetwork(idOrName string, updateSettings boo return err } - sb := container.getNetworkSandbox() + sb := daemon.getNetworkSandbox(container) if sb == nil { - options, err := container.buildSandboxOptions(n) + options, err := daemon.buildSandboxOptions(container, n) if err != nil { return err } @@ -1039,12 +1035,12 @@ func (container *Container) connectToNetwork(idOrName string, updateSettings boo return nil } -func (container *Container) initializeNetworking() error { +func (daemon *Daemon) initializeNetworking(container *Container) error { var err error if container.hostConfig.NetworkMode.IsContainer() { // we need to get the hosts files from the container to join - nc, err := container.getNetworkedContainer() + nc, err := daemon.getNetworkedContainer(container.ID, container.hostConfig.NetworkMode.ConnectedContainer()) if err != nil { return err } @@ -1070,7 +1066,7 @@ func (container *Container) initializeNetworking() error { } - if err := container.allocateNetwork(); err != nil { + if err := daemon.allocateNetwork(container); err != nil { return err } @@ -1079,21 +1075,21 @@ func (container *Container) initializeNetworking() error { // called from the libcontainer pre-start hook to set the network // namespace configuration linkage to the libnetwork "sandbox" entity -func (container *Container) setNetworkNamespaceKey(pid int) error { +func (daemon *Daemon) setNetworkNamespaceKey(containerId string, pid int) error { path := fmt.Sprintf("/proc/%d/ns/net", pid) var sandbox libnetwork.Sandbox - search := libnetwork.SandboxContainerWalker(&sandbox, container.ID) - container.daemon.netController.WalkSandboxes(search) + search := libnetwork.SandboxContainerWalker(&sandbox, containerId) + daemon.netController.WalkSandboxes(search) if sandbox == nil { - return derr.ErrorCodeNoSandbox.WithArgs(container.ID) + return derr.ErrorCodeNoSandbox.WithArgs(containerId) } return sandbox.SetKey(path) } -func (container *Container) getIpcContainer() (*Container, error) { +func (daemon *Daemon) getIpcContainer(container *Container) (*Container, error) { containerID := container.hostConfig.IpcMode.Container() - c, err := container.daemon.Get(containerID) + c, err := daemon.Get(containerID) if err != nil { return nil, err } @@ -1130,27 +1126,18 @@ func (container *Container) setupWorkingDirectory() error { return nil } -func (container *Container) getNetworkedContainer() (*Container, error) { - parts := strings.SplitN(string(container.hostConfig.NetworkMode), ":", 2) - switch parts[0] { - case "container": - if len(parts) != 2 { - return nil, derr.ErrorCodeParseContainer - } - nc, err := container.daemon.Get(parts[1]) - if err != nil { - return nil, err - } - if container == nc { - return nil, derr.ErrorCodeJoinSelf - } - if !nc.IsRunning() { - return nil, derr.ErrorCodeJoinRunning.WithArgs(parts[1]) - } - return nc, nil - default: - return nil, derr.ErrorCodeModeNotContainer +func (daemon *Daemon) getNetworkedContainer(containerId, connectedContainerId string) (*Container, error) { + nc, err := daemon.Get(connectedContainerId) + if err != nil { + return nil, err } + if containerId == nc.ID { + return nil, derr.ErrorCodeJoinSelf + } + if !nc.IsRunning() { + return nil, derr.ErrorCodeJoinRunning.WithArgs(connectedContainerId) + } + return nc, nil } func (daemon *Daemon) releaseNetwork(container *Container) { @@ -1337,8 +1324,8 @@ func (container *Container) hasMountFor(path string) bool { return exists } -func (container *Container) setupIpcDirs() error { - rootUID, rootGID := container.daemon.GetRemappedUIDGID() +func (daemon *Daemon) setupIpcDirs(container *Container) error { + rootUID, rootGID := daemon.GetRemappedUIDGID() if !container.hasMountFor("/dev/shm") { shmPath, err := container.shmPath() if err != nil { diff --git a/daemon/container_windows.go b/daemon/container_windows.go index 0ad1fc69ad..4029848911 100644 --- a/daemon/container_windows.go +++ b/daemon/container_windows.go @@ -27,7 +27,7 @@ func killProcessDirectly(container *Container) error { return nil } -func (container *Container) setupLinkedContainers() ([]string, error) { +func (daemon *Daemon) setupLinkedContainers(container *Container) ([]string, error) { return nil, nil } @@ -36,12 +36,12 @@ func (container *Container) createDaemonEnvironment(linkedEnv []string) []string return container.Config.Env } -func (container *Container) initializeNetworking() error { +func (daemon *Daemon) initializeNetworking(container *Container) error { return nil } // ConnectToNetwork connects a container to the network -func (container *Container) ConnectToNetwork(idOrName string) error { +func (daemon *Daemon) ConnectToNetwork(container *Container, idOrName string) error { return nil } @@ -54,7 +54,7 @@ func (container *Container) setupWorkingDirectory() error { return nil } -func populateCommand(c *Container, env []string) error { +func (daemon *Daemon) populateCommand(c *Container, env []string) error { en := &execdriver.Network{ Interface: nil, } @@ -66,7 +66,7 @@ func populateCommand(c *Container, env []string) error { if !c.Config.NetworkDisabled { en.Interface = &execdriver.NetworkInterface{ MacAddress: c.Config.MacAddress, - Bridge: c.daemon.configStore.Bridge.VirtualSwitchName, + Bridge: daemon.configStore.Bridge.VirtualSwitchName, PortBindings: c.hostConfig.PortBindings, // TODO Windows. Include IPAddress. There already is a @@ -99,22 +99,22 @@ func populateCommand(c *Container, env []string) error { processConfig.Env = env var layerPaths []string - img, err := c.daemon.graph.Get(c.ImageID) + img, err := daemon.graph.Get(c.ImageID) if err != nil { return derr.ErrorCodeGetGraph.WithArgs(c.ImageID, err) } - for i := img; i != nil && err == nil; i, err = c.daemon.graph.GetParent(i) { - lp, err := c.daemon.driver.Get(i.ID, "") + for i := img; i != nil && err == nil; i, err = daemon.graph.GetParent(i) { + lp, err := daemon.driver.Get(i.ID, "") if err != nil { - return derr.ErrorCodeGetLayer.WithArgs(c.daemon.driver.String(), i.ID, err) + return derr.ErrorCodeGetLayer.WithArgs(daemon.driver.String(), i.ID, err) } layerPaths = append(layerPaths, lp) - err = c.daemon.driver.Put(i.ID) + err = daemon.driver.Put(i.ID) if err != nil { - return derr.ErrorCodePutLayer.WithArgs(c.daemon.driver.String(), i.ID, err) + return derr.ErrorCodePutLayer.WithArgs(daemon.driver.String(), i.ID, err) } } - m, err := c.daemon.driver.GetMetadata(c.ID) + m, err := daemon.driver.GetMetadata(c.ID) if err != nil { return derr.ErrorCodeGetLayerMetadata.WithArgs(err) } @@ -149,16 +149,16 @@ func (daemon *Daemon) getSize(container *Container) (int64, int64) { } // setNetworkNamespaceKey is a no-op on Windows. -func (container *Container) setNetworkNamespaceKey(pid int) error { +func (daemon *Daemon) setNetworkNamespaceKey(containerId string, pid int) error { return nil } // allocateNetwork is a no-op on Windows. -func (container *Container) allocateNetwork() error { +func (daemon *Daemon) allocateNetwork(container *Container) error { return nil } -func (container *Container) updateNetwork() error { +func (daemon *Daemon) updateNetwork(container *Container) error { return nil } @@ -172,7 +172,7 @@ func appendNetworkMounts(container *Container, volumeMounts []volume.MountPoint) return volumeMounts, nil } -func (container *Container) setupIpcDirs() error { +func (daemon *Daemon) setupIpcDirs(container *Container) error { return nil } diff --git a/daemon/daemon.go b/daemon/daemon.go index 3f17027095..d902028163 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -957,7 +957,7 @@ func (daemon *Daemon) run(c *Container, pipes *execdriver.Pipes, startCallback e Start: startCallback, } hooks.PreStart = append(hooks.PreStart, func(processConfig *execdriver.ProcessConfig, pid int, chOOM <-chan struct{}) error { - return c.setNetworkNamespaceKey(pid) + return daemon.setNetworkNamespaceKey(c.ID, pid) }) return daemon.execDriver.Run(c.command, pipes, hooks) } diff --git a/daemon/delete.go b/daemon/delete.go index 1de9ba9c1d..f62f71e972 100644 --- a/daemon/delete.go +++ b/daemon/delete.go @@ -45,7 +45,7 @@ func (daemon *Daemon) ContainerRm(name string, config *ContainerRmConfig) error parentContainer, _ := daemon.Get(pe.ID()) if parentContainer != nil { - if err := parentContainer.updateNetwork(); err != nil { + if err := daemon.updateNetwork(parentContainer); err != nil { logrus.Debugf("Could not update network to remove link %s: %v", n, err) } } diff --git a/daemon/network.go b/daemon/network.go index 1184effc82..c1412cec89 100644 --- a/daemon/network.go +++ b/daemon/network.go @@ -134,7 +134,7 @@ func (daemon *Daemon) ConnectContainerToNetwork(containerName, networkName strin if err != nil { return err } - return container.ConnectToNetwork(networkName) + return daemon.ConnectToNetwork(container, networkName) } // DisconnectContainerFromNetwork disconnects the given container from diff --git a/daemon/start.go b/daemon/start.go index 89a6020f41..2943133b96 100644 --- a/daemon/start.go +++ b/daemon/start.go @@ -97,10 +97,10 @@ func (daemon *Daemon) containerStart(container *Container) (err error) { // backwards API compatibility. container.hostConfig = runconfig.SetDefaultNetModeIfBlank(container.hostConfig) - if err := container.initializeNetworking(); err != nil { + if err := daemon.initializeNetworking(container); err != nil { return err } - linkedEnv, err := container.setupLinkedContainers() + linkedEnv, err := daemon.setupLinkedContainers(container) if err != nil { return err } @@ -108,12 +108,12 @@ func (daemon *Daemon) containerStart(container *Container) (err error) { return err } env := container.createDaemonEnvironment(linkedEnv) - if err := populateCommand(container, env); err != nil { + if err := daemon.populateCommand(container, env); err != nil { return err } if !container.hostConfig.IpcMode.IsContainer() && !container.hostConfig.IpcMode.IsHost() { - if err := container.setupIpcDirs(); err != nil { + if err := daemon.setupIpcDirs(container); err != nil { return err } } diff --git a/runconfig/hostconfig_unix.go b/runconfig/hostconfig_unix.go index 0777d9ae0c..ed2bcf8e3e 100644 --- a/runconfig/hostconfig_unix.go +++ b/runconfig/hostconfig_unix.go @@ -66,6 +66,15 @@ func (n NetworkMode) IsNone() bool { return n == "none" } +// ConnectedContainer is the id of the container which network this container is connected to. +func (n NetworkMode) ConnectedContainer() string { + parts := strings.SplitN(string(n), ":", 2) + if len(parts) > 1 { + return parts[1] + } + return "" +} + // IsUserDefined indicates user-created network func (n NetworkMode) IsUserDefined() bool { return !n.IsDefault() && !n.IsBridge() && !n.IsHost() && !n.IsNone() && !n.IsContainer()