mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #37851 from adshmh/migrate-ipc-integration-tests-to-integration-container
migrated ipc integration tests to integration/container
This commit is contained in:
commit
30b5eb19d4
4 changed files with 120 additions and 142 deletions
|
@ -1,81 +0,0 @@
|
||||||
// build +linux
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"context"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"github.com/docker/docker/api/types/container"
|
|
||||||
"github.com/docker/docker/integration-cli/checker"
|
|
||||||
"github.com/docker/docker/integration-cli/cli"
|
|
||||||
"github.com/go-check/check"
|
|
||||||
)
|
|
||||||
|
|
||||||
/* testIpcCheckDevExists checks whether a given mount (identified by its
|
|
||||||
* major:minor pair from /proc/self/mountinfo) exists on the host system.
|
|
||||||
*
|
|
||||||
* The format of /proc/self/mountinfo is like:
|
|
||||||
*
|
|
||||||
* 29 23 0:24 / /dev/shm rw,nosuid,nodev shared:4 - tmpfs tmpfs rw
|
|
||||||
* ^^^^\
|
|
||||||
* - this is the minor:major we look for
|
|
||||||
*/
|
|
||||||
func testIpcCheckDevExists(mm string) (bool, error) {
|
|
||||||
f, err := os.Open("/proc/self/mountinfo")
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
s := bufio.NewScanner(f)
|
|
||||||
for s.Scan() {
|
|
||||||
fields := strings.Fields(s.Text())
|
|
||||||
if len(fields) < 7 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if fields[2] == mm {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false, s.Err()
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TestAPIIpcModeHost checks that a container created with --ipc host
|
|
||||||
* can use IPC of the host system.
|
|
||||||
*/
|
|
||||||
func (s *DockerSuite) TestAPIIpcModeHost(c *check.C) {
|
|
||||||
testRequires(c, DaemonIsLinux, SameHostDaemon, NotUserNamespace)
|
|
||||||
|
|
||||||
cfg := container.Config{
|
|
||||||
Image: "busybox",
|
|
||||||
Cmd: []string{"top"},
|
|
||||||
}
|
|
||||||
hostCfg := container.HostConfig{
|
|
||||||
IpcMode: container.IpcMode("host"),
|
|
||||||
}
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
client := testEnv.APIClient()
|
|
||||||
resp, err := client.ContainerCreate(ctx, &cfg, &hostCfg, nil, "")
|
|
||||||
c.Assert(err, checker.IsNil)
|
|
||||||
c.Assert(len(resp.Warnings), checker.Equals, 0)
|
|
||||||
name := resp.ID
|
|
||||||
|
|
||||||
err = client.ContainerStart(ctx, name, types.ContainerStartOptions{})
|
|
||||||
c.Assert(err, checker.IsNil)
|
|
||||||
|
|
||||||
// check that IPC is shared
|
|
||||||
// 1. create a file inside container
|
|
||||||
cli.DockerCmd(c, "exec", name, "sh", "-c", "printf covfefe > /dev/shm/."+name)
|
|
||||||
// 2. check it's the same on the host
|
|
||||||
bytes, err := ioutil.ReadFile("/dev/shm/." + name)
|
|
||||||
c.Assert(err, checker.IsNil)
|
|
||||||
c.Assert(string(bytes), checker.Matches, "^covfefe$")
|
|
||||||
// 3. clean up
|
|
||||||
cli.DockerCmd(c, "exec", name, "rm", "-f", "/dev/shm/."+name)
|
|
||||||
}
|
|
|
@ -2901,67 +2901,6 @@ func (s *DockerDaemonSuite) TestShmSizeReload(c *check.C) {
|
||||||
c.Assert(strings.TrimSpace(out), check.Equals, fmt.Sprintf("%v", size))
|
c.Assert(strings.TrimSpace(out), check.Equals, fmt.Sprintf("%v", size))
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is used to test both "private" and "shareable" daemon default ipc modes
|
|
||||||
func testDaemonIpcPrivateShareable(d *daemon.Daemon, c *check.C, mustExist bool) {
|
|
||||||
name := "test-ipcmode"
|
|
||||||
_, err := d.Cmd("run", "-d", "--name", name, "busybox", "top")
|
|
||||||
c.Assert(err, checker.IsNil)
|
|
||||||
|
|
||||||
// get major:minor pair for /dev/shm from container's /proc/self/mountinfo
|
|
||||||
cmd := "awk '($5 == \"/dev/shm\") {printf $3}' /proc/self/mountinfo"
|
|
||||||
mm, err := d.Cmd("exec", "-i", name, "sh", "-c", cmd)
|
|
||||||
c.Assert(err, checker.IsNil)
|
|
||||||
c.Assert(mm, checker.Matches, "^[0-9]+:[0-9]+$")
|
|
||||||
|
|
||||||
exists, err := testIpcCheckDevExists(mm)
|
|
||||||
c.Assert(err, checker.IsNil)
|
|
||||||
c.Logf("[testDaemonIpcPrivateShareable] ipcdev: %v, exists: %v, mustExist: %v\n", mm, exists, mustExist)
|
|
||||||
c.Assert(exists, checker.Equals, mustExist)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestDaemonIpcModeShareable checks that --default-ipc-mode shareable works as intended.
|
|
||||||
func (s *DockerDaemonSuite) TestDaemonIpcModeShareable(c *check.C) {
|
|
||||||
testRequires(c, DaemonIsLinux, SameHostDaemon)
|
|
||||||
|
|
||||||
s.d.StartWithBusybox(c, "--default-ipc-mode", "shareable")
|
|
||||||
testDaemonIpcPrivateShareable(s.d, c, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestDaemonIpcModePrivate checks that --default-ipc-mode private works as intended.
|
|
||||||
func (s *DockerDaemonSuite) TestDaemonIpcModePrivate(c *check.C) {
|
|
||||||
testRequires(c, DaemonIsLinux, SameHostDaemon)
|
|
||||||
|
|
||||||
s.d.StartWithBusybox(c, "--default-ipc-mode", "private")
|
|
||||||
testDaemonIpcPrivateShareable(s.d, c, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
// used to check if an IpcMode given in config works as intended
|
|
||||||
func testDaemonIpcFromConfig(s *DockerDaemonSuite, c *check.C, mode string, mustExist bool) {
|
|
||||||
f, err := ioutil.TempFile("", "test-daemon-ipc-config")
|
|
||||||
c.Assert(err, checker.IsNil)
|
|
||||||
defer os.Remove(f.Name())
|
|
||||||
|
|
||||||
config := `{"default-ipc-mode": "` + mode + `"}`
|
|
||||||
_, err = f.WriteString(config)
|
|
||||||
c.Assert(f.Close(), checker.IsNil)
|
|
||||||
c.Assert(err, checker.IsNil)
|
|
||||||
|
|
||||||
s.d.StartWithBusybox(c, "--config-file", f.Name())
|
|
||||||
testDaemonIpcPrivateShareable(s.d, c, mustExist)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestDaemonIpcModePrivateFromConfig checks that "default-ipc-mode: private" config works as intended.
|
|
||||||
func (s *DockerDaemonSuite) TestDaemonIpcModePrivateFromConfig(c *check.C) {
|
|
||||||
testRequires(c, DaemonIsLinux, SameHostDaemon)
|
|
||||||
testDaemonIpcFromConfig(s, c, "private", false)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestDaemonIpcModeShareableFromConfig checks that "default-ipc-mode: shareable" config works as intended.
|
|
||||||
func (s *DockerDaemonSuite) TestDaemonIpcModeShareableFromConfig(c *check.C) {
|
|
||||||
testRequires(c, DaemonIsLinux, SameHostDaemon)
|
|
||||||
testDaemonIpcFromConfig(s, c, "shareable", true)
|
|
||||||
}
|
|
||||||
|
|
||||||
func testDaemonStartIpcMode(c *check.C, from, mode string, valid bool) {
|
func testDaemonStartIpcMode(c *check.C, from, mode string, valid bool) {
|
||||||
d := daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution))
|
d := daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution))
|
||||||
c.Logf("Checking IpcMode %s set from %s\n", mode, from)
|
c.Logf("Checking IpcMode %s set from %s\n", mode, from)
|
||||||
|
|
|
@ -3,6 +3,7 @@ package container // import "github.com/docker/docker/integration/container"
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"context"
|
"context"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -11,9 +12,11 @@ import (
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
containertypes "github.com/docker/docker/api/types/container"
|
containertypes "github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/integration/internal/container"
|
"github.com/docker/docker/integration/internal/container"
|
||||||
|
"github.com/docker/docker/internal/test/daemon"
|
||||||
"github.com/docker/docker/internal/test/request"
|
"github.com/docker/docker/internal/test/request"
|
||||||
"gotest.tools/assert"
|
"gotest.tools/assert"
|
||||||
is "gotest.tools/assert/cmp"
|
is "gotest.tools/assert/cmp"
|
||||||
|
"gotest.tools/fs"
|
||||||
"gotest.tools/skip"
|
"gotest.tools/skip"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -179,3 +182,114 @@ func TestAPIIpcModeShareableAndContainer(t *testing.T) {
|
||||||
|
|
||||||
testIpcContainer(t, "private", false)
|
testIpcContainer(t, "private", false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TestAPIIpcModeHost checks that a container created with --ipc host
|
||||||
|
* can use IPC of the host system.
|
||||||
|
*/
|
||||||
|
func TestAPIIpcModeHost(t *testing.T) {
|
||||||
|
skip.If(t, testEnv.DaemonInfo.OSType != "linux" || testEnv.IsRemoteDaemon() || testEnv.IsUserNamespace())
|
||||||
|
|
||||||
|
cfg := containertypes.Config{
|
||||||
|
Image: "busybox",
|
||||||
|
Cmd: []string{"top"},
|
||||||
|
}
|
||||||
|
hostCfg := containertypes.HostConfig{
|
||||||
|
IpcMode: containertypes.IpcMode("host"),
|
||||||
|
}
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
client := testEnv.APIClient()
|
||||||
|
resp, err := client.ContainerCreate(ctx, &cfg, &hostCfg, nil, "")
|
||||||
|
assert.NilError(t, err)
|
||||||
|
assert.Check(t, is.Equal(len(resp.Warnings), 0))
|
||||||
|
name := resp.ID
|
||||||
|
|
||||||
|
err = client.ContainerStart(ctx, name, types.ContainerStartOptions{})
|
||||||
|
assert.NilError(t, err)
|
||||||
|
|
||||||
|
// check that IPC is shared
|
||||||
|
// 1. create a file inside container
|
||||||
|
_, err = container.Exec(ctx, client, name, []string{"sh", "-c", "printf covfefe > /dev/shm/." + name})
|
||||||
|
assert.NilError(t, err)
|
||||||
|
// 2. check it's the same on the host
|
||||||
|
bytes, err := ioutil.ReadFile("/dev/shm/." + name)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
assert.Check(t, is.Equal("covfefe", string(bytes)))
|
||||||
|
// 3. clean up
|
||||||
|
_, err = container.Exec(ctx, client, name, []string{"rm", "-f", "/dev/shm/." + name})
|
||||||
|
assert.NilError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// testDaemonIpcPrivateShareable is a helper function to test "private" and "shareable" daemon default ipc modes.
|
||||||
|
func testDaemonIpcPrivateShareable(t *testing.T, mustBeShared bool, arg ...string) {
|
||||||
|
defer setupTest(t)()
|
||||||
|
|
||||||
|
d := daemon.New(t)
|
||||||
|
d.StartWithBusybox(t, arg...)
|
||||||
|
defer d.Stop(t)
|
||||||
|
|
||||||
|
client, err := d.NewClient()
|
||||||
|
assert.Check(t, err, "error creating client")
|
||||||
|
|
||||||
|
cfg := containertypes.Config{
|
||||||
|
Image: "busybox",
|
||||||
|
Cmd: []string{"top"},
|
||||||
|
}
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
resp, err := client.ContainerCreate(ctx, &cfg, &containertypes.HostConfig{}, nil, "")
|
||||||
|
assert.NilError(t, err)
|
||||||
|
assert.Check(t, is.Equal(len(resp.Warnings), 0))
|
||||||
|
|
||||||
|
err = client.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{})
|
||||||
|
assert.NilError(t, err)
|
||||||
|
|
||||||
|
// get major:minor pair for /dev/shm from container's /proc/self/mountinfo
|
||||||
|
cmd := "awk '($5 == \"/dev/shm\") {printf $3}' /proc/self/mountinfo"
|
||||||
|
result, err := container.Exec(ctx, client, resp.ID, []string{"sh", "-c", cmd})
|
||||||
|
assert.NilError(t, err)
|
||||||
|
mm := result.Combined()
|
||||||
|
assert.Check(t, is.Equal(true, regexp.MustCompile("^[0-9]+:[0-9]+$").MatchString(mm)))
|
||||||
|
|
||||||
|
shared, err := testIpcCheckDevExists(mm)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
t.Logf("[testDaemonIpcPrivateShareable] ipcdev: %v, shared: %v, mustBeShared: %v\n", mm, shared, mustBeShared)
|
||||||
|
assert.Check(t, is.Equal(shared, mustBeShared))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestDaemonIpcModeShareable checks that --default-ipc-mode shareable works as intended.
|
||||||
|
func TestDaemonIpcModeShareable(t *testing.T) {
|
||||||
|
skip.If(t, testEnv.DaemonInfo.OSType != "linux" || testEnv.IsRemoteDaemon())
|
||||||
|
|
||||||
|
testDaemonIpcPrivateShareable(t, true, "--default-ipc-mode", "shareable")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestDaemonIpcModePrivate checks that --default-ipc-mode private works as intended.
|
||||||
|
func TestDaemonIpcModePrivate(t *testing.T) {
|
||||||
|
skip.If(t, testEnv.DaemonInfo.OSType != "linux" || testEnv.IsRemoteDaemon())
|
||||||
|
|
||||||
|
testDaemonIpcPrivateShareable(t, false, "--default-ipc-mode", "private")
|
||||||
|
}
|
||||||
|
|
||||||
|
// used to check if an IpcMode given in config works as intended
|
||||||
|
func testDaemonIpcFromConfig(t *testing.T, mode string, mustExist bool) {
|
||||||
|
config := `{"default-ipc-mode": "` + mode + `"}`
|
||||||
|
file := fs.NewFile(t, "test-daemon-ipc-config", fs.WithContent(config))
|
||||||
|
defer file.Remove()
|
||||||
|
|
||||||
|
testDaemonIpcPrivateShareable(t, mustExist, "--config-file", file.Path())
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestDaemonIpcModePrivateFromConfig checks that "default-ipc-mode: private" config works as intended.
|
||||||
|
func TestDaemonIpcModePrivateFromConfig(t *testing.T) {
|
||||||
|
skip.If(t, testEnv.DaemonInfo.OSType != "linux" || testEnv.IsRemoteDaemon())
|
||||||
|
|
||||||
|
testDaemonIpcFromConfig(t, "private", false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestDaemonIpcModeShareableFromConfig checks that "default-ipc-mode: shareable" config works as intended.
|
||||||
|
func TestDaemonIpcModeShareableFromConfig(t *testing.T) {
|
||||||
|
skip.If(t, testEnv.DaemonInfo.OSType != "linux" || testEnv.IsRemoteDaemon())
|
||||||
|
|
||||||
|
testDaemonIpcFromConfig(t, "shareable", true)
|
||||||
|
}
|
||||||
|
|
|
@ -145,6 +145,12 @@ func (e *Execution) APIClient() client.APIClient {
|
||||||
return e.client
|
return e.client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsUserNamespace returns whether the user namespace remapping is enabled
|
||||||
|
func (e *Execution) IsUserNamespace() bool {
|
||||||
|
root := os.Getenv("DOCKER_REMAP_ROOT")
|
||||||
|
return root != ""
|
||||||
|
}
|
||||||
|
|
||||||
// EnsureFrozenImagesLinux loads frozen test images into the daemon
|
// EnsureFrozenImagesLinux loads frozen test images into the daemon
|
||||||
// if they aren't already loaded
|
// if they aren't already loaded
|
||||||
func EnsureFrozenImagesLinux(testEnv *Execution) error {
|
func EnsureFrozenImagesLinux(testEnv *Execution) error {
|
||||||
|
|
Loading…
Reference in a new issue