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 20:32:42 UTC

(spark-kubernetes-operator) branch main updated: [SPARK-59503] Upgrade `Kueue` Workload CRD model to `v1beta2`

This is an automated email from the ASF dual-hosted git repository.

dongjoon-hyun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/spark-kubernetes-operator.git


The following commit(s) were added to refs/heads/main by this push:
     new 20f0e19  [SPARK-59503] Upgrade `Kueue` Workload CRD model to `v1beta2`
20f0e19 is described below

commit 20f0e191f7b01a39135f191ff91b961961d0a35b
Author: Dongjoon Hyun <do...@apache.org>
AuthorDate: Mon Sep 14 13:32:35 2026 -0700

    [SPARK-59503] Upgrade `Kueue` Workload CRD model to `v1beta2`
    
    ### What changes were proposed in this pull request?
    
    This PR upgrades the Kueue `Workload` CRD model from `v1beta1` to `v1beta2`.
    
    - Bump `Constants.KUEUE_API_VERSION` to `v1beta2` and move the model package to `org.apache.spark.k8s.operator.kueue.v1beta2`.
    - `WorkloadSpec`: replace `priorityClassName` with `priorityClassRef` (new `PriorityClassRef` type with `group`, `kind`, `name`).
    - `Admission`: rename `podSetFlavors` to `podSetAssignments` and replace `PodSetFlavors` with `PodSetAssignment` (`name`, `flavors`, `resourceUsage`, `count`) to match the `v1beta2` schema.
    - Update `KueueWorkloadFactory` imports and `WorkloadTest` accordingly.
    
    ### Why are the changes needed?
    
    Kueue exposed the `v1beta2` API in [v0.15.0](https://github.com/kubernetes-sigs/kueue/releases/tag/v0.15.0) (2025-11-28) and switched to `v1beta2` as the storage version in [v0.16.0](https://github.com/kubernetes-sigs/kueue/releases/tag/v0.16.0) (2026-01-26), with `v1beta1` scheduled to be dropped in an upcoming release (already `served: false` in the v0.20.0 release candidate). Since the Kueue integration is not released yet, we should start with the current `v1beta2` API instead of  [...]
    
    ### Does this PR introduce _any_ user-facing change?
    
    No, the Kueue integration is not released yet.
    
    ### How was this patch tested?
    
    Pass the CIs.
    
    ### Was this patch authored or co-authored using generative AI tooling?
    
    Generated-by: Claude Fable 5.1
    
    Closes #824 from dongjoon-hyun/SPARK-59503.
    
    Authored-by: Dongjoon Hyun <do...@apache.org>
    Signed-off-by: Dongjoon Hyun <do...@apache.org>
---
 .../org/apache/spark/k8s/operator/Constants.java   |  2 +-
 .../k8s/operator/kueue/KueueWorkloadFactory.java   |  6 +--
 .../kueue/{v1beta1 => v1beta2}/Admission.java      |  4 +-
 .../kueue/{v1beta1 => v1beta2}/PodSet.java         |  2 +-
 .../PodSetAssignment.java}                         | 16 ++++----
 .../PodSet.java => v1beta2/PriorityClassRef.java}  | 15 +++----
 .../kueue/{v1beta1 => v1beta2}/Workload.java       |  4 +-
 .../kueue/{v1beta1 => v1beta2}/WorkloadList.java   |  2 +-
 .../kueue/{v1beta1 => v1beta2}/WorkloadSpec.java   |  4 +-
 .../kueue/{v1beta1 => v1beta2}/WorkloadStatus.java |  2 +-
 .../operator/kueue/KueueWorkloadFactoryTest.java   |  4 +-
 .../kueue/{v1beta1 => v1beta2}/WorkloadTest.java   | 46 +++++++++++-----------
 12 files changed, 52 insertions(+), 55 deletions(-)

diff --git a/spark-operator-api/src/main/java/org/apache/spark/k8s/operator/Constants.java b/spark-operator-api/src/main/java/org/apache/spark/k8s/operator/Constants.java
index ef413a0..4b76ac0 100644
--- a/spark-operator-api/src/main/java/org/apache/spark/k8s/operator/Constants.java
+++ b/spark-operator-api/src/main/java/org/apache/spark/k8s/operator/Constants.java
@@ -51,7 +51,7 @@ public class Constants {
   public static final String KUEUE_API_GROUP = "kueue.x-k8s.io";
 
   /** The API version for Kueue resources. */
-  public static final String KUEUE_API_VERSION = "v1beta1";
+  public static final String KUEUE_API_VERSION = "v1beta2";
 
   /** The CRD name for Kueue Workload. */
   public static final String KUEUE_WORKLOAD_CRD_NAME = "workloads.kueue.x-k8s.io";
diff --git a/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/KueueWorkloadFactory.java b/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/KueueWorkloadFactory.java
index 5845e88..d0225c1 100644
--- a/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/KueueWorkloadFactory.java
+++ b/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/KueueWorkloadFactory.java
@@ -45,9 +45,9 @@ import org.apache.spark.k8s.operator.SparkApplication;
 import org.apache.spark.k8s.operator.SparkCluster;
 import org.apache.spark.k8s.operator.SparkClusterResourceSpec;
 import org.apache.spark.k8s.operator.SparkClusterSubmissionWorker;
-import org.apache.spark.k8s.operator.kueue.v1beta1.PodSet;
-import org.apache.spark.k8s.operator.kueue.v1beta1.Workload;
-import org.apache.spark.k8s.operator.kueue.v1beta1.WorkloadSpec;
+import org.apache.spark.k8s.operator.kueue.v1beta2.PodSet;
+import org.apache.spark.k8s.operator.kueue.v1beta2.Workload;
+import org.apache.spark.k8s.operator.kueue.v1beta2.WorkloadSpec;
 import org.apache.spark.k8s.operator.reconciler.SparkClusterResourceSpecFactory;
 import org.apache.spark.k8s.operator.spec.ApplicationSpec;
 import org.apache.spark.k8s.operator.spec.BaseApplicationTemplateSpec;
diff --git a/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta1/Admission.java b/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta2/Admission.java
similarity index 91%
rename from spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta1/Admission.java
rename to spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta2/Admission.java
index d235690..ff8a83f 100644
--- a/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta1/Admission.java
+++ b/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta2/Admission.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.spark.k8s.operator.kueue.v1beta1;
+package org.apache.spark.k8s.operator.kueue.v1beta2;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -41,5 +41,5 @@ import lombok.NoArgsConstructor;
 public class Admission {
   private String clusterQueue;
   @Builder.Default
-  private List<PodSetFlavors> podSetFlavors = new ArrayList<>();
+  private List<PodSetAssignment> podSetAssignments = new ArrayList<>();
 }
diff --git a/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta1/PodSet.java b/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta2/PodSet.java
similarity index 96%
copy from spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta1/PodSet.java
copy to spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta2/PodSet.java
index 74c1dc2..1477d1c 100644
--- a/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta1/PodSet.java
+++ b/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta2/PodSet.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.spark.k8s.operator.kueue.v1beta1;
+package org.apache.spark.k8s.operator.kueue.v1beta2;
 
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.JsonInclude;
diff --git a/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta1/PodSetFlavors.java b/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta2/PodSetAssignment.java
similarity index 76%
rename from spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta1/PodSetFlavors.java
rename to spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta2/PodSetAssignment.java
index 175bb15..b21131a 100644
--- a/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta1/PodSetFlavors.java
+++ b/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta2/PodSetAssignment.java
@@ -17,36 +17,34 @@
  * under the License.
  */
 
-package org.apache.spark.k8s.operator.kueue.v1beta1;
+package org.apache.spark.k8s.operator.kueue.v1beta2;
 
-import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.JsonInclude;
-import io.fabric8.kubernetes.api.model.Toleration;
+import io.fabric8.kubernetes.api.model.Quantity;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
 /**
- * PodSetFlavors represents the resource flavors and scheduling constraints assigned to a PodSet.
+ * PodSetAssignment represents the admission result (flavors and resource usage) for a PodSet.
  */
+
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
 @Builder
 @JsonInclude(JsonInclude.Include.NON_NULL)
 @JsonIgnoreProperties(ignoreUnknown = true)
-public class PodSetFlavors {
+public class PodSetAssignment {
   private String name;
   @Builder.Default
   private Map<String, String> flavors = new HashMap<>();
   @Builder.Default
-  private Map<String, String> nodeSelector = new HashMap<>();
-  @Builder.Default
-  private List<Toleration> tolerations = new ArrayList<>();
+  private Map<String, Quantity> resourceUsage = new HashMap<>();
+  private Integer count;
 }
diff --git a/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta1/PodSet.java b/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta2/PriorityClassRef.java
similarity index 78%
rename from spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta1/PodSet.java
rename to spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta2/PriorityClassRef.java
index 74c1dc2..d33604d 100644
--- a/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta1/PodSet.java
+++ b/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta2/PriorityClassRef.java
@@ -17,28 +17,29 @@
  * under the License.
  */
 
-package org.apache.spark.k8s.operator.kueue.v1beta1;
+package org.apache.spark.k8s.operator.kueue.v1beta2;
 
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.JsonInclude;
-import io.fabric8.kubernetes.api.model.PodTemplateSpec;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
 /**
- * PodSet represents a group of pods in a Kueue Workload.
+ * PriorityClassRef references a PriorityClass in a specific API group.
+ * Use group "kueue.x-k8s.io" with kind "WorkloadPriorityClass",
+ * or group "scheduling.k8s.io" with kind "PriorityClass".
  */
+
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
 @Builder
 @JsonInclude(JsonInclude.Include.NON_NULL)
 @JsonIgnoreProperties(ignoreUnknown = true)
-public class PodSet {
+public class PriorityClassRef {
+  private String group;
+  private String kind;
   private String name;
-  private PodTemplateSpec template;
-  private Integer count;
-  private Integer minCount;
 }
diff --git a/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta1/Workload.java b/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta2/Workload.java
similarity index 96%
rename from spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta1/Workload.java
rename to spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta2/Workload.java
index ee48a62..5e5a259 100644
--- a/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta1/Workload.java
+++ b/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta2/Workload.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.spark.k8s.operator.kueue.v1beta1;
+package org.apache.spark.k8s.operator.kueue.v1beta2;
 
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.JsonInclude;
@@ -32,7 +32,7 @@ import lombok.ToString;
 import org.apache.spark.k8s.operator.Constants;
 
 /**
- * Fabric8 CustomResource representation of a Kueue Workload (kueue.x-k8s.io/v1beta1).
+ * Fabric8 CustomResource representation of a Kueue Workload (kueue.x-k8s.io/v1beta2).
  */
 @JsonInclude(JsonInclude.Include.NON_NULL)
 @JsonDeserialize
diff --git a/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta1/WorkloadList.java b/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta2/WorkloadList.java
similarity index 95%
rename from spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta1/WorkloadList.java
rename to spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta2/WorkloadList.java
index af19ebc..431c068 100644
--- a/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta1/WorkloadList.java
+++ b/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta2/WorkloadList.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.spark.k8s.operator.kueue.v1beta1;
+package org.apache.spark.k8s.operator.kueue.v1beta2;
 
 import io.fabric8.kubernetes.api.model.DefaultKubernetesResourceList;
 import lombok.NoArgsConstructor;
diff --git a/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta1/WorkloadSpec.java b/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta2/WorkloadSpec.java
similarity index 93%
rename from spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta1/WorkloadSpec.java
rename to spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta2/WorkloadSpec.java
index 4f0f536..676604a 100644
--- a/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta1/WorkloadSpec.java
+++ b/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta2/WorkloadSpec.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.spark.k8s.operator.kueue.v1beta1;
+package org.apache.spark.k8s.operator.kueue.v1beta2;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -44,6 +44,6 @@ public class WorkloadSpec {
   private Boolean active = true;
   @Builder.Default
   private List<PodSet> podSets = new ArrayList<>();
-  private String priorityClassName;
+  private PriorityClassRef priorityClassRef;
   private Integer priority;
 }
diff --git a/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta1/WorkloadStatus.java b/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta2/WorkloadStatus.java
similarity index 97%
rename from spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta1/WorkloadStatus.java
rename to spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta2/WorkloadStatus.java
index f1b31dd..4deedc9 100644
--- a/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta1/WorkloadStatus.java
+++ b/spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta2/WorkloadStatus.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.spark.k8s.operator.kueue.v1beta1;
+package org.apache.spark.k8s.operator.kueue.v1beta2;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/spark-operator/src/test/java/org/apache/spark/k8s/operator/kueue/KueueWorkloadFactoryTest.java b/spark-operator/src/test/java/org/apache/spark/k8s/operator/kueue/KueueWorkloadFactoryTest.java
index 26b1b06..66926bb 100644
--- a/spark-operator/src/test/java/org/apache/spark/k8s/operator/kueue/KueueWorkloadFactoryTest.java
+++ b/spark-operator/src/test/java/org/apache/spark/k8s/operator/kueue/KueueWorkloadFactoryTest.java
@@ -43,8 +43,8 @@ import org.junit.jupiter.api.Test;
 import org.apache.spark.k8s.operator.Constants;
 import org.apache.spark.k8s.operator.SparkApplication;
 import org.apache.spark.k8s.operator.SparkCluster;
-import org.apache.spark.k8s.operator.kueue.v1beta1.PodSet;
-import org.apache.spark.k8s.operator.kueue.v1beta1.Workload;
+import org.apache.spark.k8s.operator.kueue.v1beta2.PodSet;
+import org.apache.spark.k8s.operator.kueue.v1beta2.Workload;
 import org.apache.spark.k8s.operator.spec.ApplicationSpec;
 import org.apache.spark.k8s.operator.spec.BaseApplicationTemplateSpec;
 import org.apache.spark.k8s.operator.spec.ClusterSpec;
diff --git a/spark-operator/src/test/java/org/apache/spark/k8s/operator/kueue/v1beta1/WorkloadTest.java b/spark-operator/src/test/java/org/apache/spark/k8s/operator/kueue/v1beta2/WorkloadTest.java
similarity index 82%
rename from spark-operator/src/test/java/org/apache/spark/k8s/operator/kueue/v1beta1/WorkloadTest.java
rename to spark-operator/src/test/java/org/apache/spark/k8s/operator/kueue/v1beta2/WorkloadTest.java
index b5533bb..77e5ba8 100644
--- a/spark-operator/src/test/java/org/apache/spark/k8s/operator/kueue/v1beta1/WorkloadTest.java
+++ b/spark-operator/src/test/java/org/apache/spark/k8s/operator/kueue/v1beta2/WorkloadTest.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.spark.k8s.operator.kueue.v1beta1;
+package org.apache.spark.k8s.operator.kueue.v1beta2;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -32,7 +32,7 @@ import io.fabric8.kubernetes.api.model.Condition;
 import io.fabric8.kubernetes.api.model.ConditionBuilder;
 import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
 import io.fabric8.kubernetes.api.model.PodTemplateSpecBuilder;
-import io.fabric8.kubernetes.api.model.TolerationBuilder;
+import io.fabric8.kubernetes.api.model.Quantity;
 import org.junit.jupiter.api.Test;
 
 import org.apache.spark.k8s.operator.Constants;
@@ -71,7 +71,12 @@ class WorkloadTest {
             .queueName("test-queue")
             .active(true)
             .podSets(List.of(driverPodSet, executorPodSet))
-            .priorityClassName("high-priority")
+            .priorityClassRef(
+                PriorityClassRef.builder()
+                    .group("kueue.x-k8s.io")
+                    .kind("WorkloadPriorityClass")
+                    .name("high-priority")
+                    .build())
             .priority(100)
             .build());
 
@@ -82,24 +87,18 @@ class WorkloadTest {
             .withReason("AdmittedByKueue")
             .build();
 
-    PodSetFlavors driverFlavors =
-        PodSetFlavors.builder()
+    PodSetAssignment driverAssignment =
+        PodSetAssignment.builder()
             .name("driver")
             .flavors(Map.of("cpu", "default-flavor"))
-            .nodeSelector(Map.of("instance-type", "m5.large"))
-            .tolerations(
-                List.of(
-                    new TolerationBuilder()
-                        .withKey("spot")
-                        .withOperator("Equal")
-                        .withValue("true")
-                        .build()))
+            .resourceUsage(Map.of("cpu", new Quantity("2")))
+            .count(1)
             .build();
 
     Admission admission =
         Admission.builder()
             .clusterQueue("cluster-queue")
-            .podSetFlavors(List.of(driverFlavors))
+            .podSetAssignments(List.of(driverAssignment))
             .build();
 
     workload.setStatus(
@@ -115,6 +114,8 @@ class WorkloadTest {
     assertEquals("test-workload", deserialized.getMetadata().getName());
     assertEquals("test-queue", deserialized.getSpec().getQueueName());
     assertTrue(deserialized.getSpec().getActive());
+    assertEquals("high-priority", deserialized.getSpec().getPriorityClassRef().getName());
+    assertEquals(100, deserialized.getSpec().getPriority());
     assertEquals(2, deserialized.getSpec().getPodSets().size());
     assertEquals("driver", deserialized.getSpec().getPodSets().get(0).getName());
     assertEquals(1, deserialized.getSpec().getPodSets().get(0).getCount());
@@ -125,16 +126,13 @@ class WorkloadTest {
     assertFalse(deserialized.getStatus().isFinished());
     assertNotNull(deserialized.getStatus().getAdmission());
     assertEquals("cluster-queue", deserialized.getStatus().getAdmission().getClusterQueue());
-    assertEquals(1, deserialized.getStatus().getAdmission().getPodSetFlavors().size());
-    assertEquals(
-        "m5.large",
-        deserialized
-            .getStatus()
-            .getAdmission()
-            .getPodSetFlavors()
-            .get(0)
-            .getNodeSelector()
-            .get("instance-type"));
+    assertEquals(1, deserialized.getStatus().getAdmission().getPodSetAssignments().size());
+    PodSetAssignment assignment =
+        deserialized.getStatus().getAdmission().getPodSetAssignments().get(0);
+    assertEquals("driver", assignment.getName());
+    assertEquals("default-flavor", assignment.getFlavors().get("cpu"));
+    assertEquals(new Quantity("2"), assignment.getResourceUsage().get("cpu"));
+    assertEquals(1, assignment.getCount());
   }
 
   @Test


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@spark.apache.org
For additional commands, e-mail: commits-help@spark.apache.org