You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spark.apache.org by do...@apache.org on 2026/09/14 14:56:25 UTC
(spark) branch master updated: [SPARK-59489][K8S] Promote `KubernetesExecutorSpec` to `DeveloperApi` and `Stable`
This is an automated email from the ASF dual-hosted git repository.
dongjoon-hyun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/master by this push:
new 93d40164f0da [SPARK-59489][K8S] Promote `KubernetesExecutorSpec` to `DeveloperApi` and `Stable`
93d40164f0da is described below
commit 93d40164f0daa7799e06c3eed2d97523c7af0238
Author: Dongjoon Hyun <do...@apache.org>
AuthorDate: Mon Sep 14 07:56:14 2026 -0700
[SPARK-59489][K8S] Promote `KubernetesExecutorSpec` to `DeveloperApi` and `Stable`
### What changes were proposed in this pull request?
This PR aims to promote `KubernetesExecutorSpec` to `DeveloperApi` and `Stable` with Java-friendly APIs:
- Promote `KubernetesExecutorSpec` to `public`, `DeveloperApi`, and `Stable`.
- Add Java getter: `spec.getExecutorKubernetesResourcesAsJavaList`.
- Add Java factory: `KubernetesExecutorSpec.create(pod, executorKubernetesResources)`.
### Why are the changes needed?
`KubernetesExecutorSpec` was introduced at Apache Spark 3.1.0 and has been unchanged for last 6 years.
- https://github.com/apache/spark/pull/29472
https://github.com/apache/spark/blob/07d92669ccd2c873bb5fca7aa1aaee7c463e6d70/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/KubernetesExecutorSpec.scala#L21-L23
To provide a Java-friendly `DeveloperApi` for external projects such as the Apache Spark Kubernetes Operator, symmetric to `KubernetesDriverSpec`.
https://github.com/apache/spark/blob/07d92669ccd2c873bb5fca7aa1aaee7c463e6d70/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/KubernetesDriverSpec.scala#L33-L36
### Does this PR introduce _any_ user-facing change?
No.
### How was this patch tested?
Pass the CIs with the newly added test suite.
### Was this patch authored or co-authored using generative AI tooling?
Generated-by: Antigravity (Gemini 3.8 Flash)
Closes #58773 from dongjoon-hyun/SPARK-59489.
Authored-by: Dongjoon Hyun <do...@apache.org>
Signed-off-by: Dongjoon Hyun <do...@apache.org>
---
.../spark/deploy/k8s/KubernetesExecutorSpec.scala | 39 +++++++++++++-
.../deploy/k8s/KubernetesExecutorSpecSuite.scala | 62 ++++++++++++++++++++++
2 files changed, 99 insertions(+), 2 deletions(-)
diff --git a/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/KubernetesExecutorSpec.scala b/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/KubernetesExecutorSpec.scala
index 4db9211c1e42..d785e435a059 100644
--- a/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/KubernetesExecutorSpec.scala
+++ b/resource-managers/kubernetes/core/src/main/scala/org/apache/spark/deploy/k8s/KubernetesExecutorSpec.scala
@@ -16,8 +16,43 @@
*/
package org.apache.spark.deploy.k8s
+import java.util.{List => JList}
+
+import scala.jdk.CollectionConverters._
+
import io.fabric8.kubernetes.api.model.HasMetadata
-private[spark] case class KubernetesExecutorSpec(
+import org.apache.spark.annotation.{DeveloperApi, Since, Stable}
+
+/**
+ * :: DeveloperApi ::
+ *
+ * Spec for executor pod and resources, used for K8s operations internally
+ * and Spark K8s operator.
+ */
+@Stable
+@DeveloperApi
+@Since("4.4.0")
+case class KubernetesExecutorSpec(
pod: SparkPod,
- executorKubernetesResources: Seq[HasMetadata])
+ executorKubernetesResources: Seq[HasMetadata]) {
+
+ /** Get executor Kubernetes resources as a Java-friendly list. */
+ @Since("4.4.0")
+ def getExecutorKubernetesResourcesAsJavaList: JList[HasMetadata] =
+ executorKubernetesResources.asJava
+}
+
+@Stable
+@DeveloperApi
+@Since("4.4.0")
+object KubernetesExecutorSpec {
+ @Since("4.4.0")
+ def create(
+ pod: SparkPod,
+ executorKubernetesResources: JList[HasMetadata]): KubernetesExecutorSpec = {
+ KubernetesExecutorSpec(
+ pod,
+ executorKubernetesResources.asScala.toSeq)
+ }
+}
diff --git a/resource-managers/kubernetes/core/src/test/scala/org/apache/spark/deploy/k8s/KubernetesExecutorSpecSuite.scala b/resource-managers/kubernetes/core/src/test/scala/org/apache/spark/deploy/k8s/KubernetesExecutorSpecSuite.scala
new file mode 100644
index 000000000000..446e5517f2a7
--- /dev/null
+++ b/resource-managers/kubernetes/core/src/test/scala/org/apache/spark/deploy/k8s/KubernetesExecutorSpecSuite.scala
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.spark.deploy.k8s
+
+import java.util.{Arrays, List => JList}
+
+import io.fabric8.kubernetes.api.model.{ContainerBuilder, HasMetadata, PodBuilder, SecretBuilder}
+
+import org.apache.spark.SparkFunSuite
+
+class KubernetesExecutorSpecSuite extends SparkFunSuite {
+
+ private val POD = new PodBuilder()
+ .withNewMetadata().withName("executor").endMetadata()
+ .withNewSpec().endSpec()
+ .build()
+ private val CONTAINER = new ContainerBuilder().withName("executor-container").build()
+ private val SPARK_POD = SparkPod(POD, CONTAINER)
+
+ test("create from Java collections") {
+ val secret = new SecretBuilder()
+ .withNewMetadata().withName("test-secret").endMetadata()
+ .build()
+ val resources = Arrays.asList[HasMetadata](secret)
+
+ val spec = KubernetesExecutorSpec.create(SPARK_POD, resources)
+
+ assert(spec.pod === SPARK_POD)
+ assert(spec.executorKubernetesResources.length === 1)
+ assert(spec.executorKubernetesResources.head === secret)
+
+ val javaResources = spec.getExecutorKubernetesResourcesAsJavaList
+ assert(javaResources.isInstanceOf[JList[_]])
+ assert(javaResources.size() === 1)
+ assert(javaResources.get(0) === secret)
+ }
+
+ test("create from empty Java collections") {
+ val resources = Arrays.asList[HasMetadata]()
+
+ val spec = KubernetesExecutorSpec.create(SPARK_POD, resources)
+
+ assert(spec.pod === SPARK_POD)
+ assert(spec.executorKubernetesResources.isEmpty)
+ assert(spec.getExecutorKubernetesResourcesAsJavaList.isEmpty)
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@spark.apache.org
For additional commands, e-mail: commits-help@spark.apache.org