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
|
|
@ -236,6 +236,55 @@ type rawStartInfo struct {
|
|||
execHome string
|
||||
execCWD string
|
||||
execUser string
|
||||
exdata string
|
||||
}
|
||||
|
||||
// submitStartInfo maps a Go JobInfo to the job_startinfo_t fields a
|
||||
// submission carries to the controller (and from there, unchanged, to the
|
||||
// worker's startjob request). modelJobToSubmit (convert.go) is the CGO
|
||||
// adapter that copies the result into the C struct.
|
||||
//
|
||||
// bug-1936: exdata (env, limits, transfers, interactive mode, built by the
|
||||
// submit handler into ExtendData), the exec cwd and the exec home were
|
||||
// never set, so none of them reached the worker.
|
||||
func submitStartInfo(job *models.JobInfo) rawStartInfo {
|
||||
execCWD := job.ExecCWD
|
||||
if execCWD == "" {
|
||||
execCWD = job.CWD
|
||||
}
|
||||
return rawStartInfo{
|
||||
cmdline: job.Command,
|
||||
launchType: job.LaunchType,
|
||||
preExec: job.PreExecCmd,
|
||||
postExec: job.PostExecCmd,
|
||||
execHome: job.ExecHome,
|
||||
execCWD: execCWD,
|
||||
execUser: resolveExecUser(job.ExecUser, job.SubmitUser),
|
||||
exdata: job.ExtendData.String,
|
||||
}
|
||||
}
|
||||
|
||||
// maxExdataLen is the longest exdata the worker can take: xcecd hands it to
|
||||
// xcecd_worker in job_assignment_t.exdata[EXDATA_LENGTH] (16 KiB,
|
||||
// src/worker/include/uv_ipc.h), NUL included.
|
||||
const maxExdataLen = 16*1024 - 1
|
||||
|
||||
// ValidateExdata checks a job's extended data before it is submitted: the
|
||||
// worker's parse_exdata() fails the job at launch on anything but a JSON
|
||||
// object, and a longer string than maxExdataLen would be cut short on its
|
||||
// way to the job process.
|
||||
func ValidateExdata(exdata string) error {
|
||||
if exdata == "" {
|
||||
return nil
|
||||
}
|
||||
if len(exdata) > maxExdataLen {
|
||||
return fmt.Errorf("extended job data is %d bytes, more than the limit of %d", len(exdata), maxExdataLen)
|
||||
}
|
||||
var obj map[string]interface{}
|
||||
if err := json.Unmarshal([]byte(exdata), &obj); err != nil {
|
||||
return errors.New("extended job data must be a JSON object")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// rawSubmitData mirrors the C job_submit_data_t fields used by the Go model.
|
||||
|
|
@ -358,7 +407,9 @@ func rawJobToModel(r rawJobData) *models.JobInfo {
|
|||
info.PostExecCmd = si.postExec
|
||||
info.ExecHome = si.execHome
|
||||
info.ExecCWD = si.execCWD
|
||||
info.CWD = si.execCWD // the submit cwd is sent as the exec cwd (bug-1936)
|
||||
info.ExecUser = si.execUser
|
||||
info.ExtendData = models.Jsonb{String: si.exdata}
|
||||
}
|
||||
}
|
||||
info.SubmitTime = r.subTime
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue