2018-02-05 16:05:59 -05:00
|
|
|
package container // import "github.com/docker/docker/integration/container"
|
2017-12-03 04:56:50 -05:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"io/ioutil"
|
|
|
|
"testing"
|
2018-10-11 07:03:02 -04:00
|
|
|
"time"
|
2017-12-03 04:56:50 -05:00
|
|
|
|
|
|
|
"github.com/docker/docker/api/types"
|
|
|
|
"github.com/docker/docker/api/types/strslice"
|
2018-05-04 17:15:00 -04:00
|
|
|
"github.com/docker/docker/api/types/versions"
|
2018-02-12 18:08:25 -05:00
|
|
|
"github.com/docker/docker/integration/internal/container"
|
2020-02-07 08:39:24 -05:00
|
|
|
"gotest.tools/v3/assert"
|
|
|
|
is "gotest.tools/v3/assert/cmp"
|
|
|
|
"gotest.tools/v3/skip"
|
2017-12-03 04:56:50 -05:00
|
|
|
)
|
|
|
|
|
2018-10-11 07:03:02 -04:00
|
|
|
// TestExecWithCloseStdin adds case for moby#37870 issue.
|
|
|
|
func TestExecWithCloseStdin(t *testing.T) {
|
|
|
|
skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.39"), "broken in earlier versions")
|
|
|
|
defer setupTest(t)()
|
|
|
|
|
|
|
|
ctx := context.Background()
|
2019-01-02 08:16:25 -05:00
|
|
|
client := testEnv.APIClient()
|
2018-10-11 07:03:02 -04:00
|
|
|
|
|
|
|
// run top with detached mode
|
2019-06-06 07:15:31 -04:00
|
|
|
cID := container.Run(ctx, t, client)
|
2018-10-11 07:03:02 -04:00
|
|
|
|
|
|
|
expected := "closeIO"
|
|
|
|
execResp, err := client.ContainerExecCreate(ctx, cID,
|
|
|
|
types.ExecConfig{
|
|
|
|
AttachStdin: true,
|
|
|
|
AttachStdout: true,
|
|
|
|
Cmd: strslice.StrSlice([]string{"sh", "-c", "cat && echo " + expected}),
|
|
|
|
},
|
|
|
|
)
|
|
|
|
assert.NilError(t, err)
|
|
|
|
|
|
|
|
resp, err := client.ContainerExecAttach(ctx, execResp.ID,
|
|
|
|
types.ExecStartCheck{
|
|
|
|
Detach: false,
|
|
|
|
Tty: false,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
assert.NilError(t, err)
|
|
|
|
defer resp.Close()
|
|
|
|
|
|
|
|
// close stdin to send EOF to cat
|
|
|
|
assert.NilError(t, resp.CloseWrite())
|
|
|
|
|
|
|
|
var (
|
|
|
|
waitCh = make(chan struct{})
|
|
|
|
resCh = make(chan struct {
|
|
|
|
content string
|
|
|
|
err error
|
2020-02-25 17:13:25 -05:00
|
|
|
}, 1)
|
2018-10-11 07:03:02 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
close(waitCh)
|
|
|
|
defer close(resCh)
|
|
|
|
r, err := ioutil.ReadAll(resp.Reader)
|
|
|
|
|
|
|
|
resCh <- struct {
|
|
|
|
content string
|
|
|
|
err error
|
|
|
|
}{
|
|
|
|
content: string(r),
|
|
|
|
err: err,
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
<-waitCh
|
|
|
|
select {
|
|
|
|
case <-time.After(3 * time.Second):
|
|
|
|
t.Fatal("failed to read the content in time")
|
|
|
|
case got := <-resCh:
|
|
|
|
assert.NilError(t, got.err)
|
|
|
|
|
|
|
|
// NOTE: using Contains because no-tty's stream contains UX information
|
|
|
|
// like size, stream type.
|
|
|
|
assert.Assert(t, is.Contains(got.content, expected))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-03 04:56:50 -05:00
|
|
|
func TestExec(t *testing.T) {
|
2018-05-04 17:15:00 -04:00
|
|
|
skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.35"), "broken in earlier versions")
|
2017-12-03 04:56:50 -05:00
|
|
|
defer setupTest(t)()
|
|
|
|
ctx := context.Background()
|
2019-01-02 08:16:25 -05:00
|
|
|
client := testEnv.APIClient()
|
2017-12-03 04:56:50 -05:00
|
|
|
|
2019-06-06 07:15:31 -04:00
|
|
|
cID := container.Run(ctx, t, client, container.WithTty(true), container.WithWorkingDir("/root"))
|
2017-12-03 04:56:50 -05:00
|
|
|
|
2018-02-12 18:08:25 -05:00
|
|
|
id, err := client.ContainerExecCreate(ctx, cID,
|
2017-12-03 04:56:50 -05:00
|
|
|
types.ExecConfig{
|
|
|
|
WorkingDir: "/tmp",
|
|
|
|
Env: strslice.StrSlice([]string{"FOO=BAR"}),
|
|
|
|
AttachStdout: true,
|
|
|
|
Cmd: strslice.StrSlice([]string{"sh", "-c", "env"}),
|
|
|
|
},
|
|
|
|
)
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.NilError(t, err)
|
2017-12-03 04:56:50 -05:00
|
|
|
|
2020-02-07 17:01:37 -05:00
|
|
|
inspect, err := client.ContainerExecInspect(ctx, id.ID)
|
|
|
|
assert.NilError(t, err)
|
|
|
|
assert.Check(t, is.Equal(inspect.ExecID, id.ID))
|
|
|
|
|
2017-12-03 04:56:50 -05:00
|
|
|
resp, err := client.ContainerExecAttach(ctx, id.ID,
|
|
|
|
types.ExecStartCheck{
|
|
|
|
Detach: false,
|
|
|
|
Tty: false,
|
|
|
|
},
|
|
|
|
)
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.NilError(t, err)
|
2017-12-03 04:56:50 -05:00
|
|
|
defer resp.Close()
|
|
|
|
r, err := ioutil.ReadAll(resp.Reader)
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.NilError(t, err)
|
2017-12-03 04:56:50 -05:00
|
|
|
out := string(r)
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.NilError(t, err)
|
2020-09-15 15:43:16 -04:00
|
|
|
expected := "PWD=/tmp"
|
|
|
|
if testEnv.OSType == "windows" {
|
|
|
|
expected = "PWD=C:/tmp"
|
|
|
|
}
|
|
|
|
assert.Assert(t, is.Contains(out, expected), "exec command not running in expected /tmp working directory")
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Assert(t, is.Contains(out, "FOO=BAR"), "exec command not running with expected environment variable FOO")
|
2017-12-03 04:56:50 -05:00
|
|
|
}
|
2019-03-13 16:04:28 -04:00
|
|
|
|
|
|
|
func TestExecUser(t *testing.T) {
|
|
|
|
skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.39"), "broken in earlier versions")
|
|
|
|
skip.If(t, testEnv.OSType == "windows", "FIXME. Probably needs to wait for container to be in running state.")
|
|
|
|
defer setupTest(t)()
|
|
|
|
ctx := context.Background()
|
|
|
|
client := testEnv.APIClient()
|
|
|
|
|
2019-06-06 07:15:31 -04:00
|
|
|
cID := container.Run(ctx, t, client, container.WithTty(true), container.WithUser("1:1"))
|
2019-03-13 16:04:28 -04:00
|
|
|
|
|
|
|
result, err := container.Exec(ctx, client, cID, []string{"id"})
|
|
|
|
assert.NilError(t, err)
|
|
|
|
|
|
|
|
assert.Assert(t, is.Contains(result.Stdout(), "uid=1(daemon) gid=1(daemon)"), "exec command not running as uid/gid 1")
|
|
|
|
}
|