mirror of
https://github.com/kemko/nomad.git
synced 2026-01-07 02:45:42 +03:00
nomad: Adding Client.UpdateAlloc endpoint
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user