github.com/ryanslade/nomad@v0.2.4-0.20160128061903-fc95782f2089/api/jobs.go (about)

     1  package api
     2  
     3  import (
     4  	"sort"
     5  	"time"
     6  )
     7  
     8  const (
     9  	// JobTypeService indicates a long-running processes
    10  	JobTypeService = "service"
    11  
    12  	// JobTypeBatch indicates a short-lived process
    13  	JobTypeBatch = "batch"
    14  )
    15  
    16  // Jobs is used to access the job-specific endpoints.
    17  type Jobs struct {
    18  	client *Client
    19  }
    20  
    21  // Jobs returns a handle on the jobs endpoints.
    22  func (c *Client) Jobs() *Jobs {
    23  	return &Jobs{client: c}
    24  }
    25  
    26  // Register is used to register a new job. It returns the ID
    27  // of the evaluation, along with any errors encountered.
    28  func (j *Jobs) Register(job *Job, q *WriteOptions) (string, *WriteMeta, error) {
    29  	var resp registerJobResponse
    30  
    31  	req := &registerJobRequest{job}
    32  	wm, err := j.client.write("/v1/jobs", req, &resp, q)
    33  	if err != nil {
    34  		return "", nil, err
    35  	}
    36  	return resp.EvalID, wm, nil
    37  }
    38  
    39  // List is used to list all of the existing jobs.
    40  func (j *Jobs) List(q *QueryOptions) ([]*JobListStub, *QueryMeta, error) {
    41  	var resp []*JobListStub
    42  	qm, err := j.client.query("/v1/jobs", &resp, q)
    43  	if err != nil {
    44  		return nil, qm, err
    45  	}
    46  	sort.Sort(JobIDSort(resp))
    47  	return resp, qm, nil
    48  }
    49  
    50  // PrefixList is used to list all existing jobs that match the prefix.
    51  func (j *Jobs) PrefixList(prefix string) ([]*JobListStub, *QueryMeta, error) {
    52  	return j.List(&QueryOptions{Prefix: prefix})
    53  }
    54  
    55  // Info is used to retrieve information about a particular
    56  // job given its unique ID.
    57  func (j *Jobs) Info(jobID string, q *QueryOptions) (*Job, *QueryMeta, error) {
    58  	var resp Job
    59  	qm, err := j.client.query("/v1/job/"+jobID, &resp, q)
    60  	if err != nil {
    61  		return nil, nil, err
    62  	}
    63  	return &resp, qm, nil
    64  }
    65  
    66  // Allocations is used to return the allocs for a given job ID.
    67  func (j *Jobs) Allocations(jobID string, q *QueryOptions) ([]*AllocationListStub, *QueryMeta, error) {
    68  	var resp []*AllocationListStub
    69  	qm, err := j.client.query("/v1/job/"+jobID+"/allocations", &resp, q)
    70  	if err != nil {
    71  		return nil, nil, err
    72  	}
    73  	sort.Sort(AllocIndexSort(resp))
    74  	return resp, qm, nil
    75  }
    76  
    77  // Evaluations is used to query the evaluations associated with
    78  // the given job ID.
    79  func (j *Jobs) Evaluations(jobID string, q *QueryOptions) ([]*Evaluation, *QueryMeta, error) {
    80  	var resp []*Evaluation
    81  	qm, err := j.client.query("/v1/job/"+jobID+"/evaluations", &resp, q)
    82  	if err != nil {
    83  		return nil, nil, err
    84  	}
    85  	sort.Sort(EvalIndexSort(resp))
    86  	return resp, qm, nil
    87  }
    88  
    89  // Deregister is used to remove an existing job.
    90  func (j *Jobs) Deregister(jobID string, q *WriteOptions) (string, *WriteMeta, error) {
    91  	var resp deregisterJobResponse
    92  	wm, err := j.client.delete("/v1/job/"+jobID, &resp, q)
    93  	if err != nil {
    94  		return "", nil, err
    95  	}
    96  	return resp.EvalID, wm, nil
    97  }
    98  
    99  // ForceEvaluate is used to force-evaluate an existing job.
   100  func (j *Jobs) ForceEvaluate(jobID string, q *WriteOptions) (string, *WriteMeta, error) {
   101  	var resp registerJobResponse
   102  	wm, err := j.client.write("/v1/job/"+jobID+"/evaluate", nil, &resp, q)
   103  	if err != nil {
   104  		return "", nil, err
   105  	}
   106  	return resp.EvalID, wm, nil
   107  }
   108  
   109  // PeriodicForce spawns a new instance of the periodic job and returns the eval ID
   110  func (j *Jobs) PeriodicForce(jobID string, q *WriteOptions) (string, *WriteMeta, error) {
   111  	var resp periodicForceResponse
   112  	wm, err := j.client.write("/v1/job/"+jobID+"/periodic/force", nil, &resp, q)
   113  	if err != nil {
   114  		return "", nil, err
   115  	}
   116  	return resp.EvalID, wm, nil
   117  }
   118  
   119  // periodicForceResponse is used to deserialize a force response
   120  type periodicForceResponse struct {
   121  	EvalID string
   122  }
   123  
   124  // UpdateStrategy is for serializing update strategy for a job.
   125  type UpdateStrategy struct {
   126  	Stagger     time.Duration
   127  	MaxParallel int
   128  }
   129  
   130  // PeriodicConfig is for serializing periodic config for a job.
   131  type PeriodicConfig struct {
   132  	Enabled         bool
   133  	Spec            string
   134  	SpecType        string
   135  	ProhibitOverlap bool
   136  }
   137  
   138  // Job is used to serialize a job.
   139  type Job struct {
   140  	Region            string
   141  	ID                string
   142  	Name              string
   143  	Type              string
   144  	Priority          int
   145  	AllAtOnce         bool
   146  	Datacenters       []string
   147  	Constraints       []*Constraint
   148  	TaskGroups        []*TaskGroup
   149  	Update            *UpdateStrategy
   150  	Periodic          *PeriodicConfig
   151  	Meta              map[string]string
   152  	Status            string
   153  	StatusDescription string
   154  	CreateIndex       uint64
   155  	ModifyIndex       uint64
   156  }
   157  
   158  // JobListStub is used to return a subset of information about
   159  // jobs during list operations.
   160  type JobListStub struct {
   161  	ID                string
   162  	ParentID          string
   163  	Name              string
   164  	Type              string
   165  	Priority          int
   166  	Status            string
   167  	StatusDescription string
   168  	CreateIndex       uint64
   169  	ModifyIndex       uint64
   170  }
   171  
   172  // JobIDSort is used to sort jobs by their job ID's.
   173  type JobIDSort []*JobListStub
   174  
   175  func (j JobIDSort) Len() int {
   176  	return len(j)
   177  }
   178  
   179  func (j JobIDSort) Less(a, b int) bool {
   180  	return j[a].ID < j[b].ID
   181  }
   182  
   183  func (j JobIDSort) Swap(a, b int) {
   184  	j[a], j[b] = j[b], j[a]
   185  }
   186  
   187  // NewServiceJob creates and returns a new service-style job
   188  // for long-lived processes using the provided name, ID, and
   189  // relative job priority.
   190  func NewServiceJob(id, name, region string, pri int) *Job {
   191  	return newJob(id, name, region, JobTypeService, pri)
   192  }
   193  
   194  // NewBatchJob creates and returns a new batch-style job for
   195  // short-lived processes using the provided name and ID along
   196  // with the relative job priority.
   197  func NewBatchJob(id, name, region string, pri int) *Job {
   198  	return newJob(id, name, region, JobTypeBatch, pri)
   199  }
   200  
   201  // newJob is used to create a new Job struct.
   202  func newJob(id, name, region, typ string, pri int) *Job {
   203  	return &Job{
   204  		Region:   region,
   205  		ID:       id,
   206  		Name:     name,
   207  		Type:     typ,
   208  		Priority: pri,
   209  	}
   210  }
   211  
   212  // SetMeta is used to set arbitrary k/v pairs of metadata on a job.
   213  func (j *Job) SetMeta(key, val string) *Job {
   214  	if j.Meta == nil {
   215  		j.Meta = make(map[string]string)
   216  	}
   217  	j.Meta[key] = val
   218  	return j
   219  }
   220  
   221  // AddDatacenter is used to add a datacenter to a job.
   222  func (j *Job) AddDatacenter(dc string) *Job {
   223  	j.Datacenters = append(j.Datacenters, dc)
   224  	return j
   225  }
   226  
   227  // Constrain is used to add a constraint to a job.
   228  func (j *Job) Constrain(c *Constraint) *Job {
   229  	j.Constraints = append(j.Constraints, c)
   230  	return j
   231  }
   232  
   233  // AddTaskGroup adds a task group to an existing job.
   234  func (j *Job) AddTaskGroup(grp *TaskGroup) *Job {
   235  	j.TaskGroups = append(j.TaskGroups, grp)
   236  	return j
   237  }
   238  
   239  // AddPeriodicConfig adds a periodic config to an existing job.
   240  func (j *Job) AddPeriodicConfig(cfg *PeriodicConfig) *Job {
   241  	j.Periodic = cfg
   242  	return j
   243  }
   244  
   245  // registerJobRequest is used to serialize a job registration
   246  type registerJobRequest struct {
   247  	Job *Job
   248  }
   249  
   250  // registerJobResponse is used to deserialize a job response
   251  type registerJobResponse struct {
   252  	EvalID string
   253  }
   254  
   255  // deregisterJobResponse is used to decode a deregister response
   256  type deregisterJobResponse struct {
   257  	EvalID string
   258  }