9ca2e4e8 |
package exec
import ( |
37a3be24 |
"runtime" |
9ca2e4e8 |
"sync"
|
aa3ce07c |
"github.com/containerd/containerd/cio" |
5ea75bb6 |
"github.com/docker/docker/container/stream" |
9ca2e4e8 |
"github.com/docker/docker/pkg/stringid" |
1009e6a4 |
"github.com/sirupsen/logrus" |
9ca2e4e8 |
)
// Config holds the configurations for execs. The Daemon keeps
// track of both running and finished execs so that they can be
// examined both during and after completion.
type Config struct {
sync.Mutex |
5ea75bb6 |
StreamConfig *stream.Config
ID string
Running bool
ExitCode *int
OpenStdin bool
OpenStderr bool
OpenStdout bool
CanRemove bool
ContainerID string
DetachKeys []byte
Entrypoint string
Args []string
Tty bool
Privileged bool
User string |
19f2749d |
WorkingDir string |
5ea75bb6 |
Env []string
Pid int |
9ca2e4e8 |
}
// NewConfig initializes the a new exec configuration
func NewConfig() *Config {
return &Config{
ID: stringid.GenerateNonCryptoID(), |
5ea75bb6 |
StreamConfig: stream.NewConfig(), |
9ca2e4e8 |
}
}
|
aa3ce07c |
type rio struct {
cio.IO |
ddae20c0 |
sc *stream.Config
}
|
aa3ce07c |
func (i *rio) Close() error { |
ddae20c0 |
i.IO.Close()
return i.sc.CloseStreams()
}
|
aa3ce07c |
func (i *rio) Wait() { |
ddae20c0 |
i.sc.Wait()
i.IO.Wait()
}
|
37a3be24 |
// InitializeStdio is called by libcontainerd to connect the stdio. |
3fec7c08 |
func (c *Config) InitializeStdio(iop *cio.DirectIO) (cio.IO, error) { |
37a3be24 |
c.StreamConfig.CopyToPipe(iop)
|
5ea75bb6 |
if c.StreamConfig.Stdin() == nil && !c.Tty && runtime.GOOS == "windows" { |
37a3be24 |
if iop.Stdin != nil {
if err := iop.Stdin.Close(); err != nil { |
2f7e9078 |
logrus.Errorf("error closing exec stdin: %+v", err) |
37a3be24 |
}
}
}
|
aa3ce07c |
return &rio{IO: iop, sc: c.StreamConfig}, nil |
37a3be24 |
}
|
5ea75bb6 |
// CloseStreams closes the stdio streams for the exec
func (c *Config) CloseStreams() error {
return c.StreamConfig.CloseStreams()
}
|
ebcb7d6b |
// SetExitCode sets the exec config's exit code
func (c *Config) SetExitCode(code int) {
c.ExitCode = &code
}
|
9ca2e4e8 |
// Store keeps track of the exec configurations.
type Store struct { |
6f3e86e9 |
byID map[string]*Config |
9ca2e4e8 |
sync.RWMutex
}
// NewStore initializes a new exec store.
func NewStore() *Store { |
ddae20c0 |
return &Store{ |
6f3e86e9 |
byID: make(map[string]*Config), |
ddae20c0 |
} |
9ca2e4e8 |
}
// Commands returns the exec configurations in the store.
func (e *Store) Commands() map[string]*Config { |
e5e62b96 |
e.RLock() |
ddae20c0 |
byID := make(map[string]*Config, len(e.byID))
for id, config := range e.byID {
byID[id] = config |
e5e62b96 |
}
e.RUnlock() |
ddae20c0 |
return byID |
9ca2e4e8 |
}
// Add adds a new exec configuration to the store.
func (e *Store) Add(id string, Config *Config) {
e.Lock() |
ddae20c0 |
e.byID[id] = Config |
9ca2e4e8 |
e.Unlock()
}
// Get returns an exec configuration by its id.
func (e *Store) Get(id string) *Config {
e.RLock() |
ddae20c0 |
res := e.byID[id]
e.RUnlock()
return res
}
|
9ca2e4e8 |
// Delete removes an exec configuration from the store. |
ddae20c0 |
func (e *Store) Delete(id string, pid int) { |
9ca2e4e8 |
e.Lock() |
ddae20c0 |
delete(e.byID, id) |
9ca2e4e8 |
e.Unlock()
}
// List returns the list of exec ids in the store.
func (e *Store) List() []string {
var IDs []string
e.RLock() |
ddae20c0 |
for id := range e.byID { |
9ca2e4e8 |
IDs = append(IDs, id)
}
e.RUnlock()
return IDs
} |