exec.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. package exec
  2. import (
  3. "sync"
  4. "time"
  5. "github.com/docker/docker/daemon/execdriver"
  6. derr "github.com/docker/docker/errors"
  7. "github.com/docker/docker/pkg/stringid"
  8. "github.com/docker/docker/runconfig"
  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. *runconfig.StreamConfig
  16. ID string
  17. Running bool
  18. ExitCode int
  19. ProcessConfig *execdriver.ProcessConfig
  20. OpenStdin bool
  21. OpenStderr bool
  22. OpenStdout bool
  23. CanRemove bool
  24. ContainerID string
  25. DetachKeys []byte
  26. // waitStart will be closed immediately after the exec is really started.
  27. waitStart chan struct{}
  28. }
  29. // NewConfig initializes the a new exec configuration
  30. func NewConfig() *Config {
  31. return &Config{
  32. ID: stringid.GenerateNonCryptoID(),
  33. StreamConfig: runconfig.NewStreamConfig(),
  34. waitStart: make(chan struct{}),
  35. }
  36. }
  37. // Store keeps track of the exec configurations.
  38. type Store struct {
  39. commands map[string]*Config
  40. sync.RWMutex
  41. }
  42. // NewStore initializes a new exec store.
  43. func NewStore() *Store {
  44. return &Store{commands: make(map[string]*Config, 0)}
  45. }
  46. // Commands returns the exec configurations in the store.
  47. func (e *Store) Commands() map[string]*Config {
  48. return e.commands
  49. }
  50. // Add adds a new exec configuration to the store.
  51. func (e *Store) Add(id string, Config *Config) {
  52. e.Lock()
  53. e.commands[id] = Config
  54. e.Unlock()
  55. }
  56. // Get returns an exec configuration by its id.
  57. func (e *Store) Get(id string) *Config {
  58. e.RLock()
  59. res := e.commands[id]
  60. e.RUnlock()
  61. return res
  62. }
  63. // Delete removes an exec configuration from the store.
  64. func (e *Store) Delete(id string) {
  65. e.Lock()
  66. delete(e.commands, id)
  67. e.Unlock()
  68. }
  69. // List returns the list of exec ids in the store.
  70. func (e *Store) List() []string {
  71. var IDs []string
  72. e.RLock()
  73. for id := range e.commands {
  74. IDs = append(IDs, id)
  75. }
  76. e.RUnlock()
  77. return IDs
  78. }
  79. // Wait waits until the exec process finishes or there is an error in the error channel.
  80. func (c *Config) Wait(cErr chan error) error {
  81. // Exec should not return until the process is actually running
  82. select {
  83. case <-c.waitStart:
  84. case err := <-cErr:
  85. return err
  86. }
  87. return nil
  88. }
  89. // Close closes the wait channel for the progress.
  90. func (c *Config) Close() {
  91. close(c.waitStart)
  92. }
  93. // Resize changes the size of the terminal for the exec process.
  94. func (c *Config) Resize(h, w int) error {
  95. select {
  96. case <-c.waitStart:
  97. case <-time.After(time.Second):
  98. return derr.ErrorCodeExecResize.WithArgs(c.ID)
  99. }
  100. return c.ProcessConfig.Terminal.Resize(h, w)
  101. }