diff --git a/integration-cli/docker_api_ipcmode_test.go b/integration-cli/docker_api_ipcmode_test.go index e37a875e8e..9eb483d8b2 100644 --- a/integration-cli/docker_api_ipcmode_test.go +++ b/integration-cli/docker_api_ipcmode_test.go @@ -4,7 +4,6 @@ package main import ( "bufio" "context" - "fmt" "io/ioutil" "os" "strings" @@ -46,71 +45,6 @@ func testIpcCheckDevExists(mm string) (bool, error) { return false, s.Err() } -// testIpcContainer is a helper function to test --ipc container:NNN mode in various scenarios -func testIpcContainer(s *DockerSuite, c *check.C, donorMode string, mustWork bool) { - cfg := container.Config{ - Image: "busybox", - Cmd: []string{"top"}, - } - hostCfg := container.HostConfig{ - IpcMode: container.IpcMode(donorMode), - } - ctx := context.Background() - - client := testEnv.APIClient() - - // create and start the "donor" container - resp, err := client.ContainerCreate(ctx, &cfg, &hostCfg, nil, "") - c.Assert(err, checker.IsNil) - c.Assert(len(resp.Warnings), checker.Equals, 0) - name1 := resp.ID - - err = client.ContainerStart(ctx, name1, types.ContainerStartOptions{}) - c.Assert(err, checker.IsNil) - - // create and start the second container - hostCfg.IpcMode = container.IpcMode("container:" + name1) - resp, err = client.ContainerCreate(ctx, &cfg, &hostCfg, nil, "") - c.Assert(err, checker.IsNil) - c.Assert(len(resp.Warnings), checker.Equals, 0) - name2 := resp.ID - - err = client.ContainerStart(ctx, name2, types.ContainerStartOptions{}) - if !mustWork { - // start should fail with a specific error - c.Assert(err, checker.NotNil) - c.Assert(fmt.Sprintf("%v", err), checker.Contains, "non-shareable IPC") - // no more checks to perform here - return - } - - // start should succeed - c.Assert(err, checker.IsNil) - - // check that IPC is shared - // 1. create a file in the first container - cli.DockerCmd(c, "exec", name1, "sh", "-c", "printf covfefe > /dev/shm/bar") - // 2. check it's the same file in the second one - out := cli.DockerCmd(c, "exec", "-i", name2, "cat", "/dev/shm/bar").Combined() - c.Assert(out, checker.Matches, "^covfefe$") -} - -/* TestAPIIpcModeShareableAndContainer checks that a container created with - * --ipc container:ID can use IPC of another shareable container. - */ -func (s *DockerSuite) TestAPIIpcModeShareableAndContainer(c *check.C) { - testRequires(c, DaemonIsLinux) - testIpcContainer(s, c, "shareable", true) -} - -/* TestAPIIpcModePrivateAndContainer checks that a container created with - * --ipc container:ID can NOT use IPC of another private container. - */ -func (s *DockerSuite) TestAPIIpcModePrivateAndContainer(c *check.C) { - testRequires(c, DaemonIsLinux, MinimumAPIVersion("1.32")) - testIpcContainer(s, c, "private", false) -} - /* TestAPIIpcModeHost checks that a container created with --ipc host * can use IPC of the host system. */ diff --git a/integration/container/ipcmode_test.go b/integration/container/ipcmode_test.go index 3011748cd0..b0ed84293f 100644 --- a/integration/container/ipcmode_test.go +++ b/integration/container/ipcmode_test.go @@ -114,3 +114,68 @@ func TestIpcModeShareable(t *testing.T) { testIpcNonePrivateShareable(t, "shareable", true, true) } + +// testIpcContainer is a helper function to test --ipc container:NNN mode in various scenarios +func testIpcContainer(t *testing.T, donorMode string, mustWork bool) { + t.Helper() + + defer setupTest(t)() + + cfg := containertypes.Config{ + Image: "busybox", + Cmd: []string{"top"}, + } + hostCfg := containertypes.HostConfig{ + IpcMode: containertypes.IpcMode(donorMode), + } + ctx := context.Background() + client := request.NewAPIClient(t) + + // create and start the "donor" container + resp, err := client.ContainerCreate(ctx, &cfg, &hostCfg, nil, "") + assert.NilError(t, err) + assert.Check(t, is.Equal(len(resp.Warnings), 0)) + name1 := resp.ID + + err = client.ContainerStart(ctx, name1, types.ContainerStartOptions{}) + assert.NilError(t, err) + + // create and start the second container + hostCfg.IpcMode = containertypes.IpcMode("container:" + name1) + resp, err = client.ContainerCreate(ctx, &cfg, &hostCfg, nil, "") + assert.NilError(t, err) + assert.Check(t, is.Equal(len(resp.Warnings), 0)) + name2 := resp.ID + + err = client.ContainerStart(ctx, name2, types.ContainerStartOptions{}) + if !mustWork { + // start should fail with a specific error + assert.Check(t, is.ErrorContains(err, "non-shareable IPC")) + // no more checks to perform here + return + } + + // start should succeed + assert.NilError(t, err) + + // check that IPC is shared + // 1. create a file in the first container + _, err = container.Exec(ctx, client, name1, []string{"sh", "-c", "printf covfefe > /dev/shm/bar"}) + assert.NilError(t, err) + // 2. check it's the same file in the second one + result, err := container.Exec(ctx, client, name2, []string{"cat", "/dev/shm/bar"}) + assert.NilError(t, err) + out := result.Combined() + assert.Check(t, is.Equal(true, regexp.MustCompile("^covfefe$").MatchString(out))) +} + +// TestAPIIpcModeShareableAndPrivate checks that +// 1) a container created with --ipc container:ID can use IPC of another shareable container. +// 2) a container created with --ipc container:ID can NOT use IPC of another private container. +func TestAPIIpcModeShareableAndContainer(t *testing.T) { + skip.If(t, testEnv.DaemonInfo.OSType != "linux") + + testIpcContainer(t, "shareable", true) + + testIpcContainer(t, "private", false) +}