github.com/djenriquez/nomad-1@v0.8.1/api/allocations.go (about) 1 package api 2 3 import ( 4 "fmt" 5 "sort" 6 "time" 7 ) 8 9 var ( 10 // NodeDownErr marks an operation as not able to complete since the node is 11 // down. 12 NodeDownErr = fmt.Errorf("node down") 13 ) 14 15 // Allocations is used to query the alloc-related endpoints. 16 type Allocations struct { 17 client *Client 18 } 19 20 // Allocations returns a handle on the allocs endpoints. 21 func (c *Client) Allocations() *Allocations { 22 return &Allocations{client: c} 23 } 24 25 // List returns a list of all of the allocations. 26 func (a *Allocations) List(q *QueryOptions) ([]*AllocationListStub, *QueryMeta, error) { 27 var resp []*AllocationListStub 28 qm, err := a.client.query("/v1/allocations", &resp, q) 29 if err != nil { 30 return nil, nil, err 31 } 32 sort.Sort(AllocIndexSort(resp)) 33 return resp, qm, nil 34 } 35 36 func (a *Allocations) PrefixList(prefix string) ([]*AllocationListStub, *QueryMeta, error) { 37 return a.List(&QueryOptions{Prefix: prefix}) 38 } 39 40 // Info is used to retrieve a single allocation. 41 func (a *Allocations) Info(allocID string, q *QueryOptions) (*Allocation, *QueryMeta, error) { 42 var resp Allocation 43 qm, err := a.client.query("/v1/allocation/"+allocID, &resp, q) 44 if err != nil { 45 return nil, nil, err 46 } 47 return &resp, qm, nil 48 } 49 50 func (a *Allocations) Stats(alloc *Allocation, q *QueryOptions) (*AllocResourceUsage, error) { 51 var resp AllocResourceUsage 52 path := fmt.Sprintf("/v1/client/allocation/%s/stats", alloc.ID) 53 _, err := a.client.query(path, &resp, q) 54 return &resp, err 55 } 56 57 func (a *Allocations) GC(alloc *Allocation, q *QueryOptions) error { 58 nodeClient, err := a.client.GetNodeClient(alloc.NodeID, q) 59 if err != nil { 60 return err 61 } 62 63 var resp struct{} 64 _, err = nodeClient.query("/v1/client/allocation/"+alloc.ID+"/gc", &resp, nil) 65 return err 66 } 67 68 // Allocation is used for serialization of allocations. 69 type Allocation struct { 70 ID string 71 Namespace string 72 EvalID string 73 Name string 74 NodeID string 75 JobID string 76 Job *Job 77 TaskGroup string 78 Resources *Resources 79 TaskResources map[string]*Resources 80 Services map[string]string 81 Metrics *AllocationMetric 82 DesiredStatus string 83 DesiredDescription string 84 DesiredTransition DesiredTransition 85 ClientStatus string 86 ClientDescription string 87 TaskStates map[string]*TaskState 88 DeploymentID string 89 DeploymentStatus *AllocDeploymentStatus 90 FollowupEvalID string 91 PreviousAllocation string 92 NextAllocation string 93 RescheduleTracker *RescheduleTracker 94 CreateIndex uint64 95 ModifyIndex uint64 96 AllocModifyIndex uint64 97 CreateTime int64 98 ModifyTime int64 99 } 100 101 // AllocationMetric is used to deserialize allocation metrics. 102 type AllocationMetric struct { 103 NodesEvaluated int 104 NodesFiltered int 105 NodesAvailable map[string]int 106 ClassFiltered map[string]int 107 ConstraintFiltered map[string]int 108 NodesExhausted int 109 ClassExhausted map[string]int 110 DimensionExhausted map[string]int 111 QuotaExhausted []string 112 Scores map[string]float64 113 AllocationTime time.Duration 114 CoalescedFailures int 115 } 116 117 // AllocationListStub is used to return a subset of an allocation 118 // during list operations. 119 type AllocationListStub struct { 120 ID string 121 EvalID string 122 Name string 123 NodeID string 124 JobID string 125 JobVersion uint64 126 TaskGroup string 127 DesiredStatus string 128 DesiredDescription string 129 ClientStatus string 130 ClientDescription string 131 TaskStates map[string]*TaskState 132 DeploymentStatus *AllocDeploymentStatus 133 RescheduleTracker *RescheduleTracker 134 FollowupEvalID string 135 CreateIndex uint64 136 ModifyIndex uint64 137 CreateTime int64 138 ModifyTime int64 139 } 140 141 // AllocDeploymentStatus captures the status of the allocation as part of the 142 // deployment. This can include things like if the allocation has been marked as 143 // healthy. 144 type AllocDeploymentStatus struct { 145 Healthy *bool 146 ModifyIndex uint64 147 } 148 149 // AllocIndexSort reverse sorts allocs by CreateIndex. 150 type AllocIndexSort []*AllocationListStub 151 152 func (a AllocIndexSort) Len() int { 153 return len(a) 154 } 155 156 func (a AllocIndexSort) Less(i, j int) bool { 157 return a[i].CreateIndex > a[j].CreateIndex 158 } 159 160 func (a AllocIndexSort) Swap(i, j int) { 161 a[i], a[j] = a[j], a[i] 162 } 163 164 // RescheduleInfo is used to calculate remaining reschedule attempts 165 // according to the given time and the task groups reschedule policy 166 func (a Allocation) RescheduleInfo(t time.Time) (int, int) { 167 var reschedulePolicy *ReschedulePolicy 168 for _, tg := range a.Job.TaskGroups { 169 if *tg.Name == a.TaskGroup { 170 reschedulePolicy = tg.ReschedulePolicy 171 } 172 } 173 if reschedulePolicy == nil { 174 return 0, 0 175 } 176 availableAttempts := *reschedulePolicy.Attempts 177 interval := *reschedulePolicy.Interval 178 attempted := 0 179 180 // Loop over reschedule tracker to find attempts within the restart policy's interval 181 if a.RescheduleTracker != nil && availableAttempts > 0 && interval > 0 { 182 for j := len(a.RescheduleTracker.Events) - 1; j >= 0; j-- { 183 lastAttempt := a.RescheduleTracker.Events[j].RescheduleTime 184 timeDiff := t.UTC().UnixNano() - lastAttempt 185 if timeDiff < interval.Nanoseconds() { 186 attempted += 1 187 } 188 } 189 } 190 return attempted, availableAttempts 191 } 192 193 // RescheduleTracker encapsulates previous reschedule events 194 type RescheduleTracker struct { 195 Events []*RescheduleEvent 196 } 197 198 // RescheduleEvent is used to keep track of previous attempts at rescheduling an allocation 199 type RescheduleEvent struct { 200 // RescheduleTime is the timestamp of a reschedule attempt 201 RescheduleTime int64 202 203 // PrevAllocID is the ID of the previous allocation being restarted 204 PrevAllocID string 205 206 // PrevNodeID is the node ID of the previous allocation 207 PrevNodeID string 208 } 209 210 // DesiredTransition is used to mark an allocation as having a desired state 211 // transition. This information can be used by the scheduler to make the 212 // correct decision. 213 type DesiredTransition struct { 214 // Migrate is used to indicate that this allocation should be stopped and 215 // migrated to another node. 216 Migrate *bool 217 } 218 219 // ShouldMigrate returns whether the transition object dictates a migration. 220 func (d DesiredTransition) ShouldMigrate() bool { 221 return d.Migrate != nil && *d.Migrate 222 }