Merge pull request #971 from jimmyxian/reschedule-with-image

Reschedule with soft image affinity
This commit is contained in:
Alexandre Beslic 2015-07-13 09:11:18 -07:00
commit 1a5881ec49
4 changed files with 62 additions and 1 deletions

View File

@ -146,3 +146,15 @@ func (c *ContainerConfig) Affinities() []string {
func (c *ContainerConfig) Constraints() []string {
return c.extractExprs("constraints")
}
// AddAffinity to config
func (c *ContainerConfig) AddAffinity(affinity string) error {
affinities := c.extractExprs("affinities")
affinities = append(affinities, affinity)
labels, err := json.Marshal(affinities)
if err != nil {
return err
}
c.Labels[SwarmLabelNamespace+".affinities"] = string(labels)
return nil
}

View File

@ -81,3 +81,11 @@ func TestConsolidateResourceFields(t *testing.T) {
}
}
func TestAddAffinity(t *testing.T) {
config := BuildContainerConfig(dockerclient.ContainerConfig{})
assert.Empty(t, config.Affinities())
config.AddAffinity("image==~testimage")
assert.Len(t, config.Affinities(), 1)
}

View File

@ -89,6 +89,20 @@ func (c *Cluster) generateUniqueID() string {
// CreateContainer aka schedule a brand new container into the cluster.
func (c *Cluster) CreateContainer(config *cluster.ContainerConfig, name string) (*cluster.Container, error) {
container, err := c.createContainer(config, name, false)
// fails with image not found, then try to reschedule with soft-image-affinity
if err != nil && strings.HasSuffix(err.Error(), "not found") {
// Check if the image exists in the cluster
// If exists, retry with a soft-image-affinity
if image := c.Image(config.Image); image != nil {
container, err = c.createContainer(config, name, true)
}
}
return container, err
}
func (c *Cluster) createContainer(config *cluster.ContainerConfig, name string, withSoftImageAffinity bool) (*cluster.Container, error) {
c.scheduler.Lock()
defer c.scheduler.Unlock()
@ -100,7 +114,12 @@ func (c *Cluster) CreateContainer(config *cluster.ContainerConfig, name string)
// Associate a Swarm ID to the container we are creating.
config.SetSwarmID(c.generateUniqueID())
n, err := c.scheduler.SelectNodeForContainer(c.listNodes(), config)
configTemp := config
if withSoftImageAffinity {
configTemp.AddAffinity("image==~" + config.Image)
}
n, err := c.scheduler.SelectNodeForContainer(c.listNodes(), configTemp)
if err != nil {
return nil, err
}

View File

@ -66,3 +66,25 @@ function teardown() {
# pid
[[ "${output}" == *"\"PidMode\": \"host\""* ]]
}
@test "docker run - reschedule with soft-image-affinity" {
start_docker_with_busybox 1
start_docker 1
docker -H ${HOSTS[0]} tag busybox:latest busyboxabcde:latest
swarm_manage
# make sure busyboxabcde exists
run docker_swarm images
[ "$status" -eq 0 ]
[[ "${output}" == *"busyboxabcde"* ]]
# try to create container on node-1, node-1 does not have busyboxabcde and will pull it
# but can not find busyboxabcde in dockerhub
# then will retry with soft-image-affinity
docker_swarm run -d --name test_container -e constraint:node==~node-1 busyboxabcde sleep 1000
# check container running on node-0
run docker_swarm ps
[[ "${output}" == *"node-0/test_container"* ]]
}