support not in constraints expressions

Signed-off-by: Chanwit Kaewkasi <chanwit@gmail.com>
This commit is contained in:
Chanwit Kaewkasi 2015-01-11 02:39:47 +07:00
parent 829bcb562d
commit 37e10e9656
2 changed files with 56 additions and 14 deletions

View File

@ -16,6 +16,12 @@ func (f *ConstraintFilter) Filter(config *dockerclient.ContainerConfig, nodes []
constraints := extractEnv("constraint", config.Env) constraints := extractEnv("constraint", config.Env)
for k, v := range constraints { for k, v := range constraints {
log.Debugf("matching constraint: %s=%s", k, v) 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{} candidates := []*cluster.Node{}
for _, node := range nodes { for _, node := range nodes {
switch k { switch k {
@ -27,8 +33,14 @@ func (f *ConstraintFilter) Filter(config *dockerclient.ContainerConfig, nodes []
default: default:
// By default match the node labels. // By default match the node labels.
if label, ok := node.Labels[k]; ok { if label, ok := node.Labels[k]; ok {
if match(v, label) { if negate {
candidates = append(candidates, node) if f.match(v, label) == false {
candidates = append(candidates, node)
}
} else {
if f.match(v, label) {
candidates = append(candidates, node)
}
} }
} }
} }

View File

@ -8,18 +8,12 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func TestConstraintFilter(t *testing.T) { func testFixtures() (nodes []*cluster.Node) {
var ( nodes = []*cluster.Node{
f = ConstraintFilter{} cluster.NewNode("node-0", 0),
nodes = []*cluster.Node{ cluster.NewNode("node-1", 0),
cluster.NewNode("node-0", 0), cluster.NewNode("node-2", 0),
cluster.NewNode("node-1", 0), }
cluster.NewNode("node-2", 0),
}
result []*cluster.Node
err error
)
nodes[0].ID = "node-0-id" nodes[0].ID = "node-0-id"
nodes[0].Name = "node-0-name" nodes[0].Name = "node-0-name"
nodes[0].Labels = map[string]string{ nodes[0].Labels = map[string]string{
@ -43,6 +37,17 @@ func TestConstraintFilter(t *testing.T) {
"group": "2", "group": "2",
"region": "eu", "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. // Without constraints we should get the unfiltered list of nodes back.
result, err = f.Filter(&dockerclient.ContainerConfig{}, nodes) result, err = f.Filter(&dockerclient.ContainerConfig{}, nodes)
@ -108,3 +113,28 @@ func TestConstraintFilter(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, result, 2) 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")
}