diff --git a/pkg/cri/server/container_create_linux_test.go b/pkg/cri/server/container_create_linux_test.go index 79f9a6e94..cb07d8c60 100644 --- a/pkg/cri/server/container_create_linux_test.go +++ b/pkg/cri/server/container_create_linux_test.go @@ -2311,3 +2311,141 @@ containerEdits: }) } } + +// TestLinuxVolumeMounts tests the linux-specific parts of VolumeMounts. +func TestLinuxVolumeMounts(t *testing.T) { + testContainerRootDir := "test-container-root" + idmap := []*runtime.IDMapping{ + { + ContainerId: 0, + HostId: 100, + Length: 1, + }, + } + + for _, test := range []struct { + desc string + criMounts []*runtime.Mount + imageVolumes map[string]struct{} + usernsEnabled bool + expectedMountDest []string + expectedMappings []*runtime.IDMapping + }{ + { + desc: "should skip image volumes if already mounted by CRI", + usernsEnabled: true, + criMounts: []*runtime.Mount{ + { + ContainerPath: "/test-volume-1", + HostPath: "/test-hostpath-1", + }, + }, + imageVolumes: map[string]struct{}{ + "/test-volume-1": {}, + "/test-volume-2": {}, + }, + expectedMountDest: []string{ + "/test-volume-2", + }, + expectedMappings: idmap, + }, + { + desc: "should include mappings for image volumes", + usernsEnabled: true, + imageVolumes: map[string]struct{}{ + "/test-volume-1/": {}, + "/test-volume-2/": {}, + }, + expectedMountDest: []string{ + "/test-volume-2/", + "/test-volume-2/", + }, + expectedMappings: idmap, + }, + { + desc: "should convert rel imageVolume paths to abs paths", + imageVolumes: map[string]struct{}{ + "test-volume-1/": {}, + "./test-volume-2/": {}, + "../../test-volume-3/": {}, + }, + expectedMountDest: []string{ + "/test-volume-1", + "/test-volume-2", + "/test-volume-3", + }, + }, + { + desc: "should convert rel imageVolume paths to abs paths and add userns mappings", + usernsEnabled: true, + imageVolumes: map[string]struct{}{ + "test-volume-1/": {}, + "./test-volume-2/": {}, + "../../test-volume-3/": {}, + }, + expectedMountDest: []string{ + "/test-volume-1", + "/test-volume-2", + "/test-volume-3", + }, + expectedMappings: idmap, + }, + { + desc: "doesn't include mappings for image volumes if userns is disabled", + imageVolumes: map[string]struct{}{ + "/test-volume-1/": {}, + "/test-volume-2/": {}, + }, + expectedMountDest: []string{ + "/test-volume-2/", + "/test-volume-2/", + }, + }, + } { + test := test + t.Run(test.desc, func(t *testing.T) { + config := &imagespec.ImageConfig{ + Volumes: test.imageVolumes, + } + containerConfig := &runtime.ContainerConfig{ + Mounts: test.criMounts, + } + + if test.usernsEnabled { + containerConfig.Linux = &runtime.LinuxContainerConfig{ + SecurityContext: &runtime.LinuxContainerSecurityContext{ + NamespaceOptions: &runtime.NamespaceOption{ + UsernsOptions: &runtime.UserNamespace{ + Mode: runtime.NamespaceMode_POD, + Uids: idmap, + Gids: idmap, + }, + }, + }, + } + } + + c := newTestCRIService() + got := c.volumeMounts(testContainerRootDir, containerConfig, config) + assert.Len(t, got, len(test.expectedMountDest)) + for _, dest := range test.expectedMountDest { + found := false + for _, m := range got { + if m.ContainerPath != dest { + continue + } + found = true + assert.Equal(t, + filepath.Dir(m.HostPath), + filepath.Join(testContainerRootDir, "volumes")) + + if test.expectedMappings != nil { + assert.Equal(t, test.expectedMappings, m.UidMappings) + assert.Equal(t, test.expectedMappings, m.GidMappings) + } + } + assert.True(t, found) + } + }) + } +}