func doTestWriteAndReadToLocalSsd(f *framework.Framework) { var pod = testPodWithSsd("echo 'hello world' > /mnt/disks/ssd0/data && sleep 1 && cat /mnt/disks/ssd0/data") var msg string var out = []string{"hello world"} f.TestContainerOutput(msg, pod, 0, out) }
func doTest0644FSGroup(f *framework.Framework, image string, medium api.StorageMedium) { var ( volumePath = "/test-volume" filePath = path.Join(volumePath, "test-file") source = &api.EmptyDirVolumeSource{Medium: medium} pod = testPodWithVolume(image, volumePath, source) ) pod.Spec.Containers[0].Args = []string{ fmt.Sprintf("--fs_type=%v", volumePath), fmt.Sprintf("--new_file_0644=%v", filePath), fmt.Sprintf("--file_perm=%v", filePath), } fsGroup := int64(123) pod.Spec.SecurityContext.FSGroup = &fsGroup msg := fmt.Sprintf("emptydir 0644 on %v", formatMedium(medium)) out := []string{ "perms of file \"/test-volume/test-file\": -rw-r--r--", "content of file \"/test-volume/test-file\": mount-tester new file", } if medium == api.StorageMediumMemory { out = append(out, "mount type of \"/test-volume\": tmpfs") } f.TestContainerOutput(msg, pod, 0, out) }
func doTestVolumeMode(f *framework.Framework, image string, medium api.StorageMedium) { var ( volumePath = "/test-volume" source = &api.EmptyDirVolumeSource{Medium: medium} pod = testPodWithVolume(testImageRootUid, volumePath, source) ) pod.Spec.Containers[0].Args = []string{ fmt.Sprintf("--fs_type=%v", volumePath), fmt.Sprintf("--file_perm=%v", volumePath), } msg := fmt.Sprintf("emptydir volume type on %v", formatMedium(medium)) out := []string{ "perms of file \"/test-volume\": -rwxrwxrwx", } if medium == api.StorageMediumMemory { out = append(out, "mount type of \"/test-volume\": tmpfs") } f.TestContainerOutput(msg, pod, 0, out) }
func doTest0777(f *framework.Framework, image string, medium v1.StorageMedium) { var ( volumePath = "/test-volume" filePath = path.Join(volumePath, "test-file") source = &v1.EmptyDirVolumeSource{Medium: medium} pod = testPodWithVolume(image, volumePath, source) ) pod.Spec.Containers[0].Args = []string{ fmt.Sprintf("--fs_type=%v", volumePath), fmt.Sprintf("--new_file_0777=%v", filePath), fmt.Sprintf("--file_perm=%v", filePath), } msg := fmt.Sprintf("emptydir 0777 on %v", formatMedium(medium)) out := []string{ "perms of file \"/test-volume/test-file\": -rwxrwxrwx", "content of file \"/test-volume/test-file\": mount-tester new file", } if medium == v1.StorageMediumMemory { out = append(out, "mount type of \"/test-volume\": tmpfs") } f.TestContainerOutput(msg, pod, 0, out) }
func testPodSELinuxLabeling(f *framework.Framework, hostIPC bool, hostPID bool) { // Write and read a file with an empty_dir volume // with a pod with the MCS label s0:c0,c1 pod := scTestPod(hostIPC, hostPID) volumeName := "test-volume" mountPath := "/mounted_volume" pod.Spec.Containers[0].VolumeMounts = []api.VolumeMount{ { Name: volumeName, MountPath: mountPath, }, } pod.Spec.Volumes = []api.Volume{ { Name: volumeName, VolumeSource: api.VolumeSource{ EmptyDir: &api.EmptyDirVolumeSource{ Medium: api.StorageMediumDefault, }, }, }, } pod.Spec.SecurityContext.SELinuxOptions = &api.SELinuxOptions{ Level: "s0:c0,c1", } pod.Spec.Containers[0].Command = []string{"sleep", "6000"} client := f.ClientSet.Core().Pods(f.Namespace.Name) pod, err := client.Create(pod) framework.ExpectNoError(err, "Error creating pod %v", pod) framework.ExpectNoError(framework.WaitForPodRunningInNamespace(f.ClientSet, pod)) testContent := "hello" testFilePath := mountPath + "/TEST" err = f.WriteFileViaContainer(pod.Name, pod.Spec.Containers[0].Name, testFilePath, testContent) Expect(err).To(BeNil()) content, err := f.ReadFileViaContainer(pod.Name, pod.Spec.Containers[0].Name, testFilePath) Expect(err).To(BeNil()) Expect(content).To(ContainSubstring(testContent)) foundPod, err := f.ClientSet.Core().Pods(f.Namespace.Name).Get(pod.Name) Expect(err).NotTo(HaveOccurred()) // Confirm that the file can be accessed from a second // pod using host_path with the same MCS label volumeHostPath := fmt.Sprintf("%s/pods/%s/volumes/kubernetes.io~empty-dir/%s", framework.TestContext.KubeVolumeDir, foundPod.UID, volumeName) By(fmt.Sprintf("confirming a container with the same label can read the file under --volume-dir=%s", framework.TestContext.KubeVolumeDir)) pod = scTestPod(hostIPC, hostPID) pod.Spec.NodeName = foundPod.Spec.NodeName volumeMounts := []api.VolumeMount{ { Name: volumeName, MountPath: mountPath, }, } volumes := []api.Volume{ { Name: volumeName, VolumeSource: api.VolumeSource{ HostPath: &api.HostPathVolumeSource{ Path: volumeHostPath, }, }, }, } pod.Spec.Containers[0].VolumeMounts = volumeMounts pod.Spec.Volumes = volumes pod.Spec.Containers[0].Command = []string{"cat", testFilePath} pod.Spec.SecurityContext.SELinuxOptions = &api.SELinuxOptions{ Level: "s0:c0,c1", } f.TestContainerOutput("Pod with same MCS label reading test file", pod, 0, []string{testContent}) // Confirm that the same pod with a different MCS // label cannot access the volume pod = scTestPod(hostIPC, hostPID) pod.Spec.Volumes = volumes pod.Spec.Containers[0].VolumeMounts = volumeMounts pod.Spec.Containers[0].Command = []string{"sleep", "6000"} pod.Spec.SecurityContext.SELinuxOptions = &api.SELinuxOptions{ Level: "s0:c2,c3", } _, err = client.Create(pod) framework.ExpectNoError(err, "Error creating pod %v", pod) err = f.WaitForPodRunning(pod.Name) framework.ExpectNoError(err, "Error waiting for pod to run %v", pod) content, err = f.ReadFileViaContainer(pod.Name, "test-container", testFilePath) Expect(content).NotTo(ContainSubstring(testContent)) }
func doConfigMapE2EWithMappings(f *framework.Framework, uid, fsGroup int64, itemMode *int32) { var ( name = "configmap-test-volume-map-" + string(uuid.NewUUID()) volumeName = "configmap-volume" volumeMountPath = "/etc/configmap-volume" configMap = newConfigMap(f, name) ) By(fmt.Sprintf("Creating configMap with name %s", configMap.Name)) defer func() { By("Cleaning up the configMap") if err := f.Client.ConfigMaps(f.Namespace.Name).Delete(configMap.Name); err != nil { framework.Failf("unable to delete configMap %v: %v", configMap.Name, err) } }() var err error if configMap, err = f.Client.ConfigMaps(f.Namespace.Name).Create(configMap); err != nil { framework.Failf("unable to create test configMap %s: %v", configMap.Name, err) } pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod-configmaps-" + string(uuid.NewUUID()), }, Spec: api.PodSpec{ SecurityContext: &api.PodSecurityContext{}, Volumes: []api.Volume{ { Name: volumeName, VolumeSource: api.VolumeSource{ ConfigMap: &api.ConfigMapVolumeSource{ LocalObjectReference: api.LocalObjectReference{ Name: name, }, Items: []api.KeyToPath{ { Key: "data-2", Path: "path/to/data-2", }, }, }, }, }, }, Containers: []api.Container{ { Name: "configmap-volume-test", Image: "gcr.io/google_containers/mounttest:0.7", Args: []string{"--file_content=/etc/configmap-volume/path/to/data-2", "--file_mode=/etc/configmap-volume/path/to/data-2"}, VolumeMounts: []api.VolumeMount{ { Name: volumeName, MountPath: volumeMountPath, ReadOnly: true, }, }, }, }, RestartPolicy: api.RestartPolicyNever, }, } if uid != 0 { pod.Spec.SecurityContext.RunAsUser = &uid } if fsGroup != 0 { pod.Spec.SecurityContext.FSGroup = &fsGroup } if itemMode != nil { pod.Spec.Volumes[0].VolumeSource.ConfigMap.Items[0].Mode = itemMode } else { mode := int32(0644) itemMode = &mode } // Just check file mode if fsGroup is not set. If fsGroup is set, the // final mode is adjusted and we are not testing that case. output := []string{ "content of file \"/etc/configmap-volume/path/to/data-2\": value-2", } if fsGroup == 0 { modeString := fmt.Sprintf("%v", os.FileMode(*itemMode)) output = append(output, "mode of file \"/etc/configmap-volume/path/to/data-2\": "+modeString) } f.TestContainerOutput("consume configMaps", pod, 0, output) }
func doSecretE2EWithMapping(f *framework.Framework, mode *int32) { var ( name = "secret-test-map-" + string(uuid.NewUUID()) volumeName = "secret-volume" volumeMountPath = "/etc/secret-volume" secret = secretForTest(f.Namespace.Name, name) ) By(fmt.Sprintf("Creating secret with name %s", secret.Name)) var err error if secret, err = f.ClientSet.Core().Secrets(f.Namespace.Name).Create(secret); err != nil { framework.Failf("unable to create test secret %s: %v", secret.Name, err) } pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod-secrets-" + string(uuid.NewUUID()), }, Spec: api.PodSpec{ Volumes: []api.Volume{ { Name: volumeName, VolumeSource: api.VolumeSource{ Secret: &api.SecretVolumeSource{ SecretName: name, Items: []api.KeyToPath{ { Key: "data-1", Path: "new-path-data-1", }, }, }, }, }, }, Containers: []api.Container{ { Name: "secret-volume-test", Image: "gcr.io/google_containers/mounttest:0.7", Args: []string{ "--file_content=/etc/secret-volume/new-path-data-1", "--file_mode=/etc/secret-volume/new-path-data-1"}, VolumeMounts: []api.VolumeMount{ { Name: volumeName, MountPath: volumeMountPath, }, }, }, }, RestartPolicy: api.RestartPolicyNever, }, } if mode != nil { pod.Spec.Volumes[0].VolumeSource.Secret.Items[0].Mode = mode } else { defaultItemMode := int32(0644) mode = &defaultItemMode } modeString := fmt.Sprintf("%v", os.FileMode(*mode)) expectedOutput := []string{ "content of file \"/etc/secret-volume/new-path-data-1\": value-1", "mode of file \"/etc/secret-volume/new-path-data-1\": " + modeString, } f.TestContainerOutput("consume secrets", pod, 0, expectedOutput) }
func doSecretE2E(f *framework.Framework, defaultMode *int32) { var ( name = "secret-test-" + string(uuid.NewUUID()) volumeName = "secret-volume" volumeMountPath = "/etc/secret-volume" secret = secretForTest(f.Namespace.Name, name) ) By(fmt.Sprintf("Creating secret with name %s", secret.Name)) defer func() { By("Cleaning up the secret") if err := f.Client.Secrets(f.Namespace.Name).Delete(secret.Name); err != nil { framework.Failf("unable to delete secret %v: %v", secret.Name, err) } }() var err error if secret, err = f.Client.Secrets(f.Namespace.Name).Create(secret); err != nil { framework.Failf("unable to create test secret %s: %v", secret.Name, err) } pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod-secrets-" + string(uuid.NewUUID()), }, Spec: api.PodSpec{ Volumes: []api.Volume{ { Name: volumeName, VolumeSource: api.VolumeSource{ Secret: &api.SecretVolumeSource{ SecretName: name, }, }, }, }, Containers: []api.Container{ { Name: "secret-volume-test", Image: "gcr.io/google_containers/mounttest:0.7", Args: []string{ "--file_content=/etc/secret-volume/data-1", "--file_mode=/etc/secret-volume/data-1"}, VolumeMounts: []api.VolumeMount{ { Name: volumeName, MountPath: volumeMountPath, }, }, }, }, RestartPolicy: api.RestartPolicyNever, }, } if defaultMode != nil { pod.Spec.Volumes[0].VolumeSource.Secret.DefaultMode = defaultMode } else { mode := int32(0644) defaultMode = &mode } modeString := fmt.Sprintf("%v", os.FileMode(*defaultMode)) expectedOutput := []string{ "content of file \"/etc/secret-volume/data-1\": value-1", "mode of file \"/etc/secret-volume/data-1\": " + modeString, } f.TestContainerOutput("consume secrets", pod, 0, expectedOutput) }
func doConfigMapE2EWithoutMappings(f *framework.Framework, uid, fsGroup int64, defaultMode *int32) { var ( name = "configmap-test-volume-" + string(uuid.NewUUID()) volumeName = "configmap-volume" volumeMountPath = "/etc/configmap-volume" configMap = newConfigMap(f, name) ) By(fmt.Sprintf("Creating configMap with name %s", configMap.Name)) var err error if configMap, err = f.ClientSet.Core().ConfigMaps(f.Namespace.Name).Create(configMap); err != nil { framework.Failf("unable to create test configMap %s: %v", configMap.Name, err) } pod := &v1.Pod{ ObjectMeta: v1.ObjectMeta{ Name: "pod-configmaps-" + string(uuid.NewUUID()), }, Spec: v1.PodSpec{ SecurityContext: &v1.PodSecurityContext{}, Volumes: []v1.Volume{ { Name: volumeName, VolumeSource: v1.VolumeSource{ ConfigMap: &v1.ConfigMapVolumeSource{ LocalObjectReference: v1.LocalObjectReference{ Name: name, }, }, }, }, }, Containers: []v1.Container{ { Name: "configmap-volume-test", Image: "gcr.io/google_containers/mounttest:0.7", Args: []string{ "--file_content=/etc/configmap-volume/data-1", "--file_mode=/etc/configmap-volume/data-1"}, VolumeMounts: []v1.VolumeMount{ { Name: volumeName, MountPath: volumeMountPath, }, }, }, }, RestartPolicy: v1.RestartPolicyNever, }, } if uid != 0 { pod.Spec.SecurityContext.RunAsUser = &uid } if fsGroup != 0 { pod.Spec.SecurityContext.FSGroup = &fsGroup } if defaultMode != nil { pod.Spec.Volumes[0].VolumeSource.ConfigMap.DefaultMode = defaultMode } else { mode := int32(0644) defaultMode = &mode } // Just check file mode if fsGroup is not set. If fsGroup is set, the // final mode is adjusted and we are not testing that case. output := []string{ "content of file \"/etc/configmap-volume/data-1\": value-1", } if fsGroup == 0 { modeString := fmt.Sprintf("%v", os.FileMode(*defaultMode)) output = append(output, "mode of file \"/etc/configmap-volume/data-1\": "+modeString) } f.TestContainerOutput("consume configMaps", pod, 0, output) }
func doConfigMapE2EWithoutMappings(f *framework.Framework, uid, fsGroup int64, defaultMode *int32) { var ( name = "configmap-test-volume-" + string(uuid.NewUUID()) volumeName = "configmap-volume" volumeMountPath = "/etc/configmap-volume" configMap = newConfigMap(f, name) ) By(fmt.Sprintf("Creating configMap with name %s", configMap.Name)) defer func() { By("Cleaning up the configMap") if err := f.Client.ConfigMaps(f.Namespace.Name).Delete(configMap.Name); err != nil { framework.Failf("unable to delete configMap %v: %v", configMap.Name, err) } }() var err error if configMap, err = f.Client.ConfigMaps(f.Namespace.Name).Create(configMap); err != nil { framework.Failf("unable to create test configMap %s: %v", configMap.Name, err) } pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod-configmaps-" + string(uuid.NewUUID()), }, Spec: api.PodSpec{ SecurityContext: &api.PodSecurityContext{}, Volumes: []api.Volume{ { Name: volumeName, VolumeSource: api.VolumeSource{ ConfigMap: &api.ConfigMapVolumeSource{ LocalObjectReference: api.LocalObjectReference{ Name: name, }, }, }, }, }, Containers: []api.Container{ { Name: "configmap-volume-test", Image: "gcr.io/google_containers/mounttest:0.7", Args: []string{ "--file_content=/etc/configmap-volume/data-1", "--file_mode=/etc/configmap-volume/data-1"}, VolumeMounts: []api.VolumeMount{ { Name: volumeName, MountPath: volumeMountPath, }, }, }, }, RestartPolicy: api.RestartPolicyNever, }, } if uid != 0 { pod.Spec.SecurityContext.RunAsUser = &uid } if fsGroup != 0 { pod.Spec.SecurityContext.FSGroup = &fsGroup } if defaultMode != nil { pod.Spec.Volumes[0].VolumeSource.ConfigMap.DefaultMode = defaultMode } else { mode := int32(0644) defaultMode = &mode } modeString := fmt.Sprintf("%v", os.FileMode(*defaultMode)) output := []string{ "content of file \"/etc/configmap-volume/data-1\": value-1", "mode of file \"/etc/configmap-volume/data-1\": " + modeString, } f.TestContainerOutput("consume configMaps", pod, 0, output) }
func doConfigMapE2EWithMappings(f *framework.Framework, uid, fsGroup int64) { var ( name = "configmap-test-volume-map-" + string(uuid.NewUUID()) volumeName = "configmap-volume" volumeMountPath = "/etc/configmap-volume" configMap = newConfigMap(f, name) ) By(fmt.Sprintf("Creating configMap with name %s", configMap.Name)) defer func() { By("Cleaning up the configMap") if err := f.Client.ConfigMaps(f.Namespace.Name).Delete(configMap.Name); err != nil { framework.Failf("unable to delete configMap %v: %v", configMap.Name, err) } }() var err error if configMap, err = f.Client.ConfigMaps(f.Namespace.Name).Create(configMap); err != nil { framework.Failf("unable to create test configMap %s: %v", configMap.Name, err) } pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod-configmaps-" + string(uuid.NewUUID()), }, Spec: api.PodSpec{ SecurityContext: &api.PodSecurityContext{}, Volumes: []api.Volume{ { Name: volumeName, VolumeSource: api.VolumeSource{ ConfigMap: &api.ConfigMapVolumeSource{ LocalObjectReference: api.LocalObjectReference{ Name: name, }, Items: []api.KeyToPath{ { Key: "data-2", Path: "path/to/data-2", }, }, }, }, }, }, Containers: []api.Container{ { Name: "configmap-volume-test", Image: "gcr.io/google_containers/mounttest:0.6", Args: []string{"--file_content=/etc/configmap-volume/path/to/data-2"}, VolumeMounts: []api.VolumeMount{ { Name: volumeName, MountPath: volumeMountPath, ReadOnly: true, }, }, }, }, RestartPolicy: api.RestartPolicyNever, }, } if uid != 0 { pod.Spec.SecurityContext.RunAsUser = &uid } if fsGroup != 0 { pod.Spec.SecurityContext.FSGroup = &fsGroup } f.TestContainerOutput("consume configMaps", pod, 0, []string{ "content of file \"/etc/configmap-volume/path/to/data-2\": value-2", }) }
func doSecretE2EWithoutMapping(f *framework.Framework, defaultMode *int32, secretName string, fsGroup *int64, uid *int64) { var ( volumeName = "secret-volume" volumeMountPath = "/etc/secret-volume" secret = secretForTest(f.Namespace.Name, secretName) ) By(fmt.Sprintf("Creating secret with name %s", secret.Name)) var err error if secret, err = f.ClientSet.Core().Secrets(f.Namespace.Name).Create(secret); err != nil { framework.Failf("unable to create test secret %s: %v", secret.Name, err) } pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod-secrets-" + string(uuid.NewUUID()), Namespace: f.Namespace.Name, }, Spec: api.PodSpec{ Volumes: []api.Volume{ { Name: volumeName, VolumeSource: api.VolumeSource{ Secret: &api.SecretVolumeSource{ SecretName: secretName, }, }, }, }, Containers: []api.Container{ { Name: "secret-volume-test", Image: "gcr.io/google_containers/mounttest:0.7", Args: []string{ "--file_content=/etc/secret-volume/data-1", "--file_mode=/etc/secret-volume/data-1"}, VolumeMounts: []api.VolumeMount{ { Name: volumeName, MountPath: volumeMountPath, }, }, }, }, RestartPolicy: api.RestartPolicyNever, }, } if defaultMode != nil { pod.Spec.Volumes[0].VolumeSource.Secret.DefaultMode = defaultMode } else { mode := int32(0644) defaultMode = &mode } if fsGroup != nil || uid != nil { pod.Spec.SecurityContext = &api.PodSecurityContext{ FSGroup: fsGroup, RunAsUser: uid, } } modeString := fmt.Sprintf("%v", os.FileMode(*defaultMode)) expectedOutput := []string{ "content of file \"/etc/secret-volume/data-1\": value-1", "mode of file \"/etc/secret-volume/data-1\": " + modeString, } f.TestContainerOutput("consume secrets", pod, 0, expectedOutput) }