123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- package container // import "github.com/docker/docker/container"
- import (
- "context"
- "runtime"
- "sync"
- "github.com/containerd/containerd/cio"
- "github.com/containerd/log"
- "github.com/docker/docker/container/stream"
- "github.com/docker/docker/libcontainerd/types"
- "github.com/docker/docker/pkg/stringid"
- )
- // ExecConfig holds the configurations for execs. The Daemon keeps
- // track of both running and finished execs so that they can be
- // examined both during and after completion.
- type ExecConfig struct {
- sync.Mutex
- Started chan struct{}
- StreamConfig *stream.Config
- ID string
- Running bool
- ExitCode *int
- OpenStdin bool
- OpenStderr bool
- OpenStdout bool
- CanRemove bool
- Container *Container
- DetachKeys []byte
- Entrypoint string
- Args []string
- Tty bool
- Privileged bool
- User string
- WorkingDir string
- Env []string
- Process types.Process
- ConsoleSize *[2]uint
- }
- // NewExecConfig initializes the a new exec configuration
- func NewExecConfig(c *Container) *ExecConfig {
- return &ExecConfig{
- ID: stringid.GenerateRandomID(),
- Container: c,
- StreamConfig: stream.NewConfig(),
- Started: make(chan struct{}),
- }
- }
- // InitializeStdio is called by libcontainerd to connect the stdio.
- func (c *ExecConfig) InitializeStdio(iop *cio.DirectIO) (cio.IO, error) {
- c.StreamConfig.CopyToPipe(iop)
- if c.StreamConfig.Stdin() == nil && !c.Tty && runtime.GOOS == "windows" {
- if iop.Stdin != nil {
- if err := iop.Stdin.Close(); err != nil {
- log.G(context.TODO()).Errorf("error closing exec stdin: %+v", err)
- }
- }
- }
- return &rio{IO: iop, sc: c.StreamConfig}, nil
- }
- // CloseStreams closes the stdio streams for the exec
- func (c *ExecConfig) CloseStreams() error {
- return c.StreamConfig.CloseStreams()
- }
- // SetExitCode sets the exec config's exit code
- func (c *ExecConfig) SetExitCode(code int) {
- c.ExitCode = &code
- }
- // ExecStore keeps track of the exec configurations.
- type ExecStore struct {
- byID map[string]*ExecConfig
- mu sync.RWMutex
- }
- // NewExecStore initializes a new exec store.
- func NewExecStore() *ExecStore {
- return &ExecStore{
- byID: make(map[string]*ExecConfig),
- }
- }
- // Commands returns the exec configurations in the store.
- func (e *ExecStore) Commands() map[string]*ExecConfig {
- e.mu.RLock()
- byID := make(map[string]*ExecConfig, len(e.byID))
- for id, config := range e.byID {
- byID[id] = config
- }
- e.mu.RUnlock()
- return byID
- }
- // Add adds a new exec configuration to the store.
- func (e *ExecStore) Add(id string, Config *ExecConfig) {
- e.mu.Lock()
- e.byID[id] = Config
- e.mu.Unlock()
- }
- // Get returns an exec configuration by its id.
- func (e *ExecStore) Get(id string) *ExecConfig {
- e.mu.RLock()
- res := e.byID[id]
- e.mu.RUnlock()
- return res
- }
- // Delete removes an exec configuration from the store.
- func (e *ExecStore) Delete(id string) {
- e.mu.Lock()
- delete(e.byID, id)
- e.mu.Unlock()
- }
- // List returns the list of exec ids in the store.
- func (e *ExecStore) List() []string {
- var IDs []string
- e.mu.RLock()
- for id := range e.byID {
- IDs = append(IDs, id)
- }
- e.mu.RUnlock()
- return IDs
- }
|