Mount cgroup into the container and add unit test for privileged mount.

Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
Lantao Liu 2017-06-11 02:08:49 +00:00
parent e9a930b28b
commit ffa4ffe3bf
2 changed files with 67 additions and 15 deletions

View File

@ -417,6 +417,8 @@ func addOCIDevices(g *generate.Generator, devs []*runtime.Device, privileged boo
// addOCIBindMounts adds bind mounts. // addOCIBindMounts adds bind mounts.
func addOCIBindMounts(g *generate.Generator, mounts []*runtime.Mount, privileged bool) { func addOCIBindMounts(g *generate.Generator, mounts []*runtime.Mount, privileged bool) {
// Mount cgroup into the container as readonly, which inherits docker's behavior.
g.AddCgroupsMount("ro") // nolint: errcheck
for _, mount := range mounts { for _, mount := range mounts {
dst := mount.GetContainerPath() dst := mount.GetContainerPath()
src := mount.GetHostPath() src := mount.GetHostPath()

View File

@ -40,6 +40,25 @@ import (
servertesting "github.com/kubernetes-incubator/cri-containerd/pkg/server/testing" servertesting "github.com/kubernetes-incubator/cri-containerd/pkg/server/testing"
) )
func checkMount(t *testing.T, mounts []runtimespec.Mount, src, dest, typ string,
contains, notcontains []string) {
found := false
for _, m := range mounts {
if m.Source == src && m.Destination == dest {
assert.Equal(t, m.Type, typ)
for _, c := range contains {
assert.Contains(t, m.Options, c)
}
for _, n := range notcontains {
assert.NotContains(t, m.Options, n)
}
found = true
break
}
}
assert.True(t, found, "mount from %q to %q not found", src, dest)
}
func getStartContainerTestData() (*runtime.ContainerConfig, *runtime.PodSandboxConfig, func getStartContainerTestData() (*runtime.ContainerConfig, *runtime.PodSandboxConfig,
*imagespec.ImageConfig, func(*testing.T, string, uint32, *runtimespec.Spec)) { *imagespec.ImageConfig, func(*testing.T, string, uint32, *runtimespec.Spec)) {
config := &runtime.ContainerConfig{ config := &runtime.ContainerConfig{
@ -107,22 +126,12 @@ func getStartContainerTestData() (*runtime.ContainerConfig, *runtime.PodSandboxC
assert.Equal(t, "test-cwd", spec.Process.Cwd) assert.Equal(t, "test-cwd", spec.Process.Cwd)
assert.Contains(t, spec.Process.Env, "k1=v1", "k2=v2", "ik1=iv1", "ik2=iv2") assert.Contains(t, spec.Process.Env, "k1=v1", "k2=v2", "ik1=iv1", "ik2=iv2")
t.Logf("Check cgroups bind mount")
checkMount(t, spec.Mounts, "cgroup", "/sys/fs/cgroup", "cgroup", []string{"ro"}, nil)
t.Logf("Check bind mount") t.Logf("Check bind mount")
found1, found2 := false, false checkMount(t, spec.Mounts, "host-path-1", "container-path-1", "bind", []string{"rw"}, nil)
for _, m := range spec.Mounts { checkMount(t, spec.Mounts, "host-path-2", "container-path-2", "bind", []string{"ro"}, nil)
if m.Source == "host-path-1" {
assert.Equal(t, m.Destination, "container-path-1")
assert.Contains(t, m.Options, "rw")
found1 = true
}
if m.Source == "host-path-2" {
assert.Equal(t, m.Destination, "container-path-2")
assert.Contains(t, m.Options, "ro")
found2 = true
}
}
assert.True(t, found1)
assert.True(t, found2)
t.Logf("Check resource limits") t.Logf("Check resource limits")
assert.EqualValues(t, *spec.Linux.Resources.CPU.Period, 100) assert.EqualValues(t, *spec.Linux.Resources.CPU.Period, 100)
@ -357,6 +366,47 @@ func TestGenerateContainerMounts(t *testing.T) {
} }
} }
func TestPrivilegedBindMount(t *testing.T) {
for desc, test := range map[string]struct {
privileged bool
readonlyRootFS bool
expectedSysFSRO bool
expectedCgroupFSRO bool
}{
"sysfs and cgroupfs should mount as 'ro' by default": {
expectedSysFSRO: true,
expectedCgroupFSRO: true,
},
"sysfs and cgroupfs should not mount as 'ro' if privileged": {
privileged: true,
expectedSysFSRO: false,
expectedCgroupFSRO: false,
},
"sysfs should mount as 'ro' if root filrsystem is readonly": {
privileged: true,
readonlyRootFS: true,
expectedSysFSRO: true,
expectedCgroupFSRO: false,
},
} {
t.Logf("TestCase %q", desc)
g := generate.New()
g.SetRootReadonly(test.readonlyRootFS)
addOCIBindMounts(&g, nil, test.privileged)
spec := g.Spec()
if test.expectedSysFSRO {
checkMount(t, spec.Mounts, "sysfs", "/sys", "sysfs", []string{"ro"}, nil)
} else {
checkMount(t, spec.Mounts, "sysfs", "/sys", "sysfs", nil, []string{"ro"})
}
if test.expectedCgroupFSRO {
checkMount(t, spec.Mounts, "cgroup", "/sys/fs/cgroup", "cgroup", []string{"ro"}, nil)
} else {
checkMount(t, spec.Mounts, "cgroup", "/sys/fs/cgroup", "cgroup", nil, []string{"ro"})
}
}
}
func TestStartContainer(t *testing.T) { func TestStartContainer(t *testing.T) {
testID := "test-id" testID := "test-id"
testSandboxID := "test-sandbox-id" testSandboxID := "test-sandbox-id"