Repository: moby/moby
File: daemon/container_operations.go (Go)

Code before:
				if err != nil {
					return nil, fmt.Errorf("error parsing HostPort value(%s):%v", binding.HostPort, err)
				}
			}

			publishedPorts = append(publishedPorts, types.PortBinding{
				Proto:       protocol,
				Port:        port.Num(),
				HostIP:      binding.HostIP.AsSlice(),
				HostPort:    portRange.Start(),
				HostPortEnd: portRange.End(),
			})
		}

		if ctr.HostConfig.PublishAllPorts && len(bindings) == 0 {
			publishedPorts = append(publishedPorts, types.PortBinding{
				Proto: protocol,
				Port:  port.Num(),
			})
		}
	}

	sboxOptions = append(sboxOptions, libnetwork.OptionPortMapping(publishedPorts), libnetwork.OptionExposedPorts(exposedPorts))

	if !ctr.State.StartedAt.IsZero() && !ctr.State.FinishedAt.IsZero() {
		sboxOptions = append(sboxOptions, libnetwork.OptionCreateByRestart())
	}

	return sboxOptions, nil
}

func (daemon *Daemon) updateNetworkSettings(ctr *container.Container, n *libnetwork.Network, endpointConfig *networktypes.EndpointSettings) error {
	if ctr.NetworkSettings == nil {
		ctr.NetworkSettings = &network.Settings{}
	}
	if ctr.NetworkSettings.Networks == nil {
		ctr.NetworkSettings.Networks = make(map[string]*network.EndpointSettings)
	}

	if !ctr.HostConfig.NetworkMode.IsHost() && containertypes.NetworkMode(n.Type()).IsHost() {
		return cerrdefs.ErrInvalidArgument.WithMessage("cannot connect container to host network - container must be created in host network mode")
	}

	for s, v := range ctr.NetworkSettings.Networks {
		sn, err := daemon.FindNetwork(getNetworkID(s, v.EndpointSettings))
		if err != nil {
			continue
		}

		if sn.Name() == n.Name() {
			// If the network scope is swarm, then this

Review comment (bug):
I think that won't work correctly in the case where the engine crashes, or the server loss power.

Instead of trying to detect if a container is restarting, and pass an extra sandbox option we should not overwrite `resolv.conf` if the file already exists and its hash doesn't match the recorded value.

Code after:
				if err != nil {
					return nil, fmt.Errorf("error parsing HostPort value(%s):%v", binding.HostPort, err)
				}
			}

			publishedPorts = append(publishedPorts, types.PortBinding{
				Proto:       protocol,
				Port:        port.Num(),
				HostIP:      binding.HostIP.AsSlice(),
				HostPort:    portRange.Start(),
				HostPortEnd: portRange.End(),
			})
		}

		if ctr.HostConfig.PublishAllPorts && len(bindings) == 0 {
			publishedPorts = append(publishedPorts, types.PortBinding{
				Proto: protocol,
				Port:  port.Num(),
			})
		}
	}

	sboxOptions = append(sboxOptions, libnetwork.OptionPortMapping(publishedPorts), libnetwork.OptionExposedPorts(exposedPorts))

	return sboxOptions, nil
}

func (daemon *Daemon) updateNetworkSettings(ctr *container.Container, n *libnetwork.Network, endpointConfig *networktypes.EndpointSettings) error {
	if ctr.NetworkSettings == nil {
		ctr.NetworkSettings = &network.Settings{}
	}
	if ctr.NetworkSettings.Networks == nil {
		ctr.NetworkSettings.Networks = make(map[string]*network.EndpointSettings)
	}

	if !ctr.HostConfig.NetworkMode.IsHost() && containertypes.NetworkMode(n.Type()).IsHost() {
		return cerrdefs.ErrInvalidArgument.WithMessage("cannot connect container to host network - container must be created in host network mode")
	}

	for s, v := range ctr.NetworkSettings.Networks {
		sn, err := daemon.FindNetwork(getNetworkID(s, v.EndpointSettings))
		if err != nil {
			continue
		}

		if sn.Name() == n.Name() {
			// If the network scope is swarm, then this
			// is an attachable network, which may not
			// be locally available previously.
			// So always update.
			if n.Scope() == scope.Swarm {