github.com/mheon/docker@v0.11.2-0.20150922122814-44f47903a831/daemon/container.go (about)

     1  package daemon
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"fmt"
     7  	"io"
     8  	"io/ioutil"
     9  	"os"
    10  	"path/filepath"
    11  	"sync"
    12  	"syscall"
    13  	"time"
    14  
    15  	"github.com/opencontainers/runc/libcontainer/label"
    16  
    17  	"github.com/Sirupsen/logrus"
    18  	"github.com/docker/docker/daemon/execdriver"
    19  	"github.com/docker/docker/daemon/logger"
    20  	"github.com/docker/docker/daemon/logger/jsonfilelog"
    21  	"github.com/docker/docker/daemon/network"
    22  	derr "github.com/docker/docker/errors"
    23  	"github.com/docker/docker/image"
    24  	"github.com/docker/docker/pkg/archive"
    25  	"github.com/docker/docker/pkg/broadcastwriter"
    26  	"github.com/docker/docker/pkg/fileutils"
    27  	"github.com/docker/docker/pkg/ioutils"
    28  	"github.com/docker/docker/pkg/mount"
    29  	"github.com/docker/docker/pkg/nat"
    30  	"github.com/docker/docker/pkg/promise"
    31  	"github.com/docker/docker/pkg/signal"
    32  	"github.com/docker/docker/pkg/symlink"
    33  	"github.com/docker/docker/runconfig"
    34  	"github.com/docker/docker/volume"
    35  )
    36  
    37  var (
    38  	// ErrRootFSReadOnly is returned when a container
    39  	// rootfs is marked readonly.
    40  	ErrRootFSReadOnly = errors.New("container rootfs is marked read-only")
    41  )
    42  
    43  type streamConfig struct {
    44  	stdout    *broadcastwriter.BroadcastWriter
    45  	stderr    *broadcastwriter.BroadcastWriter
    46  	stdin     io.ReadCloser
    47  	stdinPipe io.WriteCloser
    48  }
    49  
    50  // CommonContainer holds the fields for a container which are
    51  // applicable across all platforms supported by the daemon.
    52  type CommonContainer struct {
    53  	streamConfig
    54  	// embed for Container to support states directly.
    55  	*State          `json:"State"` // Needed for remote api version <= 1.11
    56  	root            string         // Path to the "home" of the container, including metadata.
    57  	basefs          string         // Path to the graphdriver mountpoint
    58  	ID              string
    59  	Created         time.Time
    60  	Path            string
    61  	Args            []string
    62  	Config          *runconfig.Config
    63  	ImageID         string `json:"Image"`
    64  	NetworkSettings *network.Settings
    65  	LogPath         string
    66  	Name            string
    67  	Driver          string
    68  	ExecDriver      string
    69  	// MountLabel contains the options for the 'mount' command
    70  	MountLabel             string
    71  	ProcessLabel           string
    72  	RestartCount           int
    73  	HasBeenStartedBefore   bool
    74  	HasBeenManuallyStopped bool // used for unless-stopped restart policy
    75  	hostConfig             *runconfig.HostConfig
    76  	command                *execdriver.Command
    77  	monitor                *containerMonitor
    78  	execCommands           *execStore
    79  	daemon                 *Daemon
    80  	// logDriver for closing
    81  	logDriver logger.Logger
    82  	logCopier *logger.Copier
    83  }
    84  
    85  func (container *Container) fromDisk() error {
    86  	pth, err := container.jsonPath()
    87  	if err != nil {
    88  		return err
    89  	}
    90  
    91  	jsonSource, err := os.Open(pth)
    92  	if err != nil {
    93  		return err
    94  	}
    95  	defer jsonSource.Close()
    96  
    97  	dec := json.NewDecoder(jsonSource)
    98  
    99  	// Load container settings
   100  	if err := dec.Decode(container); err != nil {
   101  		return err
   102  	}
   103  
   104  	if err := label.ReserveLabel(container.ProcessLabel); err != nil {
   105  		return err
   106  	}
   107  	return container.readHostConfig()
   108  }
   109  
   110  func (container *Container) toDisk() error {
   111  	data, err := json.Marshal(container)
   112  	if err != nil {
   113  		return err
   114  	}
   115  
   116  	pth, err := container.jsonPath()
   117  	if err != nil {
   118  		return err
   119  	}
   120  
   121  	if err := ioutil.WriteFile(pth, data, 0666); err != nil {
   122  		return err
   123  	}
   124  
   125  	return container.writeHostConfig()
   126  }
   127  
   128  func (container *Container) toDiskLocking() error {
   129  	container.Lock()
   130  	err := container.toDisk()
   131  	container.Unlock()
   132  	return err
   133  }
   134  
   135  func (container *Container) readHostConfig() error {
   136  	container.hostConfig = &runconfig.HostConfig{}
   137  	// If the hostconfig file does not exist, do not read it.
   138  	// (We still have to initialize container.hostConfig,
   139  	// but that's OK, since we just did that above.)
   140  	pth, err := container.hostConfigPath()
   141  	if err != nil {
   142  		return err
   143  	}
   144  
   145  	_, err = os.Stat(pth)
   146  	if os.IsNotExist(err) {
   147  		return nil
   148  	}
   149  
   150  	f, err := os.Open(pth)
   151  	if err != nil {
   152  		return err
   153  	}
   154  	defer f.Close()
   155  
   156  	return json.NewDecoder(f).Decode(&container.hostConfig)
   157  }
   158  
   159  func (container *Container) writeHostConfig() error {
   160  	data, err := json.Marshal(container.hostConfig)
   161  	if err != nil {
   162  		return err
   163  	}
   164  
   165  	pth, err := container.hostConfigPath()
   166  	if err != nil {
   167  		return err
   168  	}
   169  
   170  	return ioutil.WriteFile(pth, data, 0666)
   171  }
   172  
   173  func (container *Container) logEvent(action string) {
   174  	d := container.daemon
   175  	d.EventsService.Log(
   176  		action,
   177  		container.ID,
   178  		container.Config.Image,
   179  	)
   180  }
   181  
   182  // GetResourcePath evaluates `path` in the scope of the container's basefs, with proper path
   183  // sanitisation. Symlinks are all scoped to the basefs of the container, as
   184  // though the container's basefs was `/`.
   185  //
   186  // The basefs of a container is the host-facing path which is bind-mounted as
   187  // `/` inside the container. This method is essentially used to access a
   188  // particular path inside the container as though you were a process in that
   189  // container.
   190  //
   191  // NOTE: The returned path is *only* safely scoped inside the container's basefs
   192  //       if no component of the returned path changes (such as a component
   193  //       symlinking to a different path) between using this method and using the
   194  //       path. See symlink.FollowSymlinkInScope for more details.
   195  func (container *Container) GetResourcePath(path string) (string, error) {
   196  	// IMPORTANT - These are paths on the OS where the daemon is running, hence
   197  	// any filepath operations must be done in an OS agnostic way.
   198  	cleanPath := filepath.Join(string(os.PathSeparator), path)
   199  	r, e := symlink.FollowSymlinkInScope(filepath.Join(container.basefs, cleanPath), container.basefs)
   200  	return r, e
   201  }
   202  
   203  // Evaluates `path` in the scope of the container's root, with proper path
   204  // sanitisation. Symlinks are all scoped to the root of the container, as
   205  // though the container's root was `/`.
   206  //
   207  // The root of a container is the host-facing configuration metadata directory.
   208  // Only use this method to safely access the container's `container.json` or
   209  // other metadata files. If in doubt, use container.GetResourcePath.
   210  //
   211  // NOTE: The returned path is *only* safely scoped inside the container's root
   212  //       if no component of the returned path changes (such as a component
   213  //       symlinking to a different path) between using this method and using the
   214  //       path. See symlink.FollowSymlinkInScope for more details.
   215  func (container *Container) getRootResourcePath(path string) (string, error) {
   216  	// IMPORTANT - These are paths on the OS where the daemon is running, hence
   217  	// any filepath operations must be done in an OS agnostic way.
   218  	cleanPath := filepath.Join(string(os.PathSeparator), path)
   219  	return symlink.FollowSymlinkInScope(filepath.Join(container.root, cleanPath), container.root)
   220  }
   221  
   222  func (container *Container) exportContainerRw() (archive.Archive, error) {
   223  	if container.daemon == nil {
   224  		return nil, derr.ErrorCodeUnregisteredContainer.WithArgs(container.ID)
   225  	}
   226  	archive, err := container.daemon.diff(container)
   227  	if err != nil {
   228  		return nil, err
   229  	}
   230  	return ioutils.NewReadCloserWrapper(archive, func() error {
   231  			err := archive.Close()
   232  			return err
   233  		}),
   234  		nil
   235  }
   236  
   237  // Start prepares the container to run by setting up everything the
   238  // container needs, such as storage and networking, as well as links
   239  // between containers. The container is left waiting for a signal to
   240  // begin running.
   241  func (container *Container) Start() (err error) {
   242  	container.Lock()
   243  	defer container.Unlock()
   244  
   245  	if container.Running {
   246  		return nil
   247  	}
   248  
   249  	if container.removalInProgress || container.Dead {
   250  		return derr.ErrorCodeContainerBeingRemoved
   251  	}
   252  
   253  	// if we encounter an error during start we need to ensure that any other
   254  	// setup has been cleaned up properly
   255  	defer func() {
   256  		if err != nil {
   257  			container.setError(err)
   258  			// if no one else has set it, make sure we don't leave it at zero
   259  			if container.ExitCode == 0 {
   260  				container.ExitCode = 128
   261  			}
   262  			container.toDisk()
   263  			container.cleanup()
   264  			container.logEvent("die")
   265  		}
   266  	}()
   267  
   268  	if err := container.Mount(); err != nil {
   269  		return err
   270  	}
   271  
   272  	// Make sure NetworkMode has an acceptable value. We do this to ensure
   273  	// backwards API compatibility.
   274  	container.hostConfig = runconfig.SetDefaultNetModeIfBlank(container.hostConfig)
   275  
   276  	if err := container.initializeNetworking(); err != nil {
   277  		return err
   278  	}
   279  	linkedEnv, err := container.setupLinkedContainers()
   280  	if err != nil {
   281  		return err
   282  	}
   283  	if err := container.setupWorkingDirectory(); err != nil {
   284  		return err
   285  	}
   286  	env := container.createDaemonEnvironment(linkedEnv)
   287  	if err := populateCommand(container, env); err != nil {
   288  		return err
   289  	}
   290  
   291  	mounts, err := container.setupMounts()
   292  	if err != nil {
   293  		return err
   294  	}
   295  
   296  	container.command.Mounts = mounts
   297  	return container.waitForStart()
   298  }
   299  
   300  // streamConfig.StdinPipe returns a WriteCloser which can be used to feed data
   301  // to the standard input of the container's active process.
   302  // Container.StdoutPipe and Container.StderrPipe each return a ReadCloser
   303  // which can be used to retrieve the standard output (and error) generated
   304  // by the container's active process. The output (and error) are actually
   305  // copied and delivered to all StdoutPipe and StderrPipe consumers, using
   306  // a kind of "broadcaster".
   307  
   308  func (streamConfig *streamConfig) StdinPipe() io.WriteCloser {
   309  	return streamConfig.stdinPipe
   310  }
   311  
   312  func (streamConfig *streamConfig) StdoutPipe() io.ReadCloser {
   313  	reader, writer := io.Pipe()
   314  	streamConfig.stdout.AddWriter(writer)
   315  	return ioutils.NewBufReader(reader)
   316  }
   317  
   318  func (streamConfig *streamConfig) StderrPipe() io.ReadCloser {
   319  	reader, writer := io.Pipe()
   320  	streamConfig.stderr.AddWriter(writer)
   321  	return ioutils.NewBufReader(reader)
   322  }
   323  
   324  func (container *Container) isNetworkAllocated() bool {
   325  	return container.NetworkSettings.IPAddress != ""
   326  }
   327  
   328  // cleanup releases any network resources allocated to the container along with any rules
   329  // around how containers are linked together.  It also unmounts the container's root filesystem.
   330  func (container *Container) cleanup() {
   331  	container.releaseNetwork()
   332  
   333  	if err := container.Unmount(); err != nil {
   334  		logrus.Errorf("%v: Failed to umount filesystem: %v", container.ID, err)
   335  	}
   336  
   337  	for _, eConfig := range container.execCommands.s {
   338  		container.daemon.unregisterExecCommand(eConfig)
   339  	}
   340  
   341  	container.unmountVolumes(false)
   342  }
   343  
   344  // killSig sends the container the given signal. This wrapper for the
   345  // host specific kill command prepares the container before attempting
   346  // to send the signal. An error is returned if the container is paused
   347  // or not running, or if there is a problem returned from the
   348  // underlying kill command.
   349  func (container *Container) killSig(sig int) error {
   350  	logrus.Debugf("Sending %d to %s", sig, container.ID)
   351  	container.Lock()
   352  	defer container.Unlock()
   353  
   354  	// We could unpause the container for them rather than returning this error
   355  	if container.Paused {
   356  		return derr.ErrorCodeUnpauseContainer.WithArgs(container.ID)
   357  	}
   358  
   359  	if !container.Running {
   360  		return derr.ErrorCodeNotRunning.WithArgs(container.ID)
   361  	}
   362  
   363  	// signal to the monitor that it should not restart the container
   364  	// after we send the kill signal
   365  	container.monitor.ExitOnNext()
   366  
   367  	// if the container is currently restarting we do not need to send the signal
   368  	// to the process.  Telling the monitor that it should exit on it's next event
   369  	// loop is enough
   370  	if container.Restarting {
   371  		return nil
   372  	}
   373  
   374  	if err := container.daemon.kill(container, sig); err != nil {
   375  		return err
   376  	}
   377  	container.logEvent("kill")
   378  	return nil
   379  }
   380  
   381  // Wrapper aroung killSig() suppressing "no such process" error.
   382  func (container *Container) killPossiblyDeadProcess(sig int) error {
   383  	err := container.killSig(sig)
   384  	if err == syscall.ESRCH {
   385  		logrus.Debugf("Cannot kill process (pid=%d) with signal %d: no such process.", container.getPID(), sig)
   386  		return nil
   387  	}
   388  	return err
   389  }
   390  
   391  func (container *Container) pause() error {
   392  	container.Lock()
   393  	defer container.Unlock()
   394  
   395  	// We cannot Pause the container which is not running
   396  	if !container.Running {
   397  		return derr.ErrorCodeNotRunning.WithArgs(container.ID)
   398  	}
   399  
   400  	// We cannot Pause the container which is already paused
   401  	if container.Paused {
   402  		return derr.ErrorCodeAlreadyPaused.WithArgs(container.ID)
   403  	}
   404  
   405  	if err := container.daemon.execDriver.Pause(container.command); err != nil {
   406  		return err
   407  	}
   408  	container.Paused = true
   409  	container.logEvent("pause")
   410  	return nil
   411  }
   412  
   413  func (container *Container) unpause() error {
   414  	container.Lock()
   415  	defer container.Unlock()
   416  
   417  	// We cannot unpause the container which is not running
   418  	if !container.Running {
   419  		return derr.ErrorCodeNotRunning.WithArgs(container.ID)
   420  	}
   421  
   422  	// We cannot unpause the container which is not paused
   423  	if !container.Paused {
   424  		return derr.ErrorCodeNotPaused.WithArgs(container.ID)
   425  	}
   426  
   427  	if err := container.daemon.execDriver.Unpause(container.command); err != nil {
   428  		return err
   429  	}
   430  	container.Paused = false
   431  	container.logEvent("unpause")
   432  	return nil
   433  }
   434  
   435  // Kill forcefully terminates a container.
   436  func (container *Container) Kill() error {
   437  	if !container.IsRunning() {
   438  		return derr.ErrorCodeNotRunning.WithArgs(container.ID)
   439  	}
   440  
   441  	// 1. Send SIGKILL
   442  	if err := container.killPossiblyDeadProcess(int(syscall.SIGKILL)); err != nil {
   443  		// While normally we might "return err" here we're not going to
   444  		// because if we can't stop the container by this point then
   445  		// its probably because its already stopped. Meaning, between
   446  		// the time of the IsRunning() call above and now it stopped.
   447  		// Also, since the err return will be exec driver specific we can't
   448  		// look for any particular (common) error that would indicate
   449  		// that the process is already dead vs something else going wrong.
   450  		// So, instead we'll give it up to 2 more seconds to complete and if
   451  		// by that time the container is still running, then the error
   452  		// we got is probably valid and so we return it to the caller.
   453  
   454  		if container.IsRunning() {
   455  			container.WaitStop(2 * time.Second)
   456  			if container.IsRunning() {
   457  				return err
   458  			}
   459  		}
   460  	}
   461  
   462  	// 2. Wait for the process to die, in last resort, try to kill the process directly
   463  	if err := killProcessDirectly(container); err != nil {
   464  		return err
   465  	}
   466  
   467  	container.WaitStop(-1 * time.Second)
   468  	return nil
   469  }
   470  
   471  // Stop halts a container by sending a stop signal, waiting for the given
   472  // duration in seconds, and then calling SIGKILL and waiting for the
   473  // process to exit. If a negative duration is given, Stop will wait
   474  // for the initial signal forever. If the container is not running Stop returns
   475  // immediately.
   476  func (container *Container) Stop(seconds int) error {
   477  	if !container.IsRunning() {
   478  		return nil
   479  	}
   480  
   481  	// 1. Send a SIGTERM
   482  	if err := container.killPossiblyDeadProcess(container.stopSignal()); err != nil {
   483  		logrus.Infof("Failed to send SIGTERM to the process, force killing")
   484  		if err := container.killPossiblyDeadProcess(9); err != nil {
   485  			return err
   486  		}
   487  	}
   488  
   489  	// 2. Wait for the process to exit on its own
   490  	if _, err := container.WaitStop(time.Duration(seconds) * time.Second); err != nil {
   491  		logrus.Infof("Container %v failed to exit within %d seconds of SIGTERM - using the force", container.ID, seconds)
   492  		// 3. If it doesn't, then send SIGKILL
   493  		if err := container.Kill(); err != nil {
   494  			container.WaitStop(-1 * time.Second)
   495  			return err
   496  		}
   497  	}
   498  
   499  	container.logEvent("stop")
   500  	return nil
   501  }
   502  
   503  // Restart attempts to gracefully stop and then start the
   504  // container. When stopping, wait for the given duration in seconds to
   505  // gracefully stop, before forcefully terminating the container. If
   506  // given a negative duration, wait forever for a graceful stop.
   507  func (container *Container) Restart(seconds int) error {
   508  	// Avoid unnecessarily unmounting and then directly mounting
   509  	// the container when the container stops and then starts
   510  	// again
   511  	if err := container.Mount(); err == nil {
   512  		defer container.Unmount()
   513  	}
   514  
   515  	if err := container.Stop(seconds); err != nil {
   516  		return err
   517  	}
   518  
   519  	if err := container.Start(); err != nil {
   520  		return err
   521  	}
   522  
   523  	container.logEvent("restart")
   524  	return nil
   525  }
   526  
   527  // Resize changes the TTY of the process running inside the container
   528  // to the given height and width. The container must be running.
   529  func (container *Container) Resize(h, w int) error {
   530  	if !container.IsRunning() {
   531  		return derr.ErrorCodeNotRunning.WithArgs(container.ID)
   532  	}
   533  	if err := container.command.ProcessConfig.Terminal.Resize(h, w); err != nil {
   534  		return err
   535  	}
   536  	container.logEvent("resize")
   537  	return nil
   538  }
   539  
   540  func (container *Container) export() (archive.Archive, error) {
   541  	if err := container.Mount(); err != nil {
   542  		return nil, err
   543  	}
   544  
   545  	archive, err := archive.Tar(container.basefs, archive.Uncompressed)
   546  	if err != nil {
   547  		container.Unmount()
   548  		return nil, err
   549  	}
   550  	arch := ioutils.NewReadCloserWrapper(archive, func() error {
   551  		err := archive.Close()
   552  		container.Unmount()
   553  		return err
   554  	})
   555  	container.logEvent("export")
   556  	return arch, err
   557  }
   558  
   559  // Mount sets container.basefs
   560  func (container *Container) Mount() error {
   561  	return container.daemon.Mount(container)
   562  }
   563  
   564  func (container *Container) changes() ([]archive.Change, error) {
   565  	container.Lock()
   566  	defer container.Unlock()
   567  	return container.daemon.changes(container)
   568  }
   569  
   570  func (container *Container) getImage() (*image.Image, error) {
   571  	if container.daemon == nil {
   572  		return nil, derr.ErrorCodeImageUnregContainer
   573  	}
   574  	return container.daemon.graph.Get(container.ImageID)
   575  }
   576  
   577  // Unmount asks the daemon to release the layered filesystems that are
   578  // mounted by the container.
   579  func (container *Container) Unmount() error {
   580  	return container.daemon.unmount(container)
   581  }
   582  
   583  func (container *Container) hostConfigPath() (string, error) {
   584  	return container.getRootResourcePath("hostconfig.json")
   585  }
   586  
   587  func (container *Container) jsonPath() (string, error) {
   588  	return container.getRootResourcePath("config.json")
   589  }
   590  
   591  // This method must be exported to be used from the lxc template
   592  // This directory is only usable when the container is running
   593  func (container *Container) rootfsPath() string {
   594  	return container.basefs
   595  }
   596  
   597  func validateID(id string) error {
   598  	if id == "" {
   599  		return derr.ErrorCodeEmptyID
   600  	}
   601  	return nil
   602  }
   603  
   604  func (container *Container) copy(resource string) (rc io.ReadCloser, err error) {
   605  	container.Lock()
   606  
   607  	defer func() {
   608  		if err != nil {
   609  			// Wait to unlock the container until the archive is fully read
   610  			// (see the ReadCloseWrapper func below) or if there is an error
   611  			// before that occurs.
   612  			container.Unlock()
   613  		}
   614  	}()
   615  
   616  	if err := container.Mount(); err != nil {
   617  		return nil, err
   618  	}
   619  
   620  	defer func() {
   621  		if err != nil {
   622  			// unmount any volumes
   623  			container.unmountVolumes(true)
   624  			// unmount the container's rootfs
   625  			container.Unmount()
   626  		}
   627  	}()
   628  
   629  	if err := container.mountVolumes(); err != nil {
   630  		return nil, err
   631  	}
   632  
   633  	basePath, err := container.GetResourcePath(resource)
   634  	if err != nil {
   635  		return nil, err
   636  	}
   637  	stat, err := os.Stat(basePath)
   638  	if err != nil {
   639  		return nil, err
   640  	}
   641  	var filter []string
   642  	if !stat.IsDir() {
   643  		d, f := filepath.Split(basePath)
   644  		basePath = d
   645  		filter = []string{f}
   646  	} else {
   647  		filter = []string{filepath.Base(basePath)}
   648  		basePath = filepath.Dir(basePath)
   649  	}
   650  	archive, err := archive.TarWithOptions(basePath, &archive.TarOptions{
   651  		Compression:  archive.Uncompressed,
   652  		IncludeFiles: filter,
   653  	})
   654  	if err != nil {
   655  		return nil, err
   656  	}
   657  
   658  	reader := ioutils.NewReadCloserWrapper(archive, func() error {
   659  		err := archive.Close()
   660  		container.unmountVolumes(true)
   661  		container.Unmount()
   662  		container.Unlock()
   663  		return err
   664  	})
   665  	container.logEvent("copy")
   666  	return reader, nil
   667  }
   668  
   669  // Returns true if the container exposes a certain port
   670  func (container *Container) exposes(p nat.Port) bool {
   671  	_, exists := container.Config.ExposedPorts[p]
   672  	return exists
   673  }
   674  
   675  func (container *Container) getLogConfig() runconfig.LogConfig {
   676  	cfg := container.hostConfig.LogConfig
   677  	if cfg.Type != "" || len(cfg.Config) > 0 { // container has log driver configured
   678  		if cfg.Type == "" {
   679  			cfg.Type = jsonfilelog.Name
   680  		}
   681  		return cfg
   682  	}
   683  	// Use daemon's default log config for containers
   684  	return container.daemon.defaultLogConfig
   685  }
   686  
   687  func (container *Container) getLogger() (logger.Logger, error) {
   688  	if container.logDriver != nil && container.IsRunning() {
   689  		return container.logDriver, nil
   690  	}
   691  	cfg := container.getLogConfig()
   692  	if err := logger.ValidateLogOpts(cfg.Type, cfg.Config); err != nil {
   693  		return nil, err
   694  	}
   695  	c, err := logger.GetLogDriver(cfg.Type)
   696  	if err != nil {
   697  		return nil, derr.ErrorCodeLoggingFactory.WithArgs(err)
   698  	}
   699  	ctx := logger.Context{
   700  		Config:              cfg.Config,
   701  		ContainerID:         container.ID,
   702  		ContainerName:       container.Name,
   703  		ContainerEntrypoint: container.Path,
   704  		ContainerArgs:       container.Args,
   705  		ContainerImageID:    container.ImageID,
   706  		ContainerImageName:  container.Config.Image,
   707  		ContainerCreated:    container.Created,
   708  	}
   709  
   710  	// Set logging file for "json-logger"
   711  	if cfg.Type == jsonfilelog.Name {
   712  		ctx.LogPath, err = container.getRootResourcePath(fmt.Sprintf("%s-json.log", container.ID))
   713  		if err != nil {
   714  			return nil, err
   715  		}
   716  	}
   717  	return c(ctx)
   718  }
   719  
   720  func (container *Container) startLogging() error {
   721  	cfg := container.getLogConfig()
   722  	if cfg.Type == "none" {
   723  		return nil // do not start logging routines
   724  	}
   725  
   726  	l, err := container.getLogger()
   727  	if err != nil {
   728  		return derr.ErrorCodeInitLogger.WithArgs(err)
   729  	}
   730  
   731  	copier := logger.NewCopier(container.ID, map[string]io.Reader{"stdout": container.StdoutPipe(), "stderr": container.StderrPipe()}, l)
   732  	container.logCopier = copier
   733  	copier.Run()
   734  	container.logDriver = l
   735  
   736  	// set LogPath field only for json-file logdriver
   737  	if jl, ok := l.(*jsonfilelog.JSONFileLogger); ok {
   738  		container.LogPath = jl.LogPath()
   739  	}
   740  
   741  	return nil
   742  }
   743  
   744  func (container *Container) waitForStart() error {
   745  	container.monitor = newContainerMonitor(container, container.hostConfig.RestartPolicy)
   746  
   747  	// block until we either receive an error from the initial start of the container's
   748  	// process or until the process is running in the container
   749  	select {
   750  	case <-container.monitor.startSignal:
   751  	case err := <-promise.Go(container.monitor.Start):
   752  		return err
   753  	}
   754  
   755  	return nil
   756  }
   757  
   758  func (container *Container) getProcessLabel() string {
   759  	// even if we have a process label return "" if we are running
   760  	// in privileged mode
   761  	if container.hostConfig.Privileged {
   762  		return ""
   763  	}
   764  	return container.ProcessLabel
   765  }
   766  
   767  func (container *Container) getMountLabel() string {
   768  	if container.hostConfig.Privileged {
   769  		return ""
   770  	}
   771  	return container.MountLabel
   772  }
   773  
   774  func (container *Container) stats() (*execdriver.ResourceStats, error) {
   775  	return container.daemon.stats(container)
   776  }
   777  
   778  func (container *Container) getExecIDs() []string {
   779  	return container.execCommands.List()
   780  }
   781  
   782  func (container *Container) exec(ExecConfig *ExecConfig) error {
   783  	container.Lock()
   784  	defer container.Unlock()
   785  
   786  	callback := func(processConfig *execdriver.ProcessConfig, pid int) error {
   787  		if processConfig.Tty {
   788  			// The callback is called after the process Start()
   789  			// so we are in the parent process. In TTY mode, stdin/out/err is the PtySlave
   790  			// which we close here.
   791  			if c, ok := processConfig.Stdout.(io.Closer); ok {
   792  				c.Close()
   793  			}
   794  		}
   795  		close(ExecConfig.waitStart)
   796  		return nil
   797  	}
   798  
   799  	// We use a callback here instead of a goroutine and an chan for
   800  	// synchronization purposes
   801  	cErr := promise.Go(func() error { return container.monitorExec(ExecConfig, callback) })
   802  
   803  	// Exec should not return until the process is actually running
   804  	select {
   805  	case <-ExecConfig.waitStart:
   806  	case err := <-cErr:
   807  		return err
   808  	}
   809  
   810  	return nil
   811  }
   812  
   813  func (container *Container) monitorExec(ExecConfig *ExecConfig, callback execdriver.DriverCallback) error {
   814  	var (
   815  		err      error
   816  		exitCode int
   817  	)
   818  	pipes := execdriver.NewPipes(ExecConfig.streamConfig.stdin, ExecConfig.streamConfig.stdout, ExecConfig.streamConfig.stderr, ExecConfig.OpenStdin)
   819  	exitCode, err = container.daemon.Exec(container, ExecConfig, pipes, callback)
   820  	if err != nil {
   821  		logrus.Errorf("Error running command in existing container %s: %s", container.ID, err)
   822  	}
   823  	logrus.Debugf("Exec task in container %s exited with code %d", container.ID, exitCode)
   824  	if ExecConfig.OpenStdin {
   825  		if err := ExecConfig.streamConfig.stdin.Close(); err != nil {
   826  			logrus.Errorf("Error closing stdin while running in %s: %s", container.ID, err)
   827  		}
   828  	}
   829  	if err := ExecConfig.streamConfig.stdout.Clean(); err != nil {
   830  		logrus.Errorf("Error closing stdout while running in %s: %s", container.ID, err)
   831  	}
   832  	if err := ExecConfig.streamConfig.stderr.Clean(); err != nil {
   833  		logrus.Errorf("Error closing stderr while running in %s: %s", container.ID, err)
   834  	}
   835  	if ExecConfig.ProcessConfig.Terminal != nil {
   836  		if err := ExecConfig.ProcessConfig.Terminal.Close(); err != nil {
   837  			logrus.Errorf("Error closing terminal while running in container %s: %s", container.ID, err)
   838  		}
   839  	}
   840  	// remove the exec command from the container's store only and not the
   841  	// daemon's store so that the exec command can be inspected.
   842  	container.execCommands.Delete(ExecConfig.ID)
   843  	return err
   844  }
   845  
   846  // Attach connects to the container's TTY, delegating to standard
   847  // streams or websockets depending on the configuration.
   848  func (container *Container) Attach(stdin io.ReadCloser, stdout io.Writer, stderr io.Writer) chan error {
   849  	return attach(&container.streamConfig, container.Config.OpenStdin, container.Config.StdinOnce, container.Config.Tty, stdin, stdout, stderr)
   850  }
   851  
   852  func (container *Container) attachWithLogs(stdin io.ReadCloser, stdout, stderr io.Writer, logs, stream bool) error {
   853  	if logs {
   854  		logDriver, err := container.getLogger()
   855  		if err != nil {
   856  			return err
   857  		}
   858  		cLog, ok := logDriver.(logger.LogReader)
   859  		if !ok {
   860  			return logger.ErrReadLogsNotSupported
   861  		}
   862  		logs := cLog.ReadLogs(logger.ReadConfig{Tail: -1})
   863  
   864  	LogLoop:
   865  		for {
   866  			select {
   867  			case msg, ok := <-logs.Msg:
   868  				if !ok {
   869  					break LogLoop
   870  				}
   871  				if msg.Source == "stdout" && stdout != nil {
   872  					stdout.Write(msg.Line)
   873  				}
   874  				if msg.Source == "stderr" && stderr != nil {
   875  					stderr.Write(msg.Line)
   876  				}
   877  			case err := <-logs.Err:
   878  				logrus.Errorf("Error streaming logs: %v", err)
   879  				break LogLoop
   880  			}
   881  		}
   882  	}
   883  
   884  	container.logEvent("attach")
   885  
   886  	//stream
   887  	if stream {
   888  		var stdinPipe io.ReadCloser
   889  		if stdin != nil {
   890  			r, w := io.Pipe()
   891  			go func() {
   892  				defer w.Close()
   893  				defer logrus.Debugf("Closing buffered stdin pipe")
   894  				io.Copy(w, stdin)
   895  			}()
   896  			stdinPipe = r
   897  		}
   898  		<-container.Attach(stdinPipe, stdout, stderr)
   899  		// If we are in stdinonce mode, wait for the process to end
   900  		// otherwise, simply return
   901  		if container.Config.StdinOnce && !container.Config.Tty {
   902  			container.WaitStop(-1 * time.Second)
   903  		}
   904  	}
   905  	return nil
   906  }
   907  
   908  func attach(streamConfig *streamConfig, openStdin, stdinOnce, tty bool, stdin io.ReadCloser, stdout io.Writer, stderr io.Writer) chan error {
   909  	var (
   910  		cStdout, cStderr io.ReadCloser
   911  		cStdin           io.WriteCloser
   912  		wg               sync.WaitGroup
   913  		errors           = make(chan error, 3)
   914  	)
   915  
   916  	if stdin != nil && openStdin {
   917  		cStdin = streamConfig.StdinPipe()
   918  		wg.Add(1)
   919  	}
   920  
   921  	if stdout != nil {
   922  		cStdout = streamConfig.StdoutPipe()
   923  		wg.Add(1)
   924  	}
   925  
   926  	if stderr != nil {
   927  		cStderr = streamConfig.StderrPipe()
   928  		wg.Add(1)
   929  	}
   930  
   931  	// Connect stdin of container to the http conn.
   932  	go func() {
   933  		if stdin == nil || !openStdin {
   934  			return
   935  		}
   936  		logrus.Debugf("attach: stdin: begin")
   937  		defer func() {
   938  			if stdinOnce && !tty {
   939  				cStdin.Close()
   940  			} else {
   941  				// No matter what, when stdin is closed (io.Copy unblock), close stdout and stderr
   942  				if cStdout != nil {
   943  					cStdout.Close()
   944  				}
   945  				if cStderr != nil {
   946  					cStderr.Close()
   947  				}
   948  			}
   949  			wg.Done()
   950  			logrus.Debugf("attach: stdin: end")
   951  		}()
   952  
   953  		var err error
   954  		if tty {
   955  			_, err = copyEscapable(cStdin, stdin)
   956  		} else {
   957  			_, err = io.Copy(cStdin, stdin)
   958  
   959  		}
   960  		if err == io.ErrClosedPipe {
   961  			err = nil
   962  		}
   963  		if err != nil {
   964  			logrus.Errorf("attach: stdin: %s", err)
   965  			errors <- err
   966  			return
   967  		}
   968  	}()
   969  
   970  	attachStream := func(name string, stream io.Writer, streamPipe io.ReadCloser) {
   971  		if stream == nil {
   972  			return
   973  		}
   974  		defer func() {
   975  			// Make sure stdin gets closed
   976  			if stdin != nil {
   977  				stdin.Close()
   978  			}
   979  			streamPipe.Close()
   980  			wg.Done()
   981  			logrus.Debugf("attach: %s: end", name)
   982  		}()
   983  
   984  		logrus.Debugf("attach: %s: begin", name)
   985  		_, err := io.Copy(stream, streamPipe)
   986  		if err == io.ErrClosedPipe {
   987  			err = nil
   988  		}
   989  		if err != nil {
   990  			logrus.Errorf("attach: %s: %v", name, err)
   991  			errors <- err
   992  		}
   993  	}
   994  
   995  	go attachStream("stdout", stdout, cStdout)
   996  	go attachStream("stderr", stderr, cStderr)
   997  
   998  	return promise.Go(func() error {
   999  		wg.Wait()
  1000  		close(errors)
  1001  		for err := range errors {
  1002  			if err != nil {
  1003  				return err
  1004  			}
  1005  		}
  1006  		return nil
  1007  	})
  1008  }
  1009  
  1010  // Code c/c from io.Copy() modified to handle escape sequence
  1011  func copyEscapable(dst io.Writer, src io.ReadCloser) (written int64, err error) {
  1012  	buf := make([]byte, 32*1024)
  1013  	for {
  1014  		nr, er := src.Read(buf)
  1015  		if nr > 0 {
  1016  			// ---- Docker addition
  1017  			// char 16 is C-p
  1018  			if nr == 1 && buf[0] == 16 {
  1019  				nr, er = src.Read(buf)
  1020  				// char 17 is C-q
  1021  				if nr == 1 && buf[0] == 17 {
  1022  					if err := src.Close(); err != nil {
  1023  						return 0, err
  1024  					}
  1025  					return 0, nil
  1026  				}
  1027  			}
  1028  			// ---- End of docker
  1029  			nw, ew := dst.Write(buf[0:nr])
  1030  			if nw > 0 {
  1031  				written += int64(nw)
  1032  			}
  1033  			if ew != nil {
  1034  				err = ew
  1035  				break
  1036  			}
  1037  			if nr != nw {
  1038  				err = io.ErrShortWrite
  1039  				break
  1040  			}
  1041  		}
  1042  		if er == io.EOF {
  1043  			break
  1044  		}
  1045  		if er != nil {
  1046  			err = er
  1047  			break
  1048  		}
  1049  	}
  1050  	return written, err
  1051  }
  1052  
  1053  func (container *Container) shouldRestart() bool {
  1054  	return container.hostConfig.RestartPolicy.Name == "always" ||
  1055  		(container.hostConfig.RestartPolicy.Name == "unless-stopped" && !container.HasBeenManuallyStopped) ||
  1056  		(container.hostConfig.RestartPolicy.Name == "on-failure" && container.ExitCode != 0)
  1057  }
  1058  
  1059  func (container *Container) mountVolumes() error {
  1060  	mounts, err := container.setupMounts()
  1061  	if err != nil {
  1062  		return err
  1063  	}
  1064  
  1065  	for _, m := range mounts {
  1066  		dest, err := container.GetResourcePath(m.Destination)
  1067  		if err != nil {
  1068  			return err
  1069  		}
  1070  
  1071  		var stat os.FileInfo
  1072  		stat, err = os.Stat(m.Source)
  1073  		if err != nil {
  1074  			return err
  1075  		}
  1076  		if err = fileutils.CreateIfNotExists(dest, stat.IsDir()); err != nil {
  1077  			return err
  1078  		}
  1079  
  1080  		opts := "rbind,ro"
  1081  		if m.Writable {
  1082  			opts = "rbind,rw"
  1083  		}
  1084  
  1085  		if err := mount.Mount(m.Source, dest, "bind", opts); err != nil {
  1086  			return err
  1087  		}
  1088  	}
  1089  
  1090  	return nil
  1091  }
  1092  
  1093  func (container *Container) copyImagePathContent(v volume.Volume, destination string) error {
  1094  	rootfs, err := symlink.FollowSymlinkInScope(filepath.Join(container.basefs, destination), container.basefs)
  1095  	if err != nil {
  1096  		return err
  1097  	}
  1098  
  1099  	if _, err = ioutil.ReadDir(rootfs); err != nil {
  1100  		if os.IsNotExist(err) {
  1101  			return nil
  1102  		}
  1103  		return err
  1104  	}
  1105  
  1106  	path, err := v.Mount()
  1107  	if err != nil {
  1108  		return err
  1109  	}
  1110  
  1111  	if err := copyExistingContents(rootfs, path); err != nil {
  1112  		return err
  1113  	}
  1114  
  1115  	return v.Unmount()
  1116  }
  1117  
  1118  func (container *Container) stopSignal() int {
  1119  	var stopSignal syscall.Signal
  1120  	if container.Config.StopSignal != "" {
  1121  		stopSignal, _ = signal.ParseSignal(container.Config.StopSignal)
  1122  	}
  1123  
  1124  	if int(stopSignal) == 0 {
  1125  		stopSignal, _ = signal.ParseSignal(signal.DefaultStopSignal)
  1126  	}
  1127  	return int(stopSignal)
  1128  }