|
@@ -2299,77 +2299,3 @@ func (cli *DockerCli) CmdLoad(args ...string) error {
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
-
|
|
|
-func (cli *DockerCli) CmdExec(args ...string) error {
|
|
|
- cmd := cli.Subcmd("exec", "[OPTIONS] CONTAINER COMMAND [ARG...]", "Run a command in an existing container")
|
|
|
-
|
|
|
- execConfig, err := runconfig.ParseExec(cmd, args)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- if execConfig.Container == "" {
|
|
|
- cmd.Usage()
|
|
|
- return nil
|
|
|
- }
|
|
|
-
|
|
|
- if execConfig.Detach {
|
|
|
- _, _, err := cli.call("POST", "/containers/"+execConfig.Container+"/exec", execConfig, false)
|
|
|
- return err
|
|
|
- }
|
|
|
- var (
|
|
|
- out, stderr io.Writer
|
|
|
- in io.ReadCloser
|
|
|
- // We need to instanciate the chan because the select needs it. It can
|
|
|
- // be closed but can't be uninitialized.
|
|
|
- hijacked = make(chan io.Closer)
|
|
|
- errCh chan error
|
|
|
- )
|
|
|
- // Block the return until the chan gets closed
|
|
|
- defer func() {
|
|
|
- log.Debugf("End of CmdExec(), Waiting for hijack to finish.")
|
|
|
- if _, ok := <-hijacked; ok {
|
|
|
- log.Errorf("Hijack did not finish (chan still open)")
|
|
|
- }
|
|
|
- }()
|
|
|
-
|
|
|
- if execConfig.AttachStdin {
|
|
|
- in = cli.in
|
|
|
- }
|
|
|
- if execConfig.AttachStdout {
|
|
|
- out = cli.out
|
|
|
- }
|
|
|
- if execConfig.AttachStderr {
|
|
|
- if execConfig.Tty {
|
|
|
- stderr = cli.out
|
|
|
- } else {
|
|
|
- stderr = cli.err
|
|
|
- }
|
|
|
- }
|
|
|
- errCh = utils.Go(func() error {
|
|
|
- return cli.hijack("POST", "/containers/"+execConfig.Container+"/exec?", execConfig.Tty, in, out, stderr, hijacked, execConfig)
|
|
|
- })
|
|
|
-
|
|
|
- // Acknowledge the hijack before starting
|
|
|
- select {
|
|
|
- case closer := <-hijacked:
|
|
|
- // Make sure that hijack gets closed when returning. (result
|
|
|
- // in closing hijack chan and freeing server's goroutines.
|
|
|
- if closer != nil {
|
|
|
- defer closer.Close()
|
|
|
- }
|
|
|
- case err := <-errCh:
|
|
|
- if err != nil {
|
|
|
- log.Debugf("Error hijack: %s", err)
|
|
|
- return err
|
|
|
- }
|
|
|
- }
|
|
|
- // TODO(vishh): Enable tty size monitoring once the daemon can support that.
|
|
|
- if errCh != nil {
|
|
|
- if err := <-errCh; err != nil {
|
|
|
- log.Debugf("Error hijack: %s", err)
|
|
|
- return err
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return nil
|
|
|
-}
|