exec.go 2.7 KB

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