nomad: adding Alloc endpoint

This commit is contained in:
Armon Dadgar 2015-09-06 15:34:28 -07:00
parent 28dc212e4a
commit 46cbe8285d
6 changed files with 199 additions and 50 deletions

51
nomad/alloc_endpoint.go Normal file
View File

@ -0,0 +1,51 @@
package nomad
import (
"time"
"github.com/armon/go-metrics"
"github.com/hashicorp/nomad/nomad/structs"
)
// Alloc endpoint is used for manipulating allocations
type Alloc struct {
srv *Server
}
// List is used to list the allocations in the system
func (a *Alloc) List(args *structs.AllocListRequest, reply *structs.AllocListResponse) error {
if done, err := a.srv.forward("Alloc.List", args, args, reply); done {
return err
}
defer metrics.MeasureSince([]string{"nomad", "alloc", "list"}, time.Now())
// Capture all the allocations
snap, err := a.srv.fsm.State().Snapshot()
if err != nil {
return err
}
iter, err := snap.Allocs()
if err != nil {
return err
}
for {
raw := iter.Next()
if raw == nil {
break
}
alloc := raw.(*structs.Allocation)
reply.Allocations = append(reply.Allocations, alloc.Stub())
}
// Use the last index that affected the jobs table
index, err := snap.GetIndex("allocs")
if err != nil {
return err
}
reply.Index = index
// Set the query response
a.srv.setQueryMeta(&reply.QueryMeta)
return nil
}

View File

@ -0,0 +1,44 @@
package nomad
import (
"testing"
"github.com/hashicorp/net-rpc-msgpackrpc"
"github.com/hashicorp/nomad/nomad/mock"
"github.com/hashicorp/nomad/nomad/structs"
"github.com/hashicorp/nomad/testutil"
)
func TestAllocEndpoint_List(t *testing.T) {
s1 := testServer(t, nil)
defer s1.Shutdown()
codec := rpcClient(t, s1)
testutil.WaitForLeader(t, s1.RPC)
// Create the register request
alloc := mock.Alloc()
state := s1.fsm.State()
err := state.UpdateAllocations(1000, []*structs.Allocation{alloc})
if err != nil {
t.Fatalf("err: %v", err)
}
// Lookup the jobs
get := &structs.AllocListRequest{
QueryOptions: structs.QueryOptions{Region: "region1"},
}
var resp structs.AllocListResponse
if err := msgpackrpc.CallWithCodec(codec, "Alloc.List", get, &resp); err != nil {
t.Fatalf("err: %v", err)
}
if resp.Index != 1000 {
t.Fatalf("Bad index: %d %d", resp.Index, 1000)
}
if len(resp.Allocations) != 1 {
t.Fatalf("bad: %#v", resp.Allocations)
}
if resp.Allocations[0].ID != alloc.ID {
t.Fatalf("bad: %#v", resp.Allocations[0])
}
}

View File

@ -364,18 +364,7 @@ func (c *ClientEndpoint) List(args *structs.NodeListRequest,
break
}
node := raw.(*structs.Node)
stub := &structs.NodeListStub{
ID: node.ID,
Datacenter: node.Datacenter,
Name: node.Name,
NodeClass: node.NodeClass,
Status: node.Status,
StatusDescription: node.StatusDescription,
CreateIndex: node.CreateIndex,
ModifyIndex: node.ModifyIndex,
}
reply.Nodes = append(reply.Nodes, stub)
reply.Nodes = append(reply.Nodes, node.Stub())
}
// Use the last index that affected the jobs table

View File

@ -245,18 +245,7 @@ func (j *Job) List(args *structs.JobListRequest,
break
}
job := raw.(*structs.Job)
stub := &structs.JobListStub{
ID: job.ID,
Name: job.Name,
Type: job.Type,
Priority: job.Priority,
Status: job.Status,
StatusDescription: job.StatusDescription,
CreateIndex: job.CreateIndex,
ModifyIndex: job.ModifyIndex,
}
reply.Jobs = append(reply.Jobs, stub)
reply.Jobs = append(reply.Jobs, job.Stub())
}
// Use the last index that affected the jobs table

View File

@ -132,6 +132,7 @@ type endpoints struct {
Job *Job
Eval *Eval
Plan *Plan
Alloc *Alloc
}
// NewServer is used to construct a new Nomad server from the
@ -341,6 +342,7 @@ func (s *Server) setupRPC(tlsWrap tlsutil.DCWrapper) error {
s.endpoints.Job = &Job{s}
s.endpoints.Eval = &Eval{s}
s.endpoints.Plan = &Plan{s}
s.endpoints.Alloc = &Alloc{s}
// Register the handlers
s.rpcServer.Register(s.endpoints.Status)
@ -348,6 +350,7 @@ func (s *Server) setupRPC(tlsWrap tlsutil.DCWrapper) error {
s.rpcServer.Register(s.endpoints.Job)
s.rpcServer.Register(s.endpoints.Eval)
s.rpcServer.Register(s.endpoints.Plan)
s.rpcServer.Register(s.endpoints.Alloc)
list, err := net.ListenTCP("tcp", s.config.RPCAddr)
if err != nil {

View File

@ -233,6 +233,11 @@ type AllocUpdateRequest struct {
WriteRequest
}
// AllocListRequest is used to request a list of allocations
type AllocListRequest struct {
QueryOptions
}
// GenericRequest is used to request where no
// specific information is needed.
type GenericRequest struct {
@ -295,19 +300,6 @@ type SingleNodeResponse struct {
QueryMeta
}
// NodeListStub is used to return a subset of job information
// for the job list
type NodeListStub struct {
ID string
Datacenter string
Name string
NodeClass string
Status string
StatusDescription string
CreateIndex uint64
ModifyIndex uint64
}
// JobListResponse is used for a list request
type NodeListResponse struct {
Nodes []*NodeListStub
@ -320,19 +312,6 @@ type SingleJobResponse struct {
QueryMeta
}
// JobListStub is used to return a subset of job information
// for the job list
type JobListStub struct {
ID string
Name string
Type string
Priority int
Status string
StatusDescription string
CreateIndex uint64
ModifyIndex uint64
}
// JobListResponse is used for a list request
type JobListResponse struct {
Jobs []*JobListStub
@ -370,6 +349,12 @@ type PlanResponse struct {
WriteMeta
}
// AllocListResponse is used for a list request
type AllocListResponse struct {
Allocations []*AllocListStub
QueryMeta
}
const (
NodeStatusInit = "initializing"
NodeStatusReady = "ready"
@ -467,6 +452,33 @@ func (n *Node) TerminalStatus() bool {
}
}
// Stub returns a summarized version of the node
func (n *Node) Stub() *NodeListStub {
return &NodeListStub{
ID: n.ID,
Datacenter: n.Datacenter,
Name: n.Name,
NodeClass: n.NodeClass,
Status: n.Status,
StatusDescription: n.StatusDescription,
CreateIndex: n.CreateIndex,
ModifyIndex: n.ModifyIndex,
}
}
// NodeListStub is used to return a subset of job information
// for the job list
type NodeListStub struct {
ID string
Datacenter string
Name string
NodeClass string
Status string
StatusDescription string
CreateIndex uint64
ModifyIndex uint64
}
// Resources is used to define the resources available
// on a client
type Resources struct {
@ -658,6 +670,33 @@ func (j *Job) LookupTaskGroup(name string) *TaskGroup {
return nil
}
// Stub is used to return a summary of the job
func (j *Job) Stub() *JobListStub {
return &JobListStub{
ID: j.ID,
Name: j.Name,
Type: j.Type,
Priority: j.Priority,
Status: j.Status,
StatusDescription: j.StatusDescription,
CreateIndex: j.CreateIndex,
ModifyIndex: j.ModifyIndex,
}
}
// JobListStub is used to return a subset of job information
// for the job list
type JobListStub struct {
ID string
Name string
Type string
Priority int
Status string
StatusDescription string
CreateIndex uint64
ModifyIndex uint64
}
// TaskGroup is an atomic unit of placement. Each task group belongs to
// a job and may contain any number of tasks. A task group support running
// in many replicas using the same configuration..
@ -791,6 +830,40 @@ func (a *Allocation) TerminalStatus() bool {
}
}
// Stub returns a list stub for the allocation
func (a *Allocation) Stub() *AllocListStub {
return &AllocListStub{
ID: a.ID,
EvalID: a.EvalID,
Name: a.Name,
NodeID: a.NodeID,
JobID: a.JobID,
TaskGroup: a.TaskGroup,
DesiredStatus: a.DesiredStatus,
DesiredDescription: a.DesiredDescription,
ClientStatus: a.ClientStatus,
ClientDescription: a.ClientDescription,
CreateIndex: a.CreateIndex,
ModifyIndex: a.ModifyIndex,
}
}
// AllocListStub is used to return a subset of alloc information
type AllocListStub struct {
ID string
EvalID string
Name string
NodeID string
JobID string
TaskGroup string
DesiredStatus string
DesiredDescription string
ClientStatus string
ClientDescription string
CreateIndex uint64
ModifyIndex uint64
}
// AllocMetric is used to track various metrics while attempting
// to make an allocation. These are used to debug a job, or to better
// understand the pressure within the system.