From 5bee0b6c434f9b74e860eef89241f4e9a2c6d303 Mon Sep 17 00:00:00 2001 From: CMGS Date: Fri, 24 May 2019 17:25:27 +0800 Subject: [PATCH] fill and average plan will failed if nodes less than nodeslimit --- go.mod | 1 + go.sum | 4 ++++ scheduler/complex/average.go | 6 ++++++ scheduler/complex/average_test.go | 10 ++++++++-- scheduler/complex/cpu.go | 7 ------- scheduler/complex/fill.go | 4 ++++ scheduler/complex/fill_test.go | 25 +++++++++++++++++++++++++ scheduler/scheduler.go | 4 ++-- 8 files changed, 50 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index 1b60d0237..bed3181ba 100644 --- a/go.mod +++ b/go.mod @@ -23,6 +23,7 @@ require ( github.com/docker/go-units v0.3.3 github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect github.com/ghodss/yaml v1.0.0 // indirect + github.com/go-check/check v0.0.0-20180628173108-788fd7840127 // indirect github.com/gogo/protobuf v0.0.0-20171007142547-342cbe0a0415 // indirect github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903 // indirect github.com/golang/protobuf v1.2.0 diff --git a/go.sum b/go.sum index 849bc0e37..0b207dacc 100644 --- a/go.sum +++ b/go.sum @@ -40,6 +40,8 @@ github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/gogo/protobuf v0.0.0-20171007142547-342cbe0a0415 h1:WSBJMqJbLxsn+bTCPyPYZfqHdJmc8MK4wrBjMft6BAM= github.com/gogo/protobuf v0.0.0-20171007142547-342cbe0a0415/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -68,8 +70,10 @@ github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= diff --git a/scheduler/complex/average.go b/scheduler/complex/average.go index c9a56afaf..e344793f3 100644 --- a/scheduler/complex/average.go +++ b/scheduler/complex/average.go @@ -1,6 +1,7 @@ package complexscheduler import ( + "fmt" "sort" "github.com/projecteru2/core/types" @@ -9,7 +10,12 @@ import ( // AveragePlan deploy container each node func AveragePlan(nodesInfo []types.NodeInfo, need, limit int) ([]types.NodeInfo, error) { + log.Debugf("[AveragePlan] need %d limit %d", need, limit) nodesInfoLength := len(nodesInfo) + if nodesInfoLength < limit { + return nil, types.NewDetailedErr(types.ErrInsufficientRes, + fmt.Sprintf("node len %d cannot alloc an average node plan", nodesInfoLength)) + } sort.Slice(nodesInfo, func(i, j int) bool { return nodesInfo[i].Capacity < nodesInfo[j].Capacity }) p := sort.Search(nodesInfoLength, func(i int) bool { return nodesInfo[i].Capacity >= need }) if p == nodesInfoLength { diff --git a/scheduler/complex/average_test.go b/scheduler/complex/average_test.go index 97948d01c..51e331db7 100644 --- a/scheduler/complex/average_test.go +++ b/scheduler/complex/average_test.go @@ -19,11 +19,17 @@ func TestAveragePlan(t *testing.T) { assert.Equal(t, r[i].Deploy, 1) assert.Equal(t, r[i].Capacity, originCap[i]-1) } - + // nodes len < limit + nodes = deployedNodes() + _, err = AveragePlan(nodes, 100, 5) + assert.Error(t, err) // 超过 cap nodes = deployedNodes() _, err = AveragePlan(nodes, 100, 0) assert.Error(t, err) assert.Contains(t, err.Error(), "not enough capacity") - + // 正常 limit + nodes = deployedNodes() + _, err = AveragePlan(nodes, 1, 1) + assert.NoError(t, err) } diff --git a/scheduler/complex/cpu.go b/scheduler/complex/cpu.go index 16451baba..340c80b32 100644 --- a/scheduler/complex/cpu.go +++ b/scheduler/complex/cpu.go @@ -18,13 +18,6 @@ func min(a, b int) int { return b } -func abs(a int) int { - if a < 0 { - return -a - } - return a -} - type cpuInfo struct { no string pieces int diff --git a/scheduler/complex/fill.go b/scheduler/complex/fill.go index 3de90f135..fc427bf13 100644 --- a/scheduler/complex/fill.go +++ b/scheduler/complex/fill.go @@ -12,6 +12,10 @@ import ( func FillPlan(nodesInfo []types.NodeInfo, need, limit int) ([]types.NodeInfo, error) { log.Debugf("[FillPlan] need %d limit %d", need, limit) nodesInfoLength := len(nodesInfo) + if nodesInfoLength < limit { + return nil, types.NewDetailedErr(types.ErrInsufficientRes, + fmt.Sprintf("node len %d cannot alloc a fill node plan", nodesInfoLength)) + } sort.Slice(nodesInfo, func(i, j int) bool { return nodesInfo[i].Count > nodesInfo[j].Count }) p := sort.Search(nodesInfoLength, func(i int) bool { return nodesInfo[i].Count < need }) if p == nodesInfoLength { diff --git a/scheduler/complex/fill_test.go b/scheduler/complex/fill_test.go index 7a6833d09..16a71272f 100644 --- a/scheduler/complex/fill_test.go +++ b/scheduler/complex/fill_test.go @@ -58,4 +58,29 @@ func TestFillPlan(t *testing.T) { _, err = FillPlan(nodes, n, 0) assert.Error(t, err) assert.Contains(t, err.Error(), "each node has enough containers") + + // LimitNode + n = 15 + nodes = deployedNodes() + _, err = FillPlan(nodes, n, 2) + assert.NoError(t, err) + + // 局部补充 + n = 1 + nodes = []types.NodeInfo{ + { + Name: "65", + Capacity: 0, + Count: 0, + }, + { + Name: "67", + Capacity: 10, + Count: 0, + }, + } + + _, err = FillPlan(nodes, n, 3) + assert.Error(t, err) + assert.Contains(t, err.Error(), "cannot alloc a fill node plan") } diff --git a/scheduler/scheduler.go b/scheduler/scheduler.go index 0d1e84d93..9d22977a4 100644 --- a/scheduler/scheduler.go +++ b/scheduler/scheduler.go @@ -20,12 +20,12 @@ type Scheduler interface { // select nodes from nodes, return a list of nodenames and the corresponding cpumap, and also the changed nodes with remaining cpumap // quota and number must be given, typically used to determine where to deploy SelectCPUNodes(nodesInfo []types.NodeInfo, quota float64, memory int64) ([]types.NodeInfo, map[string][]types.CPUMap, int, error) + // global division + GlobalDivision(nodesInfo []types.NodeInfo, need, total int) ([]types.NodeInfo, error) // common division CommonDivision(nodesInfo []types.NodeInfo, need, total int) ([]types.NodeInfo, error) // average division EachDivision(nodesInfo []types.NodeInfo, need, limit int) ([]types.NodeInfo, error) // fill division FillDivision(nodesInfo []types.NodeInfo, need, limit int) ([]types.NodeInfo, error) - // global division - GlobalDivision(nodesInfo []types.NodeInfo, need, total int) ([]types.NodeInfo, error) }