Implement docker run with standalone client lib.
Signed-off-by: David Calavera <david.calavera@gmail.com>
This commit is contained in:
parent
962b2d8b9b
commit
bcb848c87f
2 changed files with 21 additions and 41 deletions
|
@ -3,12 +3,12 @@ package client
|
|||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/api/types"
|
||||
Cli "github.com/docker/docker/cli"
|
||||
derr "github.com/docker/docker/errors"
|
||||
"github.com/docker/docker/opts"
|
||||
|
@ -168,70 +168,57 @@ func (cli *DockerCli) CmdRun(args ...string) error {
|
|||
if *flAutoRemove && (hostConfig.RestartPolicy.IsAlways() || hostConfig.RestartPolicy.IsOnFailure()) {
|
||||
return ErrConflictRestartPolicyAndAutoRemove
|
||||
}
|
||||
// We need to instantiate the chan because the select needs it. It can
|
||||
// be closed but can't be uninitialized.
|
||||
hijacked := make(chan io.Closer)
|
||||
// Block the return until the chan gets closed
|
||||
defer func() {
|
||||
logrus.Debugf("End of CmdRun(), Waiting for hijack to finish.")
|
||||
if _, ok := <-hijacked; ok {
|
||||
fmt.Fprintln(cli.err, "Hijack did not finish (chan still open)")
|
||||
}
|
||||
}()
|
||||
|
||||
if config.AttachStdin || config.AttachStdout || config.AttachStderr {
|
||||
var (
|
||||
out, stderr io.Writer
|
||||
in io.ReadCloser
|
||||
v = url.Values{}
|
||||
)
|
||||
v.Set("stream", "1")
|
||||
if config.AttachStdin {
|
||||
v.Set("stdin", "1")
|
||||
in = cli.in
|
||||
}
|
||||
if config.AttachStdout {
|
||||
v.Set("stdout", "1")
|
||||
out = cli.out
|
||||
}
|
||||
if config.AttachStderr {
|
||||
v.Set("stderr", "1")
|
||||
if config.Tty {
|
||||
stderr = cli.out
|
||||
} else {
|
||||
stderr = cli.err
|
||||
}
|
||||
}
|
||||
errCh = promise.Go(func() error {
|
||||
return cli.hijack("POST", "/containers/"+createResponse.ID+"/attach?"+v.Encode(), config.Tty, in, out, stderr, hijacked, nil)
|
||||
})
|
||||
} else {
|
||||
close(hijacked)
|
||||
}
|
||||
// Acknowledge the hijack before starting
|
||||
select {
|
||||
case closer := <-hijacked:
|
||||
// Make sure that the hijack gets closed when returning (results
|
||||
// in closing the hijack chan and freeing server's goroutines)
|
||||
if closer != nil {
|
||||
defer closer.Close()
|
||||
|
||||
options := types.ContainerAttachOptions{
|
||||
ContainerID: createResponse.ID,
|
||||
Stream: true,
|
||||
Stdin: config.AttachStdin,
|
||||
Stdout: config.AttachStdout,
|
||||
Stderr: config.AttachStderr,
|
||||
}
|
||||
case err := <-errCh:
|
||||
|
||||
resp, err := cli.client.ContainerAttach(options)
|
||||
if err != nil {
|
||||
logrus.Debugf("Error hijack: %s", err)
|
||||
return err
|
||||
}
|
||||
errCh = promise.Go(func() error {
|
||||
return cli.holdHijackedConnection(config.Tty, in, out, stderr, resp)
|
||||
})
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if *flAutoRemove {
|
||||
if _, _, err = readBody(cli.call("DELETE", "/containers/"+createResponse.ID+"?v=1", nil, nil)); err != nil {
|
||||
options := types.ContainerRemoveOptions{
|
||||
ContainerID: createResponse.ID,
|
||||
RemoveVolumes: true,
|
||||
}
|
||||
if err := cli.client.ContainerRemove(options); err != nil {
|
||||
fmt.Fprintf(cli.err, "Error deleting container: %s\n", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
//start the container
|
||||
if _, _, err := readBody(cli.call("POST", "/containers/"+createResponse.ID+"/start", nil, nil)); err != nil {
|
||||
if err := cli.client.ContainerStart(createResponse.ID); err != nil {
|
||||
cmd.ReportError(err.Error(), false)
|
||||
return runStartContainerErr(err)
|
||||
}
|
||||
|
@ -262,7 +249,7 @@ func (cli *DockerCli) CmdRun(args ...string) error {
|
|||
if *flAutoRemove {
|
||||
// Autoremove: wait for the container to finish, retrieve
|
||||
// the exit code and remove the container
|
||||
if _, _, err := readBody(cli.call("POST", "/containers/"+createResponse.ID+"/wait", nil, nil)); err != nil {
|
||||
if status, err = cli.client.ContainerWait(createResponse.ID); err != nil {
|
||||
return runStartContainerErr(err)
|
||||
}
|
||||
if _, status, err = getExitCode(cli, createResponse.ID); err != nil {
|
||||
|
|
|
@ -95,13 +95,6 @@ func (cli *DockerCli) CmdStart(args ...string) error {
|
|||
return cli.holdHijackedConnection(c.Config.Tty, in, cli.out, cli.err, resp)
|
||||
})
|
||||
|
||||
select {
|
||||
case err := <-cErr:
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Start the container.
|
||||
if err := cli.client.ContainerStart(containerID); err != nil {
|
||||
return err
|
||||
|
|
Loading…
Add table
Reference in a new issue