Skip to content

Commit 96fbbc1

Browse files
[Fix][RayJob] Invalid quote for RayJob submitter (ray-project#2949)
Closes: ray-project#2943 Signed-off-by: Chi-Sheng Liu <chishengliu@chishengliu.com>
1 parent 5ffc42e commit 96fbbc1

File tree

4 files changed

+13
-22
lines changed

4 files changed

+13
-22
lines changed

ray-operator/controllers/ray/common/job.go

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"strings"
88

99
semver "github.com/Masterminds/semver/v3"
10-
"github.com/google/shlex"
1110
corev1 "k8s.io/api/core/v1"
1211
"k8s.io/apimachinery/pkg/api/resource"
1312
"sigs.k8s.io/yaml"
@@ -60,7 +59,7 @@ func GetK8sJobCommand(rayJobInstance *rayv1.RayJob) ([]string, error) {
6059
address := rayJobInstance.Status.DashboardURL
6160
metadata := rayJobInstance.Spec.Metadata
6261
jobId := rayJobInstance.Status.JobId
63-
entrypoint := rayJobInstance.Spec.Entrypoint
62+
entrypoint := strings.TrimSpace(rayJobInstance.Spec.Entrypoint)
6463
entrypointNumCpus := rayJobInstance.Spec.EntrypointNumCpus
6564
entrypointNumGpus := rayJobInstance.Spec.EntrypointNumGpus
6665
entrypointResources := rayJobInstance.Spec.EntrypointResources
@@ -120,15 +119,7 @@ func GetK8sJobCommand(rayJobInstance *rayv1.RayJob) ([]string, error) {
120119
}
121120

122121
// "--" is used to separate the entrypoint from the Ray Job CLI command and its arguments.
123-
k8sJobCommand = append(k8sJobCommand, "--")
124-
125-
commandSlice, err := shlex.Split(entrypoint)
126-
if err != nil {
127-
return nil, err
128-
}
129-
k8sJobCommand = append(k8sJobCommand, commandSlice...)
130-
131-
k8sJobCommand = append(k8sJobCommand, ";", "fi")
122+
k8sJobCommand = append(k8sJobCommand, "--", entrypoint, ";", "fi")
132123

133124
return k8sJobCommand, nil
134125
}

ray-operator/controllers/ray/common/job_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ var testRayJob = &rayv1.RayJob{
2222
RayClusterSpec: &rayv1.RayClusterSpec{
2323
RayVersion: "2.6.0",
2424
},
25-
Entrypoint: "echo hello",
25+
Entrypoint: "echo no quote 'single quote' \"double quote\"",
2626
EntrypointNumCpus: 1,
2727
EntrypointNumGpus: 0.5,
2828
EntrypointResources: `{"Custom_1": 1, "Custom_2": 5.5}`,
@@ -86,7 +86,7 @@ func TestGetK8sJobCommand(t *testing.T) {
8686
"--entrypoint-num-gpus", "0.500000",
8787
"--entrypoint-resources", strconv.Quote(`{"Custom_1": 1, "Custom_2": 5.5}`),
8888
"--",
89-
"echo", "hello",
89+
"echo no quote 'single quote' \"double quote\"",
9090
";", "fi",
9191
}
9292
command, err := GetK8sJobCommand(testRayJob)
@@ -107,7 +107,7 @@ pip: ["python-multipart==0.0.6"]
107107
RayClusterSpec: &rayv1.RayClusterSpec{
108108
RayVersion: "2.6.0",
109109
},
110-
Entrypoint: "echo hello",
110+
Entrypoint: "echo no quote 'single quote' \"double quote\"",
111111
},
112112
Status: rayv1.RayJobStatus{
113113
DashboardURL: "http://127.0.0.1:8265",
@@ -125,7 +125,7 @@ pip: ["python-multipart==0.0.6"]
125125
"--metadata-json", strconv.Quote(`{"testKey":"testValue"}`),
126126
"--submission-id", "testJobId",
127127
"--",
128-
"echo", "hello",
128+
"echo no quote 'single quote' \"double quote\"",
129129
";", "fi",
130130
}
131131
command, err := GetK8sJobCommand(rayJobWithYAML)

ray-operator/controllers/ray/rayjob_controller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ func getSubmitterTemplate(ctx context.Context, rayJobInstance *rayv1.RayJob, ray
503503
if err != nil {
504504
return corev1.PodTemplateSpec{}, err
505505
}
506-
submitterTemplate.Spec.Containers[utils.RayContainerIndex].Command = []string{"/bin/sh"}
506+
submitterTemplate.Spec.Containers[utils.RayContainerIndex].Command = []string{"/bin/bash"}
507507
submitterTemplate.Spec.Containers[utils.RayContainerIndex].Args = []string{"-c", strings.Join(k8sJobCommand, " ")}
508508
logger.Info("No command is specified in the user-provided template. Default command is used", "command", k8sJobCommand)
509509
} else {

ray-operator/controllers/ray/rayjob_controller_unit_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ func TestGetSubmitterTemplate(t *testing.T) {
9797
// RayJob instance with user-provided submitter pod template.
9898
rayJobInstanceWithTemplate := &rayv1.RayJob{
9999
Spec: rayv1.RayJobSpec{
100-
Entrypoint: "echo hello world",
100+
Entrypoint: "echo no quote 'single quote' \"double quote\"",
101101
SubmitterPodTemplate: &corev1.PodTemplateSpec{
102102
Spec: corev1.PodSpec{
103103
Containers: []corev1.Container{
@@ -118,7 +118,7 @@ func TestGetSubmitterTemplate(t *testing.T) {
118118
// In this case we should use the image of the Ray Head, so specify the image so we can test it.
119119
rayJobInstanceWithoutTemplate := &rayv1.RayJob{
120120
Spec: rayv1.RayJobSpec{
121-
Entrypoint: "echo hello world",
121+
Entrypoint: "echo no quote 'single quote' \"double quote\"",
122122
RayClusterSpec: &rayv1.RayClusterSpec{
123123
HeadGroupSpec: rayv1.HeadGroupSpec{
124124
Template: corev1.PodTemplateSpec{
@@ -165,14 +165,14 @@ func TestGetSubmitterTemplate(t *testing.T) {
165165
rayJobInstanceWithTemplate.Spec.SubmitterPodTemplate.Spec.Containers[utils.RayContainerIndex].Command = []string{}
166166
submitterTemplate, err = getSubmitterTemplate(ctx, rayJobInstanceWithTemplate, nil)
167167
require.NoError(t, err)
168-
assert.Equal(t, []string{"/bin/sh"}, submitterTemplate.Spec.Containers[utils.RayContainerIndex].Command)
169-
assert.Equal(t, []string{"-c", "if ray job status --address http://test-url test-job-id >/dev/null 2>&1 ; then ray job logs --address http://test-url --follow test-job-id ; else ray job submit --address http://test-url --submission-id test-job-id -- echo hello world ; fi"}, submitterTemplate.Spec.Containers[utils.RayContainerIndex].Args)
168+
assert.Equal(t, []string{"/bin/bash"}, submitterTemplate.Spec.Containers[utils.RayContainerIndex].Command)
169+
assert.Equal(t, []string{"-c", "if ray job status --address http://test-url test-job-id >/dev/null 2>&1 ; then ray job logs --address http://test-url --follow test-job-id ; else ray job submit --address http://test-url --submission-id test-job-id -- echo no quote 'single quote' \"double quote\" ; fi"}, submitterTemplate.Spec.Containers[utils.RayContainerIndex].Args)
170170

171171
// Test 3: User did not provide template, should use the image of the Ray Head
172172
submitterTemplate, err = getSubmitterTemplate(ctx, rayJobInstanceWithoutTemplate, rayClusterInstance)
173173
require.NoError(t, err)
174-
assert.Equal(t, []string{"/bin/sh"}, submitterTemplate.Spec.Containers[utils.RayContainerIndex].Command)
175-
assert.Equal(t, []string{"-c", "if ray job status --address http://test-url test-job-id >/dev/null 2>&1 ; then ray job logs --address http://test-url --follow test-job-id ; else ray job submit --address http://test-url --submission-id test-job-id -- echo hello world ; fi"}, submitterTemplate.Spec.Containers[utils.RayContainerIndex].Args)
174+
assert.Equal(t, []string{"/bin/bash"}, submitterTemplate.Spec.Containers[utils.RayContainerIndex].Command)
175+
assert.Equal(t, []string{"-c", "if ray job status --address http://test-url test-job-id >/dev/null 2>&1 ; then ray job logs --address http://test-url --follow test-job-id ; else ray job submit --address http://test-url --submission-id test-job-id -- echo no quote 'single quote' \"double quote\" ; fi"}, submitterTemplate.Spec.Containers[utils.RayContainerIndex].Args)
176176
assert.Equal(t, "rayproject/ray:custom-version", submitterTemplate.Spec.Containers[utils.RayContainerIndex].Image)
177177

178178
// Test 4: Check default PYTHONUNBUFFERED setting

0 commit comments

Comments
 (0)