Merge pull request #1067 from hashicorp/b-add-client-status-to-terminal
add client status to allocation terminal status
This commit is contained in:
commit
98bbb10217
|
@ -235,12 +235,7 @@ func (c *CoreScheduler) gcEval(eval *structs.Evaluation, thresholdIndex uint64)
|
|||
|
||||
// Scan the allocations to ensure they are terminal and old
|
||||
for _, alloc := range allocs {
|
||||
// TODO: This can go away once the scheduler marks an alloc as
|
||||
// DesiredStatusStop when a client fails.
|
||||
allocTerminal := alloc.TerminalStatus() ||
|
||||
alloc.ClientStatus == structs.AllocClientStatusComplete ||
|
||||
alloc.ClientStatus == structs.AllocClientStatusFailed
|
||||
if !allocTerminal || alloc.ModifyIndex > thresholdIndex {
|
||||
if !alloc.TerminalStatus() || alloc.ModifyIndex > thresholdIndex {
|
||||
return false, nil, nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -374,36 +374,26 @@ func TestCoreScheduler_NodeGC_Force(t *testing.T) {
|
|||
|
||||
func TestCoreScheduler_JobGC(t *testing.T) {
|
||||
tests := []struct {
|
||||
test, evalStatus, desiredAllocStatus, clientAllocStatus string
|
||||
shouldExist bool
|
||||
test, evalStatus, allocStatus string
|
||||
shouldExist bool
|
||||
}{
|
||||
{
|
||||
test: "Terminal",
|
||||
evalStatus: structs.EvalStatusFailed,
|
||||
desiredAllocStatus: structs.AllocDesiredStatusRun,
|
||||
clientAllocStatus: structs.AllocDesiredStatusFailed,
|
||||
shouldExist: false,
|
||||
test: "Terminal",
|
||||
evalStatus: structs.EvalStatusFailed,
|
||||
allocStatus: structs.AllocDesiredStatusFailed,
|
||||
shouldExist: false,
|
||||
},
|
||||
{
|
||||
test: "Has Failed Alloc",
|
||||
evalStatus: structs.EvalStatusFailed,
|
||||
desiredAllocStatus: structs.AllocDesiredStatusRun,
|
||||
clientAllocStatus: structs.AllocDesiredStatusFailed,
|
||||
shouldExist: false,
|
||||
test: "Has Alloc",
|
||||
evalStatus: structs.EvalStatusFailed,
|
||||
allocStatus: structs.AllocDesiredStatusRun,
|
||||
shouldExist: true,
|
||||
},
|
||||
{
|
||||
test: "Has Running Alloc",
|
||||
evalStatus: structs.EvalStatusFailed,
|
||||
desiredAllocStatus: structs.AllocDesiredStatusRun,
|
||||
clientAllocStatus: structs.AllocDesiredStatusRun,
|
||||
shouldExist: true,
|
||||
},
|
||||
{
|
||||
test: "Has Eval",
|
||||
evalStatus: structs.EvalStatusPending,
|
||||
desiredAllocStatus: structs.AllocDesiredStatusRun,
|
||||
clientAllocStatus: structs.AllocDesiredStatusFailed,
|
||||
shouldExist: true,
|
||||
test: "Has Eval",
|
||||
evalStatus: structs.EvalStatusPending,
|
||||
allocStatus: structs.AllocDesiredStatusFailed,
|
||||
shouldExist: true,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -434,8 +424,7 @@ func TestCoreScheduler_JobGC(t *testing.T) {
|
|||
alloc := mock.Alloc()
|
||||
alloc.JobID = job.ID
|
||||
alloc.EvalID = eval.ID
|
||||
alloc.DesiredStatus = test.desiredAllocStatus
|
||||
alloc.ClientStatus = test.clientAllocStatus
|
||||
alloc.DesiredStatus = test.allocStatus
|
||||
err = state.UpsertAllocs(1002, []*structs.Allocation{alloc})
|
||||
if err != nil {
|
||||
t.Fatalf("test(%s) err: %v", test.test, err)
|
||||
|
@ -489,36 +478,26 @@ func TestCoreScheduler_JobGC(t *testing.T) {
|
|||
|
||||
func TestCoreScheduler_JobGC_Force(t *testing.T) {
|
||||
tests := []struct {
|
||||
test, evalStatus, desiredAllocStatus, clientAllocStatus string
|
||||
shouldExist bool
|
||||
test, evalStatus, allocStatus string
|
||||
shouldExist bool
|
||||
}{
|
||||
{
|
||||
test: "Terminal",
|
||||
evalStatus: structs.EvalStatusFailed,
|
||||
desiredAllocStatus: structs.AllocDesiredStatusRun,
|
||||
clientAllocStatus: structs.AllocDesiredStatusFailed,
|
||||
shouldExist: false,
|
||||
test: "Terminal",
|
||||
evalStatus: structs.EvalStatusFailed,
|
||||
allocStatus: structs.AllocDesiredStatusFailed,
|
||||
shouldExist: false,
|
||||
},
|
||||
{
|
||||
test: "Has Failed Alloc",
|
||||
evalStatus: structs.EvalStatusFailed,
|
||||
desiredAllocStatus: structs.AllocDesiredStatusRun,
|
||||
clientAllocStatus: structs.AllocDesiredStatusFailed,
|
||||
shouldExist: false,
|
||||
test: "Has Alloc",
|
||||
evalStatus: structs.EvalStatusFailed,
|
||||
allocStatus: structs.AllocDesiredStatusRun,
|
||||
shouldExist: true,
|
||||
},
|
||||
{
|
||||
test: "Has Running Alloc",
|
||||
evalStatus: structs.EvalStatusFailed,
|
||||
desiredAllocStatus: structs.AllocDesiredStatusRun,
|
||||
clientAllocStatus: structs.AllocDesiredStatusRun,
|
||||
shouldExist: true,
|
||||
},
|
||||
{
|
||||
test: "Has Eval",
|
||||
evalStatus: structs.EvalStatusPending,
|
||||
desiredAllocStatus: structs.AllocDesiredStatusRun,
|
||||
clientAllocStatus: structs.AllocDesiredStatusFailed,
|
||||
shouldExist: true,
|
||||
test: "Has Eval",
|
||||
evalStatus: structs.EvalStatusPending,
|
||||
allocStatus: structs.AllocDesiredStatusFailed,
|
||||
shouldExist: true,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -549,8 +528,7 @@ func TestCoreScheduler_JobGC_Force(t *testing.T) {
|
|||
alloc := mock.Alloc()
|
||||
alloc.JobID = job.ID
|
||||
alloc.EvalID = eval.ID
|
||||
alloc.DesiredStatus = test.desiredAllocStatus
|
||||
alloc.ClientStatus = test.clientAllocStatus
|
||||
alloc.DesiredStatus = test.allocStatus
|
||||
err = state.UpsertAllocs(1002, []*structs.Allocation{alloc})
|
||||
if err != nil {
|
||||
t.Fatalf("test(%s) err: %v", test.test, err)
|
||||
|
|
|
@ -24,17 +24,25 @@ func TestRemoveAllocs(t *testing.T) {
|
|||
|
||||
func TestFilterTerminalAllocs(t *testing.T) {
|
||||
l := []*Allocation{
|
||||
&Allocation{ID: "foo", DesiredStatus: AllocDesiredStatusRun},
|
||||
&Allocation{ID: "bar", DesiredStatus: AllocDesiredStatusEvict},
|
||||
&Allocation{ID: "baz", DesiredStatus: AllocDesiredStatusStop},
|
||||
&Allocation{ID: "zip", DesiredStatus: AllocDesiredStatusRun},
|
||||
&Allocation{
|
||||
ID: "foo",
|
||||
DesiredStatus: AllocDesiredStatusRun,
|
||||
ClientStatus: AllocClientStatusPending,
|
||||
},
|
||||
&Allocation{
|
||||
ID: "bam",
|
||||
DesiredStatus: AllocDesiredStatusRun,
|
||||
ClientStatus: AllocClientStatusComplete,
|
||||
},
|
||||
}
|
||||
|
||||
out := FilterTerminalAllocs(l)
|
||||
if len(out) != 2 {
|
||||
if len(out) != 1 {
|
||||
t.Fatalf("bad: %#v", out)
|
||||
}
|
||||
if out[0].ID != "foo" && out[1].ID != "zip" {
|
||||
if out[0].ID != "foo" {
|
||||
t.Fatalf("bad: %#v", out)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2229,6 +2229,12 @@ func (a *Allocation) TerminalStatus() bool {
|
|||
switch a.DesiredStatus {
|
||||
case AllocDesiredStatusStop, AllocDesiredStatusEvict, AllocDesiredStatusFailed:
|
||||
return true
|
||||
default:
|
||||
}
|
||||
|
||||
switch a.ClientStatus {
|
||||
case AllocClientStatusComplete, AllocClientStatusFailed:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -231,8 +231,16 @@ func (s *GenericScheduler) process() (bool, error) {
|
|||
// re-placed.
|
||||
func (s *GenericScheduler) filterCompleteAllocs(allocs []*structs.Allocation) []*structs.Allocation {
|
||||
filter := func(a *structs.Allocation) bool {
|
||||
// TODO: Limit the number of times we restart a failed allocation.
|
||||
return a.TerminalStatus() || a.ClientStatus == structs.AllocClientStatusFailed
|
||||
// Allocs from batch jobs should be filtered when their status is failed
|
||||
// so that they will be replaced. If they are complete but not failed, they
|
||||
// shouldn't be replaced.
|
||||
if s.batch {
|
||||
return a.TerminalStatus() &&
|
||||
a.ClientStatus != structs.AllocClientStatusComplete
|
||||
}
|
||||
|
||||
// Filter terminal, non batch allocations
|
||||
return a.TerminalStatus()
|
||||
}
|
||||
|
||||
n := len(allocs)
|
||||
|
|
Loading…
Reference in New Issue