github.com/rita33cool1/iot-system-gateway@v0.0.0-20200911033302-e65bde238cc5/docker-engine/daemon/exec/exec.go (about)

     1  package exec // import "github.com/docker/docker/daemon/exec"
     2  
     3  import (
     4  	"runtime"
     5  	"sync"
     6  
     7  	"github.com/containerd/containerd/cio"
     8  	"github.com/docker/docker/container/stream"
     9  	"github.com/docker/docker/pkg/stringid"
    10  	"github.com/sirupsen/logrus"
    11  )
    12  
    13  // Config holds the configurations for execs. The Daemon keeps
    14  // track of both running and finished execs so that they can be
    15  // examined both during and after completion.
    16  type Config struct {
    17  	sync.Mutex
    18  	StreamConfig *stream.Config
    19  	ID           string
    20  	Running      bool
    21  	ExitCode     *int
    22  	OpenStdin    bool
    23  	OpenStderr   bool
    24  	OpenStdout   bool
    25  	CanRemove    bool
    26  	ContainerID  string
    27  	DetachKeys   []byte
    28  	Entrypoint   string
    29  	Args         []string
    30  	Tty          bool
    31  	Privileged   bool
    32  	User         string
    33  	WorkingDir   string
    34  	Env          []string
    35  	Pid          int
    36  }
    37  
    38  // NewConfig initializes the a new exec configuration
    39  func NewConfig() *Config {
    40  	return &Config{
    41  		ID:           stringid.GenerateNonCryptoID(),
    42  		StreamConfig: stream.NewConfig(),
    43  	}
    44  }
    45  
    46  type rio struct {
    47  	cio.IO
    48  
    49  	sc *stream.Config
    50  }
    51  
    52  func (i *rio) Close() error {
    53  	i.IO.Close()
    54  
    55  	return i.sc.CloseStreams()
    56  }
    57  
    58  func (i *rio) Wait() {
    59  	i.sc.Wait()
    60  
    61  	i.IO.Wait()
    62  }
    63  
    64  // InitializeStdio is called by libcontainerd to connect the stdio.
    65  func (c *Config) InitializeStdio(iop *cio.DirectIO) (cio.IO, error) {
    66  	c.StreamConfig.CopyToPipe(iop)
    67  
    68  	if c.StreamConfig.Stdin() == nil && !c.Tty && runtime.GOOS == "windows" {
    69  		if iop.Stdin != nil {
    70  			if err := iop.Stdin.Close(); err != nil {
    71  				logrus.Errorf("error closing exec stdin: %+v", err)
    72  			}
    73  		}
    74  	}
    75  
    76  	return &rio{IO: iop, sc: c.StreamConfig}, nil
    77  }
    78  
    79  // CloseStreams closes the stdio streams for the exec
    80  func (c *Config) CloseStreams() error {
    81  	return c.StreamConfig.CloseStreams()
    82  }
    83  
    84  // SetExitCode sets the exec config's exit code
    85  func (c *Config) SetExitCode(code int) {
    86  	c.ExitCode = &code
    87  }
    88  
    89  // Store keeps track of the exec configurations.
    90  type Store struct {
    91  	byID map[string]*Config
    92  	sync.RWMutex
    93  }
    94  
    95  // NewStore initializes a new exec store.
    96  func NewStore() *Store {
    97  	return &Store{
    98  		byID: make(map[string]*Config),
    99  	}
   100  }
   101  
   102  // Commands returns the exec configurations in the store.
   103  func (e *Store) Commands() map[string]*Config {
   104  	e.RLock()
   105  	byID := make(map[string]*Config, len(e.byID))
   106  	for id, config := range e.byID {
   107  		byID[id] = config
   108  	}
   109  	e.RUnlock()
   110  	return byID
   111  }
   112  
   113  // Add adds a new exec configuration to the store.
   114  func (e *Store) Add(id string, Config *Config) {
   115  	e.Lock()
   116  	e.byID[id] = Config
   117  	e.Unlock()
   118  }
   119  
   120  // Get returns an exec configuration by its id.
   121  func (e *Store) Get(id string) *Config {
   122  	e.RLock()
   123  	res := e.byID[id]
   124  	e.RUnlock()
   125  	return res
   126  }
   127  
   128  // Delete removes an exec configuration from the store.
   129  func (e *Store) Delete(id string, pid int) {
   130  	e.Lock()
   131  	delete(e.byID, id)
   132  	e.Unlock()
   133  }
   134  
   135  // List returns the list of exec ids in the store.
   136  func (e *Store) List() []string {
   137  	var IDs []string
   138  	e.RLock()
   139  	for id := range e.byID {
   140  		IDs = append(IDs, id)
   141  	}
   142  	e.RUnlock()
   143  	return IDs
   144  }