github.com/guilhermebr/docker@v1.4.2-0.20150428121140-67da055cebca/daemon/container.go (about)

     1  package daemon
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"errors"
     7  	"fmt"
     8  	"io"
     9  	"io/ioutil"
    10  	"os"
    11  	"path"
    12  	"path/filepath"
    13  	"strings"
    14  	"syscall"
    15  	"time"
    16  
    17  	"github.com/docker/libcontainer/configs"
    18  	"github.com/docker/libcontainer/devices"
    19  	"github.com/docker/libcontainer/label"
    20  
    21  	"github.com/Sirupsen/logrus"
    22  	"github.com/docker/docker/daemon/execdriver"
    23  	"github.com/docker/docker/daemon/logger"
    24  	"github.com/docker/docker/daemon/logger/journald"
    25  	"github.com/docker/docker/daemon/logger/jsonfilelog"
    26  	"github.com/docker/docker/daemon/logger/syslog"
    27  	"github.com/docker/docker/daemon/network"
    28  	"github.com/docker/docker/daemon/networkdriver/bridge"
    29  	"github.com/docker/docker/engine"
    30  	"github.com/docker/docker/image"
    31  	"github.com/docker/docker/links"
    32  	"github.com/docker/docker/nat"
    33  	"github.com/docker/docker/pkg/archive"
    34  	"github.com/docker/docker/pkg/broadcastwriter"
    35  	"github.com/docker/docker/pkg/directory"
    36  	"github.com/docker/docker/pkg/etchosts"
    37  	"github.com/docker/docker/pkg/ioutils"
    38  	"github.com/docker/docker/pkg/promise"
    39  	"github.com/docker/docker/pkg/resolvconf"
    40  	"github.com/docker/docker/pkg/stringid"
    41  	"github.com/docker/docker/pkg/symlink"
    42  	"github.com/docker/docker/pkg/ulimit"
    43  	"github.com/docker/docker/runconfig"
    44  	"github.com/docker/docker/utils"
    45  )
    46  
    47  const DefaultPathEnv = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
    48  
    49  var (
    50  	ErrNotATTY               = errors.New("The PTY is not a file")
    51  	ErrNoTTY                 = errors.New("No PTY found")
    52  	ErrContainerStart        = errors.New("The container failed to start. Unknown error")
    53  	ErrContainerStartTimeout = errors.New("The container failed to start due to timed out.")
    54  )
    55  
    56  type StreamConfig struct {
    57  	stdout    *broadcastwriter.BroadcastWriter
    58  	stderr    *broadcastwriter.BroadcastWriter
    59  	stdin     io.ReadCloser
    60  	stdinPipe io.WriteCloser
    61  }
    62  
    63  type Container struct {
    64  	*State `json:"State"` // Needed for remote api version <= 1.11
    65  	root   string         // Path to the "home" of the container, including metadata.
    66  	basefs string         // Path to the graphdriver mountpoint
    67  
    68  	ID string
    69  
    70  	Created time.Time
    71  
    72  	Path string
    73  	Args []string
    74  
    75  	Config  *runconfig.Config
    76  	ImageID string `json:"Image"`
    77  
    78  	NetworkSettings *network.Settings
    79  
    80  	ResolvConfPath string
    81  	HostnamePath   string
    82  	HostsPath      string
    83  	LogPath        string
    84  	Name           string
    85  	Driver         string
    86  	ExecDriver     string
    87  
    88  	command *execdriver.Command
    89  	StreamConfig
    90  
    91  	daemon                   *Daemon
    92  	MountLabel, ProcessLabel string
    93  	AppArmorProfile          string
    94  	RestartCount             int
    95  	UpdateDns                bool
    96  
    97  	// Maps container paths to volume paths.  The key in this is the path to which
    98  	// the volume is being mounted inside the container.  Value is the path of the
    99  	// volume on disk
   100  	Volumes map[string]string
   101  	// Store rw/ro in a separate structure to preserve reverse-compatibility on-disk.
   102  	// Easier than migrating older container configs :)
   103  	VolumesRW  map[string]bool
   104  	hostConfig *runconfig.HostConfig
   105  
   106  	activeLinks  map[string]*links.Link
   107  	monitor      *containerMonitor
   108  	execCommands *execStore
   109  	// logDriver for closing
   110  	logDriver          logger.Logger
   111  	logCopier          *logger.Copier
   112  	AppliedVolumesFrom map[string]struct{}
   113  }
   114  
   115  func (container *Container) FromDisk() error {
   116  	pth, err := container.jsonPath()
   117  	if err != nil {
   118  		return err
   119  	}
   120  
   121  	jsonSource, err := os.Open(pth)
   122  	if err != nil {
   123  		return err
   124  	}
   125  	defer jsonSource.Close()
   126  
   127  	dec := json.NewDecoder(jsonSource)
   128  
   129  	// Load container settings
   130  	// udp broke compat of docker.PortMapping, but it's not used when loading a container, we can skip it
   131  	if err := dec.Decode(container); err != nil && !strings.Contains(err.Error(), "docker.PortMapping") {
   132  		return err
   133  	}
   134  
   135  	if err := label.ReserveLabel(container.ProcessLabel); err != nil {
   136  		return err
   137  	}
   138  	return container.readHostConfig()
   139  }
   140  
   141  func (container *Container) toDisk() error {
   142  	data, err := json.Marshal(container)
   143  	if err != nil {
   144  		return err
   145  	}
   146  
   147  	pth, err := container.jsonPath()
   148  	if err != nil {
   149  		return err
   150  	}
   151  
   152  	if err := ioutil.WriteFile(pth, data, 0666); err != nil {
   153  		return err
   154  	}
   155  
   156  	return container.WriteHostConfig()
   157  }
   158  
   159  func (container *Container) ToDisk() error {
   160  	container.Lock()
   161  	err := container.toDisk()
   162  	container.Unlock()
   163  	return err
   164  }
   165  
   166  func (container *Container) readHostConfig() error {
   167  	container.hostConfig = &runconfig.HostConfig{}
   168  	// If the hostconfig file does not exist, do not read it.
   169  	// (We still have to initialize container.hostConfig,
   170  	// but that's OK, since we just did that above.)
   171  	pth, err := container.hostConfigPath()
   172  	if err != nil {
   173  		return err
   174  	}
   175  
   176  	_, err = os.Stat(pth)
   177  	if os.IsNotExist(err) {
   178  		return nil
   179  	}
   180  
   181  	f, err := os.Open(pth)
   182  	if err != nil {
   183  		return err
   184  	}
   185  	defer f.Close()
   186  
   187  	return json.NewDecoder(f).Decode(&container.hostConfig)
   188  }
   189  
   190  func (container *Container) WriteHostConfig() error {
   191  	data, err := json.Marshal(container.hostConfig)
   192  	if err != nil {
   193  		return err
   194  	}
   195  
   196  	pth, err := container.hostConfigPath()
   197  	if err != nil {
   198  		return err
   199  	}
   200  
   201  	return ioutil.WriteFile(pth, data, 0666)
   202  }
   203  
   204  func (container *Container) LogEvent(action string) {
   205  	d := container.daemon
   206  	d.EventsService.Log(
   207  		action,
   208  		container.ID,
   209  		container.Config.Image,
   210  	)
   211  }
   212  
   213  func (container *Container) getResourcePath(path string) (string, error) {
   214  	cleanPath := filepath.Join("/", path)
   215  	return symlink.FollowSymlinkInScope(filepath.Join(container.basefs, cleanPath), container.basefs)
   216  }
   217  
   218  func (container *Container) getRootResourcePath(path string) (string, error) {
   219  	cleanPath := filepath.Join("/", path)
   220  	return symlink.FollowSymlinkInScope(filepath.Join(container.root, cleanPath), container.root)
   221  }
   222  
   223  func getDevicesFromPath(deviceMapping runconfig.DeviceMapping) (devs []*configs.Device, err error) {
   224  	device, err := devices.DeviceFromPath(deviceMapping.PathOnHost, deviceMapping.CgroupPermissions)
   225  	// if there was no error, return the device
   226  	if err == nil {
   227  		device.Path = deviceMapping.PathInContainer
   228  		return append(devs, device), nil
   229  	}
   230  
   231  	// if the device is not a device node
   232  	// try to see if it's a directory holding many devices
   233  	if err == devices.ErrNotADevice {
   234  
   235  		// check if it is a directory
   236  		if src, e := os.Stat(deviceMapping.PathOnHost); e == nil && src.IsDir() {
   237  
   238  			// mount the internal devices recursively
   239  			filepath.Walk(deviceMapping.PathOnHost, func(dpath string, f os.FileInfo, e error) error {
   240  				childDevice, e := devices.DeviceFromPath(dpath, deviceMapping.CgroupPermissions)
   241  				if e != nil {
   242  					// ignore the device
   243  					return nil
   244  				}
   245  
   246  				// add the device to userSpecified devices
   247  				childDevice.Path = strings.Replace(dpath, deviceMapping.PathOnHost, deviceMapping.PathInContainer, 1)
   248  				devs = append(devs, childDevice)
   249  
   250  				return nil
   251  			})
   252  		}
   253  	}
   254  
   255  	if len(devs) > 0 {
   256  		return devs, nil
   257  	}
   258  
   259  	return devs, fmt.Errorf("error gathering device information while adding custom device %q: %s", deviceMapping.PathOnHost, err)
   260  }
   261  
   262  func populateCommand(c *Container, env []string) error {
   263  	en := &execdriver.Network{
   264  		Mtu:       c.daemon.config.Mtu,
   265  		Interface: nil,
   266  	}
   267  
   268  	parts := strings.SplitN(string(c.hostConfig.NetworkMode), ":", 2)
   269  	switch parts[0] {
   270  	case "none":
   271  	case "host":
   272  		en.HostNetworking = true
   273  	case "bridge", "": // empty string to support existing containers
   274  		if !c.Config.NetworkDisabled {
   275  			network := c.NetworkSettings
   276  			en.Interface = &execdriver.NetworkInterface{
   277  				Gateway:              network.Gateway,
   278  				Bridge:               network.Bridge,
   279  				IPAddress:            network.IPAddress,
   280  				IPPrefixLen:          network.IPPrefixLen,
   281  				MacAddress:           network.MacAddress,
   282  				LinkLocalIPv6Address: network.LinkLocalIPv6Address,
   283  				GlobalIPv6Address:    network.GlobalIPv6Address,
   284  				GlobalIPv6PrefixLen:  network.GlobalIPv6PrefixLen,
   285  				IPv6Gateway:          network.IPv6Gateway,
   286  			}
   287  		}
   288  	case "container":
   289  		nc, err := c.getNetworkedContainer()
   290  		if err != nil {
   291  			return err
   292  		}
   293  		en.ContainerID = nc.ID
   294  	default:
   295  		return fmt.Errorf("invalid network mode: %s", c.hostConfig.NetworkMode)
   296  	}
   297  
   298  	ipc := &execdriver.Ipc{}
   299  
   300  	if c.hostConfig.IpcMode.IsContainer() {
   301  		ic, err := c.getIpcContainer()
   302  		if err != nil {
   303  			return err
   304  		}
   305  		ipc.ContainerID = ic.ID
   306  	} else {
   307  		ipc.HostIpc = c.hostConfig.IpcMode.IsHost()
   308  	}
   309  
   310  	pid := &execdriver.Pid{}
   311  	pid.HostPid = c.hostConfig.PidMode.IsHost()
   312  
   313  	// Build lists of devices allowed and created within the container.
   314  	var userSpecifiedDevices []*configs.Device
   315  	for _, deviceMapping := range c.hostConfig.Devices {
   316  		devs, err := getDevicesFromPath(deviceMapping)
   317  		if err != nil {
   318  			return err
   319  		}
   320  
   321  		userSpecifiedDevices = append(userSpecifiedDevices, devs...)
   322  	}
   323  	allowedDevices := append(configs.DefaultAllowedDevices, userSpecifiedDevices...)
   324  
   325  	autoCreatedDevices := append(configs.DefaultAutoCreatedDevices, userSpecifiedDevices...)
   326  
   327  	// TODO: this can be removed after lxc-conf is fully deprecated
   328  	lxcConfig, err := mergeLxcConfIntoOptions(c.hostConfig)
   329  	if err != nil {
   330  		return err
   331  	}
   332  
   333  	var rlimits []*ulimit.Rlimit
   334  	ulimits := c.hostConfig.Ulimits
   335  
   336  	// Merge ulimits with daemon defaults
   337  	ulIdx := make(map[string]*ulimit.Ulimit)
   338  	for _, ul := range ulimits {
   339  		ulIdx[ul.Name] = ul
   340  	}
   341  	for name, ul := range c.daemon.config.Ulimits {
   342  		if _, exists := ulIdx[name]; !exists {
   343  			ulimits = append(ulimits, ul)
   344  		}
   345  	}
   346  
   347  	for _, limit := range ulimits {
   348  		rl, err := limit.GetRlimit()
   349  		if err != nil {
   350  			return err
   351  		}
   352  		rlimits = append(rlimits, rl)
   353  	}
   354  
   355  	resources := &execdriver.Resources{
   356  		Memory:     c.hostConfig.Memory,
   357  		MemorySwap: c.hostConfig.MemorySwap,
   358  		CpuShares:  c.hostConfig.CpuShares,
   359  		CpusetCpus: c.hostConfig.CpusetCpus,
   360  		CpusetMems: c.hostConfig.CpusetMems,
   361  		CpuQuota:   c.hostConfig.CpuQuota,
   362  		Rlimits:    rlimits,
   363  	}
   364  
   365  	processConfig := execdriver.ProcessConfig{
   366  		Privileged: c.hostConfig.Privileged,
   367  		Entrypoint: c.Path,
   368  		Arguments:  c.Args,
   369  		Tty:        c.Config.Tty,
   370  		User:       c.Config.User,
   371  	}
   372  
   373  	processConfig.SysProcAttr = &syscall.SysProcAttr{Setsid: true}
   374  	processConfig.Env = env
   375  
   376  	c.command = &execdriver.Command{
   377  		ID:                 c.ID,
   378  		Rootfs:             c.RootfsPath(),
   379  		ReadonlyRootfs:     c.hostConfig.ReadonlyRootfs,
   380  		InitPath:           "/.dockerinit",
   381  		WorkingDir:         c.Config.WorkingDir,
   382  		Network:            en,
   383  		Ipc:                ipc,
   384  		Pid:                pid,
   385  		Resources:          resources,
   386  		AllowedDevices:     allowedDevices,
   387  		AutoCreatedDevices: autoCreatedDevices,
   388  		CapAdd:             c.hostConfig.CapAdd,
   389  		CapDrop:            c.hostConfig.CapDrop,
   390  		ProcessConfig:      processConfig,
   391  		ProcessLabel:       c.GetProcessLabel(),
   392  		MountLabel:         c.GetMountLabel(),
   393  		LxcConfig:          lxcConfig,
   394  		AppArmorProfile:    c.AppArmorProfile,
   395  		CgroupParent:       c.hostConfig.CgroupParent,
   396  	}
   397  
   398  	return nil
   399  }
   400  
   401  func (container *Container) Start() (err error) {
   402  	container.Lock()
   403  	defer container.Unlock()
   404  
   405  	if container.Running {
   406  		return nil
   407  	}
   408  
   409  	if container.removalInProgress || container.Dead {
   410  		return fmt.Errorf("Container is marked for removal and cannot be started.")
   411  	}
   412  
   413  	// if we encounter an error during start we need to ensure that any other
   414  	// setup has been cleaned up properly
   415  	defer func() {
   416  		if err != nil {
   417  			container.setError(err)
   418  			// if no one else has set it, make sure we don't leave it at zero
   419  			if container.ExitCode == 0 {
   420  				container.ExitCode = 128
   421  			}
   422  			container.toDisk()
   423  			container.cleanup()
   424  		}
   425  	}()
   426  
   427  	if err := container.setupContainerDns(); err != nil {
   428  		return err
   429  	}
   430  	if err := container.Mount(); err != nil {
   431  		return err
   432  	}
   433  	if err := container.initializeNetworking(); err != nil {
   434  		return err
   435  	}
   436  	if err := container.updateParentsHosts(); err != nil {
   437  		return err
   438  	}
   439  	container.verifyDaemonSettings()
   440  	if err := container.prepareVolumes(); err != nil {
   441  		return err
   442  	}
   443  	linkedEnv, err := container.setupLinkedContainers()
   444  	if err != nil {
   445  		return err
   446  	}
   447  	if err := container.setupWorkingDirectory(); err != nil {
   448  		return err
   449  	}
   450  	env := container.createDaemonEnvironment(linkedEnv)
   451  	if err := populateCommand(container, env); err != nil {
   452  		return err
   453  	}
   454  	if err := container.setupMounts(); err != nil {
   455  		return err
   456  	}
   457  
   458  	return container.waitForStart()
   459  }
   460  
   461  func (container *Container) Run() error {
   462  	if err := container.Start(); err != nil {
   463  		return err
   464  	}
   465  	container.WaitStop(-1 * time.Second)
   466  	return nil
   467  }
   468  
   469  func (container *Container) Output() (output []byte, err error) {
   470  	pipe := container.StdoutPipe()
   471  	defer pipe.Close()
   472  	if err := container.Start(); err != nil {
   473  		return nil, err
   474  	}
   475  	output, err = ioutil.ReadAll(pipe)
   476  	container.WaitStop(-1 * time.Second)
   477  	return output, err
   478  }
   479  
   480  // StreamConfig.StdinPipe returns a WriteCloser which can be used to feed data
   481  // to the standard input of the container's active process.
   482  // Container.StdoutPipe and Container.StderrPipe each return a ReadCloser
   483  // which can be used to retrieve the standard output (and error) generated
   484  // by the container's active process. The output (and error) are actually
   485  // copied and delivered to all StdoutPipe and StderrPipe consumers, using
   486  // a kind of "broadcaster".
   487  
   488  func (streamConfig *StreamConfig) StdinPipe() io.WriteCloser {
   489  	return streamConfig.stdinPipe
   490  }
   491  
   492  func (streamConfig *StreamConfig) StdoutPipe() io.ReadCloser {
   493  	reader, writer := io.Pipe()
   494  	streamConfig.stdout.AddWriter(writer, "")
   495  	return ioutils.NewBufReader(reader)
   496  }
   497  
   498  func (streamConfig *StreamConfig) StderrPipe() io.ReadCloser {
   499  	reader, writer := io.Pipe()
   500  	streamConfig.stderr.AddWriter(writer, "")
   501  	return ioutils.NewBufReader(reader)
   502  }
   503  
   504  func (streamConfig *StreamConfig) StdoutLogPipe() io.ReadCloser {
   505  	reader, writer := io.Pipe()
   506  	streamConfig.stdout.AddWriter(writer, "stdout")
   507  	return ioutils.NewBufReader(reader)
   508  }
   509  
   510  func (streamConfig *StreamConfig) StderrLogPipe() io.ReadCloser {
   511  	reader, writer := io.Pipe()
   512  	streamConfig.stderr.AddWriter(writer, "stderr")
   513  	return ioutils.NewBufReader(reader)
   514  }
   515  
   516  func (container *Container) buildHostnameFile() error {
   517  	hostnamePath, err := container.getRootResourcePath("hostname")
   518  	if err != nil {
   519  		return err
   520  	}
   521  	container.HostnamePath = hostnamePath
   522  
   523  	if container.Config.Domainname != "" {
   524  		return ioutil.WriteFile(container.HostnamePath, []byte(fmt.Sprintf("%s.%s\n", container.Config.Hostname, container.Config.Domainname)), 0644)
   525  	}
   526  	return ioutil.WriteFile(container.HostnamePath, []byte(container.Config.Hostname+"\n"), 0644)
   527  }
   528  
   529  func (container *Container) buildHostsFiles(IP string) error {
   530  
   531  	hostsPath, err := container.getRootResourcePath("hosts")
   532  	if err != nil {
   533  		return err
   534  	}
   535  	container.HostsPath = hostsPath
   536  
   537  	var extraContent []etchosts.Record
   538  
   539  	children, err := container.daemon.Children(container.Name)
   540  	if err != nil {
   541  		return err
   542  	}
   543  
   544  	for linkAlias, child := range children {
   545  		_, alias := path.Split(linkAlias)
   546  		// allow access to the linked container via the alias, real name, and container hostname
   547  		aliasList := alias + " " + child.Config.Hostname
   548  		// only add the name if alias isn't equal to the name
   549  		if alias != child.Name[1:] {
   550  			aliasList = aliasList + " " + child.Name[1:]
   551  		}
   552  		extraContent = append(extraContent, etchosts.Record{Hosts: aliasList, IP: child.NetworkSettings.IPAddress})
   553  	}
   554  
   555  	for _, extraHost := range container.hostConfig.ExtraHosts {
   556  		// allow IPv6 addresses in extra hosts; only split on first ":"
   557  		parts := strings.SplitN(extraHost, ":", 2)
   558  		extraContent = append(extraContent, etchosts.Record{Hosts: parts[0], IP: parts[1]})
   559  	}
   560  
   561  	return etchosts.Build(container.HostsPath, IP, container.Config.Hostname, container.Config.Domainname, extraContent)
   562  }
   563  
   564  func (container *Container) buildHostnameAndHostsFiles(IP string) error {
   565  	if err := container.buildHostnameFile(); err != nil {
   566  		return err
   567  	}
   568  
   569  	return container.buildHostsFiles(IP)
   570  }
   571  
   572  func (container *Container) AllocateNetwork() error {
   573  	mode := container.hostConfig.NetworkMode
   574  	if container.Config.NetworkDisabled || !mode.IsPrivate() {
   575  		return nil
   576  	}
   577  
   578  	var (
   579  		err error
   580  		eng = container.daemon.eng
   581  	)
   582  
   583  	networkSettings, err := bridge.Allocate(container.ID, container.Config.MacAddress, "", "")
   584  	if err != nil {
   585  		return err
   586  	}
   587  
   588  	// Error handling: At this point, the interface is allocated so we have to
   589  	// make sure that it is always released in case of error, otherwise we
   590  	// might leak resources.
   591  
   592  	if container.Config.PortSpecs != nil {
   593  		if err = migratePortMappings(container.Config, container.hostConfig); err != nil {
   594  			bridge.Release(container.ID)
   595  			return err
   596  		}
   597  		container.Config.PortSpecs = nil
   598  		if err = container.WriteHostConfig(); err != nil {
   599  			bridge.Release(container.ID)
   600  			return err
   601  		}
   602  	}
   603  
   604  	var (
   605  		portSpecs = make(nat.PortSet)
   606  		bindings  = make(nat.PortMap)
   607  	)
   608  
   609  	if container.Config.ExposedPorts != nil {
   610  		portSpecs = container.Config.ExposedPorts
   611  	}
   612  
   613  	if container.hostConfig.PortBindings != nil {
   614  		for p, b := range container.hostConfig.PortBindings {
   615  			bindings[p] = []nat.PortBinding{}
   616  			for _, bb := range b {
   617  				bindings[p] = append(bindings[p], nat.PortBinding{
   618  					HostIp:   bb.HostIp,
   619  					HostPort: bb.HostPort,
   620  				})
   621  			}
   622  		}
   623  	}
   624  
   625  	container.NetworkSettings.PortMapping = nil
   626  
   627  	for port := range portSpecs {
   628  		if err = container.allocatePort(eng, port, bindings); err != nil {
   629  			bridge.Release(container.ID)
   630  			return err
   631  		}
   632  	}
   633  	container.WriteHostConfig()
   634  
   635  	networkSettings.Ports = bindings
   636  	container.NetworkSettings = networkSettings
   637  
   638  	return nil
   639  }
   640  
   641  func (container *Container) ReleaseNetwork() {
   642  	if container.Config.NetworkDisabled || !container.hostConfig.NetworkMode.IsPrivate() {
   643  		return
   644  	}
   645  
   646  	bridge.Release(container.ID)
   647  
   648  	container.NetworkSettings = &network.Settings{}
   649  }
   650  
   651  func (container *Container) isNetworkAllocated() bool {
   652  	return container.NetworkSettings.IPAddress != ""
   653  }
   654  
   655  func (container *Container) RestoreNetwork() error {
   656  	mode := container.hostConfig.NetworkMode
   657  	// Don't attempt a restore if we previously didn't allocate networking.
   658  	// This might be a legacy container with no network allocated, in which case the
   659  	// allocation will happen once and for all at start.
   660  	if !container.isNetworkAllocated() || container.Config.NetworkDisabled || !mode.IsPrivate() {
   661  		return nil
   662  	}
   663  
   664  	eng := container.daemon.eng
   665  
   666  	// Re-allocate the interface with the same IP and MAC address.
   667  	if _, err := bridge.Allocate(container.ID, container.NetworkSettings.MacAddress, container.NetworkSettings.IPAddress, ""); err != nil {
   668  		return err
   669  	}
   670  
   671  	// Re-allocate any previously allocated ports.
   672  	for port := range container.NetworkSettings.Ports {
   673  		if err := container.allocatePort(eng, port, container.NetworkSettings.Ports); err != nil {
   674  			return err
   675  		}
   676  	}
   677  	return nil
   678  }
   679  
   680  // cleanup releases any network resources allocated to the container along with any rules
   681  // around how containers are linked together.  It also unmounts the container's root filesystem.
   682  func (container *Container) cleanup() {
   683  	container.ReleaseNetwork()
   684  
   685  	// Disable all active links
   686  	if container.activeLinks != nil {
   687  		for _, link := range container.activeLinks {
   688  			link.Disable()
   689  		}
   690  	}
   691  
   692  	if err := container.Unmount(); err != nil {
   693  		logrus.Errorf("%v: Failed to umount filesystem: %v", container.ID, err)
   694  	}
   695  
   696  	for _, eConfig := range container.execCommands.s {
   697  		container.daemon.unregisterExecCommand(eConfig)
   698  	}
   699  }
   700  
   701  func (container *Container) KillSig(sig int) error {
   702  	logrus.Debugf("Sending %d to %s", sig, container.ID)
   703  	container.Lock()
   704  	defer container.Unlock()
   705  
   706  	// We could unpause the container for them rather than returning this error
   707  	if container.Paused {
   708  		return fmt.Errorf("Container %s is paused. Unpause the container before stopping", container.ID)
   709  	}
   710  
   711  	if !container.Running {
   712  		return nil
   713  	}
   714  
   715  	// signal to the monitor that it should not restart the container
   716  	// after we send the kill signal
   717  	container.monitor.ExitOnNext()
   718  
   719  	// if the container is currently restarting we do not need to send the signal
   720  	// to the process.  Telling the monitor that it should exit on it's next event
   721  	// loop is enough
   722  	if container.Restarting {
   723  		return nil
   724  	}
   725  
   726  	return container.daemon.Kill(container, sig)
   727  }
   728  
   729  // Wrapper aroung KillSig() suppressing "no such process" error.
   730  func (container *Container) killPossiblyDeadProcess(sig int) error {
   731  	err := container.KillSig(sig)
   732  	if err == syscall.ESRCH {
   733  		logrus.Debugf("Cannot kill process (pid=%d) with signal %d: no such process.", container.GetPid(), sig)
   734  		return nil
   735  	}
   736  	return err
   737  }
   738  
   739  func (container *Container) Pause() error {
   740  	if container.IsPaused() {
   741  		return fmt.Errorf("Container %s is already paused", container.ID)
   742  	}
   743  	if !container.IsRunning() {
   744  		return fmt.Errorf("Container %s is not running", container.ID)
   745  	}
   746  	return container.daemon.Pause(container)
   747  }
   748  
   749  func (container *Container) Unpause() error {
   750  	if !container.IsPaused() {
   751  		return fmt.Errorf("Container %s is not paused", container.ID)
   752  	}
   753  	if !container.IsRunning() {
   754  		return fmt.Errorf("Container %s is not running", container.ID)
   755  	}
   756  	return container.daemon.Unpause(container)
   757  }
   758  
   759  func (container *Container) Kill() error {
   760  	if !container.IsRunning() {
   761  		return nil
   762  	}
   763  
   764  	// 1. Send SIGKILL
   765  	if err := container.killPossiblyDeadProcess(9); err != nil {
   766  		return err
   767  	}
   768  
   769  	// 2. Wait for the process to die, in last resort, try to kill the process directly
   770  	if _, err := container.WaitStop(10 * time.Second); err != nil {
   771  		// Ensure that we don't kill ourselves
   772  		if pid := container.GetPid(); pid != 0 {
   773  			logrus.Infof("Container %s failed to exit within 10 seconds of kill - trying direct SIGKILL", stringid.TruncateID(container.ID))
   774  			if err := syscall.Kill(pid, 9); err != nil {
   775  				if err != syscall.ESRCH {
   776  					return err
   777  				}
   778  				logrus.Debugf("Cannot kill process (pid=%d) with signal 9: no such process.", pid)
   779  			}
   780  		}
   781  	}
   782  
   783  	container.WaitStop(-1 * time.Second)
   784  	return nil
   785  }
   786  
   787  func (container *Container) Stop(seconds int) error {
   788  	if !container.IsRunning() {
   789  		return nil
   790  	}
   791  
   792  	// 1. Send a SIGTERM
   793  	if err := container.killPossiblyDeadProcess(15); err != nil {
   794  		logrus.Infof("Failed to send SIGTERM to the process, force killing")
   795  		if err := container.killPossiblyDeadProcess(9); err != nil {
   796  			return err
   797  		}
   798  	}
   799  
   800  	// 2. Wait for the process to exit on its own
   801  	if _, err := container.WaitStop(time.Duration(seconds) * time.Second); err != nil {
   802  		logrus.Infof("Container %v failed to exit within %d seconds of SIGTERM - using the force", container.ID, seconds)
   803  		// 3. If it doesn't, then send SIGKILL
   804  		if err := container.Kill(); err != nil {
   805  			container.WaitStop(-1 * time.Second)
   806  			return err
   807  		}
   808  	}
   809  	return nil
   810  }
   811  
   812  func (container *Container) Restart(seconds int) error {
   813  	// Avoid unnecessarily unmounting and then directly mounting
   814  	// the container when the container stops and then starts
   815  	// again
   816  	if err := container.Mount(); err == nil {
   817  		defer container.Unmount()
   818  	}
   819  
   820  	if err := container.Stop(seconds); err != nil {
   821  		return err
   822  	}
   823  	return container.Start()
   824  }
   825  
   826  func (container *Container) Resize(h, w int) error {
   827  	if !container.IsRunning() {
   828  		return fmt.Errorf("Cannot resize container %s, container is not running", container.ID)
   829  	}
   830  	return container.command.ProcessConfig.Terminal.Resize(h, w)
   831  }
   832  
   833  func (container *Container) ExportRw() (archive.Archive, error) {
   834  	if err := container.Mount(); err != nil {
   835  		return nil, err
   836  	}
   837  	if container.daemon == nil {
   838  		return nil, fmt.Errorf("Can't load storage driver for unregistered container %s", container.ID)
   839  	}
   840  	archive, err := container.daemon.Diff(container)
   841  	if err != nil {
   842  		container.Unmount()
   843  		return nil, err
   844  	}
   845  	return ioutils.NewReadCloserWrapper(archive, func() error {
   846  			err := archive.Close()
   847  			container.Unmount()
   848  			return err
   849  		}),
   850  		nil
   851  }
   852  
   853  func (container *Container) Export() (archive.Archive, error) {
   854  	if err := container.Mount(); err != nil {
   855  		return nil, err
   856  	}
   857  
   858  	archive, err := archive.Tar(container.basefs, archive.Uncompressed)
   859  	if err != nil {
   860  		container.Unmount()
   861  		return nil, err
   862  	}
   863  	return ioutils.NewReadCloserWrapper(archive, func() error {
   864  			err := archive.Close()
   865  			container.Unmount()
   866  			return err
   867  		}),
   868  		nil
   869  }
   870  
   871  func (container *Container) Mount() error {
   872  	return container.daemon.Mount(container)
   873  }
   874  
   875  func (container *Container) changes() ([]archive.Change, error) {
   876  	return container.daemon.Changes(container)
   877  }
   878  
   879  func (container *Container) Changes() ([]archive.Change, error) {
   880  	container.Lock()
   881  	defer container.Unlock()
   882  	return container.changes()
   883  }
   884  
   885  func (container *Container) GetImage() (*image.Image, error) {
   886  	if container.daemon == nil {
   887  		return nil, fmt.Errorf("Can't get image of unregistered container")
   888  	}
   889  	return container.daemon.graph.Get(container.ImageID)
   890  }
   891  
   892  func (container *Container) Unmount() error {
   893  	return container.daemon.Unmount(container)
   894  }
   895  
   896  func (container *Container) logPath(name string) (string, error) {
   897  	return container.getRootResourcePath(fmt.Sprintf("%s-%s.log", container.ID, name))
   898  }
   899  
   900  func (container *Container) ReadLog(name string) (io.Reader, error) {
   901  	pth, err := container.logPath(name)
   902  	if err != nil {
   903  		return nil, err
   904  	}
   905  	return os.Open(pth)
   906  }
   907  
   908  func (container *Container) hostConfigPath() (string, error) {
   909  	return container.getRootResourcePath("hostconfig.json")
   910  }
   911  
   912  func (container *Container) jsonPath() (string, error) {
   913  	return container.getRootResourcePath("config.json")
   914  }
   915  
   916  // This method must be exported to be used from the lxc template
   917  // This directory is only usable when the container is running
   918  func (container *Container) RootfsPath() string {
   919  	return container.basefs
   920  }
   921  
   922  func validateID(id string) error {
   923  	if id == "" {
   924  		return fmt.Errorf("Invalid empty id")
   925  	}
   926  	return nil
   927  }
   928  
   929  // GetSize, return real size, virtual size
   930  func (container *Container) GetSize() (int64, int64) {
   931  	var (
   932  		sizeRw, sizeRootfs int64
   933  		err                error
   934  		driver             = container.daemon.driver
   935  	)
   936  
   937  	if err := container.Mount(); err != nil {
   938  		logrus.Errorf("Failed to compute size of container rootfs %s: %s", container.ID, err)
   939  		return sizeRw, sizeRootfs
   940  	}
   941  	defer container.Unmount()
   942  
   943  	initID := fmt.Sprintf("%s-init", container.ID)
   944  	sizeRw, err = driver.DiffSize(container.ID, initID)
   945  	if err != nil {
   946  		logrus.Errorf("Driver %s couldn't return diff size of container %s: %s", driver, container.ID, err)
   947  		// FIXME: GetSize should return an error. Not changing it now in case
   948  		// there is a side-effect.
   949  		sizeRw = -1
   950  	}
   951  
   952  	if _, err = os.Stat(container.basefs); err != nil {
   953  		if sizeRootfs, err = directory.Size(container.basefs); err != nil {
   954  			sizeRootfs = -1
   955  		}
   956  	}
   957  	return sizeRw, sizeRootfs
   958  }
   959  
   960  func (container *Container) Copy(resource string) (io.ReadCloser, error) {
   961  	container.Lock()
   962  	defer container.Unlock()
   963  	var err error
   964  	if err := container.Mount(); err != nil {
   965  		return nil, err
   966  	}
   967  	defer func() {
   968  		if err != nil {
   969  			container.Unmount()
   970  		}
   971  	}()
   972  
   973  	if err = container.mountVolumes(); err != nil {
   974  		container.unmountVolumes()
   975  		return nil, err
   976  	}
   977  	defer func() {
   978  		if err != nil {
   979  			container.unmountVolumes()
   980  		}
   981  	}()
   982  
   983  	basePath, err := container.getResourcePath(resource)
   984  	if err != nil {
   985  		return nil, err
   986  	}
   987  
   988  	stat, err := os.Stat(basePath)
   989  	if err != nil {
   990  		return nil, err
   991  	}
   992  	var filter []string
   993  	if !stat.IsDir() {
   994  		d, f := path.Split(basePath)
   995  		basePath = d
   996  		filter = []string{f}
   997  	} else {
   998  		filter = []string{path.Base(basePath)}
   999  		basePath = path.Dir(basePath)
  1000  	}
  1001  
  1002  	archive, err := archive.TarWithOptions(basePath, &archive.TarOptions{
  1003  		Compression:  archive.Uncompressed,
  1004  		IncludeFiles: filter,
  1005  	})
  1006  	if err != nil {
  1007  		return nil, err
  1008  	}
  1009  
  1010  	return ioutils.NewReadCloserWrapper(archive, func() error {
  1011  			err := archive.Close()
  1012  			container.unmountVolumes()
  1013  			container.Unmount()
  1014  			return err
  1015  		}),
  1016  		nil
  1017  }
  1018  
  1019  // Returns true if the container exposes a certain port
  1020  func (container *Container) Exposes(p nat.Port) bool {
  1021  	_, exists := container.Config.ExposedPorts[p]
  1022  	return exists
  1023  }
  1024  
  1025  func (container *Container) HostConfig() *runconfig.HostConfig {
  1026  	container.Lock()
  1027  	res := container.hostConfig
  1028  	container.Unlock()
  1029  	return res
  1030  }
  1031  
  1032  func (container *Container) SetHostConfig(hostConfig *runconfig.HostConfig) {
  1033  	container.Lock()
  1034  	container.hostConfig = hostConfig
  1035  	container.Unlock()
  1036  }
  1037  
  1038  func (container *Container) DisableLink(name string) {
  1039  	if container.activeLinks != nil {
  1040  		if link, exists := container.activeLinks[name]; exists {
  1041  			link.Disable()
  1042  		} else {
  1043  			logrus.Debugf("Could not find active link for %s", name)
  1044  		}
  1045  	}
  1046  }
  1047  
  1048  func (container *Container) setupContainerDns() error {
  1049  	if container.ResolvConfPath != "" {
  1050  		// check if this is an existing container that needs DNS update:
  1051  		if container.UpdateDns {
  1052  			// read the host's resolv.conf, get the hash and call updateResolvConf
  1053  			logrus.Debugf("Check container (%s) for update to resolv.conf - UpdateDns flag was set", container.ID)
  1054  			latestResolvConf, latestHash := resolvconf.GetLastModified()
  1055  
  1056  			// clean container resolv.conf re: localhost nameservers and IPv6 NS (if IPv6 disabled)
  1057  			updatedResolvConf, modified := resolvconf.FilterResolvDns(latestResolvConf, container.daemon.config.Bridge.EnableIPv6)
  1058  			if modified {
  1059  				// changes have occurred during resolv.conf localhost cleanup: generate an updated hash
  1060  				newHash, err := ioutils.HashData(bytes.NewReader(updatedResolvConf))
  1061  				if err != nil {
  1062  					return err
  1063  				}
  1064  				latestHash = newHash
  1065  			}
  1066  
  1067  			if err := container.updateResolvConf(updatedResolvConf, latestHash); err != nil {
  1068  				return err
  1069  			}
  1070  			// successful update of the restarting container; set the flag off
  1071  			container.UpdateDns = false
  1072  		}
  1073  		return nil
  1074  	}
  1075  
  1076  	var (
  1077  		config = container.hostConfig
  1078  		daemon = container.daemon
  1079  	)
  1080  
  1081  	resolvConf, err := resolvconf.Get()
  1082  	if err != nil {
  1083  		return err
  1084  	}
  1085  	container.ResolvConfPath, err = container.getRootResourcePath("resolv.conf")
  1086  	if err != nil {
  1087  		return err
  1088  	}
  1089  
  1090  	if config.NetworkMode != "host" {
  1091  		// check configurations for any container/daemon dns settings
  1092  		if len(config.Dns) > 0 || len(daemon.config.Dns) > 0 || len(config.DnsSearch) > 0 || len(daemon.config.DnsSearch) > 0 {
  1093  			var (
  1094  				dns       = resolvconf.GetNameservers(resolvConf)
  1095  				dnsSearch = resolvconf.GetSearchDomains(resolvConf)
  1096  			)
  1097  			if len(config.Dns) > 0 {
  1098  				dns = config.Dns
  1099  			} else if len(daemon.config.Dns) > 0 {
  1100  				dns = daemon.config.Dns
  1101  			}
  1102  			if len(config.DnsSearch) > 0 {
  1103  				dnsSearch = config.DnsSearch
  1104  			} else if len(daemon.config.DnsSearch) > 0 {
  1105  				dnsSearch = daemon.config.DnsSearch
  1106  			}
  1107  			return resolvconf.Build(container.ResolvConfPath, dns, dnsSearch)
  1108  		}
  1109  
  1110  		// replace any localhost/127.*, and remove IPv6 nameservers if IPv6 disabled in daemon
  1111  		resolvConf, _ = resolvconf.FilterResolvDns(resolvConf, daemon.config.Bridge.EnableIPv6)
  1112  	}
  1113  	//get a sha256 hash of the resolv conf at this point so we can check
  1114  	//for changes when the host resolv.conf changes (e.g. network update)
  1115  	resolvHash, err := ioutils.HashData(bytes.NewReader(resolvConf))
  1116  	if err != nil {
  1117  		return err
  1118  	}
  1119  	resolvHashFile := container.ResolvConfPath + ".hash"
  1120  	if err = ioutil.WriteFile(resolvHashFile, []byte(resolvHash), 0644); err != nil {
  1121  		return err
  1122  	}
  1123  	return ioutil.WriteFile(container.ResolvConfPath, resolvConf, 0644)
  1124  }
  1125  
  1126  // called when the host's resolv.conf changes to check whether container's resolv.conf
  1127  // is unchanged by the container "user" since container start: if unchanged, the
  1128  // container's resolv.conf will be updated to match the host's new resolv.conf
  1129  func (container *Container) updateResolvConf(updatedResolvConf []byte, newResolvHash string) error {
  1130  
  1131  	if container.ResolvConfPath == "" {
  1132  		return nil
  1133  	}
  1134  	if container.Running {
  1135  		//set a marker in the hostConfig to update on next start/restart
  1136  		container.UpdateDns = true
  1137  		return nil
  1138  	}
  1139  
  1140  	resolvHashFile := container.ResolvConfPath + ".hash"
  1141  
  1142  	//read the container's current resolv.conf and compute the hash
  1143  	resolvBytes, err := ioutil.ReadFile(container.ResolvConfPath)
  1144  	if err != nil {
  1145  		return err
  1146  	}
  1147  	curHash, err := ioutils.HashData(bytes.NewReader(resolvBytes))
  1148  	if err != nil {
  1149  		return err
  1150  	}
  1151  
  1152  	//read the hash from the last time we wrote resolv.conf in the container
  1153  	hashBytes, err := ioutil.ReadFile(resolvHashFile)
  1154  	if err != nil {
  1155  		if !os.IsNotExist(err) {
  1156  			return err
  1157  		}
  1158  		// backwards compat: if no hash file exists, this container pre-existed from
  1159  		// a Docker daemon that didn't contain this update feature. Given we can't know
  1160  		// if the user has modified the resolv.conf since container start time, safer
  1161  		// to just never update the container's resolv.conf during it's lifetime which
  1162  		// we can control by setting hashBytes to an empty string
  1163  		hashBytes = []byte("")
  1164  	}
  1165  
  1166  	//if the user has not modified the resolv.conf of the container since we wrote it last
  1167  	//we will replace it with the updated resolv.conf from the host
  1168  	if string(hashBytes) == curHash {
  1169  		logrus.Debugf("replacing %q with updated host resolv.conf", container.ResolvConfPath)
  1170  
  1171  		// for atomic updates to these files, use temporary files with os.Rename:
  1172  		dir := path.Dir(container.ResolvConfPath)
  1173  		tmpHashFile, err := ioutil.TempFile(dir, "hash")
  1174  		if err != nil {
  1175  			return err
  1176  		}
  1177  		tmpResolvFile, err := ioutil.TempFile(dir, "resolv")
  1178  		if err != nil {
  1179  			return err
  1180  		}
  1181  
  1182  		// write the updates to the temp files
  1183  		if err = ioutil.WriteFile(tmpHashFile.Name(), []byte(newResolvHash), 0644); err != nil {
  1184  			return err
  1185  		}
  1186  		if err = ioutil.WriteFile(tmpResolvFile.Name(), updatedResolvConf, 0644); err != nil {
  1187  			return err
  1188  		}
  1189  
  1190  		// rename the temp files for atomic replace
  1191  		if err = os.Rename(tmpHashFile.Name(), resolvHashFile); err != nil {
  1192  			return err
  1193  		}
  1194  		return os.Rename(tmpResolvFile.Name(), container.ResolvConfPath)
  1195  	}
  1196  	return nil
  1197  }
  1198  
  1199  func (container *Container) updateParentsHosts() error {
  1200  	refs := container.daemon.ContainerGraph().RefPaths(container.ID)
  1201  	for _, ref := range refs {
  1202  		if ref.ParentID == "0" {
  1203  			continue
  1204  		}
  1205  
  1206  		c, err := container.daemon.Get(ref.ParentID)
  1207  		if err != nil {
  1208  			logrus.Error(err)
  1209  		}
  1210  
  1211  		if c != nil && !container.daemon.config.DisableNetwork && container.hostConfig.NetworkMode.IsPrivate() {
  1212  			logrus.Debugf("Update /etc/hosts of %s for alias %s with ip %s", c.ID, ref.Name, container.NetworkSettings.IPAddress)
  1213  			if err := etchosts.Update(c.HostsPath, container.NetworkSettings.IPAddress, ref.Name); err != nil {
  1214  				logrus.Errorf("Failed to update /etc/hosts in parent container %s for alias %s: %v", c.ID, ref.Name, err)
  1215  			}
  1216  		}
  1217  	}
  1218  	return nil
  1219  }
  1220  
  1221  func (container *Container) initializeNetworking() error {
  1222  	var err error
  1223  	if container.hostConfig.NetworkMode.IsHost() {
  1224  		container.Config.Hostname, err = os.Hostname()
  1225  		if err != nil {
  1226  			return err
  1227  		}
  1228  
  1229  		parts := strings.SplitN(container.Config.Hostname, ".", 2)
  1230  		if len(parts) > 1 {
  1231  			container.Config.Hostname = parts[0]
  1232  			container.Config.Domainname = parts[1]
  1233  		}
  1234  
  1235  		content, err := ioutil.ReadFile("/etc/hosts")
  1236  		if os.IsNotExist(err) {
  1237  			return container.buildHostnameAndHostsFiles("")
  1238  		} else if err != nil {
  1239  			return err
  1240  		}
  1241  
  1242  		if err := container.buildHostnameFile(); err != nil {
  1243  			return err
  1244  		}
  1245  
  1246  		hostsPath, err := container.getRootResourcePath("hosts")
  1247  		if err != nil {
  1248  			return err
  1249  		}
  1250  		container.HostsPath = hostsPath
  1251  
  1252  		return ioutil.WriteFile(container.HostsPath, content, 0644)
  1253  	}
  1254  	if container.hostConfig.NetworkMode.IsContainer() {
  1255  		// we need to get the hosts files from the container to join
  1256  		nc, err := container.getNetworkedContainer()
  1257  		if err != nil {
  1258  			return err
  1259  		}
  1260  		container.HostnamePath = nc.HostnamePath
  1261  		container.HostsPath = nc.HostsPath
  1262  		container.ResolvConfPath = nc.ResolvConfPath
  1263  		container.Config.Hostname = nc.Config.Hostname
  1264  		container.Config.Domainname = nc.Config.Domainname
  1265  		return nil
  1266  	}
  1267  	if container.daemon.config.DisableNetwork {
  1268  		container.Config.NetworkDisabled = true
  1269  		return container.buildHostnameAndHostsFiles("127.0.1.1")
  1270  	}
  1271  	if err := container.AllocateNetwork(); err != nil {
  1272  		return err
  1273  	}
  1274  	return container.buildHostnameAndHostsFiles(container.NetworkSettings.IPAddress)
  1275  }
  1276  
  1277  // Make sure the config is compatible with the current kernel
  1278  func (container *Container) verifyDaemonSettings() {
  1279  	if container.hostConfig.Memory > 0 && !container.daemon.sysInfo.MemoryLimit {
  1280  		logrus.Warnf("Your kernel does not support memory limit capabilities. Limitation discarded.")
  1281  		container.hostConfig.Memory = 0
  1282  	}
  1283  	if container.hostConfig.Memory > 0 && container.hostConfig.MemorySwap != -1 && !container.daemon.sysInfo.SwapLimit {
  1284  		logrus.Warnf("Your kernel does not support swap limit capabilities. Limitation discarded.")
  1285  		container.hostConfig.MemorySwap = -1
  1286  	}
  1287  	if container.daemon.sysInfo.IPv4ForwardingDisabled {
  1288  		logrus.Warnf("IPv4 forwarding is disabled. Networking will not work")
  1289  	}
  1290  }
  1291  
  1292  func (container *Container) setupLinkedContainers() ([]string, error) {
  1293  	var (
  1294  		env    []string
  1295  		daemon = container.daemon
  1296  	)
  1297  	children, err := daemon.Children(container.Name)
  1298  	if err != nil {
  1299  		return nil, err
  1300  	}
  1301  
  1302  	if len(children) > 0 {
  1303  		container.activeLinks = make(map[string]*links.Link, len(children))
  1304  
  1305  		// If we encounter an error make sure that we rollback any network
  1306  		// config and iptables changes
  1307  		rollback := func() {
  1308  			for _, link := range container.activeLinks {
  1309  				link.Disable()
  1310  			}
  1311  			container.activeLinks = nil
  1312  		}
  1313  
  1314  		for linkAlias, child := range children {
  1315  			if !child.IsRunning() {
  1316  				return nil, fmt.Errorf("Cannot link to a non running container: %s AS %s", child.Name, linkAlias)
  1317  			}
  1318  
  1319  			link, err := links.NewLink(
  1320  				container.NetworkSettings.IPAddress,
  1321  				child.NetworkSettings.IPAddress,
  1322  				linkAlias,
  1323  				child.Config.Env,
  1324  				child.Config.ExposedPorts,
  1325  			)
  1326  
  1327  			if err != nil {
  1328  				rollback()
  1329  				return nil, err
  1330  			}
  1331  
  1332  			container.activeLinks[link.Alias()] = link
  1333  			if err := link.Enable(); err != nil {
  1334  				rollback()
  1335  				return nil, err
  1336  			}
  1337  
  1338  			for _, envVar := range link.ToEnv() {
  1339  				env = append(env, envVar)
  1340  			}
  1341  		}
  1342  	}
  1343  	return env, nil
  1344  }
  1345  
  1346  func (container *Container) createDaemonEnvironment(linkedEnv []string) []string {
  1347  	// if a domain name was specified, append it to the hostname (see #7851)
  1348  	fullHostname := container.Config.Hostname
  1349  	if container.Config.Domainname != "" {
  1350  		fullHostname = fmt.Sprintf("%s.%s", fullHostname, container.Config.Domainname)
  1351  	}
  1352  	// Setup environment
  1353  	env := []string{
  1354  		"PATH=" + DefaultPathEnv,
  1355  		"HOSTNAME=" + fullHostname,
  1356  		// Note: we don't set HOME here because it'll get autoset intelligently
  1357  		// based on the value of USER inside dockerinit, but only if it isn't
  1358  		// set already (ie, that can be overridden by setting HOME via -e or ENV
  1359  		// in a Dockerfile).
  1360  	}
  1361  	if container.Config.Tty {
  1362  		env = append(env, "TERM=xterm")
  1363  	}
  1364  	env = append(env, linkedEnv...)
  1365  	// because the env on the container can override certain default values
  1366  	// we need to replace the 'env' keys where they match and append anything
  1367  	// else.
  1368  	env = utils.ReplaceOrAppendEnvValues(env, container.Config.Env)
  1369  
  1370  	return env
  1371  }
  1372  
  1373  func (container *Container) setupWorkingDirectory() error {
  1374  	if container.Config.WorkingDir != "" {
  1375  		container.Config.WorkingDir = path.Clean(container.Config.WorkingDir)
  1376  
  1377  		pth, err := container.getResourcePath(container.Config.WorkingDir)
  1378  		if err != nil {
  1379  			return err
  1380  		}
  1381  
  1382  		pthInfo, err := os.Stat(pth)
  1383  		if err != nil {
  1384  			if !os.IsNotExist(err) {
  1385  				return err
  1386  			}
  1387  
  1388  			if err := os.MkdirAll(pth, 0755); err != nil {
  1389  				return err
  1390  			}
  1391  		}
  1392  		if pthInfo != nil && !pthInfo.IsDir() {
  1393  			return fmt.Errorf("Cannot mkdir: %s is not a directory", container.Config.WorkingDir)
  1394  		}
  1395  	}
  1396  	return nil
  1397  }
  1398  
  1399  func (container *Container) startLogging() error {
  1400  	cfg := container.hostConfig.LogConfig
  1401  	if cfg.Type == "" {
  1402  		cfg = container.daemon.defaultLogConfig
  1403  	}
  1404  	var l logger.Logger
  1405  	switch cfg.Type {
  1406  	case "json-file":
  1407  		pth, err := container.logPath("json")
  1408  		if err != nil {
  1409  			return err
  1410  		}
  1411  		container.LogPath = pth
  1412  
  1413  		dl, err := jsonfilelog.New(pth)
  1414  		if err != nil {
  1415  			return err
  1416  		}
  1417  		l = dl
  1418  	case "syslog":
  1419  		dl, err := syslog.New(container.ID[:12])
  1420  		if err != nil {
  1421  			return err
  1422  		}
  1423  		l = dl
  1424  	case "journald":
  1425  		dl, err := journald.New(container.ID[:12])
  1426  		if err != nil {
  1427  			return err
  1428  		}
  1429  		l = dl
  1430  	case "none":
  1431  		return nil
  1432  	default:
  1433  		return fmt.Errorf("Unknown logging driver: %s", cfg.Type)
  1434  	}
  1435  
  1436  	copier, err := logger.NewCopier(container.ID, map[string]io.Reader{"stdout": container.StdoutPipe(), "stderr": container.StderrPipe()}, l)
  1437  	if err != nil {
  1438  		return err
  1439  	}
  1440  	container.logCopier = copier
  1441  	copier.Run()
  1442  	container.logDriver = l
  1443  
  1444  	return nil
  1445  }
  1446  
  1447  func (container *Container) waitForStart() error {
  1448  	container.monitor = newContainerMonitor(container, container.hostConfig.RestartPolicy)
  1449  
  1450  	// block until we either receive an error from the initial start of the container's
  1451  	// process or until the process is running in the container
  1452  	select {
  1453  	case <-container.monitor.startSignal:
  1454  	case err := <-promise.Go(container.monitor.Start):
  1455  		return err
  1456  	}
  1457  
  1458  	return nil
  1459  }
  1460  
  1461  func (container *Container) allocatePort(eng *engine.Engine, port nat.Port, bindings nat.PortMap) error {
  1462  	binding := bindings[port]
  1463  	if container.hostConfig.PublishAllPorts && len(binding) == 0 {
  1464  		binding = append(binding, nat.PortBinding{})
  1465  	}
  1466  
  1467  	for i := 0; i < len(binding); i++ {
  1468  		b, err := bridge.AllocatePort(container.ID, port, binding[i])
  1469  		if err != nil {
  1470  			return err
  1471  		}
  1472  		binding[i] = b
  1473  	}
  1474  	bindings[port] = binding
  1475  	return nil
  1476  }
  1477  
  1478  func (container *Container) GetProcessLabel() string {
  1479  	// even if we have a process label return "" if we are running
  1480  	// in privileged mode
  1481  	if container.hostConfig.Privileged {
  1482  		return ""
  1483  	}
  1484  	return container.ProcessLabel
  1485  }
  1486  
  1487  func (container *Container) GetMountLabel() string {
  1488  	if container.hostConfig.Privileged {
  1489  		return ""
  1490  	}
  1491  	return container.MountLabel
  1492  }
  1493  
  1494  func (container *Container) getIpcContainer() (*Container, error) {
  1495  	containerID := container.hostConfig.IpcMode.Container()
  1496  	c, err := container.daemon.Get(containerID)
  1497  	if err != nil {
  1498  		return nil, err
  1499  	}
  1500  	if !c.IsRunning() {
  1501  		return nil, fmt.Errorf("cannot join IPC of a non running container: %s", containerID)
  1502  	}
  1503  	return c, nil
  1504  }
  1505  
  1506  func (container *Container) getNetworkedContainer() (*Container, error) {
  1507  	parts := strings.SplitN(string(container.hostConfig.NetworkMode), ":", 2)
  1508  	switch parts[0] {
  1509  	case "container":
  1510  		if len(parts) != 2 {
  1511  			return nil, fmt.Errorf("no container specified to join network")
  1512  		}
  1513  		nc, err := container.daemon.Get(parts[1])
  1514  		if err != nil {
  1515  			return nil, err
  1516  		}
  1517  		if container == nc {
  1518  			return nil, fmt.Errorf("cannot join own network")
  1519  		}
  1520  		if !nc.IsRunning() {
  1521  			return nil, fmt.Errorf("cannot join network of a non running container: %s", parts[1])
  1522  		}
  1523  		return nc, nil
  1524  	default:
  1525  		return nil, fmt.Errorf("network mode not set to container")
  1526  	}
  1527  }
  1528  
  1529  func (container *Container) Stats() (*execdriver.ResourceStats, error) {
  1530  	return container.daemon.Stats(container)
  1531  }
  1532  
  1533  func (c *Container) LogDriverType() string {
  1534  	c.Lock()
  1535  	defer c.Unlock()
  1536  	if c.hostConfig.LogConfig.Type == "" {
  1537  		return c.daemon.defaultLogConfig.Type
  1538  	}
  1539  	return c.hostConfig.LogConfig.Type
  1540  }