github.com/zhizhiboom/nomad@v0.8.5-0.20180907175415-f28fd3a1a056/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 // Deprecated, replaced with ScoreMetaData 113 Scores map[string]float64 114 AllocationTime time.Duration 115 CoalescedFailures int 116 ScoreMetaData []*NodeScoreMeta 117 } 118 119 // NodeScoreMeta is used to serialize node scoring metadata 120 // displayed in the CLI during verbose mode 121 type NodeScoreMeta struct { 122 NodeID string 123 Scores map[string]float64 124 NormScore float64 125 } 126 127 // AllocationListStub is used to return a subset of an allocation 128 // during list operations. 129 type AllocationListStub struct { 130 ID string 131 EvalID string 132 Name string 133 NodeID string 134 JobID string 135 JobVersion uint64 136 TaskGroup string 137 DesiredStatus string 138 DesiredDescription string 139 ClientStatus string 140 ClientDescription string 141 TaskStates map[string]*TaskState 142 DeploymentStatus *AllocDeploymentStatus 143 FollowupEvalID string 144 RescheduleTracker *RescheduleTracker 145 CreateIndex uint64 146 ModifyIndex uint64 147 CreateTime int64 148 ModifyTime int64 149 } 150 151 // AllocDeploymentStatus captures the status of the allocation as part of the 152 // deployment. This can include things like if the allocation has been marked as 153 // healthy. 154 type AllocDeploymentStatus struct { 155 Healthy *bool 156 Timestamp time.Time 157 Canary bool 158 ModifyIndex uint64 159 } 160 161 // AllocIndexSort reverse sorts allocs by CreateIndex. 162 type AllocIndexSort []*AllocationListStub 163 164 func (a AllocIndexSort) Len() int { 165 return len(a) 166 } 167 168 func (a AllocIndexSort) Less(i, j int) bool { 169 return a[i].CreateIndex > a[j].CreateIndex 170 } 171 172 func (a AllocIndexSort) Swap(i, j int) { 173 a[i], a[j] = a[j], a[i] 174 } 175 176 // RescheduleInfo is used to calculate remaining reschedule attempts 177 // according to the given time and the task groups reschedule policy 178 func (a Allocation) RescheduleInfo(t time.Time) (int, int) { 179 var reschedulePolicy *ReschedulePolicy 180 for _, tg := range a.Job.TaskGroups { 181 if *tg.Name == a.TaskGroup { 182 reschedulePolicy = tg.ReschedulePolicy 183 } 184 } 185 if reschedulePolicy == nil { 186 return 0, 0 187 } 188 availableAttempts := *reschedulePolicy.Attempts 189 interval := *reschedulePolicy.Interval 190 attempted := 0 191 192 // Loop over reschedule tracker to find attempts within the restart policy's interval 193 if a.RescheduleTracker != nil && availableAttempts > 0 && interval > 0 { 194 for j := len(a.RescheduleTracker.Events) - 1; j >= 0; j-- { 195 lastAttempt := a.RescheduleTracker.Events[j].RescheduleTime 196 timeDiff := t.UTC().UnixNano() - lastAttempt 197 if timeDiff < interval.Nanoseconds() { 198 attempted += 1 199 } 200 } 201 } 202 return attempted, availableAttempts 203 } 204 205 // RescheduleTracker encapsulates previous reschedule events 206 type RescheduleTracker struct { 207 Events []*RescheduleEvent 208 } 209 210 // RescheduleEvent is used to keep track of previous attempts at rescheduling an allocation 211 type RescheduleEvent struct { 212 // RescheduleTime is the timestamp of a reschedule attempt 213 RescheduleTime int64 214 215 // PrevAllocID is the ID of the previous allocation being restarted 216 PrevAllocID string 217 218 // PrevNodeID is the node ID of the previous allocation 219 PrevNodeID string 220 } 221 222 // DesiredTransition is used to mark an allocation as having a desired state 223 // transition. This information can be used by the scheduler to make the 224 // correct decision. 225 type DesiredTransition struct { 226 // Migrate is used to indicate that this allocation should be stopped and 227 // migrated to another node. 228 Migrate *bool 229 230 // Reschedule is used to indicate that this allocation is eligible to be 231 // rescheduled. 232 Reschedule *bool 233 } 234 235 // ShouldMigrate returns whether the transition object dictates a migration. 236 func (d DesiredTransition) ShouldMigrate() bool { 237 return d.Migrate != nil && *d.Migrate 238 }