github.com/coreos/docker@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 }