github.com/hspak/nomad@v0.7.2-0.20180309000617-bc4ae22a39a5/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 ClientStatus string 85 ClientDescription string 86 TaskStates map[string]*TaskState 87 DeploymentID string 88 DeploymentStatus *AllocDeploymentStatus 89 PreviousAllocation string 90 NextAllocation string 91 RescheduleTracker *RescheduleTracker 92 CreateIndex uint64 93 ModifyIndex uint64 94 AllocModifyIndex uint64 95 CreateTime int64 96 ModifyTime int64 97 } 98 99 // AllocationMetric is used to deserialize allocation metrics. 100 type AllocationMetric struct { 101 NodesEvaluated int 102 NodesFiltered int 103 NodesAvailable map[string]int 104 ClassFiltered map[string]int 105 ConstraintFiltered map[string]int 106 NodesExhausted int 107 ClassExhausted map[string]int 108 DimensionExhausted map[string]int 109 QuotaExhausted []string 110 Scores map[string]float64 111 AllocationTime time.Duration 112 CoalescedFailures int 113 } 114 115 // AllocationListStub is used to return a subset of an allocation 116 // during list operations. 117 type AllocationListStub struct { 118 ID string 119 EvalID string 120 Name string 121 NodeID string 122 JobID string 123 JobVersion uint64 124 TaskGroup string 125 DesiredStatus string 126 DesiredDescription string 127 ClientStatus string 128 ClientDescription string 129 TaskStates map[string]*TaskState 130 DeploymentStatus *AllocDeploymentStatus 131 RescheduleTracker *RescheduleTracker 132 CreateIndex uint64 133 ModifyIndex uint64 134 CreateTime int64 135 ModifyTime int64 136 } 137 138 // AllocDeploymentStatus captures the status of the allocation as part of the 139 // deployment. This can include things like if the allocation has been marked as 140 // healthy. 141 type AllocDeploymentStatus struct { 142 Healthy *bool 143 ModifyIndex uint64 144 } 145 146 // AllocIndexSort reverse sorts allocs by CreateIndex. 147 type AllocIndexSort []*AllocationListStub 148 149 func (a AllocIndexSort) Len() int { 150 return len(a) 151 } 152 153 func (a AllocIndexSort) Less(i, j int) bool { 154 return a[i].CreateIndex > a[j].CreateIndex 155 } 156 157 func (a AllocIndexSort) Swap(i, j int) { 158 a[i], a[j] = a[j], a[i] 159 } 160 161 // RescheduleInfo is used to calculate remaining reschedule attempts 162 // according to the given time and the task groups reschedule policy 163 func (a Allocation) RescheduleInfo(t time.Time) (int, int) { 164 var reschedulePolicy *ReschedulePolicy 165 for _, tg := range a.Job.TaskGroups { 166 if *tg.Name == a.TaskGroup { 167 reschedulePolicy = tg.ReschedulePolicy 168 } 169 } 170 if reschedulePolicy == nil { 171 return 0, 0 172 } 173 availableAttempts := *reschedulePolicy.Attempts 174 interval := *reschedulePolicy.Interval 175 attempted := 0 176 177 // Loop over reschedule tracker to find attempts within the restart policy's interval 178 if a.RescheduleTracker != nil && availableAttempts > 0 && interval > 0 { 179 for j := len(a.RescheduleTracker.Events) - 1; j >= 0; j-- { 180 lastAttempt := a.RescheduleTracker.Events[j].RescheduleTime 181 timeDiff := t.UTC().UnixNano() - lastAttempt 182 if timeDiff < interval.Nanoseconds() { 183 attempted += 1 184 } 185 } 186 } 187 return attempted, availableAttempts 188 } 189 190 // RescheduleTracker encapsulates previous reschedule events 191 type RescheduleTracker struct { 192 Events []*RescheduleEvent 193 } 194 195 // RescheduleEvent is used to keep track of previous attempts at rescheduling an allocation 196 type RescheduleEvent struct { 197 // RescheduleTime is the timestamp of a reschedule attempt 198 RescheduleTime int64 199 200 // PrevAllocID is the ID of the previous allocation being restarted 201 PrevAllocID string 202 203 // PrevNodeID is the node ID of the previous allocation 204 PrevNodeID string 205 }