only set args.Eval after all servers upgrade
We set the Eval field on job (de-)registration only after all servers get upgraded, to avoid dealing with duplicate evals.
This commit is contained in:
parent
910776caf0
commit
a314744210
|
@ -2,7 +2,7 @@
|
||||||
# vi: set ft=ruby :
|
# vi: set ft=ruby :
|
||||||
#
|
#
|
||||||
|
|
||||||
LINUX_BASE_BOX = "bento/ubuntu-16.04"
|
LINUX_BASE_BOX = "bento/ubuntu-18.04"
|
||||||
FREEBSD_BASE_BOX = "freebsd/FreeBSD-11.3-STABLE"
|
FREEBSD_BASE_BOX = "freebsd/FreeBSD-11.3-STABLE"
|
||||||
|
|
||||||
LINUX_IP_ADDRESS = "10.199.0.200"
|
LINUX_IP_ADDRESS = "10.199.0.200"
|
||||||
|
|
|
@ -315,13 +315,14 @@ func (j *Job) Register(args *structs.JobRegisterRequest, reply *structs.JobRegis
|
||||||
// Create a new evaluation
|
// Create a new evaluation
|
||||||
now := time.Now().UnixNano()
|
now := time.Now().UnixNano()
|
||||||
submittedEval := false
|
submittedEval := false
|
||||||
|
var eval *structs.Evaluation
|
||||||
|
|
||||||
// Set the submit time
|
// Set the submit time
|
||||||
args.Job.SubmitTime = now
|
args.Job.SubmitTime = now
|
||||||
|
|
||||||
// If the job is periodic or parameterized, we don't create an eval.
|
// If the job is periodic or parameterized, we don't create an eval.
|
||||||
if !(args.Job.IsPeriodic() || args.Job.IsParameterized()) {
|
if !(args.Job.IsPeriodic() || args.Job.IsParameterized()) {
|
||||||
args.Eval = &structs.Evaluation{
|
eval = &structs.Evaluation{
|
||||||
ID: uuid.Generate(),
|
ID: uuid.Generate(),
|
||||||
Namespace: args.RequestNamespace(),
|
Namespace: args.RequestNamespace(),
|
||||||
Priority: args.Job.Priority,
|
Priority: args.Job.Priority,
|
||||||
|
@ -332,12 +333,19 @@ func (j *Job) Register(args *structs.JobRegisterRequest, reply *structs.JobRegis
|
||||||
CreateTime: now,
|
CreateTime: now,
|
||||||
ModifyTime: now,
|
ModifyTime: now,
|
||||||
}
|
}
|
||||||
reply.EvalID = args.Eval.ID
|
reply.EvalID = eval.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the job has changed at all
|
// Check if the job has changed at all
|
||||||
if existingJob == nil || existingJob.SpecChanged(args.Job) {
|
if existingJob == nil || existingJob.SpecChanged(args.Job) {
|
||||||
|
|
||||||
|
// COMPAT(1.1.0): Remove the ServerMeetMinimumVersion check to always set args.Eval
|
||||||
|
// 0.12.1 introduced atomic eval job registration
|
||||||
|
if eval != nil && ServersMeetMinimumVersion(j.srv.Members(), minJobRegisterAtomicEvalVersion, false) {
|
||||||
|
args.Eval = eval
|
||||||
|
submittedEval = true
|
||||||
|
}
|
||||||
|
|
||||||
// Commit this update via Raft
|
// Commit this update via Raft
|
||||||
fsmErr, index, err := j.srv.raftApply(structs.JobRegisterRequestType, args)
|
fsmErr, index, err := j.srv.raftApply(structs.JobRegisterRequestType, args)
|
||||||
if err, ok := fsmErr.(error); ok && err != nil {
|
if err, ok := fsmErr.(error); ok && err != nil {
|
||||||
|
@ -349,13 +357,11 @@ func (j *Job) Register(args *structs.JobRegisterRequest, reply *structs.JobRegis
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
submittedEval = true
|
|
||||||
|
|
||||||
// Populate the reply with job information
|
// Populate the reply with job information
|
||||||
reply.JobModifyIndex = index
|
reply.JobModifyIndex = index
|
||||||
reply.Index = index
|
reply.Index = index
|
||||||
|
|
||||||
if args.Eval != nil {
|
if submittedEval {
|
||||||
reply.EvalCreateIndex = index
|
reply.EvalCreateIndex = index
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,17 +372,14 @@ func (j *Job) Register(args *structs.JobRegisterRequest, reply *structs.JobRegis
|
||||||
// used for multiregion start
|
// used for multiregion start
|
||||||
args.Job.JobModifyIndex = reply.JobModifyIndex
|
args.Job.JobModifyIndex = reply.JobModifyIndex
|
||||||
|
|
||||||
if args.Eval == nil {
|
if eval == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// COMPAT(1.1.0): Remove the ServerMeetMinimumVersion check.
|
if eval != nil && !submittedEval {
|
||||||
// 0.12.1 introduced atomic eval job registration
|
eval.JobModifyIndex = reply.JobModifyIndex
|
||||||
if args.Eval != nil &&
|
|
||||||
!(submittedEval && ServersMeetMinimumVersion(j.srv.Members(), minJobRegisterAtomicEvalVersion, false)) {
|
|
||||||
args.Eval.JobModifyIndex = reply.JobModifyIndex
|
|
||||||
update := &structs.EvalUpdateRequest{
|
update := &structs.EvalUpdateRequest{
|
||||||
Evals: []*structs.Evaluation{args.Eval},
|
Evals: []*structs.Evaluation{eval},
|
||||||
WriteRequest: structs.WriteRequest{Region: args.Region},
|
WriteRequest: structs.WriteRequest{Region: args.Region},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -389,10 +392,8 @@ func (j *Job) Register(args *structs.JobRegisterRequest, reply *structs.JobRegis
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !submittedEval {
|
reply.EvalCreateIndex = evalIndex
|
||||||
reply.EvalCreateIndex = evalIndex
|
reply.Index = evalIndex
|
||||||
reply.Index = evalIndex
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kick off a multiregion deployment (enterprise only).
|
// Kick off a multiregion deployment (enterprise only).
|
||||||
|
@ -786,12 +787,15 @@ func (j *Job) Deregister(args *structs.JobDeregisterRequest, reply *structs.JobD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var eval *structs.Evaluation
|
||||||
|
|
||||||
// The job priority / type is strange for this, since it's not a high
|
// The job priority / type is strange for this, since it's not a high
|
||||||
// priority even if the job was.
|
// priority even if the job was.
|
||||||
now := time.Now().UnixNano()
|
now := time.Now().UnixNano()
|
||||||
|
|
||||||
// If the job is periodic or parameterized, we don't create an eval.
|
// If the job is periodic or parameterized, we don't create an eval.
|
||||||
if job == nil || !(job.IsPeriodic() || job.IsParameterized()) {
|
if job == nil || !(job.IsPeriodic() || job.IsParameterized()) {
|
||||||
args.Eval = &structs.Evaluation{
|
eval = &structs.Evaluation{
|
||||||
ID: uuid.Generate(),
|
ID: uuid.Generate(),
|
||||||
Namespace: args.RequestNamespace(),
|
Namespace: args.RequestNamespace(),
|
||||||
Priority: structs.JobDefaultPriority,
|
Priority: structs.JobDefaultPriority,
|
||||||
|
@ -802,7 +806,12 @@ func (j *Job) Deregister(args *structs.JobDeregisterRequest, reply *structs.JobD
|
||||||
CreateTime: now,
|
CreateTime: now,
|
||||||
ModifyTime: now,
|
ModifyTime: now,
|
||||||
}
|
}
|
||||||
reply.EvalID = args.Eval.ID
|
reply.EvalID = eval.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
// COMPAT(1.1.0): remove conditional and always set args.Eval
|
||||||
|
if ServersMeetMinimumVersion(j.srv.Members(), minJobRegisterAtomicEvalVersion, false) {
|
||||||
|
args.Eval = eval
|
||||||
}
|
}
|
||||||
|
|
||||||
// Commit the job update via Raft
|
// Commit the job update via Raft
|
||||||
|
@ -824,23 +833,26 @@ func (j *Job) Deregister(args *structs.JobDeregisterRequest, reply *structs.JobD
|
||||||
result = multierror.Append(result, err)
|
result = multierror.Append(result, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// COMPAT(1.1.0) - 0.12.1 introduced atomic job deregistration eval
|
// COMPAT(1.1.0) - Remove entire conditional block
|
||||||
if args.Eval != nil &&
|
// 0.12.1 introduced atomic job deregistration eval
|
||||||
!ServersMeetMinimumVersion(j.srv.Members(), minJobRegisterAtomicEvalVersion, false) {
|
if eval != nil && args.Eval == nil {
|
||||||
// Create a new evaluation
|
// Create a new evaluation
|
||||||
args.Eval.JobModifyIndex = index
|
eval.JobModifyIndex = index
|
||||||
update := &structs.EvalUpdateRequest{
|
update := &structs.EvalUpdateRequest{
|
||||||
Evals: []*structs.Evaluation{args.Eval},
|
Evals: []*structs.Evaluation{eval},
|
||||||
WriteRequest: structs.WriteRequest{Region: args.Region},
|
WriteRequest: structs.WriteRequest{Region: args.Region},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Commit this evaluation via Raft
|
// Commit this evaluation via Raft
|
||||||
_, _, err := j.srv.raftApply(structs.EvalUpdateRequestType, update)
|
_, evalIndex, err := j.srv.raftApply(structs.EvalUpdateRequestType, update)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result = multierror.Append(result, err)
|
result = multierror.Append(result, err)
|
||||||
j.logger.Error("eval create failed", "error", err, "method", "deregister")
|
j.logger.Error("eval create failed", "error", err, "method", "deregister")
|
||||||
return result.ErrorOrNil()
|
return result.ErrorOrNil()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reply.EvalCreateIndex = evalIndex
|
||||||
|
reply.Index = evalIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.ErrorOrNil()
|
return result.ErrorOrNil()
|
||||||
|
|
|
@ -1640,9 +1640,7 @@ func TestJobEndpoint_Register_EvalCreation_Modern(t *testing.T) {
|
||||||
require.Equal(t, resp2.EvalCreateIndex, eval.CreateIndex)
|
require.Equal(t, resp2.EvalCreateIndex, eval.CreateIndex)
|
||||||
|
|
||||||
raftEval := evalUpdateFromRaft(t, s1, eval.ID)
|
raftEval := evalUpdateFromRaft(t, s1, eval.ID)
|
||||||
require.NotNil(t, raftEval)
|
require.Equal(t, raftEval, eval)
|
||||||
require.Equal(t, eval.CreateIndex, raftEval.CreateIndex)
|
|
||||||
require.Equal(t, eval, raftEval)
|
|
||||||
|
|
||||||
//// an update should update the job and create a new eval
|
//// an update should update the job and create a new eval
|
||||||
req.Job.TaskGroups[0].Name += "a"
|
req.Job.TaskGroups[0].Name += "a"
|
||||||
|
@ -1759,10 +1757,7 @@ func TestJobEndpoint_Register_EvalCreation_Legacy(t *testing.T) {
|
||||||
require.Equal(t, resp.EvalCreateIndex, eval.CreateIndex)
|
require.Equal(t, resp.EvalCreateIndex, eval.CreateIndex)
|
||||||
|
|
||||||
raftEval := evalUpdateFromRaft(t, s1, eval.ID)
|
raftEval := evalUpdateFromRaft(t, s1, eval.ID)
|
||||||
require.NotNil(t, raftEval)
|
require.Equal(t, eval, raftEval)
|
||||||
require.Equal(t, eval.ID, raftEval.ID)
|
|
||||||
require.Equal(t, eval.JobModifyIndex, raftEval.JobModifyIndex)
|
|
||||||
require.Greater(t, raftEval.CreateIndex, eval.CreateIndex)
|
|
||||||
|
|
||||||
//// re-registration should create a new eval, but leave the job untouched
|
//// re-registration should create a new eval, but leave the job untouched
|
||||||
var resp2 structs.JobRegisterResponse
|
var resp2 structs.JobRegisterResponse
|
||||||
|
@ -1788,7 +1783,6 @@ func TestJobEndpoint_Register_EvalCreation_Legacy(t *testing.T) {
|
||||||
|
|
||||||
// this raft eval is the one found above
|
// this raft eval is the one found above
|
||||||
raftEval = evalUpdateFromRaft(t, s1, eval.ID)
|
raftEval = evalUpdateFromRaft(t, s1, eval.ID)
|
||||||
require.Equal(t, raftEval.CreateIndex, eval.CreateIndex)
|
|
||||||
require.Equal(t, eval, raftEval)
|
require.Equal(t, eval, raftEval)
|
||||||
|
|
||||||
//// an update should update the job and create a new eval
|
//// an update should update the job and create a new eval
|
||||||
|
@ -1814,10 +1808,7 @@ func TestJobEndpoint_Register_EvalCreation_Legacy(t *testing.T) {
|
||||||
require.Equal(t, resp3.EvalCreateIndex, eval.CreateIndex)
|
require.Equal(t, resp3.EvalCreateIndex, eval.CreateIndex)
|
||||||
|
|
||||||
raftEval = evalUpdateFromRaft(t, s1, eval.ID)
|
raftEval = evalUpdateFromRaft(t, s1, eval.ID)
|
||||||
require.NotNil(t, raftEval)
|
require.Equal(t, eval, raftEval)
|
||||||
require.Equal(t, eval.ID, raftEval.ID)
|
|
||||||
require.Equal(t, eval.JobModifyIndex, raftEval.JobModifyIndex)
|
|
||||||
require.Greater(t, raftEval.CreateIndex, eval.CreateIndex)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Registering a parameterized job shouldn't create an eval
|
// Registering a parameterized job shouldn't create an eval
|
||||||
|
@ -3297,10 +3288,7 @@ func TestJobEndpoint_Deregister_EvalCreation_Legacy(t *testing.T) {
|
||||||
require.EqualValues(t, resp2.EvalCreateIndex, eval.CreateIndex)
|
require.EqualValues(t, resp2.EvalCreateIndex, eval.CreateIndex)
|
||||||
|
|
||||||
raftEval := evalUpdateFromRaft(t, s1, eval.ID)
|
raftEval := evalUpdateFromRaft(t, s1, eval.ID)
|
||||||
require.NotNil(t, raftEval)
|
require.Equal(t, eval, raftEval)
|
||||||
require.Equal(t, eval.ID, raftEval.ID)
|
|
||||||
require.Equal(t, eval.JobModifyIndex, raftEval.JobModifyIndex)
|
|
||||||
require.Greater(t, raftEval.CreateIndex, eval.CreateIndex)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Registering a parameterized job shouldn't create an eval
|
// Registering a parameterized job shouldn't create an eval
|
||||||
|
|
Loading…
Reference in New Issue