Merge pull request #68569 from davidz627/fix/driverTestResources

Fix storage test framework leaking resources on cleanup
This commit is contained in:
k8s-ci-robot 2018-09-12 21:44:42 -07:00 committed by GitHub
commit ae935d7293
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 315 additions and 156 deletions

View File

@ -721,7 +721,7 @@ func createPD(zone string) (string, error) {
} }
tags := map[string]string{} tags := map[string]string{}
err = gceCloud.CreateDisk(pdName, gcecloud.DiskTypeSSD, zone, 10 /* sizeGb */, tags) err = gceCloud.CreateDisk(pdName, gcecloud.DiskTypeStandard, zone, 2 /* sizeGb */, tags)
if err != nil { if err != nil {
return "", err return "", err
} }

View File

@ -44,9 +44,9 @@ type TestDriver interface {
type PreprovisionedVolumeTestDriver interface { type PreprovisionedVolumeTestDriver interface {
TestDriver TestDriver
// CreateVolume creates a pre-provisioned volume. // CreateVolume creates a pre-provisioned volume.
CreateVolume(testpatterns.TestVolType) CreateVolume(testpatterns.TestVolType) interface{}
// DeleteVolume deletes a volume that is created in CreateVolume // DeleteVolume deletes a volume that is created in CreateVolume
DeleteVolume(testpatterns.TestVolType) DeleteVolume(testpatterns.TestVolType, interface{})
} }
// InlineVolumeTestDriver represents an interface for a TestDriver that supports InlineVolume // InlineVolumeTestDriver represents an interface for a TestDriver that supports InlineVolume
@ -55,7 +55,7 @@ type InlineVolumeTestDriver interface {
// GetVolumeSource returns a volumeSource for inline volume. // GetVolumeSource returns a volumeSource for inline volume.
// It will set readOnly and fsType to the volumeSource, if TestDriver supports both of them. // It will set readOnly and fsType to the volumeSource, if TestDriver supports both of them.
// It will return nil, if the TestDriver doesn't support either of the parameters. // It will return nil, if the TestDriver doesn't support either of the parameters.
GetVolumeSource(readOnly bool, fsType string) *v1.VolumeSource GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource
} }
// PreprovisionedPVTestDriver represents an interface for a TestDriver that supports PreprovisionedPV // PreprovisionedPVTestDriver represents an interface for a TestDriver that supports PreprovisionedPV
@ -64,7 +64,7 @@ type PreprovisionedPVTestDriver interface {
// GetPersistentVolumeSource returns a PersistentVolumeSource for pre-provisioned Persistent Volume. // GetPersistentVolumeSource returns a PersistentVolumeSource for pre-provisioned Persistent Volume.
// It will set readOnly and fsType to the PersistentVolumeSource, if TestDriver supports both of them. // It will set readOnly and fsType to the PersistentVolumeSource, if TestDriver supports both of them.
// It will return nil, if the TestDriver doesn't support either of the parameters. // It will return nil, if the TestDriver doesn't support either of the parameters.
GetPersistentVolumeSource(readOnly bool, fsType string) *v1.PersistentVolumeSource GetPersistentVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.PersistentVolumeSource
} }
// DynamicPVTestDriver represents an interface for a TestDriver that supports DynamicPV // DynamicPVTestDriver represents an interface for a TestDriver that supports DynamicPV
@ -104,30 +104,31 @@ func GetDriverNameWithFeatureTags(driver TestDriver) string {
return fmt.Sprintf("[Driver: %s]%s", dInfo.Name, dInfo.FeatureTag) return fmt.Sprintf("[Driver: %s]%s", dInfo.Name, dInfo.FeatureTag)
} }
func CreateVolume(driver TestDriver, volType testpatterns.TestVolType) { func CreateVolume(driver TestDriver, volType testpatterns.TestVolType) interface{} {
// Create Volume for test unless dynamicPV test // Create Volume for test unless dynamicPV test
switch volType { switch volType {
case testpatterns.InlineVolume: case testpatterns.InlineVolume:
fallthrough fallthrough
case testpatterns.PreprovisionedPV: case testpatterns.PreprovisionedPV:
if pDriver, ok := driver.(PreprovisionedVolumeTestDriver); ok { if pDriver, ok := driver.(PreprovisionedVolumeTestDriver); ok {
pDriver.CreateVolume(volType) return pDriver.CreateVolume(volType)
} }
case testpatterns.DynamicPV: case testpatterns.DynamicPV:
// No need to create volume // No need to create volume
default: default:
framework.Failf("Invalid volType specified: %v", volType) framework.Failf("Invalid volType specified: %v", volType)
} }
return nil
} }
func DeleteVolume(driver TestDriver, volType testpatterns.TestVolType) { func DeleteVolume(driver TestDriver, volType testpatterns.TestVolType, testResource interface{}) {
// Delete Volume for test unless dynamicPV test // Delete Volume for test unless dynamicPV test
switch volType { switch volType {
case testpatterns.InlineVolume: case testpatterns.InlineVolume:
fallthrough fallthrough
case testpatterns.PreprovisionedPV: case testpatterns.PreprovisionedPV:
if pDriver, ok := driver.(PreprovisionedVolumeTestDriver); ok { if pDriver, ok := driver.(PreprovisionedVolumeTestDriver); ok {
pDriver.DeleteVolume(volType) pDriver.DeleteVolume(volType, testResource)
} }
case testpatterns.DynamicPV: case testpatterns.DynamicPV:
// No need to delete volume // No need to delete volume

View File

@ -62,14 +62,17 @@ import (
// NFS // NFS
type nfsDriver struct { type nfsDriver struct {
serverIP string
serverPod *v1.Pod
externalProvisionerPod *v1.Pod externalProvisionerPod *v1.Pod
externalPluginName string externalPluginName string
driverInfo DriverInfo driverInfo DriverInfo
} }
type nfsTestResource struct {
serverIP string
serverPod *v1.Pod
}
var _ TestDriver = &nfsDriver{} var _ TestDriver = &nfsDriver{}
var _ PreprovisionedVolumeTestDriver = &nfsDriver{} var _ PreprovisionedVolumeTestDriver = &nfsDriver{}
var _ InlineVolumeTestDriver = &nfsDriver{} var _ InlineVolumeTestDriver = &nfsDriver{}
@ -99,20 +102,24 @@ func (n *nfsDriver) GetDriverInfo() *DriverInfo {
func (n *nfsDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) { func (n *nfsDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) {
} }
func (n *nfsDriver) GetVolumeSource(readOnly bool, fsType string) *v1.VolumeSource { func (n *nfsDriver) GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource {
ntr, ok := testResource.(*nfsTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to NFS Test Resource")
return &v1.VolumeSource{ return &v1.VolumeSource{
NFS: &v1.NFSVolumeSource{ NFS: &v1.NFSVolumeSource{
Server: n.serverIP, Server: ntr.serverIP,
Path: "/", Path: "/",
ReadOnly: readOnly, ReadOnly: readOnly,
}, },
} }
} }
func (n *nfsDriver) GetPersistentVolumeSource(readOnly bool, fsType string) *v1.PersistentVolumeSource { func (n *nfsDriver) GetPersistentVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.PersistentVolumeSource {
ntr, ok := testResource.(*nfsTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to NFS Test Resource")
return &v1.PersistentVolumeSource{ return &v1.PersistentVolumeSource{
NFS: &v1.NFSVolumeSource{ NFS: &v1.NFSVolumeSource{
Server: n.serverIP, Server: ntr.serverIP,
Path: "/", Path: "/",
ReadOnly: readOnly, ReadOnly: readOnly,
}, },
@ -158,7 +165,7 @@ func (n *nfsDriver) CleanupDriver() {
cs.RbacV1beta1().ClusterRoleBindings().Delete(clusterRoleBindingName, metav1.NewDeleteOptions(0)) cs.RbacV1beta1().ClusterRoleBindings().Delete(clusterRoleBindingName, metav1.NewDeleteOptions(0))
} }
func (n *nfsDriver) CreateVolume(volType testpatterns.TestVolType) { func (n *nfsDriver) CreateVolume(volType testpatterns.TestVolType) interface{} {
f := n.driverInfo.Framework f := n.driverInfo.Framework
cs := f.ClientSet cs := f.ClientSet
ns := f.Namespace ns := f.Namespace
@ -170,22 +177,31 @@ func (n *nfsDriver) CreateVolume(volType testpatterns.TestVolType) {
case testpatterns.InlineVolume: case testpatterns.InlineVolume:
fallthrough fallthrough
case testpatterns.PreprovisionedPV: case testpatterns.PreprovisionedPV:
n.driverInfo.Config, n.serverPod, n.serverIP = framework.NewNFSServer(cs, ns.Name, []string{}) config, serverPod, serverIP := framework.NewNFSServer(cs, ns.Name, []string{})
n.driverInfo.Config = config
return &nfsTestResource{
serverIP: serverIP,
serverPod: serverPod,
}
case testpatterns.DynamicPV: case testpatterns.DynamicPV:
// Do nothing // Do nothing
default: default:
framework.Failf("Unsupported volType:%v is specified", volType) framework.Failf("Unsupported volType:%v is specified", volType)
} }
return nil
} }
func (n *nfsDriver) DeleteVolume(volType testpatterns.TestVolType) { func (n *nfsDriver) DeleteVolume(volType testpatterns.TestVolType, testResource interface{}) {
f := n.driverInfo.Framework f := n.driverInfo.Framework
ntr, ok := testResource.(*nfsTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to NFS Test Resource")
switch volType { switch volType {
case testpatterns.InlineVolume: case testpatterns.InlineVolume:
fallthrough fallthrough
case testpatterns.PreprovisionedPV: case testpatterns.PreprovisionedPV:
framework.CleanUpVolumeServer(f, n.serverPod) framework.CleanUpVolumeServer(f, ntr.serverPod)
case testpatterns.DynamicPV: case testpatterns.DynamicPV:
// Do nothing // Do nothing
default: default:
@ -195,12 +211,14 @@ func (n *nfsDriver) DeleteVolume(volType testpatterns.TestVolType) {
// Gluster // Gluster
type glusterFSDriver struct { type glusterFSDriver struct {
serverIP string
serverPod *v1.Pod
driverInfo DriverInfo driverInfo DriverInfo
} }
type glusterTestResource struct {
prefix string
serverPod *v1.Pod
}
var _ TestDriver = &glusterFSDriver{} var _ TestDriver = &glusterFSDriver{}
var _ PreprovisionedVolumeTestDriver = &glusterFSDriver{} var _ PreprovisionedVolumeTestDriver = &glusterFSDriver{}
var _ InlineVolumeTestDriver = &glusterFSDriver{} var _ InlineVolumeTestDriver = &glusterFSDriver{}
@ -233,8 +251,11 @@ func (g *glusterFSDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern)
} }
} }
func (g *glusterFSDriver) GetVolumeSource(readOnly bool, fsType string) *v1.VolumeSource { func (g *glusterFSDriver) GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource {
name := g.driverInfo.Config.Prefix + "-server" gtr, ok := testResource.(*glusterTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to Gluster Test Resource")
name := gtr.prefix + "-server"
return &v1.VolumeSource{ return &v1.VolumeSource{
Glusterfs: &v1.GlusterfsVolumeSource{ Glusterfs: &v1.GlusterfsVolumeSource{
EndpointsName: name, EndpointsName: name,
@ -245,8 +266,11 @@ func (g *glusterFSDriver) GetVolumeSource(readOnly bool, fsType string) *v1.Volu
} }
} }
func (g *glusterFSDriver) GetPersistentVolumeSource(readOnly bool, fsType string) *v1.PersistentVolumeSource { func (g *glusterFSDriver) GetPersistentVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.PersistentVolumeSource {
name := g.driverInfo.Config.Prefix + "-server" gtr, ok := testResource.(*glusterTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to Gluster Test Resource")
name := gtr.prefix + "-server"
return &v1.PersistentVolumeSource{ return &v1.PersistentVolumeSource{
Glusterfs: &v1.GlusterfsVolumeSource{ Glusterfs: &v1.GlusterfsVolumeSource{
EndpointsName: name, EndpointsName: name,
@ -263,20 +287,28 @@ func (g *glusterFSDriver) CreateDriver() {
func (g *glusterFSDriver) CleanupDriver() { func (g *glusterFSDriver) CleanupDriver() {
} }
func (g *glusterFSDriver) CreateVolume(volType testpatterns.TestVolType) { func (g *glusterFSDriver) CreateVolume(volType testpatterns.TestVolType) interface{} {
f := g.driverInfo.Framework f := g.driverInfo.Framework
cs := f.ClientSet cs := f.ClientSet
ns := f.Namespace ns := f.Namespace
g.driverInfo.Config, g.serverPod, g.serverIP = framework.NewGlusterfsServer(cs, ns.Name) config, serverPod, _ := framework.NewGlusterfsServer(cs, ns.Name)
g.driverInfo.Config = config
return &glusterTestResource{
prefix: config.Prefix,
serverPod: serverPod,
}
} }
func (g *glusterFSDriver) DeleteVolume(volType testpatterns.TestVolType) { func (g *glusterFSDriver) DeleteVolume(volType testpatterns.TestVolType, testResource interface{}) {
f := g.driverInfo.Framework f := g.driverInfo.Framework
cs := f.ClientSet cs := f.ClientSet
ns := f.Namespace ns := f.Namespace
name := g.driverInfo.Config.Prefix + "-server" gtr, ok := testResource.(*glusterTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to Gluster Test Resource")
name := gtr.prefix + "-server"
framework.Logf("Deleting Gluster endpoints %q...", name) framework.Logf("Deleting Gluster endpoints %q...", name)
err := cs.CoreV1().Endpoints(ns.Name).Delete(name, nil) err := cs.CoreV1().Endpoints(ns.Name).Delete(name, nil)
@ -286,8 +318,8 @@ func (g *glusterFSDriver) DeleteVolume(volType testpatterns.TestVolType) {
} }
framework.Logf("Gluster endpoints %q not found, assuming deleted", name) framework.Logf("Gluster endpoints %q not found, assuming deleted", name)
} }
framework.Logf("Deleting Gluster server pod %q...", g.serverPod.Name) framework.Logf("Deleting Gluster server pod %q...", gtr.serverPod.Name)
err = framework.DeletePodWithWait(f, cs, g.serverPod) err = framework.DeletePodWithWait(f, cs, gtr.serverPod)
if err != nil { if err != nil {
framework.Failf("Gluster server pod delete failed: %v", err) framework.Failf("Gluster server pod delete failed: %v", err)
} }
@ -296,11 +328,12 @@ func (g *glusterFSDriver) DeleteVolume(volType testpatterns.TestVolType) {
// iSCSI // iSCSI
// The iscsiadm utility and iscsi target kernel modules must be installed on all nodes. // The iscsiadm utility and iscsi target kernel modules must be installed on all nodes.
type iSCSIDriver struct { type iSCSIDriver struct {
serverIP string
serverPod *v1.Pod
driverInfo DriverInfo driverInfo DriverInfo
} }
type iSCSITestResource struct {
serverPod *v1.Pod
serverIP string
}
var _ TestDriver = &iSCSIDriver{} var _ TestDriver = &iSCSIDriver{}
var _ PreprovisionedVolumeTestDriver = &iSCSIDriver{} var _ PreprovisionedVolumeTestDriver = &iSCSIDriver{}
@ -335,10 +368,13 @@ func (i *iSCSIDriver) GetDriverInfo() *DriverInfo {
func (i *iSCSIDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) { func (i *iSCSIDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) {
} }
func (i *iSCSIDriver) GetVolumeSource(readOnly bool, fsType string) *v1.VolumeSource { func (i *iSCSIDriver) GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource {
itr, ok := testResource.(*iSCSITestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to iSCSI Test Resource")
volSource := v1.VolumeSource{ volSource := v1.VolumeSource{
ISCSI: &v1.ISCSIVolumeSource{ ISCSI: &v1.ISCSIVolumeSource{
TargetPortal: i.serverIP + ":3260", TargetPortal: itr.serverIP + ":3260",
// from test/images/volume/iscsi/initiatorname.iscsi // from test/images/volume/iscsi/initiatorname.iscsi
IQN: "iqn.2003-01.org.linux-iscsi.f21.x8664:sn.4b0aae584f7c", IQN: "iqn.2003-01.org.linux-iscsi.f21.x8664:sn.4b0aae584f7c",
Lun: 0, Lun: 0,
@ -351,10 +387,13 @@ func (i *iSCSIDriver) GetVolumeSource(readOnly bool, fsType string) *v1.VolumeSo
return &volSource return &volSource
} }
func (i *iSCSIDriver) GetPersistentVolumeSource(readOnly bool, fsType string) *v1.PersistentVolumeSource { func (i *iSCSIDriver) GetPersistentVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.PersistentVolumeSource {
itr, ok := testResource.(*iSCSITestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to iSCSI Test Resource")
pvSource := v1.PersistentVolumeSource{ pvSource := v1.PersistentVolumeSource{
ISCSI: &v1.ISCSIPersistentVolumeSource{ ISCSI: &v1.ISCSIPersistentVolumeSource{
TargetPortal: i.serverIP + ":3260", TargetPortal: itr.serverIP + ":3260",
IQN: "iqn.2003-01.org.linux-iscsi.f21.x8664:sn.4b0aae584f7c", IQN: "iqn.2003-01.org.linux-iscsi.f21.x8664:sn.4b0aae584f7c",
Lun: 0, Lun: 0,
ReadOnly: readOnly, ReadOnly: readOnly,
@ -372,29 +411,39 @@ func (i *iSCSIDriver) CreateDriver() {
func (i *iSCSIDriver) CleanupDriver() { func (i *iSCSIDriver) CleanupDriver() {
} }
func (i *iSCSIDriver) CreateVolume(volType testpatterns.TestVolType) { func (i *iSCSIDriver) CreateVolume(volType testpatterns.TestVolType) interface{} {
f := i.driverInfo.Framework f := i.driverInfo.Framework
cs := f.ClientSet cs := f.ClientSet
ns := f.Namespace ns := f.Namespace
i.driverInfo.Config, i.serverPod, i.serverIP = framework.NewISCSIServer(cs, ns.Name) config, serverPod, serverIP := framework.NewISCSIServer(cs, ns.Name)
i.driverInfo.Config = config
return &iSCSITestResource{
serverPod: serverPod,
serverIP: serverIP,
}
} }
func (i *iSCSIDriver) DeleteVolume(volType testpatterns.TestVolType) { func (i *iSCSIDriver) DeleteVolume(volType testpatterns.TestVolType, testResource interface{}) {
f := i.driverInfo.Framework f := i.driverInfo.Framework
framework.CleanUpVolumeServer(f, i.serverPod) itr, ok := testResource.(*iSCSITestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to iSCSI Test Resource")
framework.CleanUpVolumeServer(f, itr.serverPod)
} }
// Ceph RBD // Ceph RBD
type rbdDriver struct { type rbdDriver struct {
serverIP string
serverPod *v1.Pod
secret *v1.Secret
driverInfo DriverInfo driverInfo DriverInfo
} }
type rbdTestResource struct {
serverPod *v1.Pod
serverIP string
secret *v1.Secret
}
var _ TestDriver = &rbdDriver{} var _ TestDriver = &rbdDriver{}
var _ PreprovisionedVolumeTestDriver = &rbdDriver{} var _ PreprovisionedVolumeTestDriver = &rbdDriver{}
var _ InlineVolumeTestDriver = &rbdDriver{} var _ InlineVolumeTestDriver = &rbdDriver{}
@ -427,15 +476,18 @@ func (r *rbdDriver) GetDriverInfo() *DriverInfo {
func (r *rbdDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) { func (r *rbdDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) {
} }
func (r *rbdDriver) GetVolumeSource(readOnly bool, fsType string) *v1.VolumeSource { func (r *rbdDriver) GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource {
rtr, ok := testResource.(*rbdTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to RBD Test Resource")
volSource := v1.VolumeSource{ volSource := v1.VolumeSource{
RBD: &v1.RBDVolumeSource{ RBD: &v1.RBDVolumeSource{
CephMonitors: []string{r.serverIP}, CephMonitors: []string{rtr.serverIP},
RBDPool: "rbd", RBDPool: "rbd",
RBDImage: "foo", RBDImage: "foo",
RadosUser: "admin", RadosUser: "admin",
SecretRef: &v1.LocalObjectReference{ SecretRef: &v1.LocalObjectReference{
Name: r.secret.Name, Name: rtr.secret.Name,
}, },
ReadOnly: readOnly, ReadOnly: readOnly,
}, },
@ -446,17 +498,21 @@ func (r *rbdDriver) GetVolumeSource(readOnly bool, fsType string) *v1.VolumeSour
return &volSource return &volSource
} }
func (r *rbdDriver) GetPersistentVolumeSource(readOnly bool, fsType string) *v1.PersistentVolumeSource { func (r *rbdDriver) GetPersistentVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.PersistentVolumeSource {
f := r.driverInfo.Framework f := r.driverInfo.Framework
ns := f.Namespace ns := f.Namespace
rtr, ok := testResource.(*rbdTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to RBD Test Resource")
pvSource := v1.PersistentVolumeSource{ pvSource := v1.PersistentVolumeSource{
RBD: &v1.RBDPersistentVolumeSource{ RBD: &v1.RBDPersistentVolumeSource{
CephMonitors: []string{r.serverIP}, CephMonitors: []string{rtr.serverIP},
RBDPool: "rbd", RBDPool: "rbd",
RBDImage: "foo", RBDImage: "foo",
RadosUser: "admin", RadosUser: "admin",
SecretRef: &v1.SecretReference{ SecretRef: &v1.SecretReference{
Name: r.secret.Name, Name: rtr.secret.Name,
Namespace: ns.Name, Namespace: ns.Name,
}, },
ReadOnly: readOnly, ReadOnly: readOnly,
@ -474,18 +530,27 @@ func (r *rbdDriver) CreateDriver() {
func (r *rbdDriver) CleanupDriver() { func (r *rbdDriver) CleanupDriver() {
} }
func (r *rbdDriver) CreateVolume(volType testpatterns.TestVolType) { func (r *rbdDriver) CreateVolume(volType testpatterns.TestVolType) interface{} {
f := r.driverInfo.Framework f := r.driverInfo.Framework
cs := f.ClientSet cs := f.ClientSet
ns := f.Namespace ns := f.Namespace
r.driverInfo.Config, r.serverPod, r.secret, r.serverIP = framework.NewRBDServer(cs, ns.Name) config, serverPod, secret, serverIP := framework.NewRBDServer(cs, ns.Name)
r.driverInfo.Config = config
return &rbdTestResource{
serverPod: serverPod,
serverIP: serverIP,
secret: secret,
}
} }
func (r *rbdDriver) DeleteVolume(volType testpatterns.TestVolType) { func (r *rbdDriver) DeleteVolume(volType testpatterns.TestVolType, testResource interface{}) {
f := r.driverInfo.Framework f := r.driverInfo.Framework
framework.CleanUpVolumeServerWithSecret(f, r.serverPod, r.secret) rtr, ok := testResource.(*rbdTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to RBD Test Resource")
framework.CleanUpVolumeServerWithSecret(f, rtr.serverPod, rtr.secret)
} }
// Ceph // Ceph
@ -497,6 +562,12 @@ type cephFSDriver struct {
driverInfo DriverInfo driverInfo DriverInfo
} }
type cephTestResource struct {
serverPod *v1.Pod
serverIP string
secret *v1.Secret
}
var _ TestDriver = &cephFSDriver{} var _ TestDriver = &cephFSDriver{}
var _ PreprovisionedVolumeTestDriver = &cephFSDriver{} var _ PreprovisionedVolumeTestDriver = &cephFSDriver{}
var _ InlineVolumeTestDriver = &cephFSDriver{} var _ InlineVolumeTestDriver = &cephFSDriver{}
@ -526,29 +597,35 @@ func (c *cephFSDriver) GetDriverInfo() *DriverInfo {
func (c *cephFSDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) { func (c *cephFSDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) {
} }
func (c *cephFSDriver) GetVolumeSource(readOnly bool, fsType string) *v1.VolumeSource { func (c *cephFSDriver) GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource {
ctr, ok := testResource.(*cephTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to Ceph Test Resource")
return &v1.VolumeSource{ return &v1.VolumeSource{
CephFS: &v1.CephFSVolumeSource{ CephFS: &v1.CephFSVolumeSource{
Monitors: []string{c.serverIP + ":6789"}, Monitors: []string{ctr.serverIP + ":6789"},
User: "kube", User: "kube",
SecretRef: &v1.LocalObjectReference{ SecretRef: &v1.LocalObjectReference{
Name: c.secret.Name, Name: ctr.secret.Name,
}, },
ReadOnly: readOnly, ReadOnly: readOnly,
}, },
} }
} }
func (c *cephFSDriver) GetPersistentVolumeSource(readOnly bool, fsType string) *v1.PersistentVolumeSource { func (c *cephFSDriver) GetPersistentVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.PersistentVolumeSource {
f := c.driverInfo.Framework f := c.driverInfo.Framework
ns := f.Namespace ns := f.Namespace
ctr, ok := testResource.(*cephTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to Ceph Test Resource")
return &v1.PersistentVolumeSource{ return &v1.PersistentVolumeSource{
CephFS: &v1.CephFSPersistentVolumeSource{ CephFS: &v1.CephFSPersistentVolumeSource{
Monitors: []string{c.serverIP + ":6789"}, Monitors: []string{ctr.serverIP + ":6789"},
User: "kube", User: "kube",
SecretRef: &v1.SecretReference{ SecretRef: &v1.SecretReference{
Name: c.secret.Name, Name: ctr.secret.Name,
Namespace: ns.Name, Namespace: ns.Name,
}, },
ReadOnly: readOnly, ReadOnly: readOnly,
@ -562,18 +639,27 @@ func (c *cephFSDriver) CreateDriver() {
func (c *cephFSDriver) CleanupDriver() { func (c *cephFSDriver) CleanupDriver() {
} }
func (c *cephFSDriver) CreateVolume(volType testpatterns.TestVolType) { func (c *cephFSDriver) CreateVolume(volType testpatterns.TestVolType) interface{} {
f := c.driverInfo.Framework f := c.driverInfo.Framework
cs := f.ClientSet cs := f.ClientSet
ns := f.Namespace ns := f.Namespace
c.driverInfo.Config, c.serverPod, c.secret, c.serverIP = framework.NewRBDServer(cs, ns.Name) config, serverPod, secret, serverIP := framework.NewRBDServer(cs, ns.Name)
c.driverInfo.Config = config
return &cephTestResource{
serverPod: serverPod,
serverIP: serverIP,
secret: secret,
}
} }
func (c *cephFSDriver) DeleteVolume(volType testpatterns.TestVolType) { func (c *cephFSDriver) DeleteVolume(volType testpatterns.TestVolType, testResource interface{}) {
f := c.driverInfo.Framework f := c.driverInfo.Framework
framework.CleanUpVolumeServerWithSecret(f, c.serverPod, c.secret) ctr, ok := testResource.(*cephTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to Ceph Test Resource")
framework.CleanUpVolumeServerWithSecret(f, ctr.serverPod, ctr.secret)
} }
// Hostpath // Hostpath
@ -610,7 +696,7 @@ func (h *hostPathDriver) GetDriverInfo() *DriverInfo {
func (h *hostPathDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) { func (h *hostPathDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) {
} }
func (h *hostPathDriver) GetVolumeSource(readOnly bool, fsType string) *v1.VolumeSource { func (h *hostPathDriver) GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource {
// hostPath doesn't support readOnly volume // hostPath doesn't support readOnly volume
if readOnly { if readOnly {
return nil return nil
@ -628,7 +714,7 @@ func (h *hostPathDriver) CreateDriver() {
func (h *hostPathDriver) CleanupDriver() { func (h *hostPathDriver) CleanupDriver() {
} }
func (h *hostPathDriver) CreateVolume(volType testpatterns.TestVolType) { func (h *hostPathDriver) CreateVolume(volType testpatterns.TestVolType) interface{} {
f := h.driverInfo.Framework f := h.driverInfo.Framework
cs := f.ClientSet cs := f.ClientSet
@ -636,21 +722,25 @@ func (h *hostPathDriver) CreateVolume(volType testpatterns.TestVolType) {
nodes := framework.GetReadySchedulableNodesOrDie(cs) nodes := framework.GetReadySchedulableNodesOrDie(cs)
node := nodes.Items[rand.Intn(len(nodes.Items))] node := nodes.Items[rand.Intn(len(nodes.Items))]
h.driverInfo.Config.ClientNodeName = node.Name h.driverInfo.Config.ClientNodeName = node.Name
return nil
} }
func (h *hostPathDriver) DeleteVolume(volType testpatterns.TestVolType) { func (h *hostPathDriver) DeleteVolume(volType testpatterns.TestVolType, testResource interface{}) {
} }
// HostPathSymlink // HostPathSymlink
type hostPathSymlinkDriver struct { type hostPathSymlinkDriver struct {
node v1.Node node v1.Node
sourcePath string
targetPath string
prepPod *v1.Pod
driverInfo DriverInfo driverInfo DriverInfo
} }
type hostPathSymlinkTestResource struct {
targetPath string
sourcePath string
prepPod *v1.Pod
}
var _ TestDriver = &hostPathSymlinkDriver{} var _ TestDriver = &hostPathSymlinkDriver{}
var _ PreprovisionedVolumeTestDriver = &hostPathSymlinkDriver{} var _ PreprovisionedVolumeTestDriver = &hostPathSymlinkDriver{}
var _ InlineVolumeTestDriver = &hostPathSymlinkDriver{} var _ InlineVolumeTestDriver = &hostPathSymlinkDriver{}
@ -678,14 +768,17 @@ func (h *hostPathSymlinkDriver) GetDriverInfo() *DriverInfo {
func (h *hostPathSymlinkDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) { func (h *hostPathSymlinkDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) {
} }
func (h *hostPathSymlinkDriver) GetVolumeSource(readOnly bool, fsType string) *v1.VolumeSource { func (h *hostPathSymlinkDriver) GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource {
htr, ok := testResource.(*hostPathSymlinkTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to Hostpath Symlink Test Resource")
// hostPathSymlink doesn't support readOnly volume // hostPathSymlink doesn't support readOnly volume
if readOnly { if readOnly {
return nil return nil
} }
return &v1.VolumeSource{ return &v1.VolumeSource{
HostPath: &v1.HostPathVolumeSource{ HostPath: &v1.HostPathVolumeSource{
Path: h.targetPath, Path: htr.targetPath,
}, },
} }
} }
@ -696,12 +789,12 @@ func (h *hostPathSymlinkDriver) CreateDriver() {
func (h *hostPathSymlinkDriver) CleanupDriver() { func (h *hostPathSymlinkDriver) CleanupDriver() {
} }
func (h *hostPathSymlinkDriver) CreateVolume(volType testpatterns.TestVolType) { func (h *hostPathSymlinkDriver) CreateVolume(volType testpatterns.TestVolType) interface{} {
f := h.driverInfo.Framework f := h.driverInfo.Framework
cs := f.ClientSet cs := f.ClientSet
h.sourcePath = fmt.Sprintf("/tmp/%v", f.Namespace.Name) sourcePath := fmt.Sprintf("/tmp/%v", f.Namespace.Name)
h.targetPath = fmt.Sprintf("/tmp/%v-link", f.Namespace.Name) targetPath := fmt.Sprintf("/tmp/%v-link", f.Namespace.Name)
volumeName := "test-volume" volumeName := "test-volume"
// pods should be scheduled on the node // pods should be scheduled on the node
@ -709,11 +802,11 @@ func (h *hostPathSymlinkDriver) CreateVolume(volType testpatterns.TestVolType) {
node := nodes.Items[rand.Intn(len(nodes.Items))] node := nodes.Items[rand.Intn(len(nodes.Items))]
h.driverInfo.Config.ClientNodeName = node.Name h.driverInfo.Config.ClientNodeName = node.Name
cmd := fmt.Sprintf("mkdir %v -m 777 && ln -s %v %v", h.sourcePath, h.sourcePath, h.targetPath) cmd := fmt.Sprintf("mkdir %v -m 777 && ln -s %v %v", sourcePath, sourcePath, targetPath)
privileged := true privileged := true
// Launch pod to initialize hostPath directory and symlink // Launch pod to initialize hostPath directory and symlink
h.prepPod = &v1.Pod{ prepPod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("hostpath-symlink-prep-%s", f.Namespace.Name), Name: fmt.Sprintf("hostpath-symlink-prep-%s", f.Namespace.Name),
}, },
@ -749,7 +842,7 @@ func (h *hostPathSymlinkDriver) CreateVolume(volType testpatterns.TestVolType) {
}, },
} }
// h.prepPod will be reused in cleanupDriver. // h.prepPod will be reused in cleanupDriver.
pod, err := f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(h.prepPod) pod, err := f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(prepPod)
Expect(err).ToNot(HaveOccurred(), "while creating hostPath init pod") Expect(err).ToNot(HaveOccurred(), "while creating hostPath init pod")
err = framework.WaitForPodSuccessInNamespace(f.ClientSet, pod.Name, pod.Namespace) err = framework.WaitForPodSuccessInNamespace(f.ClientSet, pod.Name, pod.Namespace)
@ -757,15 +850,23 @@ func (h *hostPathSymlinkDriver) CreateVolume(volType testpatterns.TestVolType) {
err = framework.DeletePodWithWait(f, f.ClientSet, pod) err = framework.DeletePodWithWait(f, f.ClientSet, pod)
Expect(err).ToNot(HaveOccurred(), "while deleting hostPath init pod") Expect(err).ToNot(HaveOccurred(), "while deleting hostPath init pod")
return &hostPathSymlinkTestResource{
sourcePath: sourcePath,
targetPath: targetPath,
prepPod: prepPod,
}
} }
func (h *hostPathSymlinkDriver) DeleteVolume(volType testpatterns.TestVolType) { func (h *hostPathSymlinkDriver) DeleteVolume(volType testpatterns.TestVolType, testResource interface{}) {
f := h.driverInfo.Framework f := h.driverInfo.Framework
cmd := fmt.Sprintf("rm -rf %v&& rm -rf %v", h.targetPath, h.sourcePath) htr, ok := testResource.(*hostPathSymlinkTestResource)
h.prepPod.Spec.Containers[0].Command = []string{"/bin/sh", "-ec", cmd} Expect(ok).To(BeTrue(), "Failed to cast test resource to Hostpath Symlink Test Resource")
pod, err := f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(h.prepPod) cmd := fmt.Sprintf("rm -rf %v&& rm -rf %v", htr.targetPath, htr.sourcePath)
htr.prepPod.Spec.Containers[0].Command = []string{"/bin/sh", "-ec", cmd}
pod, err := f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(htr.prepPod)
Expect(err).ToNot(HaveOccurred(), "while creating hostPath teardown pod") Expect(err).ToNot(HaveOccurred(), "while creating hostPath teardown pod")
err = framework.WaitForPodSuccessInNamespace(f.ClientSet, pod.Name, pod.Namespace) err = framework.WaitForPodSuccessInNamespace(f.ClientSet, pod.Name, pod.Namespace)
@ -807,7 +908,7 @@ func (e *emptydirDriver) GetDriverInfo() *DriverInfo {
func (e *emptydirDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) { func (e *emptydirDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) {
} }
func (e *emptydirDriver) GetVolumeSource(readOnly bool, fsType string) *v1.VolumeSource { func (e *emptydirDriver) GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource {
// emptydir doesn't support readOnly volume // emptydir doesn't support readOnly volume
if readOnly { if readOnly {
return nil return nil
@ -817,10 +918,11 @@ func (e *emptydirDriver) GetVolumeSource(readOnly bool, fsType string) *v1.Volum
} }
} }
func (e *emptydirDriver) CreateVolume(volType testpatterns.TestVolType) { func (e *emptydirDriver) CreateVolume(volType testpatterns.TestVolType) interface{} {
return nil
} }
func (e *emptydirDriver) DeleteVolume(volType testpatterns.TestVolType) { func (e *emptydirDriver) DeleteVolume(volType testpatterns.TestVolType, testResource interface{}) {
} }
func (e *emptydirDriver) CreateDriver() { func (e *emptydirDriver) CreateDriver() {
@ -835,10 +937,12 @@ func (e *emptydirDriver) CleanupDriver() {
// and that the usual OpenStack authentication env. variables are set // and that the usual OpenStack authentication env. variables are set
// (OS_USERNAME, OS_PASSWORD, OS_TENANT_NAME at least). // (OS_USERNAME, OS_PASSWORD, OS_TENANT_NAME at least).
type cinderDriver struct { type cinderDriver struct {
driverInfo DriverInfo
}
type cinderTestResource struct {
volumeName string volumeName string
volumeID string volumeID string
driverInfo DriverInfo
} }
var _ TestDriver = &cinderDriver{} var _ TestDriver = &cinderDriver{}
@ -872,10 +976,13 @@ func (c *cinderDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) {
framework.SkipUnlessProviderIs("openstack") framework.SkipUnlessProviderIs("openstack")
} }
func (c *cinderDriver) GetVolumeSource(readOnly bool, fsType string) *v1.VolumeSource { func (c *cinderDriver) GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource {
ctr, ok := testResource.(*cinderTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to Cinder Test Resource")
volSource := v1.VolumeSource{ volSource := v1.VolumeSource{
Cinder: &v1.CinderVolumeSource{ Cinder: &v1.CinderVolumeSource{
VolumeID: c.volumeID, VolumeID: ctr.volumeID,
ReadOnly: readOnly, ReadOnly: readOnly,
}, },
} }
@ -885,10 +992,13 @@ func (c *cinderDriver) GetVolumeSource(readOnly bool, fsType string) *v1.VolumeS
return &volSource return &volSource
} }
func (c *cinderDriver) GetPersistentVolumeSource(readOnly bool, fsType string) *v1.PersistentVolumeSource { func (c *cinderDriver) GetPersistentVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.PersistentVolumeSource {
ctr, ok := testResource.(*cinderTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to Cinder Test Resource")
pvSource := v1.PersistentVolumeSource{ pvSource := v1.PersistentVolumeSource{
Cinder: &v1.CinderPersistentVolumeSource{ Cinder: &v1.CinderPersistentVolumeSource{
VolumeID: c.volumeID, VolumeID: ctr.volumeID,
ReadOnly: readOnly, ReadOnly: readOnly,
}, },
} }
@ -916,14 +1026,14 @@ func (c *cinderDriver) CreateDriver() {
func (c *cinderDriver) CleanupDriver() { func (c *cinderDriver) CleanupDriver() {
} }
func (c *cinderDriver) CreateVolume(volType testpatterns.TestVolType) { func (c *cinderDriver) CreateVolume(volType testpatterns.TestVolType) interface{} {
f := c.driverInfo.Framework f := c.driverInfo.Framework
ns := f.Namespace ns := f.Namespace
// We assume that namespace.Name is a random string // We assume that namespace.Name is a random string
c.volumeName = ns.Name volumeName := ns.Name
By("creating a test Cinder volume") By("creating a test Cinder volume")
output, err := exec.Command("cinder", "create", "--display-name="+c.volumeName, "1").CombinedOutput() output, err := exec.Command("cinder", "create", "--display-name="+volumeName, "1").CombinedOutput()
outputString := string(output[:]) outputString := string(output[:])
framework.Logf("cinder output:\n%s", outputString) framework.Logf("cinder output:\n%s", outputString)
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
@ -933,7 +1043,7 @@ func (c *cinderDriver) CreateVolume(volType testpatterns.TestVolType) {
// | availability_zone | nova | // | availability_zone | nova |
// ... // ...
// | id | 1d6ff08f-5d1c-41a4-ad72-4ef872cae685 | // | id | 1d6ff08f-5d1c-41a4-ad72-4ef872cae685 |
c.volumeID = "" volumeID := ""
for _, line := range strings.Split(outputString, "\n") { for _, line := range strings.Split(outputString, "\n") {
fields := strings.Fields(line) fields := strings.Fields(line)
if len(fields) != 5 { if len(fields) != 5 {
@ -942,15 +1052,22 @@ func (c *cinderDriver) CreateVolume(volType testpatterns.TestVolType) {
if fields[1] != "id" { if fields[1] != "id" {
continue continue
} }
c.volumeID = fields[3] volumeID = fields[3]
break break
} }
framework.Logf("Volume ID: %s", c.volumeID) framework.Logf("Volume ID: %s", volumeID)
Expect(c.volumeID).NotTo(Equal("")) Expect(volumeID).NotTo(Equal(""))
return &cinderTestResource{
volumeName: volumeName,
volumeID: volumeID,
}
} }
func (c *cinderDriver) DeleteVolume(volType testpatterns.TestVolType) { func (c *cinderDriver) DeleteVolume(volType testpatterns.TestVolType, testResource interface{}) {
deleteCinderVolume(c.volumeName) ctr, ok := testResource.(*cinderTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to Cinder Test Resource")
deleteCinderVolume(ctr.volumeName)
} }
func deleteCinderVolume(name string) error { func deleteCinderVolume(name string) error {
@ -975,11 +1092,13 @@ func deleteCinderVolume(name string) error {
// GCE // GCE
type gcePdDriver struct { type gcePdDriver struct {
volumeName string
driverInfo DriverInfo driverInfo DriverInfo
} }
type gcePdTestResource struct {
volumeName string
}
var _ TestDriver = &gcePdDriver{} var _ TestDriver = &gcePdDriver{}
var _ PreprovisionedVolumeTestDriver = &gcePdDriver{} var _ PreprovisionedVolumeTestDriver = &gcePdDriver{}
var _ InlineVolumeTestDriver = &gcePdDriver{} var _ InlineVolumeTestDriver = &gcePdDriver{}
@ -1017,10 +1136,12 @@ func (g *gcePdDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) {
} }
} }
func (g *gcePdDriver) GetVolumeSource(readOnly bool, fsType string) *v1.VolumeSource { func (g *gcePdDriver) GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource {
gtr, ok := testResource.(*gcePdTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to GCE PD Test Resource")
volSource := v1.VolumeSource{ volSource := v1.VolumeSource{
GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{ GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{
PDName: g.volumeName, PDName: gtr.volumeName,
ReadOnly: readOnly, ReadOnly: readOnly,
}, },
} }
@ -1030,10 +1151,12 @@ func (g *gcePdDriver) GetVolumeSource(readOnly bool, fsType string) *v1.VolumeSo
return &volSource return &volSource
} }
func (g *gcePdDriver) GetPersistentVolumeSource(readOnly bool, fsType string) *v1.PersistentVolumeSource { func (g *gcePdDriver) GetPersistentVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.PersistentVolumeSource {
gtr, ok := testResource.(*gcePdTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to GCE PD Test Resource")
pvSource := v1.PersistentVolumeSource{ pvSource := v1.PersistentVolumeSource{
GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{ GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{
PDName: g.volumeName, PDName: gtr.volumeName,
ReadOnly: readOnly, ReadOnly: readOnly,
}, },
} }
@ -1061,7 +1184,7 @@ func (g *gcePdDriver) CreateDriver() {
func (g *gcePdDriver) CleanupDriver() { func (g *gcePdDriver) CleanupDriver() {
} }
func (g *gcePdDriver) CreateVolume(volType testpatterns.TestVolType) { func (g *gcePdDriver) CreateVolume(volType testpatterns.TestVolType) interface{} {
if volType == testpatterns.InlineVolume { if volType == testpatterns.InlineVolume {
// PD will be created in framework.TestContext.CloudConfig.Zone zone, // PD will be created in framework.TestContext.CloudConfig.Zone zone,
// so pods should be also scheduled there. // so pods should be also scheduled there.
@ -1070,21 +1193,27 @@ func (g *gcePdDriver) CreateVolume(volType testpatterns.TestVolType) {
} }
} }
By("creating a test gce pd volume") By("creating a test gce pd volume")
var err error vname, err := framework.CreatePDWithRetry()
g.volumeName, err = framework.CreatePDWithRetry()
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
return &gcePdTestResource{
volumeName: vname,
}
} }
func (g *gcePdDriver) DeleteVolume(volType testpatterns.TestVolType) { func (g *gcePdDriver) DeleteVolume(volType testpatterns.TestVolType, testResource interface{}) {
framework.DeletePDWithRetry(g.volumeName) gtr, ok := testResource.(*gcePdTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to GCE PD Test Resource")
framework.DeletePDWithRetry(gtr.volumeName)
} }
// vSphere // vSphere
type vSphereDriver struct { type vSphereDriver struct {
driverInfo DriverInfo
}
type vSphereTestResource struct {
volumePath string volumePath string
nodeInfo *vspheretest.NodeInfo nodeInfo *vspheretest.NodeInfo
driverInfo DriverInfo
} }
var _ TestDriver = &vSphereDriver{} var _ TestDriver = &vSphereDriver{}
@ -1117,7 +1246,10 @@ func (v *vSphereDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) {
framework.SkipUnlessProviderIs("vsphere") framework.SkipUnlessProviderIs("vsphere")
} }
func (v *vSphereDriver) GetVolumeSource(readOnly bool, fsType string) *v1.VolumeSource { func (v *vSphereDriver) GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource {
vtr, ok := testResource.(*vSphereTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to vSphere Test Resource")
// vSphere driver doesn't seem to support readOnly volume // vSphere driver doesn't seem to support readOnly volume
// TODO: check if it is correct // TODO: check if it is correct
if readOnly { if readOnly {
@ -1125,7 +1257,7 @@ func (v *vSphereDriver) GetVolumeSource(readOnly bool, fsType string) *v1.Volume
} }
volSource := v1.VolumeSource{ volSource := v1.VolumeSource{
VsphereVolume: &v1.VsphereVirtualDiskVolumeSource{ VsphereVolume: &v1.VsphereVirtualDiskVolumeSource{
VolumePath: v.volumePath, VolumePath: vtr.volumePath,
}, },
} }
if fsType != "" { if fsType != "" {
@ -1134,7 +1266,10 @@ func (v *vSphereDriver) GetVolumeSource(readOnly bool, fsType string) *v1.Volume
return &volSource return &volSource
} }
func (v *vSphereDriver) GetPersistentVolumeSource(readOnly bool, fsType string) *v1.PersistentVolumeSource { func (v *vSphereDriver) GetPersistentVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.PersistentVolumeSource {
vtr, ok := testResource.(*vSphereTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to vSphere Test Resource")
// vSphere driver doesn't seem to support readOnly volume // vSphere driver doesn't seem to support readOnly volume
// TODO: check if it is correct // TODO: check if it is correct
if readOnly { if readOnly {
@ -1142,7 +1277,7 @@ func (v *vSphereDriver) GetPersistentVolumeSource(readOnly bool, fsType string)
} }
pvSource := v1.PersistentVolumeSource{ pvSource := v1.PersistentVolumeSource{
VsphereVolume: &v1.VsphereVirtualDiskVolumeSource{ VsphereVolume: &v1.VsphereVirtualDiskVolumeSource{
VolumePath: v.volumePath, VolumePath: vtr.volumePath,
}, },
} }
if fsType != "" { if fsType != "" {
@ -1169,26 +1304,34 @@ func (v *vSphereDriver) CreateDriver() {
func (v *vSphereDriver) CleanupDriver() { func (v *vSphereDriver) CleanupDriver() {
} }
func (v *vSphereDriver) CreateVolume(volType testpatterns.TestVolType) { func (v *vSphereDriver) CreateVolume(volType testpatterns.TestVolType) interface{} {
f := v.driverInfo.Framework f := v.driverInfo.Framework
vspheretest.Bootstrap(f) vspheretest.Bootstrap(f)
v.nodeInfo = vspheretest.GetReadySchedulableRandomNodeInfo() nodeInfo := vspheretest.GetReadySchedulableRandomNodeInfo()
var err error volumePath, err := nodeInfo.VSphere.CreateVolume(&vspheretest.VolumeOptions{}, nodeInfo.DataCenterRef)
v.volumePath, err = v.nodeInfo.VSphere.CreateVolume(&vspheretest.VolumeOptions{}, v.nodeInfo.DataCenterRef)
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
return &vSphereTestResource{
volumePath: volumePath,
nodeInfo: nodeInfo,
}
} }
func (v *vSphereDriver) DeleteVolume(volType testpatterns.TestVolType) { func (v *vSphereDriver) DeleteVolume(volType testpatterns.TestVolType, testResource interface{}) {
v.nodeInfo.VSphere.DeleteVolume(v.volumePath, v.nodeInfo.DataCenterRef) vtr, ok := testResource.(*vSphereTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to vSphere Test Resource")
vtr.nodeInfo.VSphere.DeleteVolume(vtr.volumePath, vtr.nodeInfo.DataCenterRef)
} }
// Azure // Azure
type azureDriver struct { type azureDriver struct {
volumeName string
driverInfo DriverInfo driverInfo DriverInfo
} }
type azureTestResource struct {
volumeName string
}
var _ TestDriver = &azureDriver{} var _ TestDriver = &azureDriver{}
var _ PreprovisionedVolumeTestDriver = &azureDriver{} var _ PreprovisionedVolumeTestDriver = &azureDriver{}
var _ InlineVolumeTestDriver = &azureDriver{} var _ InlineVolumeTestDriver = &azureDriver{}
@ -1220,13 +1363,16 @@ func (a *azureDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) {
framework.SkipUnlessProviderIs("azure") framework.SkipUnlessProviderIs("azure")
} }
func (a *azureDriver) GetVolumeSource(readOnly bool, fsType string) *v1.VolumeSource { func (a *azureDriver) GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource {
diskName := a.volumeName[(strings.LastIndex(a.volumeName, "/") + 1):] atr, ok := testResource.(*azureTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to Azure Test Resource")
diskName := atr.volumeName[(strings.LastIndex(atr.volumeName, "/") + 1):]
volSource := v1.VolumeSource{ volSource := v1.VolumeSource{
AzureDisk: &v1.AzureDiskVolumeSource{ AzureDisk: &v1.AzureDiskVolumeSource{
DiskName: diskName, DiskName: diskName,
DataDiskURI: a.volumeName, DataDiskURI: atr.volumeName,
ReadOnly: &readOnly, ReadOnly: &readOnly,
}, },
} }
@ -1236,13 +1382,16 @@ func (a *azureDriver) GetVolumeSource(readOnly bool, fsType string) *v1.VolumeSo
return &volSource return &volSource
} }
func (a *azureDriver) GetPersistentVolumeSource(readOnly bool, fsType string) *v1.PersistentVolumeSource { func (a *azureDriver) GetPersistentVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.PersistentVolumeSource {
diskName := a.volumeName[(strings.LastIndex(a.volumeName, "/") + 1):] atr, ok := testResource.(*azureTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to Azure Test Resource")
diskName := atr.volumeName[(strings.LastIndex(atr.volumeName, "/") + 1):]
pvSource := v1.PersistentVolumeSource{ pvSource := v1.PersistentVolumeSource{
AzureDisk: &v1.AzureDiskVolumeSource{ AzureDisk: &v1.AzureDiskVolumeSource{
DiskName: diskName, DiskName: diskName,
DataDiskURI: a.volumeName, DataDiskURI: atr.volumeName,
ReadOnly: &readOnly, ReadOnly: &readOnly,
}, },
} }
@ -1270,15 +1419,20 @@ func (a *azureDriver) CreateDriver() {
func (a *azureDriver) CleanupDriver() { func (a *azureDriver) CleanupDriver() {
} }
func (a *azureDriver) CreateVolume(volType testpatterns.TestVolType) { func (a *azureDriver) CreateVolume(volType testpatterns.TestVolType) interface{} {
By("creating a test azure disk volume") By("creating a test azure disk volume")
var err error volumeName, err := framework.CreatePDWithRetry()
a.volumeName, err = framework.CreatePDWithRetry()
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
return &azureTestResource{
volumeName: volumeName,
}
} }
func (a *azureDriver) DeleteVolume(volType testpatterns.TestVolType) { func (a *azureDriver) DeleteVolume(volType testpatterns.TestVolType, testResource interface{}) {
framework.DeletePDWithRetry(a.volumeName) atr, ok := testResource.(*azureTestResource)
Expect(ok).To(BeTrue(), "Failed to cast test resource to Azure Test Resource")
framework.DeletePDWithRetry(atr.volumeName)
} }
// AWS // AWS
@ -1323,7 +1477,7 @@ func (a *awsDriver) SkipUnsupportedTest(pattern testpatterns.TestPattern) {
// TODO: Fix authorization error in attach operation and uncomment below // TODO: Fix authorization error in attach operation and uncomment below
/* /*
func (a *awsDriver) GetVolumeSource(readOnly bool, fsType string) *v1.VolumeSource { func (a *awsDriver) GetVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.VolumeSource {
volSource := v1.VolumeSource{ volSource := v1.VolumeSource{
AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{ AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{
VolumeID: a.volumeName, VolumeID: a.volumeName,
@ -1336,7 +1490,7 @@ func (a *awsDriver) GetVolumeSource(readOnly bool, fsType string) *v1.VolumeSour
return &volSource return &volSource
} }
func (a *awsDriver) GetPersistentVolumeSource(readOnly bool, fsType string) *v1.PersistentVolumeSource { func (a *awsDriver) GetPersistentVolumeSource(readOnly bool, fsType string, testResource interface{}) *v1.PersistentVolumeSource {
pvSource := v1.PersistentVolumeSource{ pvSource := v1.PersistentVolumeSource{
AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{ AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{
VolumeID: a.volumeName, VolumeID: a.volumeName,
@ -1370,14 +1524,14 @@ func (a *awsDriver) CleanupDriver() {
// TODO: Fix authorization error in attach operation and uncomment below // TODO: Fix authorization error in attach operation and uncomment below
/* /*
func (a *awsDriver) CreateVolume(volType testpatterns.TestVolType) { func (a *awsDriver) CreateVolume(volType testpatterns.TestVolType) interface{} {
By("creating a test aws volume") By("creating a test aws volume")
var err error var err error
a.volumeName, err = framework.CreatePDWithRetry() a.volumeName, err = framework.CreatePDWithRetry()
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
} }
func (a *awsDriver) DeleteVolume(volType testpatterns.TestVolType) { func (a *awsDriver) DeleteVolume(volType testpatterns.TestVolType, testResource interface{}) {
framework.DeletePDWithRetry(a.volumeName) framework.DeletePDWithRetry(a.volumeName)
} }
*/ */

View File

@ -125,6 +125,8 @@ type genericVolumeTestResource struct {
pvc *v1.PersistentVolumeClaim pvc *v1.PersistentVolumeClaim
pv *v1.PersistentVolume pv *v1.PersistentVolume
sc *storagev1.StorageClass sc *storagev1.StorageClass
driverTestResource interface{}
} }
var _ TestResource = &genericVolumeTestResource{} var _ TestResource = &genericVolumeTestResource{}
@ -139,19 +141,19 @@ func (r *genericVolumeTestResource) setupResource(driver drivers.TestDriver, pat
volType := pattern.VolType volType := pattern.VolType
// Create volume for pre-provisioned volume tests // Create volume for pre-provisioned volume tests
drivers.CreateVolume(driver, volType) r.driverTestResource = drivers.CreateVolume(driver, volType)
switch volType { switch volType {
case testpatterns.InlineVolume: case testpatterns.InlineVolume:
framework.Logf("Creating resource for inline volume") framework.Logf("Creating resource for inline volume")
if iDriver, ok := driver.(drivers.InlineVolumeTestDriver); ok { if iDriver, ok := driver.(drivers.InlineVolumeTestDriver); ok {
r.volSource = iDriver.GetVolumeSource(false, fsType) r.volSource = iDriver.GetVolumeSource(false, fsType, r.driverTestResource)
r.volType = dInfo.Name r.volType = dInfo.Name
} }
case testpatterns.PreprovisionedPV: case testpatterns.PreprovisionedPV:
framework.Logf("Creating resource for pre-provisioned PV") framework.Logf("Creating resource for pre-provisioned PV")
if pDriver, ok := driver.(drivers.PreprovisionedPVTestDriver); ok { if pDriver, ok := driver.(drivers.PreprovisionedPVTestDriver); ok {
pvSource := pDriver.GetPersistentVolumeSource(false, fsType) pvSource := pDriver.GetPersistentVolumeSource(false, fsType, r.driverTestResource)
if pvSource != nil { if pvSource != nil {
r.volSource, r.pv, r.pvc = createVolumeSourceWithPVCPV(f, dInfo.Name, pvSource, false) r.volSource, r.pv, r.pvc = createVolumeSourceWithPVCPV(f, dInfo.Name, pvSource, false)
} }
@ -202,7 +204,7 @@ func (r *genericVolumeTestResource) cleanupResource(driver drivers.TestDriver, p
} }
// Cleanup volume for pre-provisioned volume tests // Cleanup volume for pre-provisioned volume tests
drivers.DeleteVolume(driver, volType) drivers.DeleteVolume(driver, volType, r.driverTestResource)
} }
func createVolumeSourceWithPVCPV( func createVolumeSourceWithPVCPV(

View File

@ -110,7 +110,7 @@ func (s *subPathTestSuite) execTest(driver drivers.TestDriver, pattern testpatte
needsCleanup = true needsCleanup = true
// Setup test resource for driver and testpattern // Setup test resource for driver and testpattern
resource := subPathTestResource{} resource = subPathTestResource{}
resource.setupResource(driver, pattern) resource.setupResource(driver, pattern)
// Create test input // Create test input
@ -151,7 +151,7 @@ func (s *subPathTestResource) setupResource(driver drivers.TestDriver, pattern t
switch volType { switch volType {
case testpatterns.InlineVolume: case testpatterns.InlineVolume:
if iDriver, ok := driver.(drivers.InlineVolumeTestDriver); ok { if iDriver, ok := driver.(drivers.InlineVolumeTestDriver); ok {
s.roVolSource = iDriver.GetVolumeSource(true, fsType) s.roVolSource = iDriver.GetVolumeSource(true, fsType, s.genericVolumeTestResource.driverTestResource)
} }
case testpatterns.PreprovisionedPV: case testpatterns.PreprovisionedPV:
s.roVolSource = &v1.VolumeSource{ s.roVolSource = &v1.VolumeSource{

View File

@ -121,7 +121,7 @@ func (t *volumeIOTestSuite) execTest(driver drivers.TestDriver, pattern testpatt
needsCleanup = true needsCleanup = true
// Setup test resource for driver and testpattern // Setup test resource for driver and testpattern
resource := genericVolumeTestResource{} resource = genericVolumeTestResource{}
resource.setupResource(driver, pattern) resource.setupResource(driver, pattern)
// Create test input // Create test input

View File

@ -124,7 +124,7 @@ func (t *volumeModeTestSuite) execTest(driver drivers.TestDriver, pattern testpa
needsCleanup = true needsCleanup = true
// Setup test resource for driver and testpattern // Setup test resource for driver and testpattern
resource := volumeModeTestResource{} resource = volumeModeTestResource{}
resource.setupResource(driver, pattern) resource.setupResource(driver, pattern)
// Create test input // Create test input
@ -147,6 +147,8 @@ type volumeModeTestResource struct {
sc *storagev1.StorageClass sc *storagev1.StorageClass
pvc *v1.PersistentVolumeClaim pvc *v1.PersistentVolumeClaim
pv *v1.PersistentVolume pv *v1.PersistentVolume
driverTestResource interface{}
} }
var _ TestResource = &volumeModeTestResource{} var _ TestResource = &volumeModeTestResource{}
@ -167,7 +169,7 @@ func (s *volumeModeTestResource) setupResource(driver drivers.TestDriver, patter
) )
// Create volume for pre-provisioned volume tests // Create volume for pre-provisioned volume tests
drivers.CreateVolume(driver, volType) s.driverTestResource = drivers.CreateVolume(driver, volType)
switch volType { switch volType {
case testpatterns.PreprovisionedPV: case testpatterns.PreprovisionedPV:
@ -177,7 +179,7 @@ func (s *volumeModeTestResource) setupResource(driver drivers.TestDriver, patter
scName = fmt.Sprintf("%s-%s-sc-for-file", ns.Name, dInfo.Name) scName = fmt.Sprintf("%s-%s-sc-for-file", ns.Name, dInfo.Name)
} }
if pDriver, ok := driver.(drivers.PreprovisionedPVTestDriver); ok { if pDriver, ok := driver.(drivers.PreprovisionedPVTestDriver); ok {
pvSource = pDriver.GetPersistentVolumeSource(false, fsType) pvSource = pDriver.GetPersistentVolumeSource(false, fsType, s.driverTestResource)
if pvSource == nil { if pvSource == nil {
framework.Skipf("Driver %q does not define PersistentVolumeSource - skipping", dInfo.Name) framework.Skipf("Driver %q does not define PersistentVolumeSource - skipping", dInfo.Name)
} }
@ -223,7 +225,7 @@ func (s *volumeModeTestResource) cleanupResource(driver drivers.TestDriver, patt
} }
// Cleanup volume for pre-provisioned volume tests // Cleanup volume for pre-provisioned volume tests
drivers.DeleteVolume(driver, volType) drivers.DeleteVolume(driver, volType, s.driverTestResource)
} }
type volumeModeTestInput struct { type volumeModeTestInput struct {

View File

@ -122,7 +122,7 @@ func (t *volumesTestSuite) execTest(driver drivers.TestDriver, pattern testpatte
needsCleanup = true needsCleanup = true
// Setup test resource for driver and testpattern // Setup test resource for driver and testpattern
resource := genericVolumeTestResource{} resource = genericVolumeTestResource{}
resource.setupResource(driver, pattern) resource.setupResource(driver, pattern)
// Create test input // Create test input