diff --git a/integration/addition_gids_test.go b/integration/addition_gids_test.go new file mode 100644 index 000000000..d608a74b3 --- /dev/null +++ b/integration/addition_gids_test.go @@ -0,0 +1,87 @@ +/* +Copyright 2018 The containerd Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package integration + +import ( + "io/ioutil" + "os" + "path/filepath" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" +) + +func TestAdditionalGids(t *testing.T) { + testPodLogDir, err := ioutil.TempDir("/tmp", "additional-gids") + require.NoError(t, err) + defer os.RemoveAll(testPodLogDir) + + t.Log("Create a sandbox with log directory") + sbConfig := PodSandboxConfig("sandbox", "additional-gids", + WithPodLogDirectory(testPodLogDir)) + sb, err := runtimeService.RunPodSandbox(sbConfig) + require.NoError(t, err) + defer func() { + assert.NoError(t, runtimeService.StopPodSandbox(sb)) + assert.NoError(t, runtimeService.RemovePodSandbox(sb)) + }() + + const ( + testImage = "busybox" + containerName = "test-container" + ) + t.Logf("Pull test image %q", testImage) + img, err := imageService.PullImage(&runtime.ImageSpec{Image: testImage}, nil) + require.NoError(t, err) + defer func() { + assert.NoError(t, imageService.RemoveImage(&runtime.ImageSpec{Image: img})) + }() + + t.Log("Create a container to print id") + cnConfig := ContainerConfig( + containerName, + "busybox", + WithCommand("id"), + WithLogPath(containerName), + WithSupplementalGroups([]int64{1 /*daemon*/, 1234 /*new group*/}), + ) + cn, err := runtimeService.CreateContainer(sb, cnConfig, sbConfig) + require.NoError(t, err) + + t.Log("Start the container") + require.NoError(t, runtimeService.StartContainer(cn)) + + t.Log("Wait for container to finish running") + require.NoError(t, Eventually(func() (bool, error) { + s, err := runtimeService.ContainerStatus(cn) + if err != nil { + return false, err + } + if s.GetState() == runtime.ContainerState_CONTAINER_EXITED { + return true, nil + } + return false, nil + }, time.Second, 30*time.Second)) + + t.Log("Search additional groups in container log") + content, err := ioutil.ReadFile(filepath.Join(testPodLogDir, containerName)) + assert.NoError(t, err) + assert.Contains(t, string(content), "groups=1(daemon),10(wheel),1234") +} diff --git a/integration/test_utils.go b/integration/test_utils.go index c9c31f14d..37e5cb610 100644 --- a/integration/test_utils.go +++ b/integration/test_utils.go @@ -202,6 +202,19 @@ func WithLogPath(path string) ContainerOpts { } } +// WithSupplementalGroups adds supplemental groups. +func WithSupplementalGroups(gids []int64) ContainerOpts { + return func(c *runtime.ContainerConfig) { + if c.Linux == nil { + c.Linux = &runtime.LinuxContainerConfig{} + } + if c.Linux.SecurityContext == nil { + c.Linux.SecurityContext = &runtime.LinuxContainerSecurityContext{} + } + c.Linux.SecurityContext.SupplementalGroups = gids + } +} + // ContainerConfig creates a container config given a name and image name // and additional container config options func ContainerConfig(name, image string, opts ...ContainerOpts) *runtime.ContainerConfig {