Label filter: Support for node pinning by name or id.

Signed-off-by: Andrea Luzzardi <aluzzardi@gmail.com>
This commit is contained in:
Andrea Luzzardi 2014-11-21 14:12:49 -08:00
parent 7d930b8809
commit 4f3c15d9fe
2 changed files with 34 additions and 3 deletions

View File

@ -29,10 +29,19 @@ func (f *LabelFilter) Filter(config *dockerclient.ContainerConfig, nodes []*clus
for k, v := range constraints { for k, v := range constraints {
candidates := []*cluster.Node{} candidates := []*cluster.Node{}
for _, node := range nodes { for _, node := range nodes {
if label, ok := node.Labels[k]; ok { switch k {
if strings.Contains(strings.ToLower(label), v) { case "node":
// "node" label is a special case pinning a container to a specific node.
if strings.ToLower(node.ID) == v || strings.ToLower(node.Name) == v {
candidates = append(candidates, node) candidates = append(candidates, node)
} }
default:
// By default match the node labels.
if label, ok := node.Labels[k]; ok {
if strings.Contains(strings.ToLower(label), v) {
candidates = append(candidates, node)
}
}
} }
} }
if len(candidates) == 0 { if len(candidates) == 0 {

View File

@ -12,24 +12,30 @@ func TestLabeleFilter(t *testing.T) {
var ( var (
f = LabelFilter{} f = LabelFilter{}
nodes = []*cluster.Node{ nodes = []*cluster.Node{
cluster.NewNode("node-0"),
cluster.NewNode("node-1"), cluster.NewNode("node-1"),
cluster.NewNode("node-2"), cluster.NewNode("node-2"),
cluster.NewNode("node-3"),
} }
result []*cluster.Node result []*cluster.Node
err error err error
) )
nodes[0].ID = "node-0-id"
nodes[0].Name = "node-0-name"
nodes[0].Labels = map[string]string{ nodes[0].Labels = map[string]string{
"name": "node0", "name": "node0",
"group": "1", "group": "1",
} }
nodes[1].ID = "node-1-id"
nodes[1].Name = "node-1-name"
nodes[1].Labels = map[string]string{ nodes[1].Labels = map[string]string{
"name": "node1", "name": "node1",
"group": "1", "group": "1",
} }
nodes[2].ID = "node-2-id"
nodes[2].Name = "node-2-name"
nodes[2].Labels = map[string]string{ nodes[2].Labels = map[string]string{
"name": "node2", "name": "node2",
"group": "2", "group": "2",
@ -62,6 +68,22 @@ func TestLabeleFilter(t *testing.T) {
assert.Len(t, result, 2) assert.Len(t, result, 2)
assert.NotContains(t, result, nodes[2]) assert.NotContains(t, result, nodes[2])
// Validate node pinning by id.
result, err = f.Filter(&dockerclient.ContainerConfig{
Env: []string{"constraint:node=node-2-id"},
}, nodes)
assert.NoError(t, err)
assert.Len(t, result, 1)
assert.Equal(t, result[0], nodes[2])
// Validate node pinning by name.
result, err = f.Filter(&dockerclient.ContainerConfig{
Env: []string{"constraint:node=node-1-name"},
}, nodes)
assert.NoError(t, err)
assert.Len(t, result, 1)
assert.Equal(t, result[0], nodes[1])
// Make sure constraints are evaluated as logical ANDs. // Make sure constraints are evaluated as logical ANDs.
result, err = f.Filter(&dockerclient.ContainerConfig{ result, err = f.Filter(&dockerclient.ContainerConfig{
Env: []string{"constraint:name=node0", "constraint:group=1"}, Env: []string{"constraint:name=node0", "constraint:group=1"},