mirror of https://github.com/docker/docs.git
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
|
@ -3,12 +3,12 @@ package client
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/url"
|
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
|
"github.com/docker/docker/api/types"
|
||||||
Cli "github.com/docker/docker/cli"
|
Cli "github.com/docker/docker/cli"
|
||||||
derr "github.com/docker/docker/errors"
|
derr "github.com/docker/docker/errors"
|
||||||
"github.com/docker/docker/opts"
|
"github.com/docker/docker/opts"
|
||||||
|
@ -168,70 +168,57 @@ func (cli *DockerCli) CmdRun(args ...string) error {
|
||||||
if *flAutoRemove && (hostConfig.RestartPolicy.IsAlways() || hostConfig.RestartPolicy.IsOnFailure()) {
|
if *flAutoRemove && (hostConfig.RestartPolicy.IsAlways() || hostConfig.RestartPolicy.IsOnFailure()) {
|
||||||
return ErrConflictRestartPolicyAndAutoRemove
|
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 {
|
if config.AttachStdin || config.AttachStdout || config.AttachStderr {
|
||||||
var (
|
var (
|
||||||
out, stderr io.Writer
|
out, stderr io.Writer
|
||||||
in io.ReadCloser
|
in io.ReadCloser
|
||||||
v = url.Values{}
|
|
||||||
)
|
)
|
||||||
v.Set("stream", "1")
|
|
||||||
if config.AttachStdin {
|
if config.AttachStdin {
|
||||||
v.Set("stdin", "1")
|
|
||||||
in = cli.in
|
in = cli.in
|
||||||
}
|
}
|
||||||
if config.AttachStdout {
|
if config.AttachStdout {
|
||||||
v.Set("stdout", "1")
|
|
||||||
out = cli.out
|
out = cli.out
|
||||||
}
|
}
|
||||||
if config.AttachStderr {
|
if config.AttachStderr {
|
||||||
v.Set("stderr", "1")
|
|
||||||
if config.Tty {
|
if config.Tty {
|
||||||
stderr = cli.out
|
stderr = cli.out
|
||||||
} else {
|
} else {
|
||||||
stderr = cli.err
|
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)
|
options := types.ContainerAttachOptions{
|
||||||
})
|
ContainerID: createResponse.ID,
|
||||||
} else {
|
Stream: true,
|
||||||
close(hijacked)
|
Stdin: config.AttachStdin,
|
||||||
}
|
Stdout: config.AttachStdout,
|
||||||
// Acknowledge the hijack before starting
|
Stderr: config.AttachStderr,
|
||||||
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()
|
|
||||||
}
|
}
|
||||||
case err := <-errCh:
|
|
||||||
|
resp, err := cli.client.ContainerAttach(options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Debugf("Error hijack: %s", err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
errCh = promise.Go(func() error {
|
||||||
|
return cli.holdHijackedConnection(config.Tty, in, out, stderr, resp)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if *flAutoRemove {
|
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)
|
fmt.Fprintf(cli.err, "Error deleting container: %s\n", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
//start the container
|
//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)
|
cmd.ReportError(err.Error(), false)
|
||||||
return runStartContainerErr(err)
|
return runStartContainerErr(err)
|
||||||
}
|
}
|
||||||
|
@ -262,7 +249,7 @@ func (cli *DockerCli) CmdRun(args ...string) error {
|
||||||
if *flAutoRemove {
|
if *flAutoRemove {
|
||||||
// Autoremove: wait for the container to finish, retrieve
|
// Autoremove: wait for the container to finish, retrieve
|
||||||
// the exit code and remove the container
|
// 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)
|
return runStartContainerErr(err)
|
||||||
}
|
}
|
||||||
if _, status, err = getExitCode(cli, createResponse.ID); err != nil {
|
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)
|
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.
|
// 3. Start the container.
|
||||||
if err := cli.client.ContainerStart(containerID); err != nil {
|
if err := cli.client.ContainerStart(containerID); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
Loading…
Reference in New Issue