moby/integration/container/run_cgroupns_linux_test.go
Akihiro Suda 7994443c15
integration: port TestRunModePIDHost from CLI test to API test
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2021-02-01 14:54:07 +09:00

145 lines
5.9 KiB
Go

package container // import "github.com/docker/docker/integration/container"
import (
"context"
"testing"
"time"
"github.com/docker/docker/client"
"github.com/docker/docker/integration/internal/container"
"github.com/docker/docker/integration/internal/requirement"
"github.com/docker/docker/testutil/daemon"
"gotest.tools/v3/assert"
"gotest.tools/v3/poll"
"gotest.tools/v3/skip"
)
// Bring up a daemon with the specified default cgroup namespace mode, and then create a container with the container options
func testRunWithCgroupNs(t *testing.T, daemonNsMode string, containerOpts ...func(*container.TestContainerConfig)) (string, string) {
d := daemon.New(t, daemon.WithDefaultCgroupNamespaceMode(daemonNsMode))
client := d.NewClientT(t)
ctx := context.Background()
d.StartWithBusybox(t)
defer d.Stop(t)
cID := container.Run(ctx, t, client, containerOpts...)
poll.WaitOn(t, container.IsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond))
daemonCgroup := d.CgroupNamespace(t)
containerCgroup := container.GetContainerNS(ctx, t, client, cID, "cgroup")
return containerCgroup, daemonCgroup
}
// Bring up a daemon with the specified default cgroup namespace mode. Create a container with the container options,
// expecting an error with the specified string
func testCreateFailureWithCgroupNs(t *testing.T, daemonNsMode string, errStr string, containerOpts ...func(*container.TestContainerConfig)) {
d := daemon.New(t, daemon.WithDefaultCgroupNamespaceMode(daemonNsMode))
client := d.NewClientT(t)
ctx := context.Background()
d.StartWithBusybox(t)
defer d.Stop(t)
container.CreateExpectingErr(ctx, t, client, errStr, containerOpts...)
}
func TestCgroupNamespacesRun(t *testing.T) {
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
skip.If(t, testEnv.IsRemoteDaemon())
skip.If(t, !requirement.CgroupNamespacesEnabled())
// When the daemon defaults to private cgroup namespaces, containers launched
// should be in their own private cgroup namespace by default
containerCgroup, daemonCgroup := testRunWithCgroupNs(t, "private")
assert.Assert(t, daemonCgroup != containerCgroup)
}
func TestCgroupNamespacesRunPrivileged(t *testing.T) {
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
skip.If(t, testEnv.IsRemoteDaemon())
skip.If(t, !requirement.CgroupNamespacesEnabled())
skip.If(t, testEnv.DaemonInfo.CgroupVersion == "2", "on cgroup v2, privileged containers use private cgroupns")
// When the daemon defaults to private cgroup namespaces, privileged containers
// launched should not be inside their own cgroup namespaces
containerCgroup, daemonCgroup := testRunWithCgroupNs(t, "private", container.WithPrivileged(true))
assert.Assert(t, daemonCgroup == containerCgroup)
}
func TestCgroupNamespacesRunDaemonHostMode(t *testing.T) {
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
skip.If(t, testEnv.IsRemoteDaemon())
skip.If(t, !requirement.CgroupNamespacesEnabled())
// When the daemon defaults to host cgroup namespaces, containers
// launched should not be inside their own cgroup namespaces
containerCgroup, daemonCgroup := testRunWithCgroupNs(t, "host")
assert.Assert(t, daemonCgroup == containerCgroup)
}
func TestCgroupNamespacesRunHostMode(t *testing.T) {
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
skip.If(t, testEnv.IsRemoteDaemon())
skip.If(t, !requirement.CgroupNamespacesEnabled())
// When the daemon defaults to private cgroup namespaces, containers launched
// with a cgroup ns mode of "host" should not be inside their own cgroup namespaces
containerCgroup, daemonCgroup := testRunWithCgroupNs(t, "private", container.WithCgroupnsMode("host"))
assert.Assert(t, daemonCgroup == containerCgroup)
}
func TestCgroupNamespacesRunPrivateMode(t *testing.T) {
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
skip.If(t, testEnv.IsRemoteDaemon())
skip.If(t, !requirement.CgroupNamespacesEnabled())
// When the daemon defaults to private cgroup namespaces, containers launched
// with a cgroup ns mode of "private" should be inside their own cgroup namespaces
containerCgroup, daemonCgroup := testRunWithCgroupNs(t, "private", container.WithCgroupnsMode("private"))
assert.Assert(t, daemonCgroup != containerCgroup)
}
func TestCgroupNamespacesRunPrivilegedAndPrivate(t *testing.T) {
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
skip.If(t, testEnv.IsRemoteDaemon())
skip.If(t, !requirement.CgroupNamespacesEnabled())
containerCgroup, daemonCgroup := testRunWithCgroupNs(t, "private", container.WithPrivileged(true), container.WithCgroupnsMode("private"))
assert.Assert(t, daemonCgroup != containerCgroup)
}
func TestCgroupNamespacesRunInvalidMode(t *testing.T) {
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
skip.If(t, testEnv.IsRemoteDaemon())
skip.If(t, !requirement.CgroupNamespacesEnabled())
// An invalid cgroup namespace mode should return an error on container creation
errStr := "invalid cgroup namespace mode: invalid"
testCreateFailureWithCgroupNs(t, "private", errStr, container.WithCgroupnsMode("invalid"))
}
// Clients before 1.40 expect containers to be created in the host cgroup namespace,
// regardless of the default setting of the daemon, unless running with cgroup v2
func TestCgroupNamespacesRunOlderClient(t *testing.T) {
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
skip.If(t, testEnv.IsRemoteDaemon())
skip.If(t, !requirement.CgroupNamespacesEnabled())
d := daemon.New(t, daemon.WithDefaultCgroupNamespaceMode("private"))
client := d.NewClientT(t, client.WithVersion("1.39"))
ctx := context.Background()
d.StartWithBusybox(t)
defer d.Stop(t)
cID := container.Run(ctx, t, client)
poll.WaitOn(t, container.IsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond))
daemonCgroup := d.CgroupNamespace(t)
containerCgroup := container.GetContainerNS(ctx, t, client, cID, "cgroup")
if testEnv.DaemonInfo.CgroupVersion != "2" {
assert.Assert(t, daemonCgroup == containerCgroup)
} else {
assert.Assert(t, daemonCgroup != containerCgroup)
}
}