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

Track multiple job versions and introduce a stop state for jobs #2566

Merged
merged 12 commits into from
Apr 19, 2017
Merged
34 changes: 31 additions & 3 deletions api/jobs.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,17 @@ func (j *Jobs) Info(jobID string, q *QueryOptions) (*Job, *QueryMeta, error) {
return &resp, qm, nil
}

// Versions is used to retrieve all versions of a particular
// job given its unique ID.
func (j *Jobs) Versions(jobID string, q *QueryOptions) ([]*Job, *QueryMeta, error) {
var resp []*Job
qm, err := j.client.query("/v1/job/"+jobID+"/versions", &resp, q)
if err != nil {
return nil, nil, err
}
return resp, qm, nil
}

// Allocations is used to return the allocs for a given job ID.
func (j *Jobs) Allocations(jobID string, allAllocs bool, q *QueryOptions) ([]*AllocationListStub, *QueryMeta, error) {
var resp []*AllocationListStub
Expand Down Expand Up @@ -138,10 +149,12 @@ func (j *Jobs) Evaluations(jobID string, q *QueryOptions) ([]*Evaluation, *Query
return resp, qm, nil
}

// Deregister is used to remove an existing job.
func (j *Jobs) Deregister(jobID string, q *WriteOptions) (string, *WriteMeta, error) {
// Deregister is used to remove an existing job. If purge is set to true, the job
// is deregistered and purged from the system versus still being queryable and
// eventually GC'ed from the system. Most callers should not specify purge.
func (j *Jobs) Deregister(jobID string, purge bool, q *WriteOptions) (string, *WriteMeta, error) {
var resp deregisterJobResponse
wm, err := j.client.delete("/v1/job/"+jobID, &resp, q)
wm, err := j.client.delete(fmt.Sprintf("/v1/job/%v?purge=%t", jobID, purge), &resp, q)
if err != nil {
return "", nil, err
}
Expand Down Expand Up @@ -279,6 +292,7 @@ type ParameterizedJobConfig struct {

// Job is used to serialize a job.
type Job struct {
Stop *bool
Region *string
ID *string
ParentID *string
Expand All @@ -297,6 +311,8 @@ type Job struct {
VaultToken *string `mapstructure:"vault_token"`
Status *string
StatusDescription *string
Stable *bool
Version *uint64
CreateIndex *uint64
ModifyIndex *uint64
JobModifyIndex *uint64
Expand Down Expand Up @@ -325,6 +341,9 @@ func (j *Job) Canonicalize() {
if j.Priority == nil {
j.Priority = helper.IntToPtr(50)
}
if j.Stop == nil {
j.Stop = helper.BoolToPtr(false)
}
if j.Region == nil {
j.Region = helper.StringToPtr("global")
}
Expand All @@ -343,6 +362,12 @@ func (j *Job) Canonicalize() {
if j.StatusDescription == nil {
j.StatusDescription = helper.StringToPtr("")
}
if j.Stable == nil {
j.Stable = helper.BoolToPtr(false)
}
if j.Version == nil {
j.Version = helper.Uint64ToPtr(0)
}
if j.CreateIndex == nil {
j.CreateIndex = helper.Uint64ToPtr(0)
}
Expand Down Expand Up @@ -406,6 +431,9 @@ type JobListStub struct {
Name string
Type string
Priority int
Periodic bool
ParameterizedJob bool
Stop bool
Status string
StatusDescription string
JobSummary *JobSummary
Expand Down
59 changes: 55 additions & 4 deletions api/jobs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,38 @@ func TestJobs_Info(t *testing.T) {
}
}

func TestJobs_Versions(t *testing.T) {
c, s := makeClient(t, nil, nil)
defer s.Stop()
jobs := c.Jobs()

// Trying to retrieve a job by ID before it exists returns an error
_, _, err := jobs.Versions("job1", nil)
if err == nil || !strings.Contains(err.Error(), "not found") {
t.Fatalf("expected not found error, got: %#v", err)
}

// Register the job
job := testJob()
_, wm, err := jobs.Register(job, nil)
if err != nil {
t.Fatalf("err: %s", err)
}
assertWriteMeta(t, wm)

// Query the job again and ensure it exists
result, qm, err := jobs.Versions("job1", nil)
if err != nil {
t.Fatalf("err: %s", err)
}
assertQueryMeta(t, qm)

// Check that the result is what we expect
if len(result) == 0 || *result[0].ID != *job.ID {
t.Fatalf("expect: %#v, got: %#v", job, result)
}
}

func TestJobs_PrefixList(t *testing.T) {
c, s := makeClient(t, nil, nil)
defer s.Stop()
Expand Down Expand Up @@ -658,13 +690,12 @@ func TestJobs_Deregister(t *testing.T) {
assertWriteMeta(t, wm)

// Attempting delete on non-existing job returns an error
if _, _, err = jobs.Deregister("nope", nil); err != nil {
if _, _, err = jobs.Deregister("nope", false, nil); err != nil {
t.Fatalf("unexpected error deregistering job: %v", err)

}

// Deleting an existing job works
evalID, wm3, err := jobs.Deregister("job1", nil)
// Do a soft deregister of an existing job
evalID, wm3, err := jobs.Deregister("job1", false, nil)
if err != nil {
t.Fatalf("err: %s", err)
}
Expand All @@ -673,6 +704,26 @@ func TestJobs_Deregister(t *testing.T) {
t.Fatalf("missing eval ID")
}

// Check that the job is still queryable
out, qm1, err := jobs.Info("job1", nil)
if err != nil {
t.Fatalf("err: %s", err)
}
assertQueryMeta(t, qm1)
if out == nil {
t.Fatalf("missing job")
}

// Do a purge deregister of an existing job
evalID, wm4, err := jobs.Deregister("job1", true, nil)
if err != nil {
t.Fatalf("err: %s", err)
}
assertWriteMeta(t, wm4)
if evalID == "" {
t.Fatalf("missing eval ID")
}

// Check that the job is really gone
result, qm, err := jobs.List(nil)
if err != nil {
Expand Down
Loading