diff --git a/src/frontend/apiserver/backend/convert.go b/src/frontend/apiserver/backend/convert.go index da729be7..db25c461 100644 --- a/src/frontend/apiserver/backend/convert.go +++ b/src/frontend/apiserver/backend/convert.go @@ -53,6 +53,7 @@ func cJobArrayToModels(jobArray *C.xce_job_submit_t) []*models.JobInfo { resReq: goString(s.resreq), minTasks: int(s.mintasks), maxTasks: int(s.maxtasks), + fromHost: goString(s.from_host), } if s.start_info != nil { si := s.start_info @@ -93,6 +94,7 @@ func cJobToModel(job *C.xce_job_t) *models.JobInfo { resReq: goString(s.resreq), minTasks: int(s.mintasks), maxTasks: int(s.maxtasks), + fromHost: goString(s.from_host), } if s.start_info != nil { si := s.start_info @@ -278,6 +280,9 @@ func modelJobToSubmit(job *models.JobInfo) (*C.xce_job_submit_t, *C.job_submit_d if job.ResReq != "" { sd.resreq = C.CString(job.ResReq) } + if job.FromHost != "" { + sd.from_host = C.CString(job.FromHost) + } sd.mintasks = C.uint(job.NumProcessors) if sd.mintasks == 0 { sd.mintasks = 1 @@ -313,6 +318,7 @@ func freeJobSubmit(js *C.xce_job_submit_t, sd *C.job_submit_data_t, si *C.job_st C.free(unsafe.Pointer(sd.user_group)) C.free(unsafe.Pointer(sd.job_description)) C.free(unsafe.Pointer(sd.resreq)) + C.free(unsafe.Pointer(sd.from_host)) C.free(unsafe.Pointer(sd)) } if js != nil { diff --git a/src/frontend/apiserver/backend/convert_pure.go b/src/frontend/apiserver/backend/convert_pure.go index 0ba0daf2..66e05732 100644 --- a/src/frontend/apiserver/backend/convert_pure.go +++ b/src/frontend/apiserver/backend/convert_pure.go @@ -127,6 +127,7 @@ type rawSubmitData struct { minTasks int maxTasks int startInfo *rawStartInfo + fromHost string } // rawJobData mirrors the C xce_job_t fields used by the Go model. @@ -197,6 +198,7 @@ func rawJobToModel(r rawJobData) *models.JobInfo { info.ResReq = s.resReq info.NumProcessors = s.minTasks info.MaxNumProcessors = s.maxTasks + info.FromHost = s.fromHost if s.startInfo != nil { si := s.startInfo info.Command = si.cmdline diff --git a/src/frontend/apiserver/backend/convert_test.go b/src/frontend/apiserver/backend/convert_test.go index 83d2cdba..2f1ebb45 100644 --- a/src/frontend/apiserver/backend/convert_test.go +++ b/src/frontend/apiserver/backend/convert_test.go @@ -16,6 +16,7 @@ func TestRawJobToModel_BasicFields(t *testing.T) { jobName: "myjob", minTasks: 1, maxTasks: 4, + fromHost: "203.0.113.7", startInfo: &rawStartInfo{ cmdline: "sleep 60", }, @@ -54,6 +55,25 @@ func TestRawJobToModel_BasicFields(t *testing.T) { if info.RunTime != 42 { t.Errorf("RunTime: got %d, want 42", info.RunTime) } + if info.FromHost != "203.0.113.7" { + t.Errorf("FromHost: got %q, want %q", info.FromHost, "203.0.113.7") + } +} + +// bug-1676: FromHost must round-trip through rawSubmitData into JobInfo like +// every other submit-time field, and must be empty-safe (no submit data, or +// submit data with no from_host, must not panic and must leave FromHost ""). +func TestRawJobToModel_FromHost_EmptySafe(t *testing.T) { + r := rawJobData{ + jobID: 1, + submit: &rawSubmitData{queue: "normal"}, + } + + info := rawJobToModel(r) + + if info.FromHost != "" { + t.Errorf("FromHost: got %q, want empty string when submit.fromHost is unset", info.FromHost) + } } func TestRawJobToModel_NilSubmit(t *testing.T) {