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