diff --git a/test/e2e_node/image_volume.go b/test/e2e_node/image_volume.go index 587902d7dd3..a2352844c93 100644 --- a/test/e2e_node/image_volume.go +++ b/test/e2e_node/image_volume.go @@ -30,6 +30,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/kubelet/images" + "k8s.io/kubernetes/pkg/kubelet/kuberuntime" "k8s.io/kubernetes/test/e2e/feature" "k8s.io/kubernetes/test/e2e/framework" e2enode "k8s.io/kubernetes/test/e2e/framework/node" @@ -89,7 +90,6 @@ var _ = SIGDescribe("ImageVolume", feature.ImageVolume, func() { ginkgo.By(fmt.Sprintf("Creating a pod (%s/%s)", f.Namespace.Name, podName)) e2epod.NewPodClient(f).Create(ctx, pod) - } verifyFileContents := func(podName, volumePath string) { @@ -100,7 +100,6 @@ var _ = SIGDescribe("ImageVolume", feature.ImageVolume, func() { secondFileContents := e2epod.ExecCommandInContainer(f, podName, containerName, "/bin/cat", filepath.Join(volumePath, "etc", "os-release")) gomega.Expect(secondFileContents).To(gomega.ContainSubstring("Alpine Linux")) - } f.It("should succeed with pod and pull policy of Always", func(ctx context.Context) { @@ -188,7 +187,7 @@ var _ = SIGDescribe("ImageVolume", feature.ImageVolume, func() { ginkgo.By(fmt.Sprintf("Waiting for the pod (%s/%s) to fail", f.Namespace.Name, podName)) err := e2epod.WaitForPodContainerToFail(ctx, f.ClientSet, f.Namespace.Name, podName, 0, images.ErrImagePullBackOff.Error(), time.Minute) - framework.ExpectNoError(err, "Failed to await for the pod to be running: (%s/%s)", f.Namespace.Name, podName) + framework.ExpectNoError(err, "Failed to await for the pod to be failed: (%s/%s)", f.Namespace.Name, podName) }) f.It("should succeed if image volume is not existing but unused", func(ctx context.Context) { @@ -274,4 +273,72 @@ var _ = SIGDescribe("ImageVolume", feature.ImageVolume, func() { verifyFileContents(podName, volumePathPrefix) }) + + f.Context("subPath", func() { + ginkgo.BeforeEach(func(ctx context.Context) { + runtime, _, err := getCRIClient() + framework.ExpectNoError(err, "Failed to get CRI client") + + version, err := runtime.Version(context.Background(), "") + framework.ExpectNoError(err, "Failed to get runtime version") + + // TODO: enable the subpath tests if containerd main branch has support for it. + if version.GetRuntimeName() != "cri-o" { + e2eskipper.Skip("runtime is not CRI-O") + } + }) + + f.It("should succeed when using a valid subPath", func(ctx context.Context) { + var selinuxOptions *v1.SELinuxOptions + if selinux.GetEnabled() { + selinuxOptions = &v1.SELinuxOptions{ + User: defaultSELinuxUser, + Role: defaultSELinuxRole, + Type: defaultSELinuxType, + Level: defaultSELinuxLevel, + } + ginkgo.By(fmt.Sprintf("Using SELinux on pod: %v", selinuxOptions)) + } + + createPod(ctx, + podName, + "", + []v1.Volume{{Name: volumeName, VolumeSource: v1.VolumeSource{Image: &v1.ImageVolumeSource{Reference: volumeImage}}}}, + []v1.VolumeMount{{Name: volumeName, MountPath: volumePathPrefix, SubPath: "etc"}}, + selinuxOptions, + ) + + ginkgo.By(fmt.Sprintf("Waiting for the pod (%s/%s) to be running", f.Namespace.Name, podName)) + err := e2epod.WaitForPodNameRunningInNamespace(ctx, f.ClientSet, podName, f.Namespace.Name) + framework.ExpectNoError(err, "Failed to await for the pod to be running: (%s/%s)", f.Namespace.Name, podName) + + fileContent := e2epod.ExecCommandInContainer(f, podName, containerName, "/bin/cat", filepath.Join(volumePathPrefix, "os-release")) + gomega.Expect(fileContent).To(gomega.ContainSubstring("Alpine Linux")) + }) + + f.It("should fail if subPath in volume is not existing", func(ctx context.Context) { + var selinuxOptions *v1.SELinuxOptions + if selinux.GetEnabled() { + selinuxOptions = &v1.SELinuxOptions{ + User: defaultSELinuxUser, + Role: defaultSELinuxRole, + Type: defaultSELinuxType, + Level: defaultSELinuxLevel, + } + ginkgo.By(fmt.Sprintf("Using SELinux on pod: %v", selinuxOptions)) + } + + createPod(ctx, + podName, + "", + []v1.Volume{{Name: volumeName, VolumeSource: v1.VolumeSource{Image: &v1.ImageVolumeSource{Reference: volumeImage}}}}, + []v1.VolumeMount{{Name: volumeName, MountPath: volumePathPrefix, SubPath: "not-existing"}}, + selinuxOptions, + ) + + ginkgo.By(fmt.Sprintf("Waiting for the pod (%s/%s) to fail", f.Namespace.Name, podName)) + err := e2epod.WaitForPodContainerToFail(ctx, f.ClientSet, f.Namespace.Name, podName, 0, kuberuntime.ErrCreateContainer.Error(), time.Minute) + framework.ExpectNoError(err, "Failed to await for the pod to be failed: (%s/%s)", f.Namespace.Name, podName) + }) + }) })