diff --git a/.changelog/18967.txt b/.changelog/18967.txt new file mode 100644 index 000000000..b29896b64 --- /dev/null +++ b/.changelog/18967.txt @@ -0,0 +1,3 @@ +```release-note:bug +core: Fix incorrect submit time for stopped jobs +``` \ No newline at end of file diff --git a/nomad/fsm.go b/nomad/fsm.go index 9495e7402..da22041af 100644 --- a/nomad/fsm.go +++ b/nomad/fsm.go @@ -726,7 +726,7 @@ func (n *nomadFSM) applyDeregisterJob(msgType structs.MessageType, buf []byte, i } err := n.state.WithWriteTransaction(msgType, index, func(tx state.Txn) error { - err := n.handleJobDeregister(index, req.JobID, req.Namespace, req.Purge, req.NoShutdownDelay, tx) + err := n.handleJobDeregister(index, req.JobID, req.Namespace, req.Purge, req.SubmitTime, req.NoShutdownDelay, tx) if err != nil { n.logger.Error("deregistering job failed", @@ -766,7 +766,7 @@ func (n *nomadFSM) applyBatchDeregisterJob(msgType structs.MessageType, buf []by // evals for jobs whose deregistering didn't get committed yet. err := n.state.WithWriteTransaction(msgType, index, func(tx state.Txn) error { for jobNS, options := range req.Jobs { - if err := n.handleJobDeregister(index, jobNS.ID, jobNS.Namespace, options.Purge, false, tx); err != nil { + if err := n.handleJobDeregister(index, jobNS.ID, jobNS.Namespace, options.Purge, req.SubmitTime, false, tx); err != nil { n.logger.Error("deregistering job failed", "job", jobNS.ID, "error", err) return err } @@ -791,7 +791,7 @@ func (n *nomadFSM) applyBatchDeregisterJob(msgType structs.MessageType, buf []by // handleJobDeregister is used to deregister a job. Leaves error logging up to // caller. -func (n *nomadFSM) handleJobDeregister(index uint64, jobID, namespace string, purge bool, noShutdownDelay bool, tx state.Txn) error { +func (n *nomadFSM) handleJobDeregister(index uint64, jobID, namespace string, purge bool, submitTime int64, noShutdownDelay bool, tx state.Txn) error { // If it is periodic remove it from the dispatcher if err := n.periodicDispatcher.Remove(namespace, jobID); err != nil { return fmt.Errorf("periodicDispatcher.Remove failed: %w", err) @@ -839,6 +839,9 @@ func (n *nomadFSM) handleJobDeregister(index uint64, jobID, namespace string, pu stopped := current.Copy() stopped.Stop = true + if submitTime != 0 { + stopped.SubmitTime = submitTime + } if err := n.state.UpsertJobTxn(index, nil, stopped, tx); err != nil { return fmt.Errorf("UpsertJob failed: %w", err) diff --git a/nomad/job_endpoint.go b/nomad/job_endpoint.go index 54b1345f1..af8fa5f3d 100644 --- a/nomad/job_endpoint.go +++ b/nomad/job_endpoint.go @@ -892,6 +892,7 @@ func (j *Job) Deregister(args *structs.JobDeregisterRequest, reply *structs.JobD reply.EvalID = eval.ID } + args.SubmitTime = now args.Eval = eval // Commit the job update via Raft @@ -993,6 +994,8 @@ func (j *Job) BatchDeregister(args *structs.JobBatchDeregisterRequest, reply *st args.Evals = append(args.Evals, eval) } + args.SubmitTime = time.Now().UnixNano() + // Commit this update via Raft _, index, err := j.srv.raftApply(structs.JobBatchDeregisterRequestType, args) if err != nil { @@ -1119,6 +1122,7 @@ func (j *Job) Scale(args *structs.JobScaleRequest, reply *structs.JobRegisterRes // Update group count group.Count = int(*args.Count) + job.SubmitTime = now // Block scaling event if there's an active deployment deployment, err := snap.LatestDeploymentByJobID(ws, namespace, args.JobID) diff --git a/nomad/structs/structs.go b/nomad/structs/structs.go index 66a229e0f..e1b2789a9 100644 --- a/nomad/structs/structs.go +++ b/nomad/structs/structs.go @@ -773,6 +773,9 @@ type JobDeregisterRequest struct { // Eval is the evaluation to create that's associated with job deregister Eval *Evaluation + // SubmitTime is the time at which the job was requested to be stopped + SubmitTime int64 + WriteRequest } @@ -785,6 +788,9 @@ type JobBatchDeregisterRequest struct { // Evals is the set of evaluations to create. Evals []*Evaluation + // SubmitTime is the time at which the job was requested to be stopped + SubmitTime int64 + WriteRequest } @@ -4512,8 +4518,8 @@ type Job struct { // on each job register. Version uint64 - // SubmitTime is the time at which the job was submitted as a UnixNano in - // UTC + // SubmitTime is the time at which the job version was submitted as + // UnixNano in UTC SubmitTime int64 // Raft Indexes