Skip to content

Commit 982f0ac

Browse files
author
Mahmood Ali
authored
api: Ignore User provided ParentID (#10424)
ParentID is an internal field that Nomad sets for dispatched or parameterized jobs. Job submitters should not be able to set it directly, as that messes up children tracking. Fixes #10422 . It specifically stops the scheduler from honoring the ParentID. The reason failure and why the scheduler didn't schedule that job once it was created is very interesting and requires follow up with a more technical issue.
1 parent 6f17ad6 commit 982f0ac

File tree

2 files changed

+62
-3
lines changed

2 files changed

+62
-3
lines changed

command/agent/job_endpoint.go

-1
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,6 @@ func ApiJobToStructJob(job *api.Job) *structs.Job {
782782
Region: *job.Region,
783783
Namespace: *job.Namespace,
784784
ID: *job.ID,
785-
ParentID: *job.ParentID,
786785
Name: *job.Name,
787786
Type: *job.Type,
788787
Priority: *job.Priority,

command/agent/job_endpoint_test.go

+62-2
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,68 @@ func TestHTTP_JobsRegister(t *testing.T) {
221221
})
222222
}
223223

224+
func TestHTTP_JobsRegister_IgnoresParentID(t *testing.T) {
225+
t.Parallel()
226+
httpTest(t, nil, func(s *TestAgent) {
227+
// Create the job
228+
job := MockJob()
229+
parentID := "somebadparentid"
230+
job.ParentID = &parentID
231+
args := api.JobRegisterRequest{
232+
Job: job,
233+
WriteRequest: api.WriteRequest{Region: "global"},
234+
}
235+
buf := encodeReq(args)
236+
237+
// Make the HTTP request
238+
req, err := http.NewRequest("PUT", "/v1/jobs", buf)
239+
require.NoError(t, err)
240+
respW := httptest.NewRecorder()
241+
242+
// Make the request
243+
obj, err := s.Server.JobsRequest(respW, req)
244+
require.NoError(t, err)
245+
246+
// Check the response
247+
reg := obj.(structs.JobRegisterResponse)
248+
require.NotEmpty(t, reg.EvalID)
249+
250+
// Check for the index
251+
require.NotEmpty(t, respW.HeaderMap.Get("X-Nomad-Index"))
252+
253+
// Check the job is registered
254+
getReq := structs.JobSpecificRequest{
255+
JobID: *job.ID,
256+
QueryOptions: structs.QueryOptions{
257+
Region: "global",
258+
Namespace: structs.DefaultNamespace,
259+
},
260+
}
261+
var getResp structs.SingleJobResponse
262+
err = s.Agent.RPC("Job.GetJob", &getReq, &getResp)
263+
require.NoError(t, err)
264+
265+
require.NotNil(t, getResp.Job)
266+
require.Equal(t, *job.ID, getResp.Job.ID)
267+
require.Empty(t, getResp.Job.ParentID)
268+
269+
// check the eval exists
270+
evalReq := structs.EvalSpecificRequest{
271+
EvalID: reg.EvalID,
272+
QueryOptions: structs.QueryOptions{
273+
Region: "global",
274+
Namespace: structs.DefaultNamespace,
275+
},
276+
}
277+
var evalResp structs.SingleEvalResponse
278+
err = s.Agent.RPC("Eval.GetEval", &evalReq, &evalResp)
279+
require.NoError(t, err)
280+
281+
require.NotNil(t, evalResp.Eval)
282+
require.Equal(t, reg.EvalID, evalResp.Eval.ID)
283+
})
284+
}
285+
224286
// Test that ACL token is properly threaded through to the RPC endpoint
225287
func TestHTTP_JobsRegister_ACL(t *testing.T) {
226288
t.Parallel()
@@ -2172,7 +2234,6 @@ func TestJobs_ApiJobToStructsJob(t *testing.T) {
21722234
Namespace: "foo",
21732235
VaultNamespace: "ghi789",
21742236
ID: "foo",
2175-
ParentID: "lol",
21762237
Name: "name",
21772238
Type: "service",
21782239
Priority: 50,
@@ -2673,7 +2734,6 @@ func TestJobs_ApiJobToStructsJob(t *testing.T) {
26732734
Region: "global",
26742735
Namespace: "foo",
26752736
ID: "foo",
2676-
ParentID: "lol",
26772737
Name: "name",
26782738
Type: "system",
26792739
Priority: 50,

0 commit comments

Comments
 (0)