From 37e10e9656376bfc950240d0cc4cb696476a0d22 Mon Sep 17 00:00:00 2001 From: Chanwit Kaewkasi Date: Sun, 11 Jan 2015 02:39:47 +0700 Subject: [PATCH] support not in constraints expressions Signed-off-by: Chanwit Kaewkasi --- scheduler/filter/constraint.go | 16 +++++++-- scheduler/filter/constraint_test.go | 54 ++++++++++++++++++++++------- 2 files changed, 56 insertions(+), 14 deletions(-) diff --git a/scheduler/filter/constraint.go b/scheduler/filter/constraint.go index 2671b2390b..f2192d45ad 100644 --- a/scheduler/filter/constraint.go +++ b/scheduler/filter/constraint.go @@ -16,6 +16,12 @@ func (f *ConstraintFilter) Filter(config *dockerclient.ContainerConfig, nodes [] constraints := extractEnv("constraint", config.Env) for k, v := range constraints { log.Debugf("matching constraint: %s=%s", k, v) + negate := false + if strings.HasPrefix(v, "!") { + log.Debugf("negate detected") + v = strings.TrimPrefix(v, "!") + negate = true + } candidates := []*cluster.Node{} for _, node := range nodes { switch k { @@ -27,8 +33,14 @@ func (f *ConstraintFilter) Filter(config *dockerclient.ContainerConfig, nodes [] default: // By default match the node labels. if label, ok := node.Labels[k]; ok { - if match(v, label) { - candidates = append(candidates, node) + if negate { + if f.match(v, label) == false { + candidates = append(candidates, node) + } + } else { + if f.match(v, label) { + candidates = append(candidates, node) + } } } } diff --git a/scheduler/filter/constraint_test.go b/scheduler/filter/constraint_test.go index 134dd94745..85116f77cb 100644 --- a/scheduler/filter/constraint_test.go +++ b/scheduler/filter/constraint_test.go @@ -8,18 +8,12 @@ import ( "github.com/stretchr/testify/assert" ) -func TestConstraintFilter(t *testing.T) { - var ( - f = ConstraintFilter{} - nodes = []*cluster.Node{ - cluster.NewNode("node-0", 0), - cluster.NewNode("node-1", 0), - cluster.NewNode("node-2", 0), - } - result []*cluster.Node - err error - ) - +func testFixtures() (nodes []*cluster.Node) { + nodes = []*cluster.Node{ + cluster.NewNode("node-0", 0), + cluster.NewNode("node-1", 0), + cluster.NewNode("node-2", 0), + } nodes[0].ID = "node-0-id" nodes[0].Name = "node-0-name" nodes[0].Labels = map[string]string{ @@ -43,6 +37,17 @@ func TestConstraintFilter(t *testing.T) { "group": "2", "region": "eu", } + return +} + +/* +func TestConstrainteFilter(t *testing.T) { + var ( + f = ConstraintFilter{} + nodes = testFixtures() + result []*cluster.Node + err error + ) // Without constraints we should get the unfiltered list of nodes back. result, err = f.Filter(&dockerclient.ContainerConfig{}, nodes) @@ -108,3 +113,28 @@ func TestConstraintFilter(t *testing.T) { assert.NoError(t, err) assert.Len(t, result, 2) } +*/ + +func TestConstraintNotExpression(t *testing.T) { + var ( + f = ConstraintFilter{} + nodes = testFixtures() + result []*cluster.Node + err error + ) + + // Check not (!) expression + result, err = f.Filter(&dockerclient.ContainerConfig{ + Env: []string{"constraint:name=!node0"}, + }, nodes) + assert.NoError(t, err) + assert.Len(t, result, 2) + + // Check not with globber pattern + result, err = f.Filter(&dockerclient.ContainerConfig{ + Env: []string{"constraint:region=!us*"}, + }, nodes) + assert.NoError(t, err) + assert.Len(t, result, 1) + assert.Equal(t, result[0].Labels["region"], "eu") +}