mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 19:31:44 +00:00
Merge pull request #88669 from mkimuram/snapfromfile
Add FromFile and FromExistingClassName support for SnapshotClass in external storage e2e test
This commit is contained in:
commit
c2593d3fa7
59
test/e2e/storage/external/external.go
vendored
59
test/e2e/storage/external/external.go
vendored
@ -84,7 +84,20 @@ type driverDefinition struct {
|
|||||||
// snapshotter class with DriverInfo.Name as provisioner.
|
// snapshotter class with DriverInfo.Name as provisioner.
|
||||||
FromName bool
|
FromName bool
|
||||||
|
|
||||||
// TODO (?): load from file
|
// FromFile is used only when FromName is false. It
|
||||||
|
// loads a snapshot class from the given .yaml or .json
|
||||||
|
// file. File names are resolved by the
|
||||||
|
// framework.testfiles package, which typically means
|
||||||
|
// that they can be absolute or relative to the test
|
||||||
|
// suite's --repo-root parameter.
|
||||||
|
//
|
||||||
|
// This can be used when the snapshot class is meant to have
|
||||||
|
// additional parameters.
|
||||||
|
FromFile string
|
||||||
|
|
||||||
|
// FromExistingClassName specifies the name of a pre-installed
|
||||||
|
// SnapshotClass that will be copied and used for the tests.
|
||||||
|
FromExistingClassName string
|
||||||
}
|
}
|
||||||
|
|
||||||
// InlineVolumes defines one or more volumes for use as inline
|
// InlineVolumes defines one or more volumes for use as inline
|
||||||
@ -254,7 +267,7 @@ func (d *driverDefinition) SkipUnsupportedTest(pattern testpatterns.TestPattern)
|
|||||||
case "":
|
case "":
|
||||||
supported = true
|
supported = true
|
||||||
case testpatterns.DynamicCreatedSnapshot:
|
case testpatterns.DynamicCreatedSnapshot:
|
||||||
if d.SnapshotClass.FromName {
|
if d.SnapshotClass.FromName || d.SnapshotClass.FromFile != "" || d.SnapshotClass.FromExistingClassName != "" {
|
||||||
supported = true
|
supported = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -304,15 +317,53 @@ func (d *driverDefinition) GetDynamicProvisionStorageClass(config *testsuites.Pe
|
|||||||
return testsuites.GetStorageClass(sc.Provisioner, sc.Parameters, sc.VolumeBindingMode, f.Namespace.Name, "e2e-sc")
|
return testsuites.GetStorageClass(sc.Provisioner, sc.Parameters, sc.VolumeBindingMode, f.Namespace.Name, "e2e-sc")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loadSnapshotClass(filename string) (*unstructured.Unstructured, error) {
|
||||||
|
data, err := ioutil.ReadFile(filename)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
snapshotClass := &unstructured.Unstructured{}
|
||||||
|
|
||||||
|
if err := runtime.DecodeInto(scheme.Codecs.UniversalDecoder(), data, snapshotClass); err != nil {
|
||||||
|
return nil, errors.Wrap(err, filename)
|
||||||
|
}
|
||||||
|
|
||||||
|
return snapshotClass, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (d *driverDefinition) GetSnapshotClass(config *testsuites.PerTestConfig) *unstructured.Unstructured {
|
func (d *driverDefinition) GetSnapshotClass(config *testsuites.PerTestConfig) *unstructured.Unstructured {
|
||||||
if !d.SnapshotClass.FromName {
|
if !d.SnapshotClass.FromName && d.SnapshotClass.FromFile == "" && d.SnapshotClass.FromExistingClassName == "" {
|
||||||
e2eskipper.Skipf("Driver %q does not support snapshotting - skipping", d.DriverInfo.Name)
|
e2eskipper.Skipf("Driver %q does not support snapshotting - skipping", d.DriverInfo.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f := config.Framework
|
||||||
snapshotter := d.DriverInfo.Name
|
snapshotter := d.DriverInfo.Name
|
||||||
parameters := map[string]string{}
|
parameters := map[string]string{}
|
||||||
ns := config.Framework.Namespace.Name
|
ns := config.Framework.Namespace.Name
|
||||||
suffix := snapshotter + "-vsc"
|
suffix := "vsc"
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case d.SnapshotClass.FromName:
|
||||||
|
// Do nothing (just use empty parameters)
|
||||||
|
case d.SnapshotClass.FromExistingClassName != "":
|
||||||
|
snapshotClass, err := f.DynamicClient.Resource(testsuites.SnapshotClassGVR).Get(d.SnapshotClass.FromExistingClassName, metav1.GetOptions{})
|
||||||
|
framework.ExpectNoError(err, "getting snapshot class %s", d.SnapshotClass.FromExistingClassName)
|
||||||
|
|
||||||
|
if params, ok := snapshotClass.Object["parameters"].(map[string]interface{}); ok {
|
||||||
|
for k, v := range params {
|
||||||
|
parameters[k] = v.(string)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case d.SnapshotClass.FromFile != "":
|
||||||
|
snapshotClass, err := loadSnapshotClass(d.SnapshotClass.FromFile)
|
||||||
|
framework.ExpectNoError(err, "load snapshot class from %s", d.SnapshotClass.FromFile)
|
||||||
|
|
||||||
|
if params, ok := snapshotClass.Object["parameters"].(map[string]interface{}); ok {
|
||||||
|
for k, v := range params {
|
||||||
|
parameters[k] = v.(string)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return testsuites.GetSnapshotClass(snapshotter, parameters, ns, suffix)
|
return testsuites.GetSnapshotClass(snapshotter, parameters, ns, suffix)
|
||||||
}
|
}
|
||||||
|
@ -740,12 +740,12 @@ func prepareSnapshotDataSourceForProvisioning(
|
|||||||
volume.InjectContent(f, config, nil, "", tests)
|
volume.InjectContent(f, config, nil, "", tests)
|
||||||
|
|
||||||
ginkgo.By("[Initialize dataSource]creating a SnapshotClass")
|
ginkgo.By("[Initialize dataSource]creating a SnapshotClass")
|
||||||
snapshotClass, err = dynamicClient.Resource(snapshotClassGVR).Create(snapshotClass, metav1.CreateOptions{})
|
snapshotClass, err = dynamicClient.Resource(SnapshotClassGVR).Create(snapshotClass, metav1.CreateOptions{})
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
ginkgo.By("[Initialize dataSource]creating a snapshot")
|
ginkgo.By("[Initialize dataSource]creating a snapshot")
|
||||||
snapshot := getSnapshot(updatedClaim.Name, updatedClaim.Namespace, snapshotClass.GetName())
|
snapshot := getSnapshot(updatedClaim.Name, updatedClaim.Namespace, snapshotClass.GetName())
|
||||||
snapshot, err = dynamicClient.Resource(snapshotGVR).Namespace(updatedClaim.Namespace).Create(snapshot, metav1.CreateOptions{})
|
snapshot, err = dynamicClient.Resource(SnapshotGVR).Namespace(updatedClaim.Namespace).Create(snapshot, metav1.CreateOptions{})
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
WaitForSnapshotReady(dynamicClient, snapshot.GetNamespace(), snapshot.GetName(), framework.Poll, framework.SnapshotCreateTimeout)
|
WaitForSnapshotReady(dynamicClient, snapshot.GetNamespace(), snapshot.GetName(), framework.Poll, framework.SnapshotCreateTimeout)
|
||||||
@ -753,7 +753,7 @@ func prepareSnapshotDataSourceForProvisioning(
|
|||||||
|
|
||||||
ginkgo.By("[Initialize dataSource]checking the snapshot")
|
ginkgo.By("[Initialize dataSource]checking the snapshot")
|
||||||
// Get new copy of the snapshot
|
// Get new copy of the snapshot
|
||||||
snapshot, err = dynamicClient.Resource(snapshotGVR).Namespace(snapshot.GetNamespace()).Get(snapshot.GetName(), metav1.GetOptions{})
|
snapshot, err = dynamicClient.Resource(SnapshotGVR).Namespace(snapshot.GetNamespace()).Get(snapshot.GetName(), metav1.GetOptions{})
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
group := "snapshot.storage.k8s.io"
|
group := "snapshot.storage.k8s.io"
|
||||||
dataSourceRef := &v1.TypedLocalObjectReference{
|
dataSourceRef := &v1.TypedLocalObjectReference{
|
||||||
@ -764,7 +764,7 @@ func prepareSnapshotDataSourceForProvisioning(
|
|||||||
|
|
||||||
cleanupFunc := func() {
|
cleanupFunc := func() {
|
||||||
framework.Logf("deleting snapshot %q/%q", snapshot.GetNamespace(), snapshot.GetName())
|
framework.Logf("deleting snapshot %q/%q", snapshot.GetNamespace(), snapshot.GetName())
|
||||||
err = dynamicClient.Resource(snapshotGVR).Namespace(updatedClaim.Namespace).Delete(snapshot.GetName(), nil)
|
err = dynamicClient.Resource(SnapshotGVR).Namespace(updatedClaim.Namespace).Delete(snapshot.GetName(), nil)
|
||||||
if err != nil && !apierrors.IsNotFound(err) {
|
if err != nil && !apierrors.IsNotFound(err) {
|
||||||
framework.Failf("Error deleting snapshot %q. Error: %v", snapshot.GetName(), err)
|
framework.Failf("Error deleting snapshot %q. Error: %v", snapshot.GetName(), err)
|
||||||
}
|
}
|
||||||
@ -776,7 +776,7 @@ func prepareSnapshotDataSourceForProvisioning(
|
|||||||
}
|
}
|
||||||
|
|
||||||
framework.Logf("deleting SnapshotClass %s", snapshotClass.GetName())
|
framework.Logf("deleting SnapshotClass %s", snapshotClass.GetName())
|
||||||
framework.ExpectNoError(dynamicClient.Resource(snapshotClassGVR).Delete(snapshotClass.GetName(), nil))
|
framework.ExpectNoError(dynamicClient.Resource(SnapshotClassGVR).Delete(snapshotClass.GetName(), nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
return dataSourceRef, cleanupFunc
|
return dataSourceRef, cleanupFunc
|
||||||
|
@ -42,9 +42,12 @@ const snapshotGroup = "snapshot.storage.k8s.io"
|
|||||||
const snapshotAPIVersion = "snapshot.storage.k8s.io/v1beta1"
|
const snapshotAPIVersion = "snapshot.storage.k8s.io/v1beta1"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
snapshotGVR = schema.GroupVersionResource{Group: snapshotGroup, Version: "v1beta1", Resource: "volumesnapshots"}
|
// SnapshotGVR is GroupVersionResource for volumesnapshots
|
||||||
snapshotClassGVR = schema.GroupVersionResource{Group: snapshotGroup, Version: "v1beta1", Resource: "volumesnapshotclasses"}
|
SnapshotGVR = schema.GroupVersionResource{Group: snapshotGroup, Version: "v1beta1", Resource: "volumesnapshots"}
|
||||||
snapshotContentGVR = schema.GroupVersionResource{Group: snapshotGroup, Version: "v1beta1", Resource: "volumesnapshotcontents"}
|
// SnapshotClassGVR is GroupVersionResource for volumesnapshotclasses
|
||||||
|
SnapshotClassGVR = schema.GroupVersionResource{Group: snapshotGroup, Version: "v1beta1", Resource: "volumesnapshotclasses"}
|
||||||
|
// SnapshotContentGVR is GroupVersionResource for volumesnapshotcontents
|
||||||
|
SnapshotContentGVR = schema.GroupVersionResource{Group: snapshotGroup, Version: "v1beta1", Resource: "volumesnapshotcontents"}
|
||||||
)
|
)
|
||||||
|
|
||||||
type snapshottableTestSuite struct {
|
type snapshottableTestSuite struct {
|
||||||
@ -167,22 +170,22 @@ func (s *snapshottableTestSuite) DefineTests(driver TestDriver, pattern testpatt
|
|||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
ginkgo.By("creating a SnapshotClass")
|
ginkgo.By("creating a SnapshotClass")
|
||||||
vsc, err = dc.Resource(snapshotClassGVR).Create(vsc, metav1.CreateOptions{})
|
vsc, err = dc.Resource(SnapshotClassGVR).Create(vsc, metav1.CreateOptions{})
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
defer func() {
|
defer func() {
|
||||||
framework.Logf("deleting SnapshotClass %s", vsc.GetName())
|
framework.Logf("deleting SnapshotClass %s", vsc.GetName())
|
||||||
framework.ExpectNoError(dc.Resource(snapshotClassGVR).Delete(vsc.GetName(), nil))
|
framework.ExpectNoError(dc.Resource(SnapshotClassGVR).Delete(vsc.GetName(), nil))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
ginkgo.By("creating a snapshot")
|
ginkgo.By("creating a snapshot")
|
||||||
snapshot := getSnapshot(pvc.Name, pvc.Namespace, vsc.GetName())
|
snapshot := getSnapshot(pvc.Name, pvc.Namespace, vsc.GetName())
|
||||||
|
|
||||||
snapshot, err = dc.Resource(snapshotGVR).Namespace(snapshot.GetNamespace()).Create(snapshot, metav1.CreateOptions{})
|
snapshot, err = dc.Resource(SnapshotGVR).Namespace(snapshot.GetNamespace()).Create(snapshot, metav1.CreateOptions{})
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
defer func() {
|
defer func() {
|
||||||
framework.Logf("deleting snapshot %q/%q", snapshot.GetNamespace(), snapshot.GetName())
|
framework.Logf("deleting snapshot %q/%q", snapshot.GetNamespace(), snapshot.GetName())
|
||||||
// typically this snapshot has already been deleted
|
// typically this snapshot has already been deleted
|
||||||
err = dc.Resource(snapshotGVR).Namespace(snapshot.GetNamespace()).Delete(snapshot.GetName(), nil)
|
err = dc.Resource(SnapshotGVR).Namespace(snapshot.GetNamespace()).Delete(snapshot.GetName(), nil)
|
||||||
if err != nil && !apierrors.IsNotFound(err) {
|
if err != nil && !apierrors.IsNotFound(err) {
|
||||||
framework.Failf("Error deleting snapshot %q. Error: %v", pvc.Name, err)
|
framework.Failf("Error deleting snapshot %q. Error: %v", pvc.Name, err)
|
||||||
}
|
}
|
||||||
@ -192,13 +195,13 @@ func (s *snapshottableTestSuite) DefineTests(driver TestDriver, pattern testpatt
|
|||||||
|
|
||||||
ginkgo.By("checking the snapshot")
|
ginkgo.By("checking the snapshot")
|
||||||
// Get new copy of the snapshot
|
// Get new copy of the snapshot
|
||||||
snapshot, err = dc.Resource(snapshotGVR).Namespace(snapshot.GetNamespace()).Get(snapshot.GetName(), metav1.GetOptions{})
|
snapshot, err = dc.Resource(SnapshotGVR).Namespace(snapshot.GetNamespace()).Get(snapshot.GetName(), metav1.GetOptions{})
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
// Get the bound snapshotContent
|
// Get the bound snapshotContent
|
||||||
snapshotStatus := snapshot.Object["status"].(map[string]interface{})
|
snapshotStatus := snapshot.Object["status"].(map[string]interface{})
|
||||||
snapshotContentName := snapshotStatus["boundVolumeSnapshotContentName"].(string)
|
snapshotContentName := snapshotStatus["boundVolumeSnapshotContentName"].(string)
|
||||||
snapshotContent, err := dc.Resource(snapshotContentGVR).Get(snapshotContentName, metav1.GetOptions{})
|
snapshotContent, err := dc.Resource(SnapshotContentGVR).Get(snapshotContentName, metav1.GetOptions{})
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
snapshotContentSpec := snapshotContent.Object["spec"].(map[string]interface{})
|
snapshotContentSpec := snapshotContent.Object["spec"].(map[string]interface{})
|
||||||
@ -216,7 +219,7 @@ func (s *snapshottableTestSuite) DefineTests(driver TestDriver, pattern testpatt
|
|||||||
func WaitForSnapshotReady(c dynamic.Interface, ns string, snapshotName string, Poll, timeout time.Duration) error {
|
func WaitForSnapshotReady(c dynamic.Interface, ns string, snapshotName string, Poll, timeout time.Duration) error {
|
||||||
framework.Logf("Waiting up to %v for VolumeSnapshot %s to become ready", timeout, snapshotName)
|
framework.Logf("Waiting up to %v for VolumeSnapshot %s to become ready", timeout, snapshotName)
|
||||||
for start := time.Now(); time.Since(start) < timeout; time.Sleep(Poll) {
|
for start := time.Now(); time.Since(start) < timeout; time.Sleep(Poll) {
|
||||||
snapshot, err := c.Resource(snapshotGVR).Namespace(ns).Get(snapshotName, metav1.GetOptions{})
|
snapshot, err := c.Resource(SnapshotGVR).Namespace(ns).Get(snapshotName, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
framework.Logf("Failed to get claim %q, retrying in %v. Error: %v", snapshotName, Poll, err)
|
framework.Logf("Failed to get claim %q, retrying in %v. Error: %v", snapshotName, Poll, err)
|
||||||
continue
|
continue
|
||||||
|
Loading…
Reference in New Issue
Block a user