diff --git a/cmd/experimental/kjobctl/apis/v1alpha1/application_profile_types.go b/cmd/experimental/kjobctl/apis/v1alpha1/application_profile_types.go
index 451ff4ed9e..e96a71217d 100644
--- a/cmd/experimental/kjobctl/apis/v1alpha1/application_profile_types.go
+++ b/cmd/experimental/kjobctl/apis/v1alpha1/application_profile_types.go
@@ -93,7 +93,6 @@ type TemplateReference string
// +kubebuilder:validation:XValidation:rule="!has(self.requiredFlags) || !('ntasks' in self.requiredFlags) || self.name == 'Slurm'", message="ntasks flag can be used only on Slurm mode"
// +kubebuilder:validation:XValidation:rule="!has(self.requiredFlags) || !('output' in self.requiredFlags) || self.name == 'Slurm'", message="output flag can be used only on Slurm mode"
// +kubebuilder:validation:XValidation:rule="!has(self.requiredFlags) || !('partition' in self.requiredFlags) || self.name == 'Slurm'", message="partition flag can be used only on Slurm mode"
-// +kubebuilder:validation:XValidation:rule="!has(self.requiredFlags) || !('priority' in self.requiredFlags) || self.name == 'Slurm'", message="priority flag can be used only on Slurm mode"
// +kubebuilder:validation:XValidation:rule="!has(self.requiredFlags) || self.name != 'Slurm' || !('parallelism' in self.requiredFlags)", message="parallelism flag can't be used on Slurm mode"
// +kubebuilder:validation:XValidation:rule="!has(self.requiredFlags) || self.name != 'Slurm' || !('completions' in self.requiredFlags)", message="completions flag can't be used on Slurm mode"
type SupportedMode struct {
@@ -121,9 +120,10 @@ type SupportedMode struct {
// The raycluster flag used only for the RayJob mode.
// The request flag used only for Interactive and Job modes.
// The cmd flag used only for Interactive, Job, and RayJob.
+ // The skip-priority-workload and priority flags can be used in all modes.
// If the raycluster flag are set, none of localqueue, replicas, min-replicas, or max-replicas can be set.
// For the Slurm mode, the possible values are: array, cpus-per-task, error, gpus-per-task, input, job-name, mem, mem-per-cpu,
- // mem-per-gpu, mem-per-task, nodes, ntasks, output, partition, localqueue, priority.
+ // mem-per-gpu, mem-per-task, nodes, ntasks, output, partition, localqueue.
//
// cmd and requests values are going to be added only to the first primary container.
//
diff --git a/cmd/experimental/kjobctl/config/crd/bases/kjobctl.x-k8s.io_applicationprofiles.yaml b/cmd/experimental/kjobctl/config/crd/bases/kjobctl.x-k8s.io_applicationprofiles.yaml
index 537d39d3e7..0a6ee0d7d7 100644
--- a/cmd/experimental/kjobctl/config/crd/bases/kjobctl.x-k8s.io_applicationprofiles.yaml
+++ b/cmd/experimental/kjobctl/config/crd/bases/kjobctl.x-k8s.io_applicationprofiles.yaml
@@ -62,9 +62,10 @@ spec:
The raycluster flag used only for the RayJob mode.
The request flag used only for Interactive and Job modes.
The cmd flag used only for Interactive, Job, and RayJob.
+ The skip-priority-workload and priority flags can be used in all modes.
If the raycluster flag are set, none of localqueue, replicas, min-replicas, or max-replicas can be set.
For the Slurm mode, the possible values are: array, cpus-per-task, error, gpus-per-task, input, job-name, mem, mem-per-cpu,
- mem-per-gpu, mem-per-task, nodes, ntasks, output, partition, localqueue, priority.
+ mem-per-gpu, mem-per-task, nodes, ntasks, output, partition, localqueue.
cmd and requests values are going to be added only to the first primary container.
items:
@@ -183,9 +184,6 @@ spec:
- message: partition flag can be used only on Slurm mode
rule: '!has(self.requiredFlags) || !(''partition'' in self.requiredFlags)
|| self.name == ''Slurm'''
- - message: priority flag can be used only on Slurm mode
- rule: '!has(self.requiredFlags) || !(''priority'' in self.requiredFlags)
- || self.name == ''Slurm'''
- message: parallelism flag can't be used on Slurm mode
rule: '!has(self.requiredFlags) || self.name != ''Slurm'' || !(''parallelism''
in self.requiredFlags)'
diff --git a/cmd/experimental/kjobctl/docs/commands/kjobctl_create/kjobctl_create_interactive.md b/cmd/experimental/kjobctl/docs/commands/kjobctl_create/kjobctl_create_interactive.md
index d9a84797f2..021cbd1538 100644
--- a/cmd/experimental/kjobctl/docs/commands/kjobctl_create/kjobctl_create_interactive.md
+++ b/cmd/experimental/kjobctl/docs/commands/kjobctl_create/kjobctl_create_interactive.md
@@ -12,7 +12,7 @@ The file is auto-generated from the Go source code of the component using the
Create an interactive shell
```
-kjobctl create interactive --profile APPLICATION_PROFILE_NAME [--localqueue LOCAL_QUEUE_NAME] [--skip-localqueue-validation] [--cmd COMMAND] [--request RESOURCE_NAME=QUANTITY] [--pod-running-timeout DURATION] [--rm]
+kjobctl create interactive --profile APPLICATION_PROFILE_NAME [--localqueue LOCAL_QUEUE_NAME] [--skip-localqueue-validation] [--priority NAME] [--skip-priority-validation] [--cmd COMMAND] [--request RESOURCE_NAME=QUANTITY] [--pod-running-timeout DURATION] [--rm]
```
@@ -99,6 +99,15 @@ kjobctl create interactive --profile APPLICATION_PROFILE_NAME [--localqueue LOCA
The length of time (like 5s, 2m, or 3h, higher than zero) to wait until at least one pod is running.
+
+ --priority string |
+
+
+ |
+
+ Apply priority for the entire workload.
+ |
+
-p, --profile string |
@@ -144,6 +153,15 @@ kjobctl create interactive --profile APPLICATION_PROFILE_NAME [--localqueue LOCA
Skip local queue validation. Add local queue even if the queue does not exist.
+
+ --skip-priority-validation |
+
+
+ |
+
+ Skip workload priority class validation. Add priority class label even if the class does not exist.
+ |
+
--template string |
diff --git a/cmd/experimental/kjobctl/docs/commands/kjobctl_create/kjobctl_create_job.md b/cmd/experimental/kjobctl/docs/commands/kjobctl_create/kjobctl_create_job.md
index 944b79a08f..e0f1279039 100644
--- a/cmd/experimental/kjobctl/docs/commands/kjobctl_create/kjobctl_create_job.md
+++ b/cmd/experimental/kjobctl/docs/commands/kjobctl_create/kjobctl_create_job.md
@@ -12,7 +12,7 @@ The file is auto-generated from the Go source code of the component using the
Create a job
```
-kjobctl create job --profile APPLICATION_PROFILE_NAME [--localqueue LOCAL_QUEUE_NAME] [--skip-localqueue-validation] [--cmd COMMAND] [--request RESOURCE_NAME=QUANTITY] [--parallelism PARALLELISM] [--completions COMPLETIONS]
+kjobctl create job --profile APPLICATION_PROFILE_NAME [--localqueue LOCAL_QUEUE_NAME] [--skip-localqueue-validation] [--priority NAME] [--skip-priority-validation] [--cmd COMMAND] [--request RESOURCE_NAME=QUANTITY] [--parallelism PARALLELISM] [--completions COMPLETIONS]
```
@@ -111,6 +111,15 @@ kjobctl create job --profile APPLICATION_PROFILE_NAME [--localqueue LOCAL_QUEUE_
Parallelism specifies the maximum desired number of pods the job should run at any given time.
+
+ --priority string |
+
+
+ |
+
+ Apply priority for the entire workload.
+ |
+
-p, --profile string |
@@ -147,6 +156,15 @@ kjobctl create job --profile APPLICATION_PROFILE_NAME [--localqueue LOCAL_QUEUE_
Skip local queue validation. Add local queue even if the queue does not exist.
+
+ --skip-priority-validation |
+
+
+ |
+
+ Skip workload priority class validation. Add priority class label even if the class does not exist.
+ |
+
--template string |
diff --git a/cmd/experimental/kjobctl/docs/commands/kjobctl_create/kjobctl_create_raycluster.md b/cmd/experimental/kjobctl/docs/commands/kjobctl_create/kjobctl_create_raycluster.md
index af3becab24..c0dd961f94 100644
--- a/cmd/experimental/kjobctl/docs/commands/kjobctl_create/kjobctl_create_raycluster.md
+++ b/cmd/experimental/kjobctl/docs/commands/kjobctl_create/kjobctl_create_raycluster.md
@@ -14,7 +14,7 @@ Create a raycluster.
KubeRay operator is required for RayCluster. How to install KubeRay operator you can find here https://ray-project.github.io/kuberay/deploy/installation/.
```
-kjobctl create raycluster --profile APPLICATION_PROFILE_NAME [--localqueue LOCAL_QUEUE_NAME] [--skip-localqueue-validation] [--replicas [WORKER_GROUP]=REPLICAS] [--min-replicas [WORKER_GROUP]=MIN_REPLICAS] [--max-replicas [WORKER_GROUP]=MAX_REPLICAS]
+kjobctl create raycluster --profile APPLICATION_PROFILE_NAME [--localqueue LOCAL_QUEUE_NAME] [--skip-localqueue-validation] [--priority NAME] [--skip-priority-validation] [--replicas [WORKER_GROUP]=REPLICAS] [--min-replicas [WORKER_GROUP]=MIN_REPLICAS] [--max-replicas [WORKER_GROUP]=MAX_REPLICAS]
```
@@ -103,6 +103,15 @@ kjobctl create raycluster --profile APPLICATION_PROFILE_NAME [--localqueue LOCAL
Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
+
+ --priority string |
+
+
+ |
+
+ Apply priority for the entire workload.
+ |
+
-p, --profile string |
@@ -139,6 +148,15 @@ kjobctl create raycluster --profile APPLICATION_PROFILE_NAME [--localqueue LOCAL
Skip local queue validation. Add local queue even if the queue does not exist.
+
+ --skip-priority-validation |
+
+
+ |
+
+ Skip workload priority class validation. Add priority class label even if the class does not exist.
+ |
+
--template string |
diff --git a/cmd/experimental/kjobctl/docs/commands/kjobctl_create/kjobctl_create_rayjob.md b/cmd/experimental/kjobctl/docs/commands/kjobctl_create/kjobctl_create_rayjob.md
index 1d0e778fb1..1ed7430122 100644
--- a/cmd/experimental/kjobctl/docs/commands/kjobctl_create/kjobctl_create_rayjob.md
+++ b/cmd/experimental/kjobctl/docs/commands/kjobctl_create/kjobctl_create_rayjob.md
@@ -14,7 +14,7 @@ Create a rayjob.
KubeRay operator is required for RayJob. How to install KubeRay operator you can find here https://ray-project.github.io/kuberay/deploy/installation/.
```
-kjobctl create rayjob --profile APPLICATION_PROFILE_NAME [--localqueue LOCAL_QUEUE_NAME] [--skip-localqueue-validation] [--cmd COMMAND] [--replicas [WORKER_GROUP]=REPLICAS] [--min-replicas [WORKER_GROUP]=MIN_REPLICAS] [--max-replicas [WORKER_GROUP]=MAX_REPLICAS]
+kjobctl create rayjob --profile APPLICATION_PROFILE_NAME [--localqueue LOCAL_QUEUE_NAME] [--skip-localqueue-validation] [--priority NAME] [--skip-priority-validation] [--cmd COMMAND] [--replicas [WORKER_GROUP]=REPLICAS] [--min-replicas [WORKER_GROUP]=MIN_REPLICAS] [--max-replicas [WORKER_GROUP]=MAX_REPLICAS]
```
@@ -113,6 +113,15 @@ kjobctl create rayjob --profile APPLICATION_PROFILE_NAME [--localqueue LOCAL_QUE
Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
+
+ --priority string |
+
+
+ |
+
+ Apply priority for the entire workload.
+ |
+
-p, --profile string |
@@ -158,6 +167,15 @@ kjobctl create rayjob --profile APPLICATION_PROFILE_NAME [--localqueue LOCAL_QUE
Skip local queue validation. Add local queue even if the queue does not exist.
+
+ --skip-priority-validation |
+
+
+ |
+
+ Skip workload priority class validation. Add priority class label even if the class does not exist.
+ |
+
--template string |
diff --git a/cmd/experimental/kjobctl/docs/commands/kjobctl_create/kjobctl_create_slurm.md b/cmd/experimental/kjobctl/docs/commands/kjobctl_create/kjobctl_create_slurm.md
index a3541c5dee..6f80852008 100644
--- a/cmd/experimental/kjobctl/docs/commands/kjobctl_create/kjobctl_create_slurm.md
+++ b/cmd/experimental/kjobctl/docs/commands/kjobctl_create/kjobctl_create_slurm.md
@@ -12,7 +12,7 @@ The file is auto-generated from the Go source code of the component using the
Create a slurm job
```
-kjobctl create slurm --profile APPLICATION_PROFILE_NAME [--localqueue LOCAL_QUEUE_NAME] [--skip-localqueue-validation] [--ignore-unknown-flags] [--skip-priority-validation] [--init-image IMAGE] [--first-node-ip] [--first-node-ip-timeout DURATION] -- [--array ARRAY] [--cpus-per-task QUANTITY] [--gpus-per-task QUANTITY] [--mem QUANTITY] [--mem-per-task QUANTITY] [--mem-per-cpu QUANTITY] [--mem-per-gpu QUANTITY] [--nodes COUNT] [--ntasks COUNT] [--output FILENAME_PATTERN] [--error FILENAME_PATTERN] [--input FILENAME_PATTERN] [--job-name NAME] [--partition NAME] [--priority NAME] SCRIPT
+kjobctl create slurm --profile APPLICATION_PROFILE_NAME [--localqueue LOCAL_QUEUE_NAME] [--skip-localqueue-validation] [--priority NAME] [--skip-priority-validation] [--ignore-unknown-flags] [--init-image IMAGE] [--first-node-ip] [--first-node-ip-timeout DURATION] -- [--array ARRAY] [--cpus-per-task QUANTITY] [--gpus-per-task QUANTITY] [--mem QUANTITY] [--mem-per-task QUANTITY] [--mem-per-cpu QUANTITY] [--mem-per-gpu QUANTITY] [--nodes COUNT] [--ntasks COUNT] [--output FILENAME_PATTERN] [--error FILENAME_PATTERN] [--input FILENAME_PATTERN] [--job-name NAME] [--partition NAME] SCRIPT
```
@@ -115,6 +115,15 @@ kjobctl create slurm --profile APPLICATION_PROFILE_NAME [--localqueue LOCAL_QUEU
Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
+
+ --priority string |
+
+
+ |
+
+ Apply priority for the entire workload.
+ |
+
-p, --profile string |
diff --git a/cmd/experimental/kjobctl/pkg/builder/builder.go b/cmd/experimental/kjobctl/pkg/builder/builder.go
index 679da8f09f..32c78bfb81 100644
--- a/cmd/experimental/kjobctl/pkg/builder/builder.go
+++ b/cmd/experimental/kjobctl/pkg/builder/builder.go
@@ -325,6 +325,14 @@ func (b *Builder) validateGeneral(ctx context.Context) error {
}
}
+ // check that priority class exists
+ if len(b.priority) != 0 && !b.skipPriorityValidation {
+ _, err := b.kueueClientset.KueueV1beta1().WorkloadPriorityClasses().Get(ctx, b.priority, metav1.GetOptions{})
+ if err != nil {
+ return err
+ }
+ }
+
return nil
}
@@ -533,6 +541,10 @@ func (b *Builder) buildObjectMeta(templateObjectMeta metav1.ObjectMeta) metav1.O
objectMeta.Labels[kueueconstants.QueueLabel] = b.localQueue
}
+ if len(b.priority) != 0 {
+ objectMeta.Labels[kueueconstants.WorkloadPriorityClassLabel] = b.priority
+ }
+
return objectMeta
}
diff --git a/cmd/experimental/kjobctl/pkg/builder/slurm_builder.go b/cmd/experimental/kjobctl/pkg/builder/slurm_builder.go
index 212334ffa1..f0381d59d3 100644
--- a/cmd/experimental/kjobctl/pkg/builder/slurm_builder.go
+++ b/cmd/experimental/kjobctl/pkg/builder/slurm_builder.go
@@ -35,7 +35,6 @@ import (
"k8s.io/apimachinery/pkg/runtime"
utilrand "k8s.io/apimachinery/pkg/util/rand"
"k8s.io/utils/ptr"
- kueue "sigs.k8s.io/kueue/pkg/controller/constants"
"sigs.k8s.io/kueue/cmd/experimental/kjobctl/apis/v1alpha1"
"sigs.k8s.io/kueue/cmd/experimental/kjobctl/pkg/parser"
@@ -116,7 +115,7 @@ type slurmBuilder struct {
var _ builder = (*slurmBuilder)(nil)
-func (b *slurmBuilder) validateGeneral(ctx context.Context) error {
+func (b *slurmBuilder) validateGeneral() error {
if len(b.script) == 0 {
return noScriptSpecifiedErr
}
@@ -129,14 +128,6 @@ func (b *slurmBuilder) validateGeneral(ctx context.Context) error {
return noGpusPerTaskSpecifiedErr
}
- // check that priority class exists
- if len(b.priority) != 0 && !b.skipPriorityValidation {
- _, err := b.kueueClientset.KueueV1beta1().WorkloadPriorityClasses().Get(ctx, b.priority, metav1.GetOptions{})
- if err != nil {
- return err
- }
- }
-
return nil
}
@@ -213,7 +204,7 @@ func (b *slurmBuilder) validateMutuallyExclusiveFlags() error {
}
func (b *slurmBuilder) build(ctx context.Context) (runtime.Object, []runtime.Object, error) {
- if err := b.validateGeneral(ctx); err != nil {
+ if err := b.validateGeneral(); err != nil {
return nil, nil, err
}
@@ -239,10 +230,6 @@ func (b *slurmBuilder) build(ctx context.Context) (runtime.Object, []runtime.Obj
job.Spec.CompletionMode = ptr.To(batchv1.IndexedCompletion)
job.Spec.Template.Spec.Subdomain = b.objectName
- if len(b.priority) != 0 {
- job.Labels[kueue.WorkloadPriorityClassLabel] = b.priority
- }
-
b.buildPodSpecVolumesAndEnv(&job.Spec.Template.Spec)
job.Spec.Template.Spec.Volumes = append(job.Spec.Template.Spec.Volumes,
corev1.Volume{
diff --git a/cmd/experimental/kjobctl/pkg/cmd/create/create.go b/cmd/experimental/kjobctl/pkg/cmd/create/create.go
index 9a55073b36..bc34f002c7 100644
--- a/cmd/experimental/kjobctl/pkg/cmd/create/create.go
+++ b/cmd/experimental/kjobctl/pkg/cmd/create/create.go
@@ -330,7 +330,6 @@ var createModeSubcommands = map[string]modeSubcommand{
ModeName: v1alpha1.SlurmMode,
Setup: func(clientGetter util.ClientGetter, subcmd *cobra.Command, o *CreateOptions) {
subcmd.Use += " [--ignore-unknown-flags]" +
- " [--skip-priority-validation]" +
" [--init-image IMAGE]" +
" [--first-node-ip]" +
" [--first-node-ip-timeout DURATION]" +
@@ -349,7 +348,6 @@ var createModeSubcommands = map[string]modeSubcommand{
" [--input FILENAME_PATTERN]" +
" [--job-name NAME]" +
" [--partition NAME]" +
- " [--priority NAME]" +
" SCRIPT"
subcmd.Short = "Create a slurm job"
@@ -360,8 +358,6 @@ var createModeSubcommands = map[string]modeSubcommand{
"Ignore all the unsupported flags in the bash script.")
subcmd.Flags().StringVar(&o.InitImage, initImageFlagName, "registry.k8s.io/busybox:1.27.2",
"The image used for the init container.")
- subcmd.Flags().BoolVar(&o.SkipPriorityValidation, skipPriorityValidationFlagName, false,
- "Skip workload priority class validation. Add priority class label even if the class does not exist.")
subcmd.Flags().BoolVar(&o.FirstNodeIP, firstNodeIPFlagName, false,
"Enable the retrieval of the first node's IP address.")
subcmd.Flags().DurationVar(&o.FirstNodeIPTimeout, firstNodeIPTimeoutFlagName, time.Minute,
@@ -400,8 +396,6 @@ The minimum index value is 0. The maximum index value is 2147483647.`)
"What is the job name.")
o.SlurmFlagSet.StringVar(&o.Partition, partitionFlagName, "",
"Local queue name.")
- o.SlurmFlagSet.StringVar(&o.Priority, priorityFlagName, "",
- "Apply priority for the entire workload.")
o.SlurmFlagSet.StringVarP(&o.ChangeDir, changeDirFlagName, "D", "",
"Change directory before executing the script.")
},
@@ -428,7 +422,9 @@ func NewCreateCmd(clientGetter util.ClientGetter, streams genericiooptions.IOStr
Use: modeName +
" --profile APPLICATION_PROFILE_NAME" +
" [--localqueue LOCAL_QUEUE_NAME]" +
- " [--skip-localqueue-validation]",
+ " [--skip-localqueue-validation]" +
+ " [--priority NAME]" +
+ " [--skip-priority-validation]",
DisableFlagsInUseLine: true,
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
@@ -451,6 +447,10 @@ func NewCreateCmd(clientGetter util.ClientGetter, streams genericiooptions.IOStr
"Kueue localqueue name which is associated with the resource.")
subcmd.Flags().BoolVar(&o.SkipLocalQueueValidation, skipLocalQueueValidationFlagName, false,
"Skip local queue validation. Add local queue even if the queue does not exist.")
+ subcmd.Flags().StringVar(&o.Priority, priorityFlagName, "",
+ "Apply priority for the entire workload.")
+ subcmd.Flags().BoolVar(&o.SkipPriorityValidation, skipPriorityValidationFlagName, false,
+ "Skip workload priority class validation. Add priority class label even if the class does not exist.")
modeSubcommand.Setup(clientGetter, subcmd, o)
diff --git a/cmd/experimental/kjobctl/pkg/cmd/create/create_test.go b/cmd/experimental/kjobctl/pkg/cmd/create/create_test.go
index 36c9709d05..30e807ff1e 100644
--- a/cmd/experimental/kjobctl/pkg/cmd/create/create_test.go
+++ b/cmd/experimental/kjobctl/pkg/cmd/create/create_test.go
@@ -341,6 +341,69 @@ func TestCreateCmd(t *testing.T) {
// Fake dynamic client not generating name. That's why we have .
wantOut: "job.batch/ created\n",
},
+ "should create job with --priority flag": {
+ args: func(tc *createCmdTestCase) []string {
+ return []string{"job", "--profile", "profile", "--priority", "sample-priority"}
+ },
+ kjobctlObjs: []runtime.Object{
+ wrappers.MakeJobTemplate("job-template", metav1.NamespaceDefault).
+ Obj(),
+ wrappers.MakeApplicationProfile("profile", metav1.NamespaceDefault).
+ WithSupportedMode(*wrappers.MakeSupportedMode(v1alpha1.JobMode, "job-template").Obj()).
+ Obj(),
+ },
+ kueueObjs: []runtime.Object{
+ &kueue.WorkloadPriorityClass{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "sample-priority",
+ },
+ },
+ },
+ gvks: []schema.GroupVersionKind{{Group: "batch", Version: "v1", Kind: "Job"}},
+ wantLists: []runtime.Object{
+ &batchv1.JobList{
+ TypeMeta: metav1.TypeMeta{Kind: "JobList", APIVersion: "batch/v1"},
+ Items: []batchv1.Job{
+ *wrappers.MakeJob("", metav1.NamespaceDefault).
+ Priority("sample-priority").
+ GenerateName("profile-job-").
+ Profile("profile").
+ Mode(v1alpha1.JobMode).
+ Obj(),
+ },
+ },
+ },
+ // Fake dynamic client not generating name. That's why we have .
+ wantOut: "job.batch/ created\n",
+ },
+ "should create job with --priority flag and skip workload priority class validation": {
+ args: func(tc *createCmdTestCase) []string {
+ return []string{"job", "--profile", "profile", "--skip-priority-validation", "--priority", "sample-priority"}
+ },
+ kjobctlObjs: []runtime.Object{
+ wrappers.MakeJobTemplate("job-template", metav1.NamespaceDefault).
+ Obj(),
+ wrappers.MakeApplicationProfile("profile", metav1.NamespaceDefault).
+ WithSupportedMode(*wrappers.MakeSupportedMode(v1alpha1.JobMode, "job-template").Obj()).
+ Obj(),
+ },
+ gvks: []schema.GroupVersionKind{{Group: "batch", Version: "v1", Kind: "Job"}},
+ wantLists: []runtime.Object{
+ &batchv1.JobList{
+ TypeMeta: metav1.TypeMeta{Kind: "JobList", APIVersion: "batch/v1"},
+ Items: []batchv1.Job{
+ *wrappers.MakeJob("", metav1.NamespaceDefault).
+ Priority("sample-priority").
+ GenerateName("profile-job-").
+ Profile("profile").
+ Mode(v1alpha1.JobMode).
+ Obj(),
+ },
+ },
+ },
+ // Fake dynamic client not generating name. That's why we have .
+ wantOut: "job.batch/ created\n",
+ },
"should create job with completions replacement": {
args: func(tc *createCmdTestCase) []string {
return []string{"job", "--profile", "profile", "--completions", "5"}
@@ -623,6 +686,69 @@ func TestCreateCmd(t *testing.T) {
// Fake dynamic client not generating name. That's why we have .
wantOut: "rayjob.ray.io/ created\n",
},
+ "should create ray job with --priority flag": {
+ args: func(tc *createCmdTestCase) []string {
+ return []string{"rayjob", "--profile", "profile", "--priority", "sample-priority"}
+ },
+ kjobctlObjs: []runtime.Object{
+ wrappers.MakeRayJobTemplate("ray-job-template", metav1.NamespaceDefault).
+ Obj(),
+ wrappers.MakeApplicationProfile("profile", metav1.NamespaceDefault).
+ WithSupportedMode(*wrappers.MakeSupportedMode(v1alpha1.RayJobMode, "ray-job-template").Obj()).
+ Obj(),
+ },
+ kueueObjs: []runtime.Object{
+ &kueue.WorkloadPriorityClass{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "sample-priority",
+ },
+ },
+ },
+ gvks: []schema.GroupVersionKind{{Group: "ray.io", Version: "v1", Kind: "RayJob"}},
+ wantLists: []runtime.Object{
+ &rayv1.RayJobList{
+ TypeMeta: metav1.TypeMeta{Kind: "RayJobList", APIVersion: "ray.io/v1"},
+ Items: []rayv1.RayJob{
+ *wrappers.MakeRayJob("", metav1.NamespaceDefault).
+ Priority("sample-priority").
+ GenerateName("profile-rayjob-").
+ Profile("profile").
+ Mode(v1alpha1.RayJobMode).
+ Obj(),
+ },
+ },
+ },
+ // Fake dynamic client not generating name. That's why we have .
+ wantOut: "rayjob.ray.io/ created\n",
+ },
+ "should create ray job with --priority flag and skip workload priority class validation": {
+ args: func(tc *createCmdTestCase) []string {
+ return []string{"rayjob", "--profile", "profile", "--skip-priority-validation", "--priority", "sample-priority"}
+ },
+ kjobctlObjs: []runtime.Object{
+ wrappers.MakeRayJobTemplate("ray-job-template", metav1.NamespaceDefault).
+ Obj(),
+ wrappers.MakeApplicationProfile("profile", metav1.NamespaceDefault).
+ WithSupportedMode(*wrappers.MakeSupportedMode(v1alpha1.RayJobMode, "ray-job-template").Obj()).
+ Obj(),
+ },
+ gvks: []schema.GroupVersionKind{{Group: "ray.io", Version: "v1", Kind: "RayJob"}},
+ wantLists: []runtime.Object{
+ &rayv1.RayJobList{
+ TypeMeta: metav1.TypeMeta{Kind: "RayJobList", APIVersion: "ray.io/v1"},
+ Items: []rayv1.RayJob{
+ *wrappers.MakeRayJob("", metav1.NamespaceDefault).
+ Priority("sample-priority").
+ GenerateName("profile-rayjob-").
+ Profile("profile").
+ Mode(v1alpha1.RayJobMode).
+ Obj(),
+ },
+ },
+ },
+ // Fake dynamic client not generating name. That's why we have .
+ wantOut: "rayjob.ray.io/ created\n",
+ },
"shouldn't create ray job with raycluster and localqueue replacements because mutually exclusive": {
args: func(tc *createCmdTestCase) []string {
return []string{"rayjob", "--profile", "profile", "--raycluster", "rc1", "--localqueue", "lq1"}
@@ -671,6 +797,76 @@ func TestCreateCmd(t *testing.T) {
// Fake dynamic client not generating name. That's why we have .
wantOut: "raycluster.ray.io/ created\n",
},
+ "should create raycluster with --priority flag": {
+ args: func(tc *createCmdTestCase) []string {
+ return []string{
+ "raycluster",
+ "--profile", "profile",
+ "--priority", "sample-priority",
+ }
+ },
+ kjobctlObjs: []runtime.Object{
+ wrappers.MakeRayClusterTemplate("ray-cluster-template", metav1.NamespaceDefault).Obj(),
+ wrappers.MakeApplicationProfile("profile", metav1.NamespaceDefault).
+ WithSupportedMode(*wrappers.MakeSupportedMode(v1alpha1.RayClusterMode, "ray-cluster-template").Obj()).
+ Obj(),
+ },
+ kueueObjs: []runtime.Object{
+ &kueue.WorkloadPriorityClass{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "sample-priority",
+ },
+ },
+ },
+ gvks: []schema.GroupVersionKind{{Group: "ray.io", Version: "v1", Kind: "RayCluster"}},
+ wantLists: []runtime.Object{
+ &rayv1.RayClusterList{
+ TypeMeta: metav1.TypeMeta{Kind: "RayClusterList", APIVersion: "ray.io/v1"},
+ Items: []rayv1.RayCluster{
+ *wrappers.MakeRayCluster("", metav1.NamespaceDefault).
+ Priority("sample-priority").
+ GenerateName("profile-raycluster-").
+ Profile("profile").
+ Mode(v1alpha1.RayClusterMode).
+ Obj(),
+ },
+ },
+ },
+ // Fake dynamic client not generating name. That's why we have .
+ wantOut: "raycluster.ray.io/ created\n",
+ },
+ "should create raycluster with --priority flag and skip workload priority class validation": {
+ args: func(tc *createCmdTestCase) []string {
+ return []string{
+ "raycluster",
+ "--profile", "profile",
+ "--skip-priority-validation",
+ "--priority", "sample-priority",
+ }
+ },
+ kjobctlObjs: []runtime.Object{
+ wrappers.MakeRayClusterTemplate("ray-cluster-template", metav1.NamespaceDefault).Obj(),
+ wrappers.MakeApplicationProfile("profile", metav1.NamespaceDefault).
+ WithSupportedMode(*wrappers.MakeSupportedMode(v1alpha1.RayClusterMode, "ray-cluster-template").Obj()).
+ Obj(),
+ },
+ gvks: []schema.GroupVersionKind{{Group: "ray.io", Version: "v1", Kind: "RayCluster"}},
+ wantLists: []runtime.Object{
+ &rayv1.RayClusterList{
+ TypeMeta: metav1.TypeMeta{Kind: "RayClusterList", APIVersion: "ray.io/v1"},
+ Items: []rayv1.RayCluster{
+ *wrappers.MakeRayCluster("", metav1.NamespaceDefault).
+ Priority("sample-priority").
+ GenerateName("profile-raycluster-").
+ Profile("profile").
+ Mode(v1alpha1.RayClusterMode).
+ Obj(),
+ },
+ },
+ },
+ // Fake dynamic client not generating name. That's why we have .
+ wantOut: "raycluster.ray.io/ created\n",
+ },
"shouldn't create slurm because slurm args must be specified": {
args: func(tc *createCmdTestCase) []string {
return []string{"slurm", "--profile", "profile"}
@@ -1478,8 +1674,8 @@ cd /mydir
return []string{
"slurm",
"--profile", "profile",
- "--",
"--priority", "sample-priority",
+ "--",
tc.tempFile,
}
},
@@ -1640,9 +1836,9 @@ cd /mydir
return []string{
"slurm",
"--profile", "profile",
+ "--priority", "sample-priority",
"--skip-priority-validation",
"--",
- "--priority", "sample-priority",
tc.tempFile,
}
},
diff --git a/cmd/experimental/kjobctl/pkg/cmd/printcrds/embed/manifest.gz b/cmd/experimental/kjobctl/pkg/cmd/printcrds/embed/manifest.gz
index 8b9e98e165..24ddd146c4 100644
Binary files a/cmd/experimental/kjobctl/pkg/cmd/printcrds/embed/manifest.gz and b/cmd/experimental/kjobctl/pkg/cmd/printcrds/embed/manifest.gz differ
diff --git a/cmd/experimental/kjobctl/pkg/testing/wrappers/ray_cluster_wrappers.go b/cmd/experimental/kjobctl/pkg/testing/wrappers/ray_cluster_wrappers.go
index 60072127a2..ad0f45e6e3 100644
--- a/cmd/experimental/kjobctl/pkg/testing/wrappers/ray_cluster_wrappers.go
+++ b/cmd/experimental/kjobctl/pkg/testing/wrappers/ray_cluster_wrappers.go
@@ -171,3 +171,8 @@ func (j *RayClusterWrapper) Reason(reason string) *RayClusterWrapper {
j.RayCluster.Status.Reason = reason
return j
}
+
+// Priority sets the workload priority class label.
+func (j *RayClusterWrapper) Priority(v string) *RayClusterWrapper {
+ return j.Label(kueueconstants.WorkloadPriorityClassLabel, v)
+}
diff --git a/cmd/experimental/kjobctl/pkg/testing/wrappers/ray_job_wrappers.go b/cmd/experimental/kjobctl/pkg/testing/wrappers/ray_job_wrappers.go
index d93ff4f084..b8557d6544 100644
--- a/cmd/experimental/kjobctl/pkg/testing/wrappers/ray_job_wrappers.go
+++ b/cmd/experimental/kjobctl/pkg/testing/wrappers/ray_job_wrappers.go
@@ -174,3 +174,8 @@ func (j *RayJobWrapper) RayClusterName(rayClusterName string) *RayJobWrapper {
j.RayJob.Status.RayClusterName = rayClusterName
return j
}
+
+// Priority sets the workload priority class label.
+func (j *RayJobWrapper) Priority(v string) *RayJobWrapper {
+ return j.Label(kueueconstants.WorkloadPriorityClassLabel, v)
+}