github.com/anuvu/nomad@v0.8.7-atom1/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 FollowupEvalID string 134 RescheduleTracker *RescheduleTracker 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 Timestamp time.Time 147 Canary bool 148 ModifyIndex uint64 149 } 150 151 // AllocIndexSort reverse sorts allocs by CreateIndex. 152 type AllocIndexSort []*AllocationListStub 153 154 func (a AllocIndexSort) Len() int { 155 return len(a) 156 } 157 158 func (a AllocIndexSort) Less(i, j int) bool { 159 return a[i].CreateIndex > a[j].CreateIndex 160 } 161 162 func (a AllocIndexSort) Swap(i, j int) { 163 a[i], a[j] = a[j], a[i] 164 } 165 166 // RescheduleInfo is used to calculate remaining reschedule attempts 167 // according to the given time and the task groups reschedule policy 168 func (a Allocation) RescheduleInfo(t time.Time) (int, int) { 169 var reschedulePolicy *ReschedulePolicy 170 for _, tg := range a.Job.TaskGroups { 171 if *tg.Name == a.TaskGroup { 172 reschedulePolicy = tg.ReschedulePolicy 173 } 174 } 175 if reschedulePolicy == nil { 176 return 0, 0 177 } 178 availableAttempts := *reschedulePolicy.Attempts 179 interval := *reschedulePolicy.Interval 180 attempted := 0 181 182 // Loop over reschedule tracker to find attempts within the restart policy's interval 183 if a.RescheduleTracker != nil && availableAttempts > 0 && interval > 0 { 184 for j := len(a.RescheduleTracker.Events) - 1; j >= 0; j-- { 185 lastAttempt := a.RescheduleTracker.Events[j].RescheduleTime 186 timeDiff := t.UTC().UnixNano() - lastAttempt 187 if timeDiff < interval.Nanoseconds() { 188 attempted += 1 189 } 190 } 191 } 192 return attempted, availableAttempts 193 } 194 195 // RescheduleTracker encapsulates previous reschedule events 196 type RescheduleTracker struct { 197 Events []*RescheduleEvent 198 } 199 200 // RescheduleEvent is used to keep track of previous attempts at rescheduling an allocation 201 type RescheduleEvent struct { 202 // RescheduleTime is the timestamp of a reschedule attempt 203 RescheduleTime int64 204 205 // PrevAllocID is the ID of the previous allocation being restarted 206 PrevAllocID string 207 208 // PrevNodeID is the node ID of the previous allocation 209 PrevNodeID string 210 } 211 212 // DesiredTransition is used to mark an allocation as having a desired state 213 // transition. This information can be used by the scheduler to make the 214 // correct decision. 215 type DesiredTransition struct { 216 // Migrate is used to indicate that this allocation should be stopped and 217 // migrated to another node. 218 Migrate *bool 219 220 // Reschedule is used to indicate that this allocation is eligible to be 221 // rescheduled. 222 Reschedule *bool 223 } 224 225 // ShouldMigrate returns whether the transition object dictates a migration. 226 func (d DesiredTransition) ShouldMigrate() bool { 227 return d.Migrate != nil && *d.Migrate 228 }