nomad: adding RPC endpoints for fetching Eval

This commit is contained in:
Armon Dadgar 2015-07-23 16:00:19 -07:00
parent 9b921d9f92
commit eff7170c77
4 changed files with 114 additions and 0 deletions

49
nomad/eval_endpoint.go Normal file
View File

@ -0,0 +1,49 @@
package nomad
import (
"time"
"github.com/armon/go-metrics"
"github.com/hashicorp/nomad/nomad/structs"
)
// Eval endpoint is used for eval interactions
type Eval struct {
srv *Server
}
// GetEval is used to request information about a specific evaluation
func (e *Eval) GetEval(args *structs.EvalSpecificRequest,
reply *structs.SingleEvalResponse) error {
if done, err := e.srv.forward("Eval.GetEval", args, args, reply); done {
return err
}
defer metrics.MeasureSince([]string{"nomad", "eval", "get_eval"}, time.Now())
// Look for the job
snap, err := e.srv.fsm.State().Snapshot()
if err != nil {
return err
}
out, err := snap.GetEvalByID(args.EvalID)
if err != nil {
return err
}
// Setup the output
if out != nil {
reply.Eval = out
reply.Index = out.ModifyIndex
} else {
// Use the last index that affected the nodes table
index, err := snap.GetIndex("evals")
if err != nil {
return err
}
reply.Index = index
}
// Set the query response
e.srv.setQueryMeta(&reply.QueryMeta)
return nil
}

View File

@ -0,0 +1,50 @@
package nomad
import (
"reflect"
"testing"
"github.com/hashicorp/net-rpc-msgpackrpc"
"github.com/hashicorp/nomad/nomad/structs"
"github.com/hashicorp/nomad/testutil"
)
func TestEvalEndpoint_GetEval(t *testing.T) {
s1 := testServer(t, nil)
defer s1.Shutdown()
codec := rpcClient(t, s1)
testutil.WaitForLeader(t, s1.RPC)
// Create the register request
eval1 := mockEval()
s1.fsm.State().UpsertEval(1000, eval1)
// Lookup the eval
get := &structs.EvalSpecificRequest{
EvalID: eval1.ID,
WriteRequest: structs.WriteRequest{Region: "region1"},
}
var resp structs.SingleEvalResponse
if err := msgpackrpc.CallWithCodec(codec, "Eval.GetEval", get, &resp); err != nil {
t.Fatalf("err: %v", err)
}
if resp.Index != 1000 {
t.Fatalf("Bad index: %d %d", resp.Index, 1000)
}
if !reflect.DeepEqual(eval1, resp.Eval) {
t.Fatalf("bad: %#v %#v", eval1, resp.Eval)
}
// Lookup non-existing node
get.EvalID = generateUUID()
if err := msgpackrpc.CallWithCodec(codec, "Eval.GetEval", get, &resp); err != nil {
t.Fatalf("err: %v", err)
}
if resp.Index != 1000 {
t.Fatalf("Bad index: %d %d", resp.Index, 1000)
}
if resp.Eval != nil {
t.Fatalf("unexpected eval")
}
}

View File

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

View File

@ -173,6 +173,12 @@ type EvalDeleteRequest struct {
WriteRequest
}
// EvalSpecificRequest is used when we just need to specify a target evaluation
type EvalSpecificRequest struct {
EvalID string
WriteRequest
}
// GenericResponse is used to respond to a request where no
// specific response information is needed.
type GenericResponse struct {
@ -191,6 +197,12 @@ type SingleJobResponse struct {
QueryMeta
}
// SingleEvalResponse is used to return a single evaluation
type SingleEvalResponse struct {
Eval *Evaluation
QueryMeta
}
const (
NodeStatusInit = "initializing"
NodeStatusReady = "ready"