Signed-off-by: Andy Goldstein <agoldste@redhat.com>
| ... | ... |
@@ -28,6 +28,9 @@ func (cli *Client) ContainerAttach(ctx context.Context, container string, option |
| 28 | 28 |
if options.DetachKeys != "" {
|
| 29 | 29 |
query.Set("detachKeys", options.DetachKeys)
|
| 30 | 30 |
} |
| 31 |
+ if options.Logs {
|
|
| 32 |
+ query.Set("logs", "1")
|
|
| 33 |
+ } |
|
| 31 | 34 |
|
| 32 | 35 |
headers := map[string][]string{"Content-Type": {"text/plain"}}
|
| 33 | 36 |
return cli.postHijacked(ctx, "/containers/"+container+"/attach", query, nil, headers) |
| ... | ... |
@@ -2,13 +2,18 @@ package main |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"bufio" |
| 5 |
+ "bytes" |
|
| 6 |
+ "context" |
|
| 5 | 7 |
"io" |
| 6 | 8 |
"net" |
| 7 | 9 |
"net/http" |
| 8 | 10 |
"strings" |
| 9 | 11 |
"time" |
| 10 | 12 |
|
| 13 |
+ "github.com/docker/docker/api/types" |
|
| 14 |
+ "github.com/docker/docker/client" |
|
| 11 | 15 |
"github.com/docker/docker/pkg/integration/checker" |
| 16 |
+ "github.com/docker/docker/pkg/stdcopy" |
|
| 12 | 17 |
"github.com/go-check/check" |
| 13 | 18 |
"golang.org/x/net/websocket" |
| 14 | 19 |
) |
| ... | ... |
@@ -168,4 +173,38 @@ func (s *DockerSuite) TestPostContainersAttach(c *check.C) {
|
| 168 | 168 |
// Nothing should be received because both the stdout and stderr of the container will be |
| 169 | 169 |
// sent to the client as stdout when tty is enabled. |
| 170 | 170 |
expectTimeout(conn, br, "stdout") |
| 171 |
+ |
|
| 172 |
+ // Test the client API |
|
| 173 |
+ // Make sure we don't see "hello" if Logs is false |
|
| 174 |
+ client, err := client.NewEnvClient() |
|
| 175 |
+ c.Assert(err, checker.IsNil) |
|
| 176 |
+ |
|
| 177 |
+ cid, _ = dockerCmd(c, "run", "-di", "busybox", "/bin/sh", "-c", "echo hello; cat") |
|
| 178 |
+ cid = strings.TrimSpace(cid) |
|
| 179 |
+ |
|
| 180 |
+ attachOpts := types.ContainerAttachOptions{
|
|
| 181 |
+ Stream: true, |
|
| 182 |
+ Stdin: true, |
|
| 183 |
+ Stdout: true, |
|
| 184 |
+ } |
|
| 185 |
+ |
|
| 186 |
+ resp, err := client.ContainerAttach(context.Background(), cid, attachOpts) |
|
| 187 |
+ c.Assert(err, checker.IsNil) |
|
| 188 |
+ expectSuccess(resp.Conn, resp.Reader, "stdout", false) |
|
| 189 |
+ |
|
| 190 |
+ // Make sure we do see "hello" if Logs is true |
|
| 191 |
+ attachOpts.Logs = true |
|
| 192 |
+ resp, err = client.ContainerAttach(context.Background(), cid, attachOpts) |
|
| 193 |
+ c.Assert(err, checker.IsNil) |
|
| 194 |
+ |
|
| 195 |
+ defer resp.Conn.Close() |
|
| 196 |
+ resp.Conn.SetReadDeadline(time.Now().Add(time.Second)) |
|
| 197 |
+ |
|
| 198 |
+ _, err = resp.Conn.Write([]byte("success"))
|
|
| 199 |
+ c.Assert(err, checker.IsNil) |
|
| 200 |
+ |
|
| 201 |
+ actualStdout := new(bytes.Buffer) |
|
| 202 |
+ actualStderr := new(bytes.Buffer) |
|
| 203 |
+ stdcopy.StdCopy(actualStdout, actualStderr, resp.Reader) |
|
| 204 |
+ c.Assert(actualStdout.Bytes(), checker.DeepEquals, []byte("hello\nsuccess"), check.Commentf("Attach didn't return the expected data from stdout"))
|
|
| 171 | 205 |
} |