volume_mode.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. Copyright 2018 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package storage
  14. import (
  15. "fmt"
  16. "time"
  17. "k8s.io/api/core/v1"
  18. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  19. "k8s.io/apimachinery/pkg/util/version"
  20. "k8s.io/kubernetes/test/e2e/framework"
  21. "k8s.io/kubernetes/test/e2e/storage/utils"
  22. "k8s.io/kubernetes/test/e2e/upgrades"
  23. "github.com/onsi/ginkgo"
  24. )
  25. const devicePath = "/mnt/volume1"
  26. // VolumeModeDowngradeTest tests that a VolumeMode Block PV is not mistakenly
  27. // formatted and mounted like a nil/Filesystem PV after a downgrade to a version
  28. // where the BlockVolume feature is disabled
  29. type VolumeModeDowngradeTest struct {
  30. pvSource *v1.PersistentVolumeSource
  31. pv *v1.PersistentVolume
  32. pvc *v1.PersistentVolumeClaim
  33. pod *v1.Pod
  34. }
  35. // Name returns the tracking name of the test.
  36. func (VolumeModeDowngradeTest) Name() string {
  37. return "[sig-storage] volume-mode-downgrade"
  38. }
  39. // Skip returns true when this test can be skipped.
  40. func (t *VolumeModeDowngradeTest) Skip(upgCtx upgrades.UpgradeContext) bool {
  41. if !framework.ProviderIs("openstack", "gce", "aws", "gke", "vsphere", "azure") {
  42. return true
  43. }
  44. // Only run when downgrading from >= 1.13 to < 1.13
  45. blockVersion := version.MustParseSemantic("1.13.0-alpha.0")
  46. if upgCtx.Versions[0].Version.LessThan(blockVersion) {
  47. return true
  48. }
  49. if !upgCtx.Versions[1].Version.LessThan(blockVersion) {
  50. return true
  51. }
  52. return false
  53. }
  54. // Setup creates a block pv and then verifies that a pod can consume it. The pod writes data to the volume.
  55. func (t *VolumeModeDowngradeTest) Setup(f *framework.Framework) {
  56. var err error
  57. cs := f.ClientSet
  58. ns := f.Namespace.Name
  59. ginkgo.By("Creating a PVC")
  60. block := v1.PersistentVolumeBlock
  61. pvcConfig := framework.PersistentVolumeClaimConfig{
  62. StorageClassName: nil,
  63. VolumeMode: &block,
  64. }
  65. t.pvc = framework.MakePersistentVolumeClaim(pvcConfig, ns)
  66. t.pvc, err = framework.CreatePVC(cs, ns, t.pvc)
  67. framework.ExpectNoError(err)
  68. err = framework.WaitForPersistentVolumeClaimPhase(v1.ClaimBound, cs, ns, t.pvc.Name, framework.Poll, framework.ClaimProvisionTimeout)
  69. framework.ExpectNoError(err)
  70. t.pvc, err = cs.CoreV1().PersistentVolumeClaims(t.pvc.Namespace).Get(t.pvc.Name, metav1.GetOptions{})
  71. framework.ExpectNoError(err)
  72. t.pv, err = cs.CoreV1().PersistentVolumes().Get(t.pvc.Spec.VolumeName, metav1.GetOptions{})
  73. framework.ExpectNoError(err)
  74. ginkgo.By("Consuming the PVC before downgrade")
  75. t.pod, err = framework.CreateSecPod(cs, ns, []*v1.PersistentVolumeClaim{t.pvc}, false, "", false, false, framework.SELinuxLabel, nil, framework.PodStartTimeout)
  76. framework.ExpectNoError(err)
  77. ginkgo.By("Checking if PV exists as expected volume mode")
  78. utils.CheckVolumeModeOfPath(t.pod, block, devicePath)
  79. ginkgo.By("Checking if read/write to PV works properly")
  80. utils.CheckReadWriteToPath(t.pod, block, devicePath)
  81. }
  82. // Test waits for the downgrade to complete, and then verifies that a pod can no
  83. // longer consume the pv as it is not mapped nor mounted into the pod
  84. func (t *VolumeModeDowngradeTest) Test(f *framework.Framework, done <-chan struct{}, upgrade upgrades.UpgradeType) {
  85. ginkgo.By("Waiting for downgrade to finish")
  86. <-done
  87. ginkgo.By("Verifying that nothing exists at the device path in the pod")
  88. utils.VerifyExecInPodFail(t.pod, fmt.Sprintf("test -e %s", devicePath), 1)
  89. }
  90. // Teardown cleans up any remaining resources.
  91. func (t *VolumeModeDowngradeTest) Teardown(f *framework.Framework) {
  92. ginkgo.By("Deleting the pod")
  93. framework.ExpectNoError(framework.DeletePodWithWait(f, f.ClientSet, t.pod))
  94. ginkgo.By("Deleting the PVC")
  95. framework.ExpectNoError(f.ClientSet.CoreV1().PersistentVolumeClaims(t.pvc.Namespace).Delete(t.pvc.Name, nil))
  96. ginkgo.By("Waiting for the PV to be deleted")
  97. framework.ExpectNoError(framework.WaitForPersistentVolumeDeleted(f.ClientSet, t.pv.Name, 5*time.Second, 20*time.Minute))
  98. }