mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 11:21:47 +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.
|
||||
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
|
||||
@ -254,7 +267,7 @@ func (d *driverDefinition) SkipUnsupportedTest(pattern testpatterns.TestPattern)
|
||||
case "":
|
||||
supported = true
|
||||
case testpatterns.DynamicCreatedSnapshot:
|
||||
if d.SnapshotClass.FromName {
|
||||
if d.SnapshotClass.FromName || d.SnapshotClass.FromFile != "" || d.SnapshotClass.FromExistingClassName != "" {
|
||||
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")
|
||||
}
|
||||
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
|
||||
f := config.Framework
|
||||
snapshotter := d.DriverInfo.Name
|
||||
parameters := map[string]string{}
|
||||
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)
|
||||
}
|
||||
|
@ -740,12 +740,12 @@ func prepareSnapshotDataSourceForProvisioning(
|
||||
volume.InjectContent(f, config, nil, "", tests)
|
||||
|
||||
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)
|
||||
|
||||
ginkgo.By("[Initialize dataSource]creating a snapshot")
|
||||
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)
|
||||
|
||||
WaitForSnapshotReady(dynamicClient, snapshot.GetNamespace(), snapshot.GetName(), framework.Poll, framework.SnapshotCreateTimeout)
|
||||
@ -753,7 +753,7 @@ func prepareSnapshotDataSourceForProvisioning(
|
||||
|
||||
ginkgo.By("[Initialize dataSource]checking 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)
|
||||
group := "snapshot.storage.k8s.io"
|
||||
dataSourceRef := &v1.TypedLocalObjectReference{
|
||||
@ -764,7 +764,7 @@ func prepareSnapshotDataSourceForProvisioning(
|
||||
|
||||
cleanupFunc := func() {
|
||||
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) {
|
||||
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.ExpectNoError(dynamicClient.Resource(snapshotClassGVR).Delete(snapshotClass.GetName(), nil))
|
||||
framework.ExpectNoError(dynamicClient.Resource(SnapshotClassGVR).Delete(snapshotClass.GetName(), nil))
|
||||
}
|
||||
|
||||
return dataSourceRef, cleanupFunc
|
||||
|
@ -42,9 +42,12 @@ const snapshotGroup = "snapshot.storage.k8s.io"
|
||||
const snapshotAPIVersion = "snapshot.storage.k8s.io/v1beta1"
|
||||
|
||||
var (
|
||||
snapshotGVR = schema.GroupVersionResource{Group: snapshotGroup, Version: "v1beta1", Resource: "volumesnapshots"}
|
||||
snapshotClassGVR = schema.GroupVersionResource{Group: snapshotGroup, Version: "v1beta1", Resource: "volumesnapshotclasses"}
|
||||
snapshotContentGVR = schema.GroupVersionResource{Group: snapshotGroup, Version: "v1beta1", Resource: "volumesnapshotcontents"}
|
||||
// SnapshotGVR is GroupVersionResource for volumesnapshots
|
||||
SnapshotGVR = schema.GroupVersionResource{Group: snapshotGroup, Version: "v1beta1", Resource: "volumesnapshots"}
|
||||
// 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 {
|
||||
@ -167,22 +170,22 @@ func (s *snapshottableTestSuite) DefineTests(driver TestDriver, pattern testpatt
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
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)
|
||||
defer func() {
|
||||
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")
|
||||
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)
|
||||
defer func() {
|
||||
framework.Logf("deleting snapshot %q/%q", snapshot.GetNamespace(), snapshot.GetName())
|
||||
// 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) {
|
||||
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")
|
||||
// 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)
|
||||
|
||||
// Get the bound snapshotContent
|
||||
snapshotStatus := snapshot.Object["status"].(map[string]interface{})
|
||||
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)
|
||||
|
||||
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 {
|
||||
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) {
|
||||
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 {
|
||||
framework.Logf("Failed to get claim %q, retrying in %v. Error: %v", snapshotName, Poll, err)
|
||||
continue
|
||||
|
Loading…
Reference in New Issue
Block a user