2015-09-08 23:24:26 +00:00
|
|
|
package api
|
|
|
|
|
2015-09-17 19:40:51 +00:00
|
|
|
import (
|
|
|
|
"sort"
|
|
|
|
)
|
|
|
|
|
2015-09-10 00:29:43 +00:00
|
|
|
const (
|
|
|
|
// JobTypeService indicates a long-running processes
|
|
|
|
JobTypeService = "service"
|
|
|
|
|
|
|
|
// JobTypeBatch indicates a short-lived process
|
|
|
|
JobTypeBatch = "batch"
|
|
|
|
)
|
|
|
|
|
2015-09-08 23:24:26 +00:00
|
|
|
// Jobs is used to access the job-specific endpoints.
|
|
|
|
type Jobs struct {
|
|
|
|
client *Client
|
|
|
|
}
|
|
|
|
|
|
|
|
// Jobs returns a handle on the jobs endpoints.
|
|
|
|
func (c *Client) Jobs() *Jobs {
|
|
|
|
return &Jobs{client: c}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Register is used to register a new job. It returns the ID
|
|
|
|
// of the evaluation, along with any errors encountered.
|
|
|
|
func (j *Jobs) Register(job *Job, q *WriteOptions) (string, *WriteMeta, error) {
|
|
|
|
var resp registerJobResponse
|
|
|
|
|
|
|
|
req := ®isterJobRequest{job}
|
|
|
|
wm, err := j.client.write("/v1/jobs", req, &resp, q)
|
|
|
|
if err != nil {
|
|
|
|
return "", nil, err
|
|
|
|
}
|
|
|
|
return resp.EvalID, wm, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// List is used to list all of the existing jobs.
|
2015-09-14 02:55:47 +00:00
|
|
|
func (j *Jobs) List(q *QueryOptions) ([]*JobListStub, *QueryMeta, error) {
|
|
|
|
var resp []*JobListStub
|
2015-09-09 20:18:50 +00:00
|
|
|
qm, err := j.client.query("/v1/jobs", &resp, q)
|
2015-09-08 23:24:26 +00:00
|
|
|
if err != nil {
|
2015-09-08 23:45:16 +00:00
|
|
|
return nil, qm, err
|
2015-09-08 23:24:26 +00:00
|
|
|
}
|
2015-09-17 19:40:51 +00:00
|
|
|
sort.Sort(JobIDSort(resp))
|
2015-09-08 23:45:16 +00:00
|
|
|
return resp, qm, nil
|
2015-09-08 23:24:26 +00:00
|
|
|
}
|
|
|
|
|
2015-09-09 00:49:31 +00:00
|
|
|
// Info is used to retrieve information about a particular
|
2015-09-09 00:20:52 +00:00
|
|
|
// job given its unique ID.
|
2015-09-09 20:18:50 +00:00
|
|
|
func (j *Jobs) Info(jobID string, q *QueryOptions) (*Job, *QueryMeta, error) {
|
2015-09-09 00:20:52 +00:00
|
|
|
var resp Job
|
2015-09-09 20:18:50 +00:00
|
|
|
qm, err := j.client.query("/v1/job/"+jobID, &resp, q)
|
2015-09-09 00:20:52 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
return &resp, qm, nil
|
|
|
|
}
|
|
|
|
|
2015-09-09 00:49:31 +00:00
|
|
|
// Allocations is used to return the allocs for a given job ID.
|
2015-09-14 02:55:47 +00:00
|
|
|
func (j *Jobs) Allocations(jobID string, q *QueryOptions) ([]*AllocationListStub, *QueryMeta, error) {
|
|
|
|
var resp []*AllocationListStub
|
2015-09-09 20:18:50 +00:00
|
|
|
qm, err := j.client.query("/v1/job/"+jobID+"/allocations", &resp, q)
|
2015-09-09 00:49:31 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
2015-09-17 19:40:51 +00:00
|
|
|
sort.Sort(AllocIndexSort(resp))
|
2015-09-09 00:49:31 +00:00
|
|
|
return resp, qm, nil
|
|
|
|
}
|
|
|
|
|
2015-09-09 01:42:34 +00:00
|
|
|
// Evaluations is used to query the evaluations associated with
|
|
|
|
// the given job ID.
|
2015-09-09 20:18:50 +00:00
|
|
|
func (j *Jobs) Evaluations(jobID string, q *QueryOptions) ([]*Evaluation, *QueryMeta, error) {
|
2015-09-09 01:42:34 +00:00
|
|
|
var resp []*Evaluation
|
2015-09-09 20:18:50 +00:00
|
|
|
qm, err := j.client.query("/v1/job/"+jobID+"/evaluations", &resp, q)
|
2015-09-09 01:42:34 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
2015-09-17 19:40:51 +00:00
|
|
|
sort.Sort(EvalIndexSort(resp))
|
2015-09-09 01:42:34 +00:00
|
|
|
return resp, qm, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Delete is used to remove an existing job.
|
|
|
|
func (j *Jobs) Delete(jobID string, q *WriteOptions) (*WriteMeta, error) {
|
|
|
|
wm, err := j.client.delete("/v1/job/"+jobID, nil, q)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return wm, nil
|
|
|
|
}
|
|
|
|
|
2015-09-10 01:39:24 +00:00
|
|
|
// ForceEvaluate is used to force-evaluate an existing job.
|
|
|
|
func (j *Jobs) ForceEvaluate(jobID string, q *WriteOptions) (string, *WriteMeta, error) {
|
|
|
|
var resp registerJobResponse
|
|
|
|
wm, err := j.client.write("/v1/job/"+jobID+"/evaluate", nil, &resp, q)
|
|
|
|
if err != nil {
|
|
|
|
return "", nil, err
|
|
|
|
}
|
|
|
|
return resp.EvalID, wm, nil
|
|
|
|
}
|
|
|
|
|
2015-09-08 23:24:26 +00:00
|
|
|
// Job is used to serialize a job.
|
|
|
|
type Job struct {
|
2015-09-16 18:19:38 +00:00
|
|
|
Region string
|
2015-09-08 23:24:26 +00:00
|
|
|
ID string
|
|
|
|
Name string
|
|
|
|
Type string
|
|
|
|
Priority int
|
|
|
|
AllAtOnce bool
|
|
|
|
Datacenters []string
|
2015-09-09 02:27:04 +00:00
|
|
|
Constraints []*Constraint
|
2015-09-10 00:29:43 +00:00
|
|
|
TaskGroups []*TaskGroup
|
2015-09-08 23:24:26 +00:00
|
|
|
Meta map[string]string
|
|
|
|
Status string
|
|
|
|
StatusDescription string
|
2015-09-14 02:55:47 +00:00
|
|
|
CreateIndex uint64
|
|
|
|
ModifyIndex uint64
|
|
|
|
}
|
|
|
|
|
|
|
|
// JobListStub is used to return a subset of information about
|
|
|
|
// jobs during list operations.
|
|
|
|
type JobListStub struct {
|
|
|
|
ID string
|
|
|
|
Name string
|
|
|
|
Type string
|
|
|
|
Priority int
|
|
|
|
Status string
|
|
|
|
StatusDescription string
|
|
|
|
CreateIndex uint64
|
|
|
|
ModifyIndex uint64
|
2015-09-08 23:24:26 +00:00
|
|
|
}
|
|
|
|
|
2015-09-17 19:40:51 +00:00
|
|
|
// JobIDSort is used to sort jobs by their job ID's.
|
|
|
|
type JobIDSort []*JobListStub
|
|
|
|
|
|
|
|
func (j JobIDSort) Len() int {
|
|
|
|
return len(j)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (j JobIDSort) Less(a, b int) bool {
|
|
|
|
return j[a].ID < j[b].ID
|
|
|
|
}
|
|
|
|
|
|
|
|
func (j JobIDSort) Swap(a, b int) {
|
|
|
|
j[a], j[b] = j[b], j[a]
|
|
|
|
}
|
|
|
|
|
2015-09-10 00:29:43 +00:00
|
|
|
// NewServiceJob creates and returns a new service-style job
|
|
|
|
// for long-lived processes using the provided name, ID, and
|
|
|
|
// relative job priority.
|
2015-09-16 18:42:08 +00:00
|
|
|
func NewServiceJob(id, name, region string, pri int) *Job {
|
|
|
|
return newJob(id, name, region, JobTypeService, pri)
|
2015-09-10 00:29:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// NewBatchJob creates and returns a new batch-style job for
|
|
|
|
// short-lived processes using the provided name and ID along
|
|
|
|
// with the relative job priority.
|
2015-09-16 18:42:08 +00:00
|
|
|
func NewBatchJob(id, name, region string, pri int) *Job {
|
|
|
|
return newJob(id, name, region, JobTypeBatch, pri)
|
2015-09-10 00:29:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// newJob is used to create a new Job struct.
|
2015-09-16 18:42:08 +00:00
|
|
|
func newJob(id, name, region, typ string, pri int) *Job {
|
2015-09-10 00:29:43 +00:00
|
|
|
return &Job{
|
2015-09-16 18:42:08 +00:00
|
|
|
Region: region,
|
|
|
|
ID: id,
|
|
|
|
Name: name,
|
|
|
|
Type: typ,
|
2015-09-10 00:29:43 +00:00
|
|
|
Priority: pri,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetMeta is used to set arbitrary k/v pairs of metadata on a job.
|
|
|
|
func (j *Job) SetMeta(key, val string) *Job {
|
|
|
|
if j.Meta == nil {
|
|
|
|
j.Meta = make(map[string]string)
|
|
|
|
}
|
|
|
|
j.Meta[key] = val
|
|
|
|
return j
|
|
|
|
}
|
|
|
|
|
|
|
|
// AddDatacenter is used to add a datacenter to a job.
|
|
|
|
func (j *Job) AddDatacenter(dc string) *Job {
|
|
|
|
j.Datacenters = append(j.Datacenters, dc)
|
|
|
|
return j
|
|
|
|
}
|
|
|
|
|
|
|
|
// Constrain is used to add a constraint to a job.
|
|
|
|
func (j *Job) Constrain(c *Constraint) *Job {
|
|
|
|
j.Constraints = append(j.Constraints, c)
|
|
|
|
return j
|
|
|
|
}
|
|
|
|
|
|
|
|
// AddTaskGroup adds a task group to an existing job.
|
|
|
|
func (j *Job) AddTaskGroup(grp *TaskGroup) *Job {
|
|
|
|
j.TaskGroups = append(j.TaskGroups, grp)
|
|
|
|
return j
|
|
|
|
}
|
|
|
|
|
2015-09-08 23:24:26 +00:00
|
|
|
// registerJobRequest is used to serialize a job registration
|
|
|
|
type registerJobRequest struct {
|
|
|
|
Job *Job
|
|
|
|
}
|
|
|
|
|
|
|
|
// registerJobResponse is used to deserialize a job response
|
|
|
|
type registerJobResponse struct {
|
|
|
|
EvalID string
|
|
|
|
}
|