exec.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. package exec
  2. import (
  3. "runtime"
  4. "sync"
  5. "github.com/Sirupsen/logrus"
  6. "github.com/docker/docker/container/stream"
  7. "github.com/docker/docker/libcontainerd"
  8. "github.com/docker/docker/pkg/stringid"
  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. // Store keeps track of the exec configurations.
  57. type Store struct {
  58. commands map[string]*Config
  59. sync.RWMutex
  60. }
  61. // NewStore initializes a new exec store.
  62. func NewStore() *Store {
  63. return &Store{commands: make(map[string]*Config, 0)}
  64. }
  65. // Commands returns the exec configurations in the store.
  66. func (e *Store) Commands() map[string]*Config {
  67. e.RLock()
  68. commands := make(map[string]*Config, len(e.commands))
  69. for id, config := range e.commands {
  70. commands[id] = config
  71. }
  72. e.RUnlock()
  73. return commands
  74. }
  75. // Add adds a new exec configuration to the store.
  76. func (e *Store) Add(id string, Config *Config) {
  77. e.Lock()
  78. e.commands[id] = Config
  79. e.Unlock()
  80. }
  81. // Get returns an exec configuration by its id.
  82. func (e *Store) Get(id string) *Config {
  83. e.RLock()
  84. res := e.commands[id]
  85. e.RUnlock()
  86. return res
  87. }
  88. // Delete removes an exec configuration from the store.
  89. func (e *Store) Delete(id string) {
  90. e.Lock()
  91. delete(e.commands, id)
  92. e.Unlock()
  93. }
  94. // List returns the list of exec ids in the store.
  95. func (e *Store) List() []string {
  96. var IDs []string
  97. e.RLock()
  98. for id := range e.commands {
  99. IDs = append(IDs, id)
  100. }
  101. e.RUnlock()
  102. return IDs
  103. }