@@ -1024,6 +1024,66 @@ var _ = framework.KubeDescribe("Security Context", func() {
10241024
10251025 matchContainerOutputRe (podConfig , containerName , `\s+0\s+1000\s+100000\n` )
10261026 })
1027+
1028+ It ("runtime should support image volumes with user namespaces" , func () {
1029+ By ("pull test image for image volume" )
1030+ testImage := framework .TestContext .TestImageList .DefaultTestContainerImage
1031+ framework .PullPublicImage (ic , testImage , nil )
1032+
1033+ By ("create pod sandbox with user namespace" )
1034+ namespaceOption := & runtimeapi.NamespaceOption {
1035+ UsernsOptions : & runtimeapi.UserNamespace {
1036+ Mode : runtimeapi .NamespaceMode_POD ,
1037+ Uids : defaultMapping ,
1038+ Gids : defaultMapping ,
1039+ },
1040+ }
1041+
1042+ hostLogPath , podLogPath := createLogTempDir (podName )
1043+ defer os .RemoveAll (hostLogPath )
1044+ podID , podConfig = createNamespacePodSandbox (rc , namespaceOption , podName , podLogPath )
1045+
1046+ By ("create container with image volume mount" )
1047+ containerName := "image-volume-userns-container-" + framework .NewUUID ()
1048+ containerConfig := & runtimeapi.ContainerConfig {
1049+ Metadata : framework .BuildContainerMetadata (containerName , framework .DefaultAttempt ),
1050+ Image : & runtimeapi.ImageSpec {
1051+ Image : testImage ,
1052+ UserSpecifiedImage : testImage ,
1053+ },
1054+ Command : []string {"sh" , "-c" , "ls -ln /image-volume && stat -c '%u:%g' /image-volume" },
1055+ LogPath : containerName + ".log" ,
1056+ Mounts : []* runtimeapi.Mount {
1057+ {
1058+ ContainerPath : "/image-volume" ,
1059+ Readonly : true ,
1060+ Image : & runtimeapi.ImageSpec {
1061+ Image : testImage ,
1062+ },
1063+ },
1064+ },
1065+ Linux : & runtimeapi.LinuxContainerConfig {
1066+ SecurityContext : & runtimeapi.LinuxContainerSecurityContext {
1067+ NamespaceOptions : podConfig .GetLinux ().GetSecurityContext ().GetNamespaceOptions (),
1068+ },
1069+ },
1070+ }
1071+
1072+ containerID := createContainerWithExpectation (rc , ic , containerConfig , podID , podConfig , true )
1073+
1074+ By ("start container" )
1075+ startContainer (rc , containerID )
1076+
1077+ By ("wait for container to complete" )
1078+ Eventually (func () runtimeapi.ContainerState {
1079+ return getContainerStatus (rc , containerID ).GetState ()
1080+ }, time .Minute , time .Second * 4 ).Should (Equal (runtimeapi .ContainerState_CONTAINER_EXITED ))
1081+
1082+ By ("verify image volume is accessible with correct ownership" )
1083+ // The files in the image volume should be accessible inside the container
1084+ // with ownership mapped through idmap mounts
1085+ verifyLogContents (podConfig , containerName + ".log" , "0:0" , stdoutType )
1086+ })
10271087 })
10281088
10291089 When ("Host idmap mount support is not needed" , func () {
0 commit comments