nomad: Adding Client.UpdateAlloc endpoint

This commit is contained in:
Armon Dadgar
2015-08-25 18:12:51 -07:00
parent c52596f1b6
commit 4cdb77cf2f
3 changed files with 81 additions and 0 deletions

View File

@@ -316,6 +316,30 @@ func (c *ClientEndpoint) GetAllocs(args *structs.NodeSpecificRequest,
return c.srv.blockingRPC(&opts)
}
// UpdateAlloc is used to update the client status of an allocation
func (c *ClientEndpoint) UpdateAlloc(args *structs.AllocUpdateRequest, reply *structs.GenericResponse) error {
if done, err := c.srv.forward("Client.UpdateAlloc", args, args, reply); done {
return err
}
defer metrics.MeasureSince([]string{"nomad", "client", "update_alloc"}, time.Now())
// Ensure only a single alloc
if len(args.Alloc) != 1 {
return fmt.Errorf("must update a single allocation")
}
// Commit this update via Raft
_, index, err := c.srv.raftApply(structs.AllocClientUpdateRequestType, args)
if err != nil {
c.srv.logger.Printf("[ERR] nomad.client: alloc update failed: %v", err)
return err
}
// Setup the response
reply.Index = index
return nil
}
// createNodeEvals is used to create evaluations for each alloc on a node.
// Each Eval is scoped to a job, so we need to potentially trigger many evals.
func (c *ClientEndpoint) createNodeEvals(nodeID string, nodeIndex uint64) ([]string, uint64, error) {

View File

@@ -368,6 +368,62 @@ func TestClientEndpoint_GetAllocs_Blocking(t *testing.T) {
}
}
func TestClientEndpoint_UpdateAlloc(t *testing.T) {
s1 := testServer(t, nil)
defer s1.Shutdown()
codec := rpcClient(t, s1)
testutil.WaitForLeader(t, s1.RPC)
// Create the register request
node := mock.Node()
reg := &structs.NodeRegisterRequest{
Node: node,
WriteRequest: structs.WriteRequest{Region: "region1"},
}
// Fetch the response
var resp structs.GenericResponse
if err := msgpackrpc.CallWithCodec(codec, "Client.Register", reg, &resp); err != nil {
t.Fatalf("err: %v", err)
}
// Inject fake evaluations
alloc := mock.Alloc()
alloc.NodeID = node.ID
state := s1.fsm.State()
err := state.UpdateAllocations(100, []*structs.Allocation{alloc})
if err != nil {
t.Fatalf("err: %v", err)
}
// Attempt update
clientAlloc := new(structs.Allocation)
*clientAlloc = *alloc
clientAlloc.ClientStatus = structs.AllocClientStatusFailed
// Update the alloc
update := &structs.AllocUpdateRequest{
Alloc: []*structs.Allocation{clientAlloc},
WriteRequest: structs.WriteRequest{Region: "region1"},
}
var resp2 structs.NodeAllocsResponse
if err := msgpackrpc.CallWithCodec(codec, "Client.UpdateAlloc", update, &resp2); err != nil {
t.Fatalf("err: %v", err)
}
if resp2.Index == 0 {
t.Fatalf("Bad index: %d", resp2.Index)
}
// Lookup the alloc
out, err := state.GetAllocByID(alloc.ID)
if err != nil {
t.Fatalf("err: %v", err)
}
if out.ClientStatus != structs.AllocClientStatusFailed {
t.Fatalf("Bad: %#v", out)
}
}
func TestClientEndpoint_CreateNodeEvals(t *testing.T) {
s1 := testServer(t, nil)
defer s1.Shutdown()

View File

@@ -220,6 +220,7 @@ type PlanRequest struct {
type AllocUpdateRequest struct {
// Alloc is the list of new allocations to assign
Alloc []*Allocation
WriteRequest
}
// GenericRequest is used to request where no