Skip to content

Commit

Permalink
Allow ReadWriteOncePod DVs (#3093)
Browse files Browse the repository at this point in the history
* Allow ReadWriteOncePod in validating webhook

Signed-off-by: Alex Kalenyuk <[email protected]>

* Use RWOP in some e2e tests

Signed-off-by: Alex Kalenyuk <[email protected]>

* Stop using "local" storage class in external population test

Signed-off-by: Alex Kalenyuk <[email protected]>

* Skip static local PV clone across nodes test for CSI storage

Signed-off-by: Alex Kalenyuk <[email protected]>

---------

Signed-off-by: Alex Kalenyuk <[email protected]>
  • Loading branch information
akalenyu authored Feb 1, 2024
1 parent e1665ee commit fa1f1bb
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 47 deletions.
8 changes: 4 additions & 4 deletions pkg/apiserver/webhooks/datavolume-validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,10 @@ func (wh *dataVolumeValidatingWebhook) validateDataVolumeSpec(request *admission
return causes
}
// We know we have one access mode
if accessModes[0] != v1.ReadWriteOnce && accessModes[0] != v1.ReadOnlyMany && accessModes[0] != v1.ReadWriteMany {
if accessModes[0] != v1.ReadWriteOnce && accessModes[0] != v1.ReadOnlyMany && accessModes[0] != v1.ReadWriteMany && accessModes[0] != v1.ReadWriteOncePod {
causes = append(causes, metav1.StatusCause{
Type: metav1.CauseTypeFieldValueInvalid,
Message: fmt.Sprintf(`Unsupported value: "%s": supported values: "ReadOnlyMany", "ReadWriteMany", "ReadWriteOnce"`, string(accessModes[0])),
Message: fmt.Sprintf(`Unsupported value: "%s": supported values: "ReadOnlyMany", "ReadWriteMany", "ReadWriteOnce", "ReadWriteOncePod"`, string(accessModes[0])),
Field: field.Child("PVC", "accessModes").String(),
})
return causes
Expand All @@ -126,10 +126,10 @@ func (wh *dataVolumeValidatingWebhook) validateDataVolumeSpec(request *admission
// here in storage spec we allow empty access mode and AccessModes with more than one entry
accessModes := spec.Storage.AccessModes
for _, mode := range accessModes {
if mode != v1.ReadWriteOnce && mode != v1.ReadOnlyMany && mode != v1.ReadWriteMany {
if mode != v1.ReadWriteOnce && mode != v1.ReadOnlyMany && mode != v1.ReadWriteMany && mode != v1.ReadWriteOncePod {
causes = append(causes, metav1.StatusCause{
Type: metav1.CauseTypeFieldValueInvalid,
Message: fmt.Sprintf("Unsupported value: \"%s\": supported values: \"ReadOnlyMany\", \"ReadWriteMany\", \"ReadWriteOnce\"", string(accessModes[0])),
Message: fmt.Sprintf("Unsupported value: \"%s\": supported values: \"ReadOnlyMany\", \"ReadWriteMany\", \"ReadWriteOnce\", \"ReadWriteOncePod\"", string(accessModes[0])),
Field: field.Child("PVC", "accessModes").String(),
})
return causes
Expand Down
3 changes: 3 additions & 0 deletions tests/cloner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,9 @@ var _ = Describe("all clone tests", func() {
})

It("[posneg:negative][test_id:3617]Should clone across nodes when multiple local filesystem volumes exist,", func() {
if utils.DefaultStorageClassCsiDriver != nil {
Skip("this test is only relevant for non CSI local storage")
}
// Get nodes, need at least 2
nodeList, err := f.K8sClient.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})
Expect(err).ToNot(HaveOccurred())
Expand Down
35 changes: 10 additions & 25 deletions tests/datavolume_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1246,30 +1246,12 @@ var _ = Describe("[vendor:[email protected]][level:component]DataVolume tests",
}}),
)

DescribeTable("should have an alert suppressing label on corresponding PVC", func(dvFunc func(string, string, string) *cdiv1.DataVolume, url string) {
dataVolume := dvFunc("suppress-fillingup-alert-dv", "1Gi", url)

By(fmt.Sprintf("creating new datavolume %s", dataVolume.Name))
dataVolume, err := utils.CreateDataVolumeFromDefinition(f.CdiClient, f.Namespace.Name, dataVolume)
Expect(err).ToNot(HaveOccurred())

// verify PVC was created
By("verifying pvc was created and is Bound")
pvc, err := utils.WaitForPVC(f.K8sClient, dataVolume.Namespace, dataVolume.Name)
Expect(err).ToNot(HaveOccurred())

// Alert-suppressing label exists
Expect(pvc.Labels[common.KubePersistentVolumeFillingUpSuppressLabelKey]).To(Equal(common.KubePersistentVolumeFillingUpSuppressLabelValue))
},
Entry("[test_id:8043]for import DataVolume", utils.NewDataVolumeWithHTTPImport, tinyCoreIsoURL()),
Entry("[test_id:8044]for upload DataVolume", createUploadDataVolume, tinyCoreIsoURL()),
Entry("[test_id:8045]for clone DataVolume", createCloneDataVolume, fillCommand),
)

DescribeTable("Should pass all DV labels and annotations to the PVC", func(dvFunc func(string, string, string) *cdiv1.DataVolume, url string) {
dataVolume := dvFunc("pass-all-labels-dv", "1Gi", url)
DescribeTable("should have an alert suppressing label and inherit labels & annotations from DV on corresponding PVC", func(dvFunc func(string, string, string) *cdiv1.DataVolume, url string) {
dataVolume := dvFunc("dv-labels-behaviour", "1Gi", url)
dataVolume.Labels = map[string]string{"test-label-1": "test-label-1", "test-label-2": "test-label-2"}
dataVolume.Annotations = map[string]string{"test-annotation-1": "test-annotation-1", "test-annotation-2": "test-annotation-2"}
// Stir things up with this non widely used access mode
dataVolume.Spec.PVC.AccessModes = []v1.PersistentVolumeAccessMode{v1.ReadWriteOncePod}

By(fmt.Sprintf("creating new datavolume %s", dataVolume.Name))
dataVolume, err := utils.CreateDataVolumeFromDefinition(f.CdiClient, f.Namespace.Name, dataVolume)
Expand All @@ -1280,15 +1262,18 @@ var _ = Describe("[vendor:[email protected]][level:component]DataVolume tests",
pvc, err := utils.WaitForPVC(f.K8sClient, dataVolume.Namespace, dataVolume.Name)
Expect(err).ToNot(HaveOccurred())

// Alert-suppressing label exists
Expect(pvc.Labels[common.KubePersistentVolumeFillingUpSuppressLabelKey]).To(Equal(common.KubePersistentVolumeFillingUpSuppressLabelValue))

// All labels and annotations passed
Expect(pvc.Labels["test-label-1"]).To(Equal("test-label-1"))
Expect(pvc.Labels["test-label-2"]).To(Equal("test-label-2"))
Expect(pvc.Annotations["test-annotation-1"]).To(Equal("test-annotation-1"))
Expect(pvc.Annotations["test-annotation-2"]).To(Equal("test-annotation-2"))
},
Entry("for import DataVolume", utils.NewDataVolumeWithHTTPImport, tinyCoreIsoURL()),
Entry("for upload DataVolume", createUploadDataVolume, tinyCoreIsoURL()),
Entry("for clone DataVolume", createCloneDataVolume, fillCommand),
Entry("[test_id:8043]for import DataVolume", utils.NewDataVolumeWithHTTPImport, tinyCoreIsoURL()),
Entry("[test_id:8044]for upload DataVolume", createUploadDataVolume, tinyCoreIsoURL()),
Entry("[test_id:8045]for clone DataVolume", createCloneDataVolume, fillCommand),
)

Context("default virt storage class", Serial, func() {
Expand Down
21 changes: 3 additions & 18 deletions tests/external_population_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,20 +111,6 @@ var _ = Describe("Population tests", func() {
return err
}

getNonCSIStorage := func() (string, bool) {
localSCName := "local"
// We first check if the default storage class lacks CSI drivers
if utils.DefaultStorageClassCsiDriver == nil {
return utils.DefaultStorageClass.GetName(), true
}
// If it doesn't, we attempt to get the local storage class
_, err := f.K8sClient.StorageV1().StorageClasses().Get(context.TODO(), localSCName, metav1.GetOptions{})
if err == nil {
return localSCName, true
}
return "", false
}

Context("External populator", func() {
BeforeEach(func() {
err := deploySamplePopulator()
Expand Down Expand Up @@ -213,13 +199,12 @@ var _ = Describe("Population tests", func() {

It("Should not populate PVC when CSI drivers are not available", func() {
By("Checking if non-CSI storage class is available")
scName, available := getNonCSIStorage()
if !available {
Skip("No storage class to run without CSI drivers, cannot run test")
if utils.DefaultStorageClassCsiDriver != nil {
Skip("default storage class has CSI Driver, cannot run test")
}

By(fmt.Sprintf("Creating new datavolume %s", dataVolumeName))
dataVolume := utils.NewDataVolumeWithExternalPopulationAndStorageSpec(dataVolumeName, "100Mi", scName, corev1.PersistentVolumeMode(corev1.PersistentVolumeFilesystem), nil, dummySourceRef)
dataVolume := utils.NewDataVolumeWithExternalPopulationAndStorageSpec(dataVolumeName, "100Mi", utils.DefaultStorageClass.Name, corev1.PersistentVolumeMode(corev1.PersistentVolumeFilesystem), nil, dummySourceRef)
dataVolume, err := utils.CreateDataVolumeFromDefinition(f.CdiClient, f.Namespace.Name, dataVolume)
Expect(err).ToNot(HaveOccurred())

Expand Down

0 comments on commit fa1f1bb

Please sign in to comment.