@@ -30,6 +30,7 @@ import (
30
30
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
31
31
"k8s.io/kubernetes/pkg/features"
32
32
"k8s.io/kubernetes/pkg/kubelet/images"
33
+ "k8s.io/kubernetes/pkg/kubelet/kuberuntime"
33
34
"k8s.io/kubernetes/test/e2e/feature"
34
35
"k8s.io/kubernetes/test/e2e/framework"
35
36
e2enode "k8s.io/kubernetes/test/e2e/framework/node"
@@ -89,7 +90,6 @@ var _ = SIGDescribe("ImageVolume", feature.ImageVolume, func() {
89
90
90
91
ginkgo .By (fmt .Sprintf ("Creating a pod (%s/%s)" , f .Namespace .Name , podName ))
91
92
e2epod .NewPodClient (f ).Create (ctx , pod )
92
-
93
93
}
94
94
95
95
verifyFileContents := func (podName , volumePath string ) {
@@ -100,7 +100,6 @@ var _ = SIGDescribe("ImageVolume", feature.ImageVolume, func() {
100
100
101
101
secondFileContents := e2epod .ExecCommandInContainer (f , podName , containerName , "/bin/cat" , filepath .Join (volumePath , "etc" , "os-release" ))
102
102
gomega .Expect (secondFileContents ).To (gomega .ContainSubstring ("Alpine Linux" ))
103
-
104
103
}
105
104
106
105
f .It ("should succeed with pod and pull policy of Always" , func (ctx context.Context ) {
@@ -188,7 +187,7 @@ var _ = SIGDescribe("ImageVolume", feature.ImageVolume, func() {
188
187
189
188
ginkgo .By (fmt .Sprintf ("Waiting for the pod (%s/%s) to fail" , f .Namespace .Name , podName ))
190
189
err := e2epod .WaitForPodContainerToFail (ctx , f .ClientSet , f .Namespace .Name , podName , 0 , images .ErrImagePullBackOff .Error (), time .Minute )
191
- framework .ExpectNoError (err , "Failed to await for the pod to be running : (%s/%s)" , f .Namespace .Name , podName )
190
+ framework .ExpectNoError (err , "Failed to await for the pod to be failed : (%s/%s)" , f .Namespace .Name , podName )
192
191
})
193
192
194
193
f .It ("should succeed if image volume is not existing but unused" , func (ctx context.Context ) {
@@ -274,4 +273,72 @@ var _ = SIGDescribe("ImageVolume", feature.ImageVolume, func() {
274
273
275
274
verifyFileContents (podName , volumePathPrefix )
276
275
})
276
+
277
+ f .Context ("subPath" , func () {
278
+ ginkgo .BeforeEach (func (ctx context.Context ) {
279
+ runtime , _ , err := getCRIClient ()
280
+ framework .ExpectNoError (err , "Failed to get CRI client" )
281
+
282
+ version , err := runtime .Version (context .Background (), "" )
283
+ framework .ExpectNoError (err , "Failed to get runtime version" )
284
+
285
+ // TODO: enable the subpath tests if containerd main branch has support for it.
286
+ if version .GetRuntimeName () != "cri-o" {
287
+ e2eskipper .Skip ("runtime is not CRI-O" )
288
+ }
289
+ })
290
+
291
+ f .It ("should succeed when using a valid subPath" , func (ctx context.Context ) {
292
+ var selinuxOptions * v1.SELinuxOptions
293
+ if selinux .GetEnabled () {
294
+ selinuxOptions = & v1.SELinuxOptions {
295
+ User : defaultSELinuxUser ,
296
+ Role : defaultSELinuxRole ,
297
+ Type : defaultSELinuxType ,
298
+ Level : defaultSELinuxLevel ,
299
+ }
300
+ ginkgo .By (fmt .Sprintf ("Using SELinux on pod: %v" , selinuxOptions ))
301
+ }
302
+
303
+ createPod (ctx ,
304
+ podName ,
305
+ "" ,
306
+ []v1.Volume {{Name : volumeName , VolumeSource : v1.VolumeSource {Image : & v1.ImageVolumeSource {Reference : volumeImage }}}},
307
+ []v1.VolumeMount {{Name : volumeName , MountPath : volumePathPrefix , SubPath : "etc" }},
308
+ selinuxOptions ,
309
+ )
310
+
311
+ ginkgo .By (fmt .Sprintf ("Waiting for the pod (%s/%s) to be running" , f .Namespace .Name , podName ))
312
+ err := e2epod .WaitForPodNameRunningInNamespace (ctx , f .ClientSet , podName , f .Namespace .Name )
313
+ framework .ExpectNoError (err , "Failed to await for the pod to be running: (%s/%s)" , f .Namespace .Name , podName )
314
+
315
+ fileContent := e2epod .ExecCommandInContainer (f , podName , containerName , "/bin/cat" , filepath .Join (volumePathPrefix , "os-release" ))
316
+ gomega .Expect (fileContent ).To (gomega .ContainSubstring ("Alpine Linux" ))
317
+ })
318
+
319
+ f .It ("should fail if subPath in volume is not existing" , func (ctx context.Context ) {
320
+ var selinuxOptions * v1.SELinuxOptions
321
+ if selinux .GetEnabled () {
322
+ selinuxOptions = & v1.SELinuxOptions {
323
+ User : defaultSELinuxUser ,
324
+ Role : defaultSELinuxRole ,
325
+ Type : defaultSELinuxType ,
326
+ Level : defaultSELinuxLevel ,
327
+ }
328
+ ginkgo .By (fmt .Sprintf ("Using SELinux on pod: %v" , selinuxOptions ))
329
+ }
330
+
331
+ createPod (ctx ,
332
+ podName ,
333
+ "" ,
334
+ []v1.Volume {{Name : volumeName , VolumeSource : v1.VolumeSource {Image : & v1.ImageVolumeSource {Reference : volumeImage }}}},
335
+ []v1.VolumeMount {{Name : volumeName , MountPath : volumePathPrefix , SubPath : "not-existing" }},
336
+ selinuxOptions ,
337
+ )
338
+
339
+ ginkgo .By (fmt .Sprintf ("Waiting for the pod (%s/%s) to fail" , f .Namespace .Name , podName ))
340
+ err := e2epod .WaitForPodContainerToFail (ctx , f .ClientSet , f .Namespace .Name , podName , 0 , kuberuntime .ErrCreateContainer .Error (), time .Minute )
341
+ framework .ExpectNoError (err , "Failed to await for the pod to be failed: (%s/%s)" , f .Namespace .Name , podName )
342
+ })
343
+ })
277
344
})
0 commit comments