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 := ®isterJobRequest{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 }