@@ -369,6 +369,12 @@ type hostPathDriver struct {
369
369
driverInfo storageframework.DriverInfo
370
370
}
371
371
372
+ type hostPathVolume struct {
373
+ targetPath string
374
+ prepPod * v1.Pod
375
+ f * framework.Framework
376
+ }
377
+
372
378
var _ storageframework.TestDriver = & hostPathDriver {}
373
379
var _ storageframework.PreprovisionedVolumeTestDriver = & hostPathDriver {}
374
380
var _ storageframework.InlineVolumeTestDriver = & hostPathDriver {}
@@ -403,13 +409,18 @@ func (h *hostPathDriver) SkipUnsupportedTest(pattern storageframework.TestPatter
403
409
}
404
410
405
411
func (h * hostPathDriver ) GetVolumeSource (readOnly bool , fsType string , e2evolume storageframework.TestVolume ) * v1.VolumeSource {
412
+ hv , ok := e2evolume .(* hostPathVolume )
413
+ if ! ok {
414
+ framework .Failf ("Failed to cast test volume of type %T to the Hostpath test volume" , e2evolume )
415
+ }
416
+
406
417
// hostPath doesn't support readOnly volume
407
418
if readOnly {
408
419
return nil
409
420
}
410
421
return & v1.VolumeSource {
411
422
HostPath : & v1.HostPathVolumeSource {
412
- Path : "/tmp" ,
423
+ Path : hv . targetPath ,
413
424
},
414
425
}
415
426
}
@@ -426,11 +437,86 @@ func (h *hostPathDriver) CreateVolume(ctx context.Context, config *storageframew
426
437
f := config .Framework
427
438
cs := f .ClientSet
428
439
440
+ targetPath := fmt .Sprintf ("/tmp/%v" , f .Namespace .Name )
441
+ volumeName := "test-volume"
442
+
429
443
// pods should be scheduled on the node
430
444
node , err := e2enode .GetRandomReadySchedulableNode (ctx , cs )
431
445
framework .ExpectNoError (err )
432
446
config .ClientNodeSelection = e2epod.NodeSelection {Name : node .Name }
433
- return nil
447
+
448
+ cmd := fmt .Sprintf ("mkdir %v -m 777" , targetPath )
449
+ privileged := true
450
+
451
+ // Launch pod to initialize hostPath directory
452
+ prepPod := & v1.Pod {
453
+ ObjectMeta : metav1.ObjectMeta {
454
+ Name : fmt .Sprintf ("hostpath-prep-%s" , f .Namespace .Name ),
455
+ },
456
+ Spec : v1.PodSpec {
457
+ Containers : []v1.Container {
458
+ {
459
+ Name : fmt .Sprintf ("init-volume-%s" , f .Namespace .Name ),
460
+ Image : imageutils .GetE2EImage (imageutils .BusyBox ),
461
+ Command : []string {"/bin/sh" , "-ec" , cmd },
462
+ VolumeMounts : []v1.VolumeMount {
463
+ {
464
+ Name : volumeName ,
465
+ MountPath : "/tmp" ,
466
+ },
467
+ },
468
+ SecurityContext : & v1.SecurityContext {
469
+ Privileged : & privileged ,
470
+ },
471
+ },
472
+ },
473
+ RestartPolicy : v1 .RestartPolicyNever ,
474
+ Volumes : []v1.Volume {
475
+ {
476
+ Name : volumeName ,
477
+ VolumeSource : v1.VolumeSource {
478
+ HostPath : & v1.HostPathVolumeSource {
479
+ Path : "/tmp" ,
480
+ },
481
+ },
482
+ },
483
+ },
484
+ NodeName : node .Name ,
485
+ },
486
+ }
487
+ // h.prepPod will be reused in cleanupDriver.
488
+ pod , err := f .ClientSet .CoreV1 ().Pods (f .Namespace .Name ).Create (ctx , prepPod , metav1.CreateOptions {})
489
+ framework .ExpectNoError (err , "while creating hostPath init pod" )
490
+
491
+ err = e2epod .WaitForPodSuccessInNamespaceTimeout (ctx , f .ClientSet , pod .Name , pod .Namespace , f .Timeouts .PodStart )
492
+ framework .ExpectNoError (err , "while waiting for hostPath init pod to succeed" )
493
+
494
+ err = e2epod .DeletePodWithWait (ctx , f .ClientSet , pod )
495
+ framework .ExpectNoError (err , "while deleting hostPath init pod" )
496
+ return & hostPathVolume {
497
+ targetPath : targetPath ,
498
+ prepPod : prepPod ,
499
+ f : f ,
500
+ }
501
+ }
502
+
503
+ var _ storageframework.TestVolume = & hostPathVolume {}
504
+
505
+ // DeleteVolume implements the storageframework.TestVolume interface method
506
+ func (v * hostPathVolume ) DeleteVolume (ctx context.Context ) {
507
+ f := v .f
508
+
509
+ cmd := fmt .Sprintf ("rm -rf %v" , v .targetPath )
510
+ v .prepPod .Spec .Containers [0 ].Command = []string {"/bin/sh" , "-ec" , cmd }
511
+
512
+ pod , err := f .ClientSet .CoreV1 ().Pods (f .Namespace .Name ).Create (ctx , v .prepPod , metav1.CreateOptions {})
513
+ framework .ExpectNoError (err , "while creating hostPath teardown pod" )
514
+
515
+ err = e2epod .WaitForPodSuccessInNamespaceTimeout (ctx , f .ClientSet , pod .Name , pod .Namespace , f .Timeouts .PodStart )
516
+ framework .ExpectNoError (err , "while waiting for hostPath teardown pod to succeed" )
517
+
518
+ err = e2epod .DeletePodWithWait (ctx , f .ClientSet , pod )
519
+ framework .ExpectNoError (err , "while deleting hostPath teardown pod" )
434
520
}
435
521
436
522
// HostPathSymlink
@@ -572,6 +658,9 @@ func (h *hostPathSymlinkDriver) CreateVolume(ctx context.Context, config *storag
572
658
}
573
659
}
574
660
661
+ var _ storageframework.TestVolume = & hostPathSymlinkVolume {}
662
+
663
+ // DeleteVolume implements the storageframework.TestVolume interface method
575
664
func (v * hostPathSymlinkVolume ) DeleteVolume (ctx context.Context ) {
576
665
f := v .f
577
666
0 commit comments