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