From 451b77d5d761e58d5c877b2cbbc6b97b1d2bddf1 Mon Sep 17 00:00:00 2001 From: Alex Dadgar Date: Tue, 27 Feb 2018 14:08:29 -0800 Subject: [PATCH] Unblock evals once eligible --- nomad/fsm.go | 15 +++++++++++++ nomad/fsm_test.go | 54 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/nomad/fsm.go b/nomad/fsm.go index 7df2582db..b377f09b3 100644 --- a/nomad/fsm.go +++ b/nomad/fsm.go @@ -344,10 +344,25 @@ func (n *nomadFSM) applyNodeEligibilityUpdate(buf []byte, index uint64) interfac panic(fmt.Errorf("failed to decode request: %v", err)) } + // Lookup the existing node + node, err := n.state.NodeByID(nil, req.NodeID) + if err != nil { + n.logger.Printf("[ERR] nomad.fsm: UpdateNodeEligibility failed to lookup node %q: %v", req.NodeID, err) + return err + } + if err := n.state.UpdateNodeEligibility(index, req.NodeID, req.Eligibility); err != nil { n.logger.Printf("[ERR] nomad.fsm: UpdateNodeEligibility failed: %v", err) return err } + + // Unblock evals for the nodes computed node class if it is in a ready + // state. + if node != nil && node.SchedulingEligibility == structs.NodeSchedulingIneligible && + req.Eligibility == structs.NodeSchedulingEligible { + n.blockedEvals.Unblock(node.ComputedClass, index) + } + return nil } diff --git a/nomad/fsm_test.go b/nomad/fsm_test.go index b834b432f..9f8ed205a 100644 --- a/nomad/fsm_test.go +++ b/nomad/fsm_test.go @@ -377,6 +377,60 @@ func TestFSM_UpdateNodeEligibility(t *testing.T) { require.Contains(err.Error(), "draining") } +func TestFSM_UpdateNodeEligibility_Unblock(t *testing.T) { + t.Parallel() + require := require.New(t) + fsm := testFSM(t) + + node := mock.Node() + req := structs.NodeRegisterRequest{ + Node: node, + } + buf, err := structs.Encode(structs.NodeRegisterRequestType, req) + require.Nil(err) + + resp := fsm.Apply(makeLog(buf)) + require.Nil(resp) + + // Set the eligibility + req2 := structs.NodeUpdateEligibilityRequest{ + NodeID: node.ID, + Eligibility: structs.NodeSchedulingIneligible, + } + buf, err = structs.Encode(structs.NodeUpdateEligibilityRequestType, req2) + require.Nil(err) + + resp = fsm.Apply(makeLog(buf)) + require.Nil(resp) + + // Mark an eval as blocked. + eval := mock.Eval() + eval.ClassEligibility = map[string]bool{node.ComputedClass: true} + fsm.blockedEvals.Block(eval) + + // Set eligible + req4 := structs.NodeUpdateEligibilityRequest{ + NodeID: node.ID, + Eligibility: structs.NodeSchedulingEligible, + } + buf, err = structs.Encode(structs.NodeUpdateEligibilityRequestType, req4) + require.Nil(err) + + resp = fsm.Apply(makeLog(buf)) + require.Nil(resp) + + // Verify the eval was unblocked. + testutil.WaitForResult(func() (bool, error) { + bStats := fsm.blockedEvals.Stats() + if bStats.TotalBlocked != 0 { + return false, fmt.Errorf("bad: %#v", bStats) + } + return true, nil + }, func(err error) { + t.Fatalf("err: %s", err) + }) +} + func TestFSM_RegisterJob(t *testing.T) { t.Parallel() fsm := testFSM(t)