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