Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
d1eb8a61
Commit
d1eb8a61
authored
Nov 20, 2017
by
Luis Pabón
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
e2e: CSI Volume tests
This e2e test tests the CSI volume plugin in kubernetes with a CSI hostPath driver. It is also setup to be able to be tested with more drivers in the future.
parent
3d652cae
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
544 additions
and
94 deletions
+544
-94
BUILD
test/e2e/storage/BUILD
+3
-0
csi_hostpath.go
test/e2e/storage/csi_hostpath.go
+199
-0
csi_volumes.go
test/e2e/storage/csi_volumes.go
+243
-0
volume_provisioning.go
test/e2e/storage/volume_provisioning.go
+99
-94
No files found.
test/e2e/storage/BUILD
View file @
d1eb8a61
...
@@ -8,6 +8,8 @@ load(
...
@@ -8,6 +8,8 @@ load(
go_library(
go_library(
name = "go_default_library",
name = "go_default_library",
srcs = [
srcs = [
"csi_hostpath.go",
"csi_volumes.go",
"empty_dir_wrapper.go",
"empty_dir_wrapper.go",
"flexvolume.go",
"flexvolume.go",
"pd.go",
"pd.go",
...
@@ -47,6 +49,7 @@ go_library(
...
@@ -47,6 +49,7 @@ go_library(
"//vendor/k8s.io/api/batch/v1:go_default_library",
"//vendor/k8s.io/api/batch/v1:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/api/policy/v1beta1:go_default_library",
"//vendor/k8s.io/api/policy/v1beta1:go_default_library",
"//vendor/k8s.io/api/rbac/v1:go_default_library",
"//vendor/k8s.io/api/rbac/v1beta1:go_default_library",
"//vendor/k8s.io/api/rbac/v1beta1:go_default_library",
"//vendor/k8s.io/api/storage/v1:go_default_library",
"//vendor/k8s.io/api/storage/v1:go_default_library",
"//vendor/k8s.io/api/storage/v1beta1:go_default_library",
"//vendor/k8s.io/api/storage/v1beta1:go_default_library",
...
...
test/e2e/storage/csi_hostpath.go
0 → 100644
View file @
d1eb8a61
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// This file is used to deploy the CSI hostPath plugin
// More Information: https://github.com/kubernetes-csi/drivers/tree/master/pkg/hostpath
package
storage
import
(
"k8s.io/api/core/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
clientset
"k8s.io/client-go/kubernetes"
"k8s.io/kubernetes/test/e2e/framework"
)
const
(
csiHostPathPluginImage
string
=
"docker.io/k8scsi/hostpathplugin:0.1"
)
func
csiHostPathPod
(
client
clientset
.
Interface
,
config
framework
.
VolumeTestConfig
,
teardown
bool
,
f
*
framework
.
Framework
,
sa
*
v1
.
ServiceAccount
,
)
*
v1
.
Pod
{
podClient
:=
client
.
CoreV1
()
.
Pods
(
config
.
Namespace
)
priv
:=
true
mountPropagation
:=
v1
.
MountPropagationBidirectional
hostPathType
:=
v1
.
HostPathDirectoryOrCreate
pod
:=
&
v1
.
Pod
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
config
.
Prefix
+
"-pod"
,
Namespace
:
config
.
Namespace
,
Labels
:
map
[
string
]
string
{
"app"
:
"hostpath-driver"
,
},
},
Spec
:
v1
.
PodSpec
{
ServiceAccountName
:
sa
.
GetName
(),
NodeName
:
config
.
ServerNodeName
,
RestartPolicy
:
v1
.
RestartPolicyNever
,
Containers
:
[]
v1
.
Container
{
{
Name
:
"external-provisioner"
,
Image
:
csiExternalProvisionerImage
,
ImagePullPolicy
:
v1
.
PullAlways
,
Args
:
[]
string
{
"--v=5"
,
"--provisioner=csi-hostpath"
,
"--csi-address=/csi/csi.sock"
,
},
VolumeMounts
:
[]
v1
.
VolumeMount
{
{
Name
:
"socket-dir"
,
MountPath
:
"/csi"
,
},
},
},
{
Name
:
"driver-registrar"
,
Image
:
csiDriverRegistrarImage
,
ImagePullPolicy
:
v1
.
PullAlways
,
Args
:
[]
string
{
"--v=5"
,
"--csi-address=/csi/csi.sock"
,
},
Env
:
[]
v1
.
EnvVar
{
{
Name
:
"KUBE_NODE_NAME"
,
ValueFrom
:
&
v1
.
EnvVarSource
{
FieldRef
:
&
v1
.
ObjectFieldSelector
{
FieldPath
:
"spec.nodeName"
,
},
},
},
},
VolumeMounts
:
[]
v1
.
VolumeMount
{
{
Name
:
"socket-dir"
,
MountPath
:
"/csi"
,
},
},
},
{
Name
:
"external-attacher"
,
Image
:
csiExternalAttacherImage
,
ImagePullPolicy
:
v1
.
PullAlways
,
Args
:
[]
string
{
"--v=5"
,
"--csi-address=$(ADDRESS)"
,
},
Env
:
[]
v1
.
EnvVar
{
{
Name
:
"ADDRESS"
,
Value
:
"/csi/csi.sock"
,
},
},
VolumeMounts
:
[]
v1
.
VolumeMount
{
{
Name
:
"socket-dir"
,
MountPath
:
"/csi"
,
},
},
},
{
Name
:
"hostpath-driver"
,
Image
:
csiHostPathPluginImage
,
ImagePullPolicy
:
v1
.
PullAlways
,
SecurityContext
:
&
v1
.
SecurityContext
{
Privileged
:
&
priv
,
},
Args
:
[]
string
{
"--v=5"
,
"--endpoint=$(CSI_ENDPOINT)"
,
"--nodeid=$(KUBE_NODE_NAME)"
,
},
Env
:
[]
v1
.
EnvVar
{
{
Name
:
"CSI_ENDPOINT"
,
Value
:
"unix://"
+
"/csi/csi.sock"
,
},
{
Name
:
"KUBE_NODE_NAME"
,
ValueFrom
:
&
v1
.
EnvVarSource
{
FieldRef
:
&
v1
.
ObjectFieldSelector
{
FieldPath
:
"spec.nodeName"
,
},
},
},
},
VolumeMounts
:
[]
v1
.
VolumeMount
{
{
Name
:
"socket-dir"
,
MountPath
:
"/csi"
,
},
{
Name
:
"mountpoint-dir"
,
MountPath
:
"/var/lib/kubelet/pods"
,
MountPropagation
:
&
mountPropagation
,
},
},
},
},
Volumes
:
[]
v1
.
Volume
{
{
Name
:
"socket-dir"
,
VolumeSource
:
v1
.
VolumeSource
{
HostPath
:
&
v1
.
HostPathVolumeSource
{
Path
:
"/var/lib/kubelet/plugins/csi-hostpath"
,
Type
:
&
hostPathType
,
},
},
},
{
Name
:
"mountpoint-dir"
,
VolumeSource
:
v1
.
VolumeSource
{
HostPath
:
&
v1
.
HostPathVolumeSource
{
Path
:
"/var/lib/kubelet/pods"
,
Type
:
&
hostPathType
,
},
},
},
},
},
}
err
:=
framework
.
DeletePodWithWait
(
f
,
client
,
pod
)
framework
.
ExpectNoError
(
err
,
"Failed to delete pod %s/%s: %v"
,
pod
.
GetNamespace
(),
pod
.
GetName
(),
err
)
if
teardown
{
return
nil
}
ret
,
err
:=
podClient
.
Create
(
pod
)
if
err
!=
nil
{
framework
.
ExpectNoError
(
err
,
"Failed to create %q pod: %v"
,
pod
.
GetName
(),
err
)
}
// Wait for pod to come up
framework
.
ExpectNoError
(
framework
.
WaitForPodRunningInNamespace
(
client
,
ret
))
return
ret
}
test/e2e/storage/csi_volumes.go
0 → 100644
View file @
d1eb8a61
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package
storage
import
(
"math/rand"
"time"
"k8s.io/api/core/v1"
rbacv1
"k8s.io/api/rbac/v1"
apierrs
"k8s.io/apimachinery/pkg/api/errors"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
clientset
"k8s.io/client-go/kubernetes"
"k8s.io/kubernetes/test/e2e/framework"
"k8s.io/kubernetes/test/e2e/storage/utils"
.
"github.com/onsi/ginkgo"
)
const
(
csiExternalAttacherImage
string
=
"docker.io/k8scsi/csi-attacher:0.1"
csiExternalProvisionerImage
string
=
"docker.io/k8scsi/csi-provisioner:0.1"
csiDriverRegistrarImage
string
=
"docker.io/k8scsi/driver-registrar"
)
func
externalAttacherServiceAccount
(
client
clientset
.
Interface
,
config
framework
.
VolumeTestConfig
,
teardown
bool
,
)
*
v1
.
ServiceAccount
{
serviceAccountName
:=
config
.
Prefix
+
"-service-account"
serviceAccountClient
:=
client
.
CoreV1
()
.
ServiceAccounts
(
config
.
Namespace
)
sa
:=
&
v1
.
ServiceAccount
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
serviceAccountName
,
},
}
serviceAccountClient
.
Delete
(
sa
.
GetName
(),
&
metav1
.
DeleteOptions
{})
err
:=
wait
.
Poll
(
2
*
time
.
Second
,
10
*
time
.
Minute
,
func
()
(
bool
,
error
)
{
_
,
err
:=
serviceAccountClient
.
Get
(
sa
.
GetName
(),
metav1
.
GetOptions
{})
return
apierrs
.
IsNotFound
(
err
),
nil
})
framework
.
ExpectNoError
(
err
,
"Timed out waiting for deletion: %v"
,
err
)
if
teardown
{
return
nil
}
ret
,
err
:=
serviceAccountClient
.
Create
(
sa
)
if
err
!=
nil
{
framework
.
ExpectNoError
(
err
,
"Failed to create %s service account: %v"
,
sa
.
GetName
(),
err
)
}
return
ret
}
func
externalAttacherClusterRole
(
client
clientset
.
Interface
,
config
framework
.
VolumeTestConfig
,
teardown
bool
,
)
*
rbacv1
.
ClusterRole
{
clusterRoleClient
:=
client
.
RbacV1
()
.
ClusterRoles
()
role
:=
&
rbacv1
.
ClusterRole
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
config
.
Prefix
+
"-cluster-role"
,
},
Rules
:
[]
rbacv1
.
PolicyRule
{
{
APIGroups
:
[]
string
{
""
},
Resources
:
[]
string
{
"persistentvolumes"
},
Verbs
:
[]
string
{
"create"
,
"delete"
,
"get"
,
"list"
,
"watch"
,
"update"
},
},
{
APIGroups
:
[]
string
{
""
},
Resources
:
[]
string
{
"persistentvolumesclaims"
},
Verbs
:
[]
string
{
"get"
,
"list"
,
"watch"
,
"update"
},
},
{
APIGroups
:
[]
string
{
""
},
Resources
:
[]
string
{
"nodes"
},
Verbs
:
[]
string
{
"get"
,
"list"
,
"watch"
,
"update"
},
},
{
APIGroups
:
[]
string
{
"storage.k8s.io"
},
Resources
:
[]
string
{
"volumeattachments"
},
Verbs
:
[]
string
{
"get"
,
"list"
,
"watch"
,
"update"
},
},
{
APIGroups
:
[]
string
{
"storage.k8s.io"
},
Resources
:
[]
string
{
"storageclasses"
},
Verbs
:
[]
string
{
"get"
,
"list"
,
"watch"
},
},
},
}
clusterRoleClient
.
Delete
(
role
.
GetName
(),
&
metav1
.
DeleteOptions
{})
err
:=
wait
.
Poll
(
2
*
time
.
Second
,
10
*
time
.
Minute
,
func
()
(
bool
,
error
)
{
_
,
err
:=
clusterRoleClient
.
Get
(
role
.
GetName
(),
metav1
.
GetOptions
{})
return
apierrs
.
IsNotFound
(
err
),
nil
})
framework
.
ExpectNoError
(
err
,
"Timed out waiting for deletion: %v"
,
err
)
if
teardown
{
return
nil
}
ret
,
err
:=
clusterRoleClient
.
Create
(
role
)
if
err
!=
nil
{
framework
.
ExpectNoError
(
err
,
"Failed to create %s cluster role: %v"
,
role
.
GetName
(),
err
)
}
return
ret
}
func
externalAttacherClusterRoleBinding
(
client
clientset
.
Interface
,
config
framework
.
VolumeTestConfig
,
teardown
bool
,
sa
*
v1
.
ServiceAccount
,
clusterRole
*
rbacv1
.
ClusterRole
,
)
*
rbacv1
.
ClusterRoleBinding
{
clusterRoleBindingClient
:=
client
.
RbacV1
()
.
ClusterRoleBindings
()
binding
:=
&
rbacv1
.
ClusterRoleBinding
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
config
.
Prefix
+
"-role-binding"
,
},
Subjects
:
[]
rbacv1
.
Subject
{
{
Kind
:
"ServiceAccount"
,
Name
:
sa
.
GetName
(),
Namespace
:
sa
.
GetNamespace
(),
},
},
RoleRef
:
rbacv1
.
RoleRef
{
Kind
:
"ClusterRole"
,
Name
:
clusterRole
.
GetName
(),
APIGroup
:
"rbac.authorization.k8s.io"
,
},
}
clusterRoleBindingClient
.
Delete
(
binding
.
GetName
(),
&
metav1
.
DeleteOptions
{})
err
:=
wait
.
Poll
(
2
*
time
.
Second
,
10
*
time
.
Minute
,
func
()
(
bool
,
error
)
{
_
,
err
:=
clusterRoleBindingClient
.
Get
(
binding
.
GetName
(),
metav1
.
GetOptions
{})
return
apierrs
.
IsNotFound
(
err
),
nil
})
framework
.
ExpectNoError
(
err
,
"Timed out waiting for deletion: %v"
,
err
)
if
teardown
{
return
nil
}
ret
,
err
:=
clusterRoleBindingClient
.
Create
(
binding
)
if
err
!=
nil
{
framework
.
ExpectNoError
(
err
,
"Failed to create %s role binding: %v"
,
binding
.
GetName
(),
err
)
}
return
ret
}
var
_
=
utils
.
SIGDescribe
(
"CSI Volumes [Feature:CSI]"
,
func
()
{
f
:=
framework
.
NewDefaultFramework
(
"csi-mock-plugin"
)
var
(
cs
clientset
.
Interface
ns
*
v1
.
Namespace
node
v1
.
Node
config
framework
.
VolumeTestConfig
suffix
string
)
BeforeEach
(
func
()
{
cs
=
f
.
ClientSet
ns
=
f
.
Namespace
nodes
:=
framework
.
GetReadySchedulableNodesOrDie
(
f
.
ClientSet
)
node
=
nodes
.
Items
[
rand
.
Intn
(
len
(
nodes
.
Items
))]
config
=
framework
.
VolumeTestConfig
{
Namespace
:
ns
.
Name
,
Prefix
:
"csi"
,
ClientNodeName
:
node
.
Name
,
ServerNodeName
:
node
.
Name
,
WaitForCompletion
:
true
,
}
suffix
=
ns
.
Name
})
// Create one of these for each of the drivers to be tested
// CSI hostPath driver test
Describe
(
"Sanity CSI plugin test using hostPath CSI driver"
,
func
()
{
var
(
clusterRole
*
rbacv1
.
ClusterRole
serviceAccount
*
v1
.
ServiceAccount
)
BeforeEach
(
func
()
{
By
(
"deploying csi hostpath driver"
)
clusterRole
=
externalAttacherClusterRole
(
cs
,
config
,
false
)
serviceAccount
=
externalAttacherServiceAccount
(
cs
,
config
,
false
)
externalAttacherClusterRoleBinding
(
cs
,
config
,
false
,
serviceAccount
,
clusterRole
)
csiHostPathPod
(
cs
,
config
,
false
,
f
,
serviceAccount
)
})
AfterEach
(
func
()
{
By
(
"uninstalling csi hostpath driver"
)
csiHostPathPod
(
cs
,
config
,
true
,
f
,
serviceAccount
)
externalAttacherClusterRoleBinding
(
cs
,
config
,
true
,
serviceAccount
,
clusterRole
)
serviceAccount
=
externalAttacherServiceAccount
(
cs
,
config
,
true
)
clusterRole
=
externalAttacherClusterRole
(
cs
,
config
,
true
)
})
It
(
"should provision storage with a hostPath CSI driver"
,
func
()
{
t
:=
storageClassTest
{
name
:
"csi-hostpath"
,
provisioner
:
"csi-hostpath"
,
parameters
:
map
[
string
]
string
{},
claimSize
:
"1Gi"
,
expectedSize
:
"1Gi"
,
nodeName
:
node
.
Name
,
}
claim
:=
newClaim
(
t
,
ns
.
GetName
(),
""
)
class
:=
newStorageClass
(
t
,
ns
.
GetName
(),
""
)
testDynamicProvisioning
(
t
,
cs
,
claim
,
class
)
})
})
})
test/e2e/storage/volume_provisioning.go
View file @
d1eb8a61
...
@@ -56,6 +56,7 @@ type storageClassTest struct {
...
@@ -56,6 +56,7 @@ type storageClassTest struct {
claimSize
string
claimSize
string
expectedSize
string
expectedSize
string
pvCheck
func
(
volume
*
v1
.
PersistentVolume
)
error
pvCheck
func
(
volume
*
v1
.
PersistentVolume
)
error
nodeName
string
}
}
const
(
const
(
...
@@ -139,10 +140,10 @@ func testDynamicProvisioning(t storageClassTest, client clientset.Interface, cla
...
@@ -139,10 +140,10 @@ func testDynamicProvisioning(t storageClassTest, client clientset.Interface, cla
// Get entry, get mount options at 6th word, replace brackets with commas
// Get entry, get mount options at 6th word, replace brackets with commas
command
+=
fmt
.
Sprintf
(
" && ( mount | grep 'on /mnt/test' | awk '{print $6}' | sed 's/^(/,/; s/)$/,/' | grep -q ,%s, )"
,
option
)
command
+=
fmt
.
Sprintf
(
" && ( mount | grep 'on /mnt/test' | awk '{print $6}' | sed 's/^(/,/; s/)$/,/' | grep -q ,%s, )"
,
option
)
}
}
runInPodWithVolume
(
client
,
claim
.
Namespace
,
claim
.
Name
,
command
)
runInPodWithVolume
(
client
,
claim
.
Namespace
,
claim
.
Name
,
t
.
nodeName
,
command
)
By
(
"checking the created volume is readable and retains data"
)
By
(
"checking the created volume is readable and retains data"
)
runInPodWithVolume
(
client
,
claim
.
Namespace
,
claim
.
Name
,
"grep 'hello world' /mnt/test/data"
)
runInPodWithVolume
(
client
,
claim
.
Namespace
,
claim
.
Name
,
t
.
nodeName
,
"grep 'hello world' /mnt/test/data"
)
By
(
fmt
.
Sprintf
(
"deleting claim %q/%q"
,
claim
.
Namespace
,
claim
.
Name
))
By
(
fmt
.
Sprintf
(
"deleting claim %q/%q"
,
claim
.
Namespace
,
claim
.
Name
))
framework
.
ExpectNoError
(
client
.
CoreV1
()
.
PersistentVolumeClaims
(
claim
.
Namespace
)
.
Delete
(
claim
.
Name
,
nil
))
framework
.
ExpectNoError
(
client
.
CoreV1
()
.
PersistentVolumeClaims
(
claim
.
Namespace
)
.
Delete
(
claim
.
Name
,
nil
))
...
@@ -250,140 +251,140 @@ var _ = utils.SIGDescribe("Dynamic Provisioning", func() {
...
@@ -250,140 +251,140 @@ var _ = utils.SIGDescribe("Dynamic Provisioning", func() {
// that can be used to persist data among pods.
// that can be used to persist data among pods.
tests
:=
[]
storageClassTest
{
tests
:=
[]
storageClassTest
{
{
{
"SSD PD on GCE/GKE"
,
name
:
"SSD PD on GCE/GKE"
,
[]
string
{
"gce"
,
"gke"
},
cloudProviders
:
[]
string
{
"gce"
,
"gke"
},
"kubernetes.io/gce-pd"
,
provisioner
:
"kubernetes.io/gce-pd"
,
map
[
string
]
string
{
parameters
:
map
[
string
]
string
{
"type"
:
"pd-ssd"
,
"type"
:
"pd-ssd"
,
"zone"
:
cloudZone
,
"zone"
:
cloudZone
,
},
},
"1.5G"
,
claimSize
:
"1.5G"
,
"2G"
,
expectedSize
:
"2G"
,
func
(
volume
*
v1
.
PersistentVolume
)
error
{
pvCheck
:
func
(
volume
*
v1
.
PersistentVolume
)
error
{
return
checkGCEPD
(
volume
,
"pd-ssd"
)
return
checkGCEPD
(
volume
,
"pd-ssd"
)
},
},
},
},
{
{
"HDD PD on GCE/GKE"
,
name
:
"HDD PD on GCE/GKE"
,
[]
string
{
"gce"
,
"gke"
},
cloudProviders
:
[]
string
{
"gce"
,
"gke"
},
"kubernetes.io/gce-pd"
,
provisioner
:
"kubernetes.io/gce-pd"
,
map
[
string
]
string
{
parameters
:
map
[
string
]
string
{
"type"
:
"pd-standard"
,
"type"
:
"pd-standard"
,
},
},
"1.5G"
,
claimSize
:
"1.5G"
,
"2G"
,
expectedSize
:
"2G"
,
func
(
volume
*
v1
.
PersistentVolume
)
error
{
pvCheck
:
func
(
volume
*
v1
.
PersistentVolume
)
error
{
return
checkGCEPD
(
volume
,
"pd-standard"
)
return
checkGCEPD
(
volume
,
"pd-standard"
)
},
},
},
},
// AWS
// AWS
{
{
"gp2 EBS on AWS"
,
name
:
"gp2 EBS on AWS"
,
[]
string
{
"aws"
},
cloudProviders
:
[]
string
{
"aws"
},
"kubernetes.io/aws-ebs"
,
provisioner
:
"kubernetes.io/aws-ebs"
,
map
[
string
]
string
{
parameters
:
map
[
string
]
string
{
"type"
:
"gp2"
,
"type"
:
"gp2"
,
"zone"
:
cloudZone
,
"zone"
:
cloudZone
,
},
},
"1.5Gi"
,
claimSize
:
"1.5Gi"
,
"2Gi"
,
expectedSize
:
"2Gi"
,
func
(
volume
*
v1
.
PersistentVolume
)
error
{
pvCheck
:
func
(
volume
*
v1
.
PersistentVolume
)
error
{
return
checkAWSEBS
(
volume
,
"gp2"
,
false
)
return
checkAWSEBS
(
volume
,
"gp2"
,
false
)
},
},
},
},
{
{
"io1 EBS on AWS"
,
name
:
"io1 EBS on AWS"
,
[]
string
{
"aws"
},
cloudProviders
:
[]
string
{
"aws"
},
"kubernetes.io/aws-ebs"
,
provisioner
:
"kubernetes.io/aws-ebs"
,
map
[
string
]
string
{
parameters
:
map
[
string
]
string
{
"type"
:
"io1"
,
"type"
:
"io1"
,
"iopsPerGB"
:
"50"
,
"iopsPerGB"
:
"50"
,
},
},
"3.5Gi"
,
claimSize
:
"3.5Gi"
,
"4Gi"
,
// 4 GiB is minimum for io1
expectedSize
:
"4Gi"
,
// 4 GiB is minimum for io1
func
(
volume
*
v1
.
PersistentVolume
)
error
{
pvCheck
:
func
(
volume
*
v1
.
PersistentVolume
)
error
{
return
checkAWSEBS
(
volume
,
"io1"
,
false
)
return
checkAWSEBS
(
volume
,
"io1"
,
false
)
},
},
},
},
{
{
"sc1 EBS on AWS"
,
name
:
"sc1 EBS on AWS"
,
[]
string
{
"aws"
},
cloudProviders
:
[]
string
{
"aws"
},
"kubernetes.io/aws-ebs"
,
provisioner
:
"kubernetes.io/aws-ebs"
,
map
[
string
]
string
{
parameters
:
map
[
string
]
string
{
"type"
:
"sc1"
,
"type"
:
"sc1"
,
},
},
"500Gi"
,
// minimum for sc1
claimSize
:
"500Gi"
,
// minimum for sc1
"500Gi"
,
expectedSize
:
"500Gi"
,
func
(
volume
*
v1
.
PersistentVolume
)
error
{
pvCheck
:
func
(
volume
*
v1
.
PersistentVolume
)
error
{
return
checkAWSEBS
(
volume
,
"sc1"
,
false
)
return
checkAWSEBS
(
volume
,
"sc1"
,
false
)
},
},
},
},
{
{
"st1 EBS on AWS"
,
name
:
"st1 EBS on AWS"
,
[]
string
{
"aws"
},
cloudProviders
:
[]
string
{
"aws"
},
"kubernetes.io/aws-ebs"
,
provisioner
:
"kubernetes.io/aws-ebs"
,
map
[
string
]
string
{
parameters
:
map
[
string
]
string
{
"type"
:
"st1"
,
"type"
:
"st1"
,
},
},
"500Gi"
,
// minimum for st1
claimSize
:
"500Gi"
,
// minimum for st1
"500Gi"
,
expectedSize
:
"500Gi"
,
func
(
volume
*
v1
.
PersistentVolume
)
error
{
pvCheck
:
func
(
volume
*
v1
.
PersistentVolume
)
error
{
return
checkAWSEBS
(
volume
,
"st1"
,
false
)
return
checkAWSEBS
(
volume
,
"st1"
,
false
)
},
},
},
},
{
{
"encrypted EBS on AWS"
,
name
:
"encrypted EBS on AWS"
,
[]
string
{
"aws"
},
cloudProviders
:
[]
string
{
"aws"
},
"kubernetes.io/aws-ebs"
,
provisioner
:
"kubernetes.io/aws-ebs"
,
map
[
string
]
string
{
parameters
:
map
[
string
]
string
{
"encrypted"
:
"true"
,
"encrypted"
:
"true"
,
},
},
"1Gi"
,
claimSize
:
"1Gi"
,
"1Gi"
,
expectedSize
:
"1Gi"
,
func
(
volume
*
v1
.
PersistentVolume
)
error
{
pvCheck
:
func
(
volume
*
v1
.
PersistentVolume
)
error
{
return
checkAWSEBS
(
volume
,
"gp2"
,
true
)
return
checkAWSEBS
(
volume
,
"gp2"
,
true
)
},
},
},
},
// OpenStack generic tests (works on all OpenStack deployments)
// OpenStack generic tests (works on all OpenStack deployments)
{
{
"generic Cinder volume on OpenStack"
,
name
:
"generic Cinder volume on OpenStack"
,
[]
string
{
"openstack"
},
cloudProviders
:
[]
string
{
"openstack"
},
"kubernetes.io/cinder"
,
provisioner
:
"kubernetes.io/cinder"
,
map
[
string
]
string
{},
parameters
:
map
[
string
]
string
{},
"1.5Gi"
,
claimSize
:
"1.5Gi"
,
"2Gi"
,
expectedSize
:
"2Gi"
,
nil
,
// there is currently nothing to check on OpenStack
pvCheck
:
nil
,
// there is currently nothing to check on OpenStack
},
},
{
{
"Cinder volume with empty volume type and zone on OpenStack"
,
name
:
"Cinder volume with empty volume type and zone on OpenStack"
,
[]
string
{
"openstack"
},
cloudProviders
:
[]
string
{
"openstack"
},
"kubernetes.io/cinder"
,
provisioner
:
"kubernetes.io/cinder"
,
map
[
string
]
string
{
parameters
:
map
[
string
]
string
{
"type"
:
""
,
"type"
:
""
,
"availability"
:
""
,
"availability"
:
""
,
},
},
"1.5Gi"
,
claimSize
:
"1.5Gi"
,
"2Gi"
,
expectedSize
:
"2Gi"
,
nil
,
// there is currently nothing to check on OpenStack
pvCheck
:
nil
,
// there is currently nothing to check on OpenStack
},
},
// vSphere generic test
// vSphere generic test
{
{
"generic vSphere volume"
,
name
:
"generic vSphere volume"
,
[]
string
{
"vsphere"
},
cloudProviders
:
[]
string
{
"vsphere"
},
"kubernetes.io/vsphere-volume"
,
provisioner
:
"kubernetes.io/vsphere-volume"
,
map
[
string
]
string
{},
parameters
:
map
[
string
]
string
{},
"1.5Gi"
,
claimSize
:
"1.5Gi"
,
"1.5Gi"
,
expectedSize
:
"1.5Gi"
,
nil
,
pvCheck
:
nil
,
},
},
{
{
"Azure disk volume with empty sku and location"
,
name
:
"Azure disk volume with empty sku and location"
,
[]
string
{
"azure"
},
cloudProviders
:
[]
string
{
"azure"
},
"kubernetes.io/azure-disk"
,
provisioner
:
"kubernetes.io/azure-disk"
,
map
[
string
]
string
{},
parameters
:
map
[
string
]
string
{},
"1Gi"
,
claimSize
:
"1Gi"
,
"1Gi"
,
expectedSize
:
"1Gi"
,
nil
,
pvCheck
:
nil
,
},
},
}
}
...
@@ -430,15 +431,15 @@ var _ = utils.SIGDescribe("Dynamic Provisioning", func() {
...
@@ -430,15 +431,15 @@ var _ = utils.SIGDescribe("Dynamic Provisioning", func() {
framework
.
SkipUnlessProviderIs
(
"gce"
,
"gke"
)
framework
.
SkipUnlessProviderIs
(
"gce"
,
"gke"
)
test
:=
storageClassTest
{
test
:=
storageClassTest
{
"HDD PD on GCE/GKE"
,
name
:
"HDD PD on GCE/GKE"
,
[]
string
{
"gce"
,
"gke"
},
cloudProviders
:
[]
string
{
"gce"
,
"gke"
},
"kubernetes.io/gce-pd"
,
provisioner
:
"kubernetes.io/gce-pd"
,
map
[
string
]
string
{
parameters
:
map
[
string
]
string
{
"type"
:
"pd-standard"
,
"type"
:
"pd-standard"
,
},
},
"1G"
,
claimSize
:
"1G"
,
"1G"
,
expectedSize
:
"1G"
,
func
(
volume
*
v1
.
PersistentVolume
)
error
{
pvCheck
:
func
(
volume
*
v1
.
PersistentVolume
)
error
{
return
checkGCEPD
(
volume
,
"pd-standard"
)
return
checkGCEPD
(
volume
,
"pd-standard"
)
},
},
}
}
...
@@ -464,15 +465,15 @@ var _ = utils.SIGDescribe("Dynamic Provisioning", func() {
...
@@ -464,15 +465,15 @@ var _ = utils.SIGDescribe("Dynamic Provisioning", func() {
framework
.
SkipUnlessProviderIs
(
"gce"
,
"gke"
)
framework
.
SkipUnlessProviderIs
(
"gce"
,
"gke"
)
test
:=
storageClassTest
{
test
:=
storageClassTest
{
"HDD PD on GCE/GKE"
,
name
:
"HDD PD on GCE/GKE"
,
[]
string
{
"gce"
,
"gke"
},
cloudProviders
:
[]
string
{
"gce"
,
"gke"
},
"kubernetes.io/gce-pd"
,
provisioner
:
"kubernetes.io/gce-pd"
,
map
[
string
]
string
{
parameters
:
map
[
string
]
string
{
"type"
:
"pd-standard"
,
"type"
:
"pd-standard"
,
},
},
"1G"
,
claimSize
:
"1G"
,
"1G"
,
expectedSize
:
"1G"
,
func
(
volume
*
v1
.
PersistentVolume
)
error
{
pvCheck
:
func
(
volume
*
v1
.
PersistentVolume
)
error
{
return
checkGCEPD
(
volume
,
"pd-standard"
)
return
checkGCEPD
(
volume
,
"pd-standard"
)
},
},
}
}
...
@@ -791,7 +792,7 @@ func newClaim(t storageClassTest, ns, suffix string) *v1.PersistentVolumeClaim {
...
@@ -791,7 +792,7 @@ func newClaim(t storageClassTest, ns, suffix string) *v1.PersistentVolumeClaim {
}
}
// runInPodWithVolume runs a command in a pod with given claim mounted to /mnt directory.
// runInPodWithVolume runs a command in a pod with given claim mounted to /mnt directory.
func
runInPodWithVolume
(
c
clientset
.
Interface
,
ns
,
claimName
,
command
string
)
{
func
runInPodWithVolume
(
c
clientset
.
Interface
,
ns
,
claimName
,
nodeName
,
command
string
)
{
pod
:=
&
v1
.
Pod
{
pod
:=
&
v1
.
Pod
{
TypeMeta
:
metav1
.
TypeMeta
{
TypeMeta
:
metav1
.
TypeMeta
{
Kind
:
"Pod"
,
Kind
:
"Pod"
,
...
@@ -829,6 +830,10 @@ func runInPodWithVolume(c clientset.Interface, ns, claimName, command string) {
...
@@ -829,6 +830,10 @@ func runInPodWithVolume(c clientset.Interface, ns, claimName, command string) {
},
},
},
},
}
}
if
len
(
nodeName
)
!=
0
{
pod
.
Spec
.
NodeName
=
nodeName
}
pod
,
err
:=
c
.
CoreV1
()
.
Pods
(
ns
)
.
Create
(
pod
)
pod
,
err
:=
c
.
CoreV1
()
.
Pods
(
ns
)
.
Create
(
pod
)
framework
.
ExpectNoError
(
err
,
"Failed to create pod: %v"
,
err
)
framework
.
ExpectNoError
(
err
,
"Failed to create pod: %v"
,
err
)
defer
func
()
{
defer
func
()
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment