Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

job_endpoint: check spec for all regions #14519

Merged
merged 2 commits into from
Sep 12, 2022
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 53 additions & 1 deletion nomad/job_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,12 @@ func (j *Job) Register(args *structs.JobRegisterRequest, reply *structs.JobRegis
}

// Check if the job has changed at all
if existingJob == nil || existingJob.SpecChanged(args.Job) {
specChanged, err := j.specChanged(existingJob, args)
if err != nil {
return err
}

if existingJob == nil || specChanged {

// COMPAT(1.1.0): Remove the ServerMeetMinimumVersion check to always set args.Eval
// 0.12.1 introduced atomic eval job registration
Expand Down Expand Up @@ -433,6 +438,53 @@ func (j *Job) Register(args *structs.JobRegisterRequest, reply *structs.JobRegis
return nil
}

// specChanged checks to see if the job spec has changed. If the job is multiregion,
// it checks all regions. This handles the case of a multiregion job that has been
// stopped in one or more regions being restarted via the run command.
DerekStrickland marked this conversation as resolved.
Show resolved Hide resolved
func (j *Job) specChanged(existingJob *structs.Job, args *structs.JobRegisterRequest) (bool, error) {
DerekStrickland marked this conversation as resolved.
Show resolved Hide resolved
if existingJob == nil {
return false, nil
}

if existingJob.SpecChanged(args.Job) {
return true, nil
}
DerekStrickland marked this conversation as resolved.
Show resolved Hide resolved

if !existingJob.IsMultiregion() {
return false, nil
}

// If the spec hasn't changed, but this is a multiregion job, check other regions.
DerekStrickland marked this conversation as resolved.
Show resolved Hide resolved
for _, region := range existingJob.Multiregion.Regions {
// Copy the job so we can mutate it by region and compare it with the response.
incomingJob := args.Job.Copy()
DerekStrickland marked this conversation as resolved.
Show resolved Hide resolved
incomingJob.Region = region.Name
req := &structs.JobSpecificRequest{
JobID: incomingJob.ID,
QueryOptions: structs.QueryOptions{
Region: region.Name,
Namespace: incomingJob.Namespace,
AuthToken: args.AuthToken,
},
}
resp := structs.SingleJobResponse{}
j.logger.Debug("checking spec for multiregion job")
DerekStrickland marked this conversation as resolved.
Show resolved Hide resolved
err := j.GetJob(req, &resp)
if err != nil {
j.logger.Error("job lookup failed", "error", err)
return false, err
}

// If the jobspec changed or is nil (purged) for that region, assume it's being re-registered
// and treat like a spec change.
if resp.Job.SpecChanged(incomingJob) || resp.Job == nil {
DerekStrickland marked this conversation as resolved.
Show resolved Hide resolved
return true, nil
}
}

return false, nil
}

// propagateScalingPolicyIDs propagates scaling policy IDs from existing job
// to updated job, or generates random IDs in new job
func propagateScalingPolicyIDs(old, new *structs.Job) error {
Expand Down