github.com/hhrutter/nomad@v0.6.0-rc2.0.20170723054333-80c4b03f0705/command/agent/alloc_endpoint.go (about) 1 package agent 2 3 import ( 4 "fmt" 5 "net/http" 6 "strings" 7 8 "github.com/golang/snappy" 9 "github.com/hashicorp/nomad/nomad/structs" 10 ) 11 12 const ( 13 allocNotFoundErr = "allocation not found" 14 resourceNotFoundErr = "resource not found" 15 ) 16 17 func (s *HTTPServer) AllocsRequest(resp http.ResponseWriter, req *http.Request) (interface{}, error) { 18 if req.Method != "GET" { 19 return nil, CodedError(405, ErrInvalidMethod) 20 } 21 22 args := structs.AllocListRequest{} 23 if s.parse(resp, req, &args.Region, &args.QueryOptions) { 24 return nil, nil 25 } 26 27 var out structs.AllocListResponse 28 if err := s.agent.RPC("Alloc.List", &args, &out); err != nil { 29 return nil, err 30 } 31 32 setMeta(resp, &out.QueryMeta) 33 if out.Allocations == nil { 34 out.Allocations = make([]*structs.AllocListStub, 0) 35 } 36 return out.Allocations, nil 37 } 38 39 func (s *HTTPServer) AllocSpecificRequest(resp http.ResponseWriter, req *http.Request) (interface{}, error) { 40 allocID := strings.TrimPrefix(req.URL.Path, "/v1/allocation/") 41 if req.Method != "GET" { 42 return nil, CodedError(405, ErrInvalidMethod) 43 } 44 45 args := structs.AllocSpecificRequest{ 46 AllocID: allocID, 47 } 48 if s.parse(resp, req, &args.Region, &args.QueryOptions) { 49 return nil, nil 50 } 51 52 var out structs.SingleAllocResponse 53 if err := s.agent.RPC("Alloc.GetAlloc", &args, &out); err != nil { 54 return nil, err 55 } 56 57 setMeta(resp, &out.QueryMeta) 58 if out.Alloc == nil { 59 return nil, CodedError(404, "alloc not found") 60 } 61 62 // Decode the payload if there is any 63 alloc := out.Alloc 64 if alloc.Job != nil && len(alloc.Job.Payload) != 0 { 65 decoded, err := snappy.Decode(nil, alloc.Job.Payload) 66 if err != nil { 67 return nil, err 68 } 69 alloc = alloc.Copy() 70 alloc.Job.Payload = decoded 71 } 72 73 return alloc, nil 74 } 75 76 func (s *HTTPServer) ClientAllocRequest(resp http.ResponseWriter, req *http.Request) (interface{}, error) { 77 if s.agent.client == nil { 78 return nil, clientNotRunning 79 } 80 81 reqSuffix := strings.TrimPrefix(req.URL.Path, "/v1/client/allocation/") 82 83 // tokenize the suffix of the path to get the alloc id and find the action 84 // invoked on the alloc id 85 tokens := strings.Split(reqSuffix, "/") 86 if len(tokens) != 2 { 87 return nil, CodedError(404, resourceNotFoundErr) 88 } 89 allocID := tokens[0] 90 switch tokens[1] { 91 case "stats": 92 return s.allocStats(allocID, resp, req) 93 case "snapshot": 94 return s.allocSnapshot(allocID, resp, req) 95 case "gc": 96 return s.allocGC(allocID, resp, req) 97 } 98 99 return nil, CodedError(404, resourceNotFoundErr) 100 } 101 102 func (s *HTTPServer) ClientGCRequest(resp http.ResponseWriter, req *http.Request) (interface{}, error) { 103 if s.agent.client == nil { 104 return nil, clientNotRunning 105 } 106 return nil, s.agent.Client().CollectAllAllocs() 107 } 108 109 func (s *HTTPServer) allocGC(allocID string, resp http.ResponseWriter, req *http.Request) (interface{}, error) { 110 return nil, s.agent.Client().CollectAllocation(allocID) 111 } 112 113 func (s *HTTPServer) allocSnapshot(allocID string, resp http.ResponseWriter, req *http.Request) (interface{}, error) { 114 allocFS, err := s.agent.Client().GetAllocFS(allocID) 115 if err != nil { 116 return nil, fmt.Errorf(allocNotFoundErr) 117 } 118 if err := allocFS.Snapshot(resp); err != nil { 119 return nil, fmt.Errorf("error making snapshot: %v", err) 120 } 121 return nil, nil 122 } 123 124 func (s *HTTPServer) allocStats(allocID string, resp http.ResponseWriter, req *http.Request) (interface{}, error) { 125 clientStats := s.agent.client.StatsReporter() 126 aStats, err := clientStats.GetAllocStats(allocID) 127 if err != nil { 128 return nil, err 129 } 130 131 task := req.URL.Query().Get("task") 132 return aStats.LatestAllocStats(task) 133 }