affinity: Fix expression matching by passing arguments in bulk.

Signed-off-by: Andrea Luzzardi <aluzzardi@gmail.com>
This commit is contained in:
Andrea Luzzardi 2015-01-28 11:50:40 -08:00
parent 5627b390df
commit fc192b7077
2 changed files with 49 additions and 29 deletions

View File

@ -26,33 +26,25 @@ func (f *AffinityFilter) Filter(config *dockerclient.ContainerConfig, nodes []*c
for _, node := range nodes {
switch affinity.key {
case "container":
if len(node.Containers()) == 0 && affinity.MatchEmpty() {
candidates = append(candidates, node)
break
}
containers := []string{}
for _, container := range node.Containers() {
if affinity.Match(container.Id, strings.TrimPrefix(container.Names[0], "/")) {
candidates = append(candidates, node)
break
}
containers = append(containers, container.Id, strings.TrimPrefix(container.Names[0], "/"))
}
if affinity.Match(containers...) {
candidates = append(candidates, node)
}
case "image":
if len(node.Images()) == 0 && affinity.MatchEmpty() {
candidates = append(candidates, node)
break
}
done:
images := []string{}
for _, image := range node.Images() {
whats := append(image.RepoTags, image.Id)
images = append(images, image.Id)
images = append(images, image.RepoTags...)
for _, tag := range image.RepoTags {
whats = append(whats, strings.Split(tag, ":")[0])
}
if affinity.Match(whats...) {
candidates = append(candidates, node)
break done
images = append(images, strings.Split(tag, ":")[0])
}
}
if affinity.Match(images...) {
candidates = append(candidates, node)
}
}
}
if len(candidates) == 0 {

View File

@ -24,8 +24,14 @@ func TestAffinityFilter(t *testing.T) {
nodes[0].Name = "node-0-name"
nodes[0].AddContainer(&cluster.Container{
Container: dockerclient.Container{
Id: "container-0-id",
Names: []string{"/container-0-name"},
Id: "container-n0-0-id",
Names: []string{"/container-n0-0-name"},
},
})
nodes[0].AddContainer(&cluster.Container{
Container: dockerclient.Container{
Id: "container-n0-1-id",
Names: []string{"/container-n0-1-name"},
},
})
nodes[0].AddImage(&dockerclient.Image{
@ -37,8 +43,14 @@ func TestAffinityFilter(t *testing.T) {
nodes[1].Name = "node-1-name"
nodes[1].AddContainer(&cluster.Container{
Container: dockerclient.Container{
Id: "container-1-id",
Names: []string{"/container-1-name"},
Id: "container-n1-0-id",
Names: []string{"/container-n1-0-name"},
},
})
nodes[1].AddContainer(&cluster.Container{
Container: dockerclient.Container{
Id: "container-n1-1-id",
Names: []string{"/container-n1-1-name"},
},
})
nodes[1].AddImage(&dockerclient.Image{
@ -62,7 +74,7 @@ func TestAffinityFilter(t *testing.T) {
// Set a contraint that can only be filled by a single node.
result, err = f.Filter(&dockerclient.ContainerConfig{
Env: []string{"affinity:container==container-0*"},
Env: []string{"affinity:container==container-n0*"},
}, nodes)
assert.NoError(t, err)
assert.Len(t, result, 1)
@ -78,7 +90,7 @@ func TestAffinityFilter(t *testing.T) {
// Validate by id.
result, err = f.Filter(&dockerclient.ContainerConfig{
Env: []string{"affinity:container==container-0-id"},
Env: []string{"affinity:container==container-n0-0-id"},
}, nodes)
assert.NoError(t, err)
assert.Len(t, result, 1)
@ -86,7 +98,15 @@ func TestAffinityFilter(t *testing.T) {
// Validate by id.
result, err = f.Filter(&dockerclient.ContainerConfig{
Env: []string{"affinity:container!=container-0-id"},
Env: []string{"affinity:container!=container-n0-0-id"},
}, nodes)
assert.NoError(t, err)
assert.Len(t, result, 2)
assert.NotContains(t, result, nodes[0])
// Validate by id.
result, err = f.Filter(&dockerclient.ContainerConfig{
Env: []string{"affinity:container!=container-n0-1-id"},
}, nodes)
assert.NoError(t, err)
assert.Len(t, result, 2)
@ -94,7 +114,7 @@ func TestAffinityFilter(t *testing.T) {
// Validate by name.
result, err = f.Filter(&dockerclient.ContainerConfig{
Env: []string{"affinity:container==container-1-name"},
Env: []string{"affinity:container==container-n1-0-name"},
}, nodes)
assert.NoError(t, err)
assert.Len(t, result, 1)
@ -102,7 +122,15 @@ func TestAffinityFilter(t *testing.T) {
// Validate by name.
result, err = f.Filter(&dockerclient.ContainerConfig{
Env: []string{"affinity:container!=container-1-name"},
Env: []string{"affinity:container!=container-n1-0-name"},
}, nodes)
assert.NoError(t, err)
assert.Len(t, result, 2)
assert.NotContains(t, result, nodes[1])
// Validate by name.
result, err = f.Filter(&dockerclient.ContainerConfig{
Env: []string{"affinity:container!=container-n1-1-name"},
}, nodes)
assert.NoError(t, err)
assert.Len(t, result, 2)