github.com/walkingsparrow/docker@v1.4.2-0.20151218153551-b708a2249bfa/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 29 // waitStart will be closed immediately after the exec is really started. 30 waitStart chan struct{} 31 } 32 33 // NewConfig initializes the a new exec configuration 34 func NewConfig() *Config { 35 return &Config{ 36 ID: stringid.GenerateNonCryptoID(), 37 StreamConfig: runconfig.NewStreamConfig(), 38 waitStart: make(chan struct{}), 39 } 40 } 41 42 // Store keeps track of the exec configurations. 43 type Store struct { 44 commands map[string]*Config 45 sync.RWMutex 46 } 47 48 // NewStore initializes a new exec store. 49 func NewStore() *Store { 50 return &Store{commands: make(map[string]*Config, 0)} 51 } 52 53 // Commands returns the exec configurations in the store. 54 func (e *Store) Commands() map[string]*Config { 55 return e.commands 56 } 57 58 // Add adds a new exec configuration to the store. 59 func (e *Store) Add(id string, Config *Config) { 60 e.Lock() 61 e.commands[id] = Config 62 e.Unlock() 63 } 64 65 // Get returns an exec configuration by its id. 66 func (e *Store) Get(id string) *Config { 67 e.RLock() 68 res := e.commands[id] 69 e.RUnlock() 70 return res 71 } 72 73 // Delete removes an exec configuration from the store. 74 func (e *Store) Delete(id string) { 75 e.Lock() 76 delete(e.commands, id) 77 e.Unlock() 78 } 79 80 // List returns the list of exec ids in the store. 81 func (e *Store) List() []string { 82 var IDs []string 83 e.RLock() 84 for id := range e.commands { 85 IDs = append(IDs, id) 86 } 87 e.RUnlock() 88 return IDs 89 } 90 91 // Wait waits until the exec process finishes or there is an error in the error channel. 92 func (c *Config) Wait(cErr chan error) error { 93 // Exec should not return until the process is actually running 94 select { 95 case <-c.waitStart: 96 case err := <-cErr: 97 return err 98 } 99 return nil 100 } 101 102 // Close closes the wait channel for the progress. 103 func (c *Config) Close() { 104 close(c.waitStart) 105 } 106 107 // Resize changes the size of the terminal for the exec process. 108 func (c *Config) Resize(h, w int) error { 109 select { 110 case <-c.waitStart: 111 case <-time.After(time.Second): 112 return derr.ErrorCodeExecResize.WithArgs(c.ID) 113 } 114 return c.ProcessConfig.Terminal.Resize(h, w) 115 }