github.com/olljanat/moby@v1.13.1/daemon/exec/exec.go (about)

     1  package exec
     2  
     3  import (
     4  	"runtime"
     5  	"sync"
     6  
     7  	"github.com/Sirupsen/logrus"
     8  	"github.com/docker/docker/container/stream"
     9  	"github.com/docker/docker/libcontainerd"
    10  	"github.com/docker/docker/pkg/stringid"
    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  	Env          []string
    34  	Pid          int
    35  }
    36  
    37  // NewConfig initializes the a new exec configuration
    38  func NewConfig() *Config {
    39  	return &Config{
    40  		ID:           stringid.GenerateNonCryptoID(),
    41  		StreamConfig: stream.NewConfig(),
    42  	}
    43  }
    44  
    45  // InitializeStdio is called by libcontainerd to connect the stdio.
    46  func (c *Config) InitializeStdio(iop libcontainerd.IOPipe) error {
    47  	c.StreamConfig.CopyToPipe(iop)
    48  
    49  	if c.StreamConfig.Stdin() == nil && !c.Tty && runtime.GOOS == "windows" {
    50  		if iop.Stdin != nil {
    51  			if err := iop.Stdin.Close(); err != nil {
    52  				logrus.Errorf("error closing exec stdin: %+v", err)
    53  			}
    54  		}
    55  	}
    56  
    57  	return nil
    58  }
    59  
    60  // CloseStreams closes the stdio streams for the exec
    61  func (c *Config) CloseStreams() error {
    62  	return c.StreamConfig.CloseStreams()
    63  }
    64  
    65  // Store keeps track of the exec configurations.
    66  type Store struct {
    67  	commands map[string]*Config
    68  	sync.RWMutex
    69  }
    70  
    71  // NewStore initializes a new exec store.
    72  func NewStore() *Store {
    73  	return &Store{commands: make(map[string]*Config, 0)}
    74  }
    75  
    76  // Commands returns the exec configurations in the store.
    77  func (e *Store) Commands() map[string]*Config {
    78  	e.RLock()
    79  	commands := make(map[string]*Config, len(e.commands))
    80  	for id, config := range e.commands {
    81  		commands[id] = config
    82  	}
    83  	e.RUnlock()
    84  	return commands
    85  }
    86  
    87  // Add adds a new exec configuration to the store.
    88  func (e *Store) Add(id string, Config *Config) {
    89  	e.Lock()
    90  	e.commands[id] = Config
    91  	e.Unlock()
    92  }
    93  
    94  // Get returns an exec configuration by its id.
    95  func (e *Store) Get(id string) *Config {
    96  	e.RLock()
    97  	res := e.commands[id]
    98  	e.RUnlock()
    99  	return res
   100  }
   101  
   102  // Delete removes an exec configuration from the store.
   103  func (e *Store) Delete(id string) {
   104  	e.Lock()
   105  	delete(e.commands, id)
   106  	e.Unlock()
   107  }
   108  
   109  // List returns the list of exec ids in the store.
   110  func (e *Store) List() []string {
   111  	var IDs []string
   112  	e.RLock()
   113  	for id := range e.commands {
   114  		IDs = append(IDs, id)
   115  	}
   116  	e.RUnlock()
   117  	return IDs
   118  }