From 233db366ccd4221c7316d7d77ea10d8230a9f3a5 Mon Sep 17 00:00:00 2001 From: Michelle Au Date: Thu, 30 Aug 2018 12:30:23 -0700 Subject: [PATCH] Fix multizone gce pd subpath test --- test/e2e/storage/drivers/in_tree.go | 38 ++++++------ test/e2e/storage/in_tree_volumes.go | 2 +- test/e2e/storage/subpath.go | 10 ++-- test/e2e/storage/testsuites/subpath.go | 80 +++++++++++++++----------- 4 files changed, 70 insertions(+), 60 deletions(-) diff --git a/test/e2e/storage/drivers/in_tree.go b/test/e2e/storage/drivers/in_tree.go index f87a564ea56..cf28a547831 100644 --- a/test/e2e/storage/drivers/in_tree.go +++ b/test/e2e/storage/drivers/in_tree.go @@ -1046,23 +1046,23 @@ func deleteCinderVolume(name string) error { } // GCE -type gceDriver struct { +type gcePdDriver struct { volumeName string driverInfo DriverInfo } -var _ TestDriver = &gceDriver{} -var _ PreprovisionedVolumeTestDriver = &gceDriver{} -var _ InlineVolumeTestDriver = &gceDriver{} -var _ PreprovisionedPVTestDriver = &gceDriver{} -var _ DynamicPVTestDriver = &gceDriver{} +var _ TestDriver = &gcePdDriver{} +var _ PreprovisionedVolumeTestDriver = &gcePdDriver{} +var _ InlineVolumeTestDriver = &gcePdDriver{} +var _ PreprovisionedPVTestDriver = &gcePdDriver{} +var _ DynamicPVTestDriver = &gcePdDriver{} -// InitGceDriver returns gceDriver that implements TestDriver interface -func InitGceDriver() TestDriver { - return &gceDriver{ +// InitGceDriver returns gcePdDriver that implements TestDriver interface +func InitGcePdDriver() TestDriver { + return &gcePdDriver{ driverInfo: DriverInfo{ - Name: "gce", + Name: "gcepd", MaxFileSize: testpatterns.FileSizeMedium, SupportedFsType: sets.NewString( "", // Default fsType @@ -1078,18 +1078,18 @@ func InitGceDriver() TestDriver { } } -func (g *gceDriver) GetDriverInfo() *DriverInfo { +func (g *gcePdDriver) GetDriverInfo() *DriverInfo { return &g.driverInfo } -func (g *gceDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) { +func (g *gcePdDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) { framework.SkipUnlessProviderIs("gce", "gke") if pattern.FsType == "xfs" { framework.SkipUnlessNodeOSDistroIs("ubuntu", "custom") } } -func (g *gceDriver) GetVolumeSource(readOnly bool, fsType string) *v1.VolumeSource { +func (g *gcePdDriver) GetVolumeSource(readOnly bool, fsType string) *v1.VolumeSource { volSource := v1.VolumeSource{ GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{ PDName: g.volumeName, @@ -1102,7 +1102,7 @@ func (g *gceDriver) GetVolumeSource(readOnly bool, fsType string) *v1.VolumeSour return &volSource } -func (g *gceDriver) GetPersistentVolumeSource(readOnly bool, fsType string) *v1.PersistentVolumeSource { +func (g *gcePdDriver) GetPersistentVolumeSource(readOnly bool, fsType string) *v1.PersistentVolumeSource { pvSource := v1.PersistentVolumeSource{ GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{ PDName: g.volumeName, @@ -1115,7 +1115,7 @@ func (g *gceDriver) GetPersistentVolumeSource(readOnly bool, fsType string) *v1. return &pvSource } -func (g *gceDriver) GetDynamicProvisionStorageClass(fsType string) *storagev1.StorageClass { +func (g *gcePdDriver) GetDynamicProvisionStorageClass(fsType string) *storagev1.StorageClass { provisioner := "kubernetes.io/gce-pd" parameters := map[string]string{} if fsType != "" { @@ -1127,13 +1127,13 @@ func (g *gceDriver) GetDynamicProvisionStorageClass(fsType string) *storagev1.St return getStorageClass(provisioner, parameters, nil, ns, suffix) } -func (g *gceDriver) CreateDriver() { +func (g *gcePdDriver) CreateDriver() { } -func (g *gceDriver) CleanupDriver() { +func (g *gcePdDriver) CleanupDriver() { } -func (g *gceDriver) CreateVolume(volType testpatterns.TestVolType) { +func (g *gcePdDriver) CreateVolume(volType testpatterns.TestVolType) { if volType == testpatterns.InlineVolume { // PD will be created in framework.TestContext.CloudConfig.Zone zone, // so pods should be also scheduled there. @@ -1147,7 +1147,7 @@ func (g *gceDriver) CreateVolume(volType testpatterns.TestVolType) { Expect(err).NotTo(HaveOccurred()) } -func (g *gceDriver) DeleteVolume(volType testpatterns.TestVolType) { +func (g *gcePdDriver) DeleteVolume(volType testpatterns.TestVolType) { framework.DeletePDWithRetry(g.volumeName) } diff --git a/test/e2e/storage/in_tree_volumes.go b/test/e2e/storage/in_tree_volumes.go index 2e1d78cf1e1..c4d65b4b730 100644 --- a/test/e2e/storage/in_tree_volumes.go +++ b/test/e2e/storage/in_tree_volumes.go @@ -38,7 +38,7 @@ var testDrivers = []func() drivers.TestDriver{ drivers.InitHostpathSymlinkDriver, drivers.InitEmptydirDriver, drivers.InitCinderDriver, - drivers.InitGceDriver, + drivers.InitGcePdDriver, drivers.InitVSphereDriver, drivers.InitAzureDriver, drivers.InitAwsDriver, diff --git a/test/e2e/storage/subpath.go b/test/e2e/storage/subpath.go index 44563fe72af..9a0548a1dd3 100644 --- a/test/e2e/storage/subpath.go +++ b/test/e2e/storage/subpath.go @@ -57,7 +57,7 @@ var _ = utils.SIGDescribe("Subpath", func() { Description: Containers in a pod can read content from a secret mounted volume which was configured with a subpath. */ framework.ConformanceIt("should support subpaths with secret pod", func() { - pod := testsuites.TestPodSubpath(f, "secret-key", "secret", &v1.VolumeSource{Secret: &v1.SecretVolumeSource{SecretName: "my-secret"}}, privilegedSecurityContext) + pod := testsuites.SubpathTestPod(f, "secret-key", "secret", &v1.VolumeSource{Secret: &v1.SecretVolumeSource{SecretName: "my-secret"}}, privilegedSecurityContext) testsuites.TestBasicSubpath(f, "secret-value", pod) }) @@ -67,7 +67,7 @@ var _ = utils.SIGDescribe("Subpath", func() { Description: Containers in a pod can read content from a configmap mounted volume which was configured with a subpath. */ framework.ConformanceIt("should support subpaths with configmap pod", func() { - pod := testsuites.TestPodSubpath(f, "configmap-key", "configmap", &v1.VolumeSource{ConfigMap: &v1.ConfigMapVolumeSource{LocalObjectReference: v1.LocalObjectReference{Name: "my-configmap"}}}, privilegedSecurityContext) + pod := testsuites.SubpathTestPod(f, "configmap-key", "configmap", &v1.VolumeSource{ConfigMap: &v1.ConfigMapVolumeSource{LocalObjectReference: v1.LocalObjectReference{Name: "my-configmap"}}}, privilegedSecurityContext) testsuites.TestBasicSubpath(f, "configmap-value", pod) }) @@ -77,7 +77,7 @@ var _ = utils.SIGDescribe("Subpath", func() { Description: Containers in a pod can read content from a configmap mounted volume which was configured with a subpath and also using a mountpath that is a specific file. */ framework.ConformanceIt("should support subpaths with configmap pod with mountPath of existing file", func() { - pod := testsuites.TestPodSubpath(f, "configmap-key", "configmap", &v1.VolumeSource{ConfigMap: &v1.ConfigMapVolumeSource{LocalObjectReference: v1.LocalObjectReference{Name: "my-configmap"}}}, privilegedSecurityContext) + pod := testsuites.SubpathTestPod(f, "configmap-key", "configmap", &v1.VolumeSource{ConfigMap: &v1.ConfigMapVolumeSource{LocalObjectReference: v1.LocalObjectReference{Name: "my-configmap"}}}, privilegedSecurityContext) file := "/etc/resolv.conf" pod.Spec.Containers[0].VolumeMounts[0].MountPath = file testsuites.TestBasicSubpathFile(f, "configmap-value", pod, file) @@ -89,7 +89,7 @@ var _ = utils.SIGDescribe("Subpath", func() { Description: Containers in a pod can read content from a downwardAPI mounted volume which was configured with a subpath. */ framework.ConformanceIt("should support subpaths with downward pod", func() { - pod := testsuites.TestPodSubpath(f, "downward/podname", "downwardAPI", &v1.VolumeSource{ + pod := testsuites.SubpathTestPod(f, "downward/podname", "downwardAPI", &v1.VolumeSource{ DownwardAPI: &v1.DownwardAPIVolumeSource{ Items: []v1.DownwardAPIVolumeFile{{Path: "downward/podname", FieldRef: &v1.ObjectFieldSelector{APIVersion: "v1", FieldPath: "metadata.name"}}}, }, @@ -103,7 +103,7 @@ var _ = utils.SIGDescribe("Subpath", func() { Description: Containers in a pod can read content from a projected mounted volume which was configured with a subpath. */ framework.ConformanceIt("should support subpaths with projected pod", func() { - pod := testsuites.TestPodSubpath(f, "projected/configmap-key", "projected", &v1.VolumeSource{ + pod := testsuites.SubpathTestPod(f, "projected/configmap-key", "projected", &v1.VolumeSource{ Projected: &v1.ProjectedVolumeSource{ Sources: []v1.VolumeProjection{ {ConfigMap: &v1.ConfigMapProjection{ diff --git a/test/e2e/storage/testsuites/subpath.go b/test/e2e/storage/testsuites/subpath.go index ade96f60ee7..fb8b54abda0 100644 --- a/test/e2e/storage/testsuites/subpath.go +++ b/test/e2e/storage/testsuites/subpath.go @@ -89,6 +89,7 @@ func createSubPathTestInput(pattern testpatterns.TestPattern, resource subPathTe filePathInVolume: filepath.Join(subPathDir, fileName), volType: resource.volType, pod: resource.pod, + formatPod: resource.formatPod, volSource: resource.genericVolumeTestResource.volSource, roVol: resource.roVolSource, } @@ -131,6 +132,7 @@ type subPathTestResource struct { roVolSource *v1.VolumeSource pod *v1.Pod + formatPod *v1.Pod } var _ TestResource = &subPathTestResource{} @@ -171,9 +173,13 @@ func (s *subPathTestResource) setupResource(driver drivers.TestDriver, pattern t subPath := f.Namespace.Name config := dInfo.Config - s.pod = TestPodSubpath(f, subPath, s.volType, s.volSource, true) + s.pod = SubpathTestPod(f, subPath, s.volType, s.volSource, true) s.pod.Spec.NodeName = config.ClientNodeName s.pod.Spec.NodeSelector = config.NodeSelector + + s.formatPod = volumeFormatPod(f, s.volSource) + s.formatPod.Spec.NodeName = config.ClientNodeName + s.formatPod.Spec.NodeSelector = config.NodeSelector } func (s *subPathTestResource) cleanupResource(driver drivers.TestDriver, pattern testpatterns.TestPattern) { @@ -196,6 +202,7 @@ type subPathTestInput struct { filePathInVolume string volType string pod *v1.Pod + formatPod *v1.Pod volSource *v1.VolumeSource roVol *v1.VolumeSource } @@ -359,7 +366,7 @@ func testSubPath(input *subPathTestInput) { } // Format the volume while it's writable - formatVolume(input.f, input.volSource) + formatVolume(input.f, input.formatPod) // Set volume source to read only input.pod.Spec.Volumes[0].VolumeSource = *input.roVol @@ -387,8 +394,8 @@ func TestBasicSubpathFile(f *framework.Framework, contents string, pod *v1.Pod, Expect(err).NotTo(HaveOccurred(), "while deleting pod") } -// TestPodSubpath runs pod subpath test -func TestPodSubpath(f *framework.Framework, subpath, volumeType string, source *v1.VolumeSource, privilegedSecurityContext bool) *v1.Pod { +// SubpathTestPod returns a pod spec for subpath tests +func SubpathTestPod(f *framework.Framework, subpath, volumeType string, source *v1.VolumeSource, privilegedSecurityContext bool) *v1.Pod { var ( suffix = strings.ToLower(fmt.Sprintf("%s-%s", volumeType, rand.String(4))) gracePeriod = int64(1) @@ -479,6 +486,38 @@ func TestPodSubpath(f *framework.Framework, subpath, volumeType string, source * } } +// volumeFormatPod returns a Pod that does nothing but will cause the plugin to format a filesystem +// on first use +func volumeFormatPod(f *framework.Framework, volumeSource *v1.VolumeSource) *v1.Pod { + return &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("volume-prep-%s", f.Namespace.Name), + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: fmt.Sprintf("init-volume-%s", f.Namespace.Name), + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"/bin/sh", "-ec", "echo nothing"}, + VolumeMounts: []v1.VolumeMount{ + { + Name: volumeName, + MountPath: "/vol", + }, + }, + }, + }, + RestartPolicy: v1.RestartPolicyNever, + Volumes: []v1.Volume{ + { + Name: volumeName, + VolumeSource: *volumeSource, + }, + }, + }, + } +} + func clearSubpathPodCommands(pod *v1.Pod) { pod.Spec.InitContainers[0].Command = nil pod.Spec.Containers[0].Args = nil @@ -684,38 +723,9 @@ func testSubpathReconstruction(f *framework.Framework, pod *v1.Pod, forceDelete utils.TestVolumeUnmountsFromDeletedPodWithForceOption(f.ClientSet, f, pod, forceDelete, true) } -func formatVolume(f *framework.Framework, volumeSource *v1.VolumeSource) { - var err error - // Launch pod to format the volume - pod := &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("volume-prep-%s", f.Namespace.Name), - }, - Spec: v1.PodSpec{ - Containers: []v1.Container{ - { - Name: fmt.Sprintf("init-volume-%s", f.Namespace.Name), - Image: imageutils.GetE2EImage(imageutils.BusyBox), - Command: []string{"/bin/sh", "-ec", "echo nothing"}, - VolumeMounts: []v1.VolumeMount{ - { - Name: volumeName, - MountPath: "/vol", - }, - }, - }, - }, - RestartPolicy: v1.RestartPolicyNever, - Volumes: []v1.Volume{ - { - Name: volumeName, - VolumeSource: *volumeSource, - }, - }, - }, - } +func formatVolume(f *framework.Framework, pod *v1.Pod) { By(fmt.Sprintf("Creating pod to format volume %s", pod.Name)) - pod, err = f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(pod) + pod, err := f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(pod) Expect(err).ToNot(HaveOccurred(), "while creating volume init pod") err = framework.WaitForPodSuccessInNamespace(f.ClientSet, pod.Name, pod.Namespace)