fix(apiserver): send exdata, exec cwd and exec home with submitted jobs (bug-1936)
Cause: modelJobToSubmit() filled only cmdline, execuser, launch_type and pre/post-exec of job_startinfo_t, so the extended data the submit handler builds (env, *_limit incl. -W run limit, file transfers, interactive mode), the cwd and the exec home never reached the controller or the worker. Fix: map the start info in a pure submitStartInfo() (exdata from ExtendData, execcwd from ExecCWD or CWD, exechome from ExecHome) that modelJobToSubmit copies into the C struct; decode exdata back in cJobToModel/cJobArrayToModels so the store keeps ExtendData and CWD. Reject extend_data the worker's parse_exdata() cannot take (not a JSON object, over EXDATA_LENGTH-1 bytes) and drop an empty transfer list instead of sending a null. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7a9d75d661
commit
d01ced9bd0
5 changed files with 236 additions and 14 deletions
|
|
@ -1920,7 +1920,9 @@ func processJobRequest(ctx *gin.Context, req *models.JobSubmitRequest, defaultVa
|
|||
extendData[i] = entry
|
||||
}
|
||||
}
|
||||
extendDataMap["transfer_files"] = extendData
|
||||
if len(extendData) > 0 {
|
||||
extendDataMap["transfer_files"] = extendData
|
||||
}
|
||||
}
|
||||
|
||||
// handle env into json format
|
||||
|
|
@ -1990,6 +1992,12 @@ func processJobRequest(ctx *gin.Context, req *models.JobSubmitRequest, defaultVa
|
|||
req.ExtendData = string(updatedExtendDataBytes)
|
||||
}
|
||||
|
||||
// bug-1936: ExtendData is the job's exdata at the worker; reject what
|
||||
// the worker could not parse instead of failing the job at launch.
|
||||
if err := backend.ValidateExdata(req.ExtendData); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1519,3 +1519,60 @@ func TestJobHandler_RestartNamedJob(t *testing.T) {
|
|||
w.Code, len(f.submitted)-before, w.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
// bug-1936: the job handed to the backend carries the cwd and the extended
|
||||
// data under the key names and units the worker's parse_exdata()/
|
||||
// parse_limits() read (run_limit in seconds, memory limits in MB,
|
||||
// sub_env_vars as a string map); modelJobToSubmit copies them into the
|
||||
// start info.
|
||||
func TestJobHandler_SubmitCarriesCwdEnvLimitsInExdata(t *testing.T) {
|
||||
f := newHandlerFixture(t)
|
||||
f.seedQueue("normal")
|
||||
|
||||
w := f.submit(map[string]interface{}{
|
||||
"command": "sleep 120", "queue_name": "normal", "cwd": "/tmp/work",
|
||||
"env": []string{"A=1"}, "run_limit": "1", "mem_limit": "1 GB",
|
||||
})
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("status = %d, want 200; body: %s", w.Code, w.Body.String())
|
||||
}
|
||||
subs := f.submissions()
|
||||
if len(subs) != 1 {
|
||||
t.Fatalf("submitJob calls = %d, want 1", len(subs))
|
||||
}
|
||||
job := subs[0].Job
|
||||
if job.CWD != "/tmp/work" {
|
||||
t.Errorf("CWD = %q, want /tmp/work", job.CWD)
|
||||
}
|
||||
var ex struct {
|
||||
Env map[string]string `json:"sub_env_vars"`
|
||||
Limits map[string]float64 `json:"limits"`
|
||||
}
|
||||
if err := json.Unmarshal([]byte(job.ExtendData.String), &ex); err != nil {
|
||||
t.Fatalf("ExtendData %q is not a JSON object: %v", job.ExtendData.String, err)
|
||||
}
|
||||
if ex.Env["A"] != "1" {
|
||||
t.Errorf("sub_env_vars = %v, want A=1", ex.Env)
|
||||
}
|
||||
if ex.Limits["run_limit"] != 60 || ex.Limits["rss_limit"] != 1024 {
|
||||
t.Errorf("limits = %v, want run_limit 60 (s) and rss_limit 1024 (MB)", ex.Limits)
|
||||
}
|
||||
}
|
||||
|
||||
// bug-1936: extend_data the worker cannot parse (not a JSON object) would
|
||||
// fail the job at launch; the submission is rejected instead.
|
||||
func TestJobHandler_SubmitRejectsNonObjectExtendData(t *testing.T) {
|
||||
f := newHandlerFixture(t)
|
||||
f.seedQueue("normal")
|
||||
|
||||
for _, ex := range []string{"abc", `[1,2]`} {
|
||||
before := len(f.submissions())
|
||||
w := f.submit(map[string]interface{}{
|
||||
"command": "sleep 1", "queue_name": "normal", "extend_data": ex,
|
||||
})
|
||||
if w.Code == http.StatusOK || len(f.submissions()) != before {
|
||||
t.Errorf("extend_data %q: status %d, %d submits; want an error and none; body %s",
|
||||
ex, w.Code, len(f.submissions())-before, w.Body.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue