github.com/demonoid81/moby@v0.0.0-20200517203328-62dd8e17c460/integration/container/run_cgroupns_linux_test.go (about) 1 package container // import "github.com/demonoid81/moby/integration/container" 2 3 import ( 4 "context" 5 "strings" 6 "testing" 7 "time" 8 9 "github.com/demonoid81/moby/client" 10 "github.com/demonoid81/moby/integration/internal/container" 11 "github.com/demonoid81/moby/integration/internal/requirement" 12 "github.com/demonoid81/moby/testutil/daemon" 13 "gotest.tools/v3/assert" 14 is "gotest.tools/v3/assert/cmp" 15 "gotest.tools/v3/poll" 16 "gotest.tools/v3/skip" 17 ) 18 19 // Gets the value of the cgroup namespace for pid 1 of a container 20 func containerCgroupNamespace(ctx context.Context, t *testing.T, client *client.Client, cID string) string { 21 res, err := container.Exec(ctx, client, cID, []string{"readlink", "/proc/1/ns/cgroup"}) 22 assert.NilError(t, err) 23 assert.Assert(t, is.Len(res.Stderr(), 0)) 24 assert.Equal(t, 0, res.ExitCode) 25 return strings.TrimSpace(res.Stdout()) 26 } 27 28 // Bring up a daemon with the specified default cgroup namespace mode, and then create a container with the container options 29 func testRunWithCgroupNs(t *testing.T, daemonNsMode string, containerOpts ...func(*container.TestContainerConfig)) (string, string) { 30 d := daemon.New(t, daemon.WithDefaultCgroupNamespaceMode(daemonNsMode)) 31 client := d.NewClientT(t) 32 ctx := context.Background() 33 34 d.StartWithBusybox(t) 35 defer d.Stop(t) 36 37 cID := container.Run(ctx, t, client, containerOpts...) 38 poll.WaitOn(t, container.IsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond)) 39 40 daemonCgroup := d.CgroupNamespace(t) 41 containerCgroup := containerCgroupNamespace(ctx, t, client, cID) 42 return containerCgroup, daemonCgroup 43 } 44 45 // Bring up a daemon with the specified default cgroup namespace mode. Create a container with the container options, 46 // expecting an error with the specified string 47 func testCreateFailureWithCgroupNs(t *testing.T, daemonNsMode string, errStr string, containerOpts ...func(*container.TestContainerConfig)) { 48 d := daemon.New(t, daemon.WithDefaultCgroupNamespaceMode(daemonNsMode)) 49 client := d.NewClientT(t) 50 ctx := context.Background() 51 52 d.StartWithBusybox(t) 53 defer d.Stop(t) 54 container.CreateExpectingErr(ctx, t, client, errStr, containerOpts...) 55 } 56 57 func TestCgroupNamespacesRun(t *testing.T) { 58 skip.If(t, testEnv.DaemonInfo.OSType != "linux") 59 skip.If(t, testEnv.IsRemoteDaemon()) 60 skip.If(t, !requirement.CgroupNamespacesEnabled()) 61 62 // When the daemon defaults to private cgroup namespaces, containers launched 63 // should be in their own private cgroup namespace by default 64 containerCgroup, daemonCgroup := testRunWithCgroupNs(t, "private") 65 assert.Assert(t, daemonCgroup != containerCgroup) 66 } 67 68 func TestCgroupNamespacesRunPrivileged(t *testing.T) { 69 skip.If(t, testEnv.DaemonInfo.OSType != "linux") 70 skip.If(t, testEnv.IsRemoteDaemon()) 71 skip.If(t, !requirement.CgroupNamespacesEnabled()) 72 73 // When the daemon defaults to private cgroup namespaces, privileged containers 74 // launched should not be inside their own cgroup namespaces 75 containerCgroup, daemonCgroup := testRunWithCgroupNs(t, "private", container.WithPrivileged(true)) 76 assert.Assert(t, daemonCgroup == containerCgroup) 77 } 78 79 func TestCgroupNamespacesRunDaemonHostMode(t *testing.T) { 80 skip.If(t, testEnv.DaemonInfo.OSType != "linux") 81 skip.If(t, testEnv.IsRemoteDaemon()) 82 skip.If(t, !requirement.CgroupNamespacesEnabled()) 83 84 // When the daemon defaults to host cgroup namespaces, containers 85 // launched should not be inside their own cgroup namespaces 86 containerCgroup, daemonCgroup := testRunWithCgroupNs(t, "host") 87 assert.Assert(t, daemonCgroup == containerCgroup) 88 } 89 90 func TestCgroupNamespacesRunHostMode(t *testing.T) { 91 skip.If(t, testEnv.DaemonInfo.OSType != "linux") 92 skip.If(t, testEnv.IsRemoteDaemon()) 93 skip.If(t, !requirement.CgroupNamespacesEnabled()) 94 95 // When the daemon defaults to private cgroup namespaces, containers launched 96 // with a cgroup ns mode of "host" should not be inside their own cgroup namespaces 97 containerCgroup, daemonCgroup := testRunWithCgroupNs(t, "private", container.WithCgroupnsMode("host")) 98 assert.Assert(t, daemonCgroup == containerCgroup) 99 } 100 101 func TestCgroupNamespacesRunPrivateMode(t *testing.T) { 102 skip.If(t, testEnv.DaemonInfo.OSType != "linux") 103 skip.If(t, testEnv.IsRemoteDaemon()) 104 skip.If(t, !requirement.CgroupNamespacesEnabled()) 105 106 // When the daemon defaults to private cgroup namespaces, containers launched 107 // with a cgroup ns mode of "private" should be inside their own cgroup namespaces 108 containerCgroup, daemonCgroup := testRunWithCgroupNs(t, "private", container.WithCgroupnsMode("private")) 109 assert.Assert(t, daemonCgroup != containerCgroup) 110 } 111 112 func TestCgroupNamespacesRunPrivilegedAndPrivate(t *testing.T) { 113 skip.If(t, testEnv.DaemonInfo.OSType != "linux") 114 skip.If(t, testEnv.IsRemoteDaemon()) 115 skip.If(t, !requirement.CgroupNamespacesEnabled()) 116 117 containerCgroup, daemonCgroup := testRunWithCgroupNs(t, "private", container.WithPrivileged(true), container.WithCgroupnsMode("private")) 118 assert.Assert(t, daemonCgroup != containerCgroup) 119 } 120 121 func TestCgroupNamespacesRunInvalidMode(t *testing.T) { 122 skip.If(t, testEnv.DaemonInfo.OSType != "linux") 123 skip.If(t, testEnv.IsRemoteDaemon()) 124 skip.If(t, !requirement.CgroupNamespacesEnabled()) 125 126 // An invalid cgroup namespace mode should return an error on container creation 127 errStr := "invalid cgroup namespace mode: invalid" 128 testCreateFailureWithCgroupNs(t, "private", errStr, container.WithCgroupnsMode("invalid")) 129 } 130 131 // Clients before 1.40 expect containers to be created in the host cgroup namespace, 132 // regardless of the default setting of the daemon 133 func TestCgroupNamespacesRunOlderClient(t *testing.T) { 134 skip.If(t, testEnv.DaemonInfo.OSType != "linux") 135 skip.If(t, testEnv.IsRemoteDaemon()) 136 skip.If(t, !requirement.CgroupNamespacesEnabled()) 137 138 d := daemon.New(t, daemon.WithDefaultCgroupNamespaceMode("private")) 139 client := d.NewClientT(t, client.WithVersion("1.39")) 140 141 ctx := context.Background() 142 d.StartWithBusybox(t) 143 defer d.Stop(t) 144 145 cID := container.Run(ctx, t, client) 146 poll.WaitOn(t, container.IsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond)) 147 148 daemonCgroup := d.CgroupNamespace(t) 149 containerCgroup := containerCgroupNamespace(ctx, t, client, cID) 150 assert.Assert(t, daemonCgroup == containerCgroup) 151 }