From a2476d0176c1bd5f4558b508206f9ff97fb4122b Mon Sep 17 00:00:00 2001 From: Rongsong Shen Date: Sat, 9 May 2026 05:15:31 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20xcecli=20jobs=20list=20-l=20=E2=80=94=20?= =?UTF-8?q?hide=20spurious=20start=20line=20and=20show=20pending=20reason?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three fixes: 1. ExecHosts.UnmarshalJSON: JSON null (sent when no allocation exists) was treated as a non-"-" string because json.Unmarshal(null, &str) returns nil with str="". This created a phantom HostSlot{NumSlots:1, HostName:""} producing "<1*>" for every PEND job. Now null and "" are both treated as empty hosts. 2. page_print_jobs.go: added !startTime.IsZero() guard so a zero timestamp ("0001-01-01T00:00:00Z") never produces a start line even if the status check is bypassed. 3. Added PENDING_REASON field to JobFieldsMap so it is requested from the API when -l is passed, and rendered in printJobsVerboseOutput for PEND/PSUSP jobs before the start-time section. --- .../xcecli/common/output/page_print_jobs.go | 16 ++++++++++++++-- src/frontend/xcecli/models/jobs.go | 15 ++++++++++++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/frontend/xcecli/common/output/page_print_jobs.go b/src/frontend/xcecli/common/output/page_print_jobs.go index cfa01a8..9bb44c6 100644 --- a/src/frontend/xcecli/common/output/page_print_jobs.go +++ b/src/frontend/xcecli/common/output/page_print_jobs.go @@ -322,9 +322,20 @@ func printJobsVerboseOutput(jobs *models.JobsResponse, filter []string) { } PrintWrappedLine(w, submitLine, 80, 18) - // (3) print the start time info + // (3) print the pending reason for jobs waiting to be dispatched + if job.JobStatus == "PEND" || job.JobStatus == "PSUSP" { + if job.PendingReason != "" { + fmt.Fprintf(w, " PENDING REASONS:\n") + fmt.Fprintf(w, " %s\n", job.PendingReason) + } + } + + // (4) print the start time info — skip for jobs that haven't started yet startLine := "" - if startTime, err := parseJobTime(job.StartTime); err == nil { + if job.JobStatus == "PEND" || job.JobStatus == "PSUSP" { + goto printEndLine + } + if startTime, err := parseJobTime(job.StartTime); err == nil && !startTime.IsZero() { month := startTime.Format("Jan") day := startTime.Format("02") exec_hostname := "" @@ -380,6 +391,7 @@ func printJobsVerboseOutput(jobs *models.JobsResponse, filter []string) { } PrintWrappedLine(w, startLine, 80, 18) + printEndLine: // (4) print end line endLine := "" if job.JobStatus == "DONE" || job.JobStatus == "EXIT" { diff --git a/src/frontend/xcecli/models/jobs.go b/src/frontend/xcecli/models/jobs.go index 57048bf..8125148 100755 --- a/src/frontend/xcecli/models/jobs.go +++ b/src/frontend/xcecli/models/jobs.go @@ -32,6 +32,7 @@ const ( HEADER_JOB_LAUNCH_TYPE = "LAUNCH_TYPE" HEADER_JOB_NUM_PROCESSORS = "NUM_PROCESSORS" HEADER_JOB_INTERACTIVE_URL = "INTERACTIVE_URL" + HEADER_JOB_PENDING_REASON = "PENDING_REASON" // second line HEADER_JOB_R15S = "r15s" @@ -210,6 +211,7 @@ var JobFieldsMap = map[string]string{ HEADER_JOB_LAUNCH_TYPE: "launch_type", HEADER_JOB_NUM_PROCESSORS: "num_processors", HEADER_JOB_INTERACTIVE_URL: "interactive_job_url", + HEADER_JOB_PENDING_REASON: "pending_reason", //job_filter.HEADER_JOB_PRIORITY: "job_priority", } @@ -258,16 +260,23 @@ func (e ExecHosts) String() string { // UnmarshalJSON customizes the JSON parsing method, compatible with both string "-" and structure formats func (e *ExecHosts) UnmarshalJSON(data []byte) error { + // JSON null means no allocation — treat as empty + if string(data) == "null" { + e.HostSlots = []HostSlot{} + e.NumHosts = 0 + return nil + } + // First try to parse as a string var str string if err := json.Unmarshal(data, &str); err == nil { - // If the string is "-", return an empty ExecHosts - if str == "-" { + // Empty string or "-" both mean no hosts + if str == "" || str == "-" { e.HostSlots = []HostSlot{} e.NumHosts = 0 return nil } - // If it's any other string, treat it as a single hostname + // Any other non-empty string is a single hostname e.HostSlots = []HostSlot{{HostName: str, NumSlots: 1}} e.NumHosts = 1 return nil