diff --git a/scheduler/scheduler.go b/scheduler/scheduler.go index 165e6d79e..82ee4879b 100644 --- a/scheduler/scheduler.go +++ b/scheduler/scheduler.go @@ -57,6 +57,9 @@ type State interface { // AllocsByJob returns the allocations by JobID AllocsByJob(jobID string) ([]*structs.Allocation, error) + + // GetNodeByID is used to lookup a node by ID + GetNodeByID(nodeID string) (*structs.Node, error) } // Planner interface is used to submit a task allocation plan. diff --git a/scheduler/service_sched.go b/scheduler/service_sched.go index b64c14220..6e87fd2c1 100644 --- a/scheduler/service_sched.go +++ b/scheduler/service_sched.go @@ -52,6 +52,23 @@ func (s *ServiceScheduler) handleJobRegister(eval *structs.Evaluation) error { // handleJobDeregister is used to handle a job being deregistered func (s *ServiceScheduler) handleJobDeregister(eval *structs.Evaluation) error { START: + // Lookup the node ID + node, err := s.state.GetNodeByID(eval.NodeID) + if err != nil { + return fmt.Errorf("failed to get node '%s': %v", + eval.NodeID, err) + } + + // Could be a potential race, and the node is actually fine + if node != nil { + switch node.Status { + case structs.NodeStatusInit, structs.NodeStatusReady, structs.NodeStatusMaint: + s.logger.Printf("[DEBUG] sched: (eval %s) not evicting node %s allocs, status %s", + eval.ID, eval.NodeID, node.Status) + return nil + } + } + // Lookup the allocations by JobID allocs, err := s.state.AllocsByJob(eval.JobID) if err != nil {