Skip to content

Commit 7c1be8a

Browse files
author
madanadit
committed
Driver hostPath volumes with tests
1 parent ccdc799 commit 7c1be8a

File tree

2 files changed

+66
-1
lines changed

2 files changed

+66
-1
lines changed

resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/features/BasicDriverFeatureStep.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,13 @@ private[spark] class BasicDriverFeatureStep(
109109
.addToImagePullSecrets(conf.imagePullSecrets(): _*)
110110
.endSpec()
111111
.build()
112-
SparkPod(driverPod, driverContainer)
112+
113+
val driverHostPathVolumesSpec = KubernetesUtils.parseHostPathVolumesWithPrefix(
114+
conf.sparkConf, KUBERNETES_DRIVER_VOLUMES_PREFIX)
115+
val (driverPodWithHostPathVolumes, driverContainerWithHostPathVolumes) =
116+
KubernetesUtils.addHostPathVolumes(driverPod, driverContainer, driverHostPathVolumesSpec)
117+
118+
SparkPod(driverPodWithHostPathVolumes, driverContainerWithHostPathVolumes)
113119
}
114120

115121
override def getAdditionalPodSystemProperties(): Map[String, String] = {

resource-managers/kubernetes/core/src/test/scala/org/apache/spark/deploy/k8s/features/BasicDriverFeatureStepSuite.scala

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,4 +150,63 @@ class BasicDriverFeatureStepSuite extends SparkFunSuite {
150150
"spark.files" -> "https://localhost:9000/file1.txt,/opt/spark/file2.txt")
151151
assert(additionalProperties === expectedSparkConf)
152152
}
153+
154+
test("single driver hostPath volume gets mounted") {
155+
hostPathVolumeTest(1, false)
156+
}
157+
158+
test("multiple driver hostPath volumes get mounted") {
159+
hostPathVolumeTest(2, false)
160+
}
161+
162+
test("single driver hostPath volume gets mounted w/ readOnly option") {
163+
hostPathVolumeTest(1, true)
164+
}
165+
166+
test("multiple driver hostPath volumes get mounted w/ readOnly option") {
167+
hostPathVolumeTest(2, true)
168+
}
169+
170+
private def hostPathVolumeTest(numVolumes: Int, readOnly: Boolean): Unit = {
171+
val sparkConf = new SparkConf()
172+
.set(KUBERNETES_DRIVER_POD_NAME, "spark-driver-pod")
173+
.set(CONTAINER_IMAGE, "spark-driver:latest")
174+
for (i <- 0 until numVolumes) {
175+
sparkConf.set(s"spark.kubernetes.driver.volumes.hostPath.hostPath-$i.mount.path",
176+
s"/opt/mount$i")
177+
sparkConf.set(s"spark.kubernetes.driver.volumes.hostPath.hostPath-$i.options.path",
178+
s"/tmp/mount$i")
179+
if (readOnly) {
180+
sparkConf.set(s"spark.kubernetes.driver.volumes.hostPath.hostPath-$i.mount.readOnly",
181+
"true")
182+
}
183+
}
184+
val kubernetesConf = KubernetesConf(
185+
sparkConf,
186+
KubernetesDriverSpecificConf(
187+
None,
188+
APP_NAME,
189+
MAIN_CLASS,
190+
APP_ARGS),
191+
RESOURCE_NAME_PREFIX,
192+
APP_ID,
193+
DRIVER_LABELS,
194+
DRIVER_ANNOTATIONS,
195+
Map.empty,
196+
Map.empty)
197+
val step = new BasicDriverFeatureStep(kubernetesConf)
198+
val driver = step.configurePod(SparkPod.initialPod())
199+
200+
assert(driver.container.getVolumeMounts.size() === numVolumes)
201+
assert(driver.pod.getSpec.getVolumes.size() === numVolumes)
202+
for (i <- 0 until numVolumes) {
203+
assert(driver.container.getVolumeMounts.asScala
204+
.exists(v => (v.getName == s"hostPath-$i" && v.getMountPath == s"/opt/mount$i")))
205+
assert(driver.pod.getSpec.getVolumes.asScala
206+
.exists(v => (v.getName == s"hostPath-$i" && v.getHostPath.getPath == s"/tmp/mount$i")))
207+
if (readOnly) {
208+
assert(driver.container.getVolumeMounts.get(i).getReadOnly == true)
209+
}
210+
}
211+
}
153212
}

0 commit comments

Comments
 (0)