Пример #1
0
func TestFilterSoftConstraint(t *testing.T) {
	var (
		f      = ConstraintFilter{}
		nodes  = testFixtures()
		result []*node.Node
		err    error
	)

	result, err = f.Filter(cluster.BuildContainerConfig(containertypes.Config{Env: []string{"constraint:node==~node-1-name"}}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), nodes, true)
	assert.NoError(t, err)
	assert.Len(t, result, 1)
	assert.Equal(t, result[0], nodes[1])

	result, err = f.Filter(cluster.BuildContainerConfig(containertypes.Config{Env: []string{`constraint:name!=~/(?i)abc*/`}}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), nodes, true)
	assert.NoError(t, err)
	assert.Len(t, result, 4)

	// Check not with globber pattern
	result, err = f.Filter(cluster.BuildContainerConfig(containertypes.Config{Env: []string{"constraint:region!=~us*"}}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), nodes, true)
	assert.NoError(t, err)
	assert.Len(t, result, 2)

	result, err = f.Filter(cluster.BuildContainerConfig(containertypes.Config{Env: []string{"constraint:region!=~can*"}}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), nodes, true)
	assert.NoError(t, err)
	assert.Len(t, result, 4)

	// Check matching
	result, err = f.Filter(cluster.BuildContainerConfig(containertypes.Config{Env: []string{"constraint:region==~us~"}}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), nodes, true)
	assert.Error(t, err)
	assert.Len(t, result, 0)
}
Пример #2
0
func TestConstraintRegExp(t *testing.T) {
	var (
		f      = ConstraintFilter{}
		nodes  = testFixtures()
		result []*node.Node
		err    error
	)

	// Check with regular expression /node\d/ matches node{0..2}
	result, err = f.Filter(cluster.BuildContainerConfig(containertypes.Config{Env: []string{`constraint:name==/node\d/`}}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), nodes, true)
	assert.NoError(t, err)
	assert.Len(t, result, 3)

	// Check with regular expression /node\d/ matches node{0..2}
	result, err = f.Filter(cluster.BuildContainerConfig(containertypes.Config{Env: []string{`constraint:name==/node[12]/`}}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), nodes, true)
	assert.NoError(t, err)
	assert.Len(t, result, 2)

	// Check with regular expression ! and regexp /node[12]/ matches node[0] and node[3]
	result, err = f.Filter(cluster.BuildContainerConfig(containertypes.Config{Env: []string{`constraint:name!=/node[12]/`}}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), nodes, true)
	assert.NoError(t, err)
	assert.Len(t, result, 2)

	// Validate node pinning by ! and regexp.
	result, err = f.Filter(cluster.BuildContainerConfig(containertypes.Config{Env: []string{"constraint:node!=/node-[01]-id/"}}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), nodes, true)
	assert.NoError(t, err)
	assert.Len(t, result, 2)
}
Пример #3
0
func TestFilterRegExpCaseInsensitive(t *testing.T) {
	var (
		f      = ConstraintFilter{}
		nodes  = testFixtures()
		result []*node.Node
		err    error
	)

	// Prepare node with a strange name
	nodes[3].Labels = map[string]string{
		"name":   "aBcDeF",
		"group":  "2",
		"region": "eu",
	}

	// Case-sensitive, so not match
	result, err = f.Filter(cluster.BuildContainerConfig(containertypes.Config{Env: []string{`constraint:name==/abcdef/`}}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), nodes, true)
	assert.Error(t, err)
	assert.Len(t, result, 0)

	// Match with case-insensitive
	result, err = f.Filter(cluster.BuildContainerConfig(containertypes.Config{Env: []string{`constraint:name==/(?i)abcdef/`}}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), nodes, true)
	assert.NoError(t, err)
	assert.Len(t, result, 1)
	assert.Equal(t, result[0], nodes[3])
	assert.Equal(t, result[0].Labels["name"], "aBcDeF")

	// Test ! filter combined with case insensitive
	result, err = f.Filter(cluster.BuildContainerConfig(containertypes.Config{Env: []string{`constraint:name!=/(?i)abc*/`}}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), nodes, true)
	assert.NoError(t, err)
	assert.Len(t, result, 3)
}
Пример #4
0
func TestConstraintNotExpr(t *testing.T) {
	var (
		f      = ConstraintFilter{}
		nodes  = testFixtures()
		result []*node.Node
		err    error
	)

	// Check not (!) expression
	result, err = f.Filter(cluster.BuildContainerConfig(containertypes.Config{Env: []string{"constraint:name!=node0"}}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), nodes, true)
	assert.NoError(t, err)
	assert.Len(t, result, 3)

	// Check not does_not_exist. All should be found
	result, err = f.Filter(cluster.BuildContainerConfig(containertypes.Config{Env: []string{"constraint:name!=does_not_exist"}}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), nodes, true)
	assert.NoError(t, err)
	assert.Len(t, result, 4)

	// Check name must not start with n
	result, err = f.Filter(cluster.BuildContainerConfig(containertypes.Config{Env: []string{"constraint:name!=n*"}}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), nodes, true)
	assert.NoError(t, err)
	assert.Len(t, result, 1)

	// Check not with globber pattern
	result, err = f.Filter(cluster.BuildContainerConfig(containertypes.Config{Env: []string{"constraint:region!=us*"}}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), nodes, true)
	assert.NoError(t, err)
	assert.Len(t, result, 2)
}
Пример #5
0
func TestAffinityFilterLabels(t *testing.T) {
	var (
		f     = AffinityFilter{}
		nodes = []*node.Node{
			{
				ID:   "node-0-id",
				Name: "node-0-name",
				Addr: "node-0",
				Containers: []*cluster.Container{
					{Container: dockerclient.Container{
						Id:    "container-n0-id",
						Names: []string{"/container-n0-name"},
					}},
				},
				Images: []*cluster.Image{{Image: types.Image{
					ID:       "image-0-id",
					RepoTags: []string{"image-0:tag0"},
				}}},
			},
			{
				ID:   "node-1-id",
				Name: "node-1-name",
				Addr: "node-1",
				Containers: []*cluster.Container{
					{Container: dockerclient.Container{
						Id:    "container-n1-id",
						Names: []string{"/container-n1-name"},
					}},
				},
				Images: []*cluster.Image{{Image: types.Image{
					ID:       "image-1-id",
					RepoTags: []string{"image-1:tag1"},
				}}},
			},
		}
		result []*node.Node
		err    error
	)

	result, err = f.Filter(cluster.BuildContainerConfig(dockerclient.ContainerConfig{Env: []string{"affinity:image==image-1"}}), nodes, true)
	assert.NoError(t, err)
	assert.Len(t, result, 1)
	assert.Equal(t, result[0], nodes[1])

	result, err = f.Filter(cluster.BuildContainerConfig(dockerclient.ContainerConfig{Env: []string{"affinity:image!=image-1"}}), nodes, true)
	assert.NoError(t, err)
	assert.Len(t, result, 1)
	assert.Equal(t, result[0], nodes[0])

	result, err = f.Filter(cluster.BuildContainerConfig(dockerclient.ContainerConfig{Labels: map[string]string{"com.docker.swarm.affinities": "[\"image==image-1\"]"}}), nodes, true)
	assert.NoError(t, err)
	assert.Len(t, result, 1)
	assert.Equal(t, result[0], nodes[1])

	result, err = f.Filter(cluster.BuildContainerConfig(dockerclient.ContainerConfig{Labels: map[string]string{"com.docker.swarm.affinities": "[\"image!=image-1\"]"}}), nodes, true)
	assert.NoError(t, err)
	assert.Len(t, result, 1)
	assert.Equal(t, result[0], nodes[0])
}
Пример #6
0
func TestContainerLookup(t *testing.T) {
	c := &Cluster{
		engines: make(map[string]*cluster.Engine),
	}
	container1 := &cluster.Container{
		Container: types.Container{
			ID:    "container1-id",
			Names: []string{"/container1-name1", "/container1-name2"},
		},
		Config: cluster.BuildContainerConfig(containertypes.Config{
			Labels: map[string]string{
				"com.docker.swarm.id": "swarm1-id",
			},
		}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}),
	}

	container2 := &cluster.Container{
		Container: types.Container{
			ID:    "container2-id",
			Names: []string{"/con"},
		},
		Config: cluster.BuildContainerConfig(containertypes.Config{
			Labels: map[string]string{
				"com.docker.swarm.id": "swarm2-id",
			},
		}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}),
	}

	n := createEngine(t, "test-engine", container1, container2)
	c.engines[n.ID] = n

	assert.Equal(t, len(c.Containers()), 2)

	// Invalid lookup
	assert.Nil(t, c.Container("invalid-id"))
	assert.Nil(t, c.Container(""))
	// Container ID lookup.
	assert.NotNil(t, c.Container("container1-id"))
	// Container ID prefix lookup.
	assert.NotNil(t, c.Container("container1-"))
	assert.Nil(t, c.Container("container"))
	// Container name lookup.
	assert.NotNil(t, c.Container("container1-name1"))
	assert.NotNil(t, c.Container("container1-name2"))
	// Container engine/name matching.
	assert.NotNil(t, c.Container("test-engine/container1-name1"))
	assert.NotNil(t, c.Container("test-engine/container1-name2"))
	// Swarm ID lookup.
	assert.NotNil(t, c.Container("swarm1-id"))
	// Swarm ID prefix lookup.
	assert.NotNil(t, c.Container("swarm1-"))
	assert.Nil(t, c.Container("swarm"))
	// Match name before ID prefix
	cc := c.Container("con")
	assert.NotNil(t, cc)
	assert.Equal(t, cc.ID, "container2-id")
}
Пример #7
0
func TestConstrainteFilter(t *testing.T) {
	var (
		f      = ConstraintFilter{}
		nodes  = testFixtures()
		result []*node.Node
		err    error
	)

	// Without constraints we should get the unfiltered list of nodes back.
	result, err = f.Filter(&cluster.ContainerConfig{}, nodes, true)
	assert.NoError(t, err)
	assert.Equal(t, result, nodes)

	// Set a constraint that cannot be fulfilled and expect an error back.
	result, err = f.Filter(cluster.BuildContainerConfig(containertypes.Config{Env: []string{"constraint:does_not_exist==true"}}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), nodes, true)
	assert.Error(t, err)

	// Set a contraint that can only be filled by a single node.
	result, err = f.Filter(cluster.BuildContainerConfig(containertypes.Config{Env: []string{"constraint:name==node1"}}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), nodes, true)
	assert.NoError(t, err)
	assert.Len(t, result, 1)
	assert.Equal(t, result[0], nodes[1])

	// This constraint can only be fulfilled by a subset of nodes.
	result, err = f.Filter(cluster.BuildContainerConfig(containertypes.Config{Env: []string{"constraint:group==1"}}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), nodes, true)
	assert.NoError(t, err)
	assert.Len(t, result, 2)
	assert.NotContains(t, result, nodes[2])

	// Validate node pinning by id.
	result, err = f.Filter(cluster.BuildContainerConfig(containertypes.Config{Env: []string{"constraint:node==node-2-id"}}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), nodes, true)
	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(cluster.BuildContainerConfig(containertypes.Config{Env: []string{"constraint:node==node-1-name"}}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), nodes, true)
	assert.NoError(t, err)
	assert.Len(t, result, 1)
	assert.Equal(t, result[0], nodes[1])

	// Make sure constraints are evaluated as logical ANDs.
	result, err = f.Filter(cluster.BuildContainerConfig(containertypes.Config{Env: []string{"constraint:name==node0", "constraint:group==1"}}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), nodes, true)
	assert.NoError(t, err)
	assert.Len(t, result, 1)
	assert.Equal(t, result[0], nodes[0])

	// Check matching
	result, err = f.Filter(cluster.BuildContainerConfig(containertypes.Config{Env: []string{"constraint:region==us"}}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), nodes, true)
	assert.Error(t, err)
	assert.Len(t, result, 0)

	result, err = f.Filter(cluster.BuildContainerConfig(containertypes.Config{Env: []string{"constraint:region==us*"}}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), nodes, true)
	assert.NoError(t, err)
	assert.Len(t, result, 2)

	result, err = f.Filter(cluster.BuildContainerConfig(containertypes.Config{Env: []string{"constraint:region==*us*"}}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), nodes, true)
	assert.NoError(t, err)
	assert.Len(t, result, 2)
}
Пример #8
0
func TestContainerLookup(t *testing.T) {
	c := &Cluster{
		slaves: make(map[string]*slave),
	}
	container1 := &cluster.Container{
		Container: dockerclient.Container{
			Id:    "container1-id",
			Names: []string{"/container1-name1", "/container1-name2"},
		},
		Config: cluster.BuildContainerConfig(dockerclient.ContainerConfig{
			Labels: map[string]string{
				"com.docker.swarm.id": "swarm1-id",
			},
		}),
	}

	container2 := &cluster.Container{
		Container: dockerclient.Container{
			Id:    "container2-id",
			Names: []string{"/con"},
		},
		Config: cluster.BuildContainerConfig(dockerclient.ContainerConfig{
			Labels: map[string]string{
				"com.docker.swarm.id": "swarm2-id",
			},
		}),
	}

	s := createSlave(t, "test-engine", container1, container2)
	c.slaves[s.id] = s

	// Invalid lookup
	assert.Nil(t, c.Container("invalid-id"))
	assert.Nil(t, c.Container(""))
	// Container ID lookup.
	assert.NotNil(t, c.Container("container1-id"))
	// Container ID prefix lookup.
	assert.NotNil(t, c.Container("container1-"))
	assert.Nil(t, c.Container("container"))
	// Container name lookup.
	assert.NotNil(t, c.Container("container1-name1"))
	assert.NotNil(t, c.Container("container1-name2"))
	// Container engine/name matching.
	assert.NotNil(t, c.Container("test-engine/container1-name1"))
	assert.NotNil(t, c.Container("test-engine/container1-name2"))
	// Swarm ID lookup.
	assert.NotNil(t, c.Container("swarm1-id"))
	// Swarm ID prefix lookup.
	assert.NotNil(t, c.Container("swarm1-"))
	assert.Nil(t, c.Container("swarm"))
	// Match name before ID prefix
	cc := c.Container("con")
	assert.NotNil(t, cc)
	assert.Equal(t, cc.Id, "container2-id")
}
Пример #9
0
func TestAdd(t *testing.T) {
	q := NewTasks(&testLauncher{count: 1})

	task1, _ := NewTask(cluster.BuildContainerConfig(containerConfig, hostConfig, networkingConfig), "name1", 5*time.Second)

	task2, _ := NewTask(cluster.BuildContainerConfig(containerConfig, hostConfig, networkingConfig), "name2", 5*time.Second)
	q.Add(task1)
	assert.Equal(t, len(q.Tasks), 0)

	q.Add(task2)
	assert.Equal(t, len(q.Tasks), 1)

}
Пример #10
0
func TestBuild(t *testing.T) {
	task, err := NewTask(cluster.BuildContainerConfig(containerConfig, hostConfig, networkingConfig), name, 5*time.Second)
	assert.NoError(t, err)

	task.Build("slave-id", nil)

	assert.Equal(t, task.Container.GetType(), mesosproto.ContainerInfo_DOCKER)
	assert.Equal(t, task.Container.Docker.GetImage(), "test-image")
	assert.Equal(t, task.Container.Docker.GetNetwork(), mesosproto.ContainerInfo_DockerInfo_BRIDGE)

	assert.Equal(t, len(task.Resources), 2)
	assert.Equal(t, task.Resources[0], mesosutil.NewScalarResource("cpus", 42.0))
	assert.Equal(t, task.Resources[1], mesosutil.NewScalarResource("mem", 2))

	assert.Equal(t, task.Command.GetValue(), "ls")
	assert.Equal(t, task.Command.GetArguments(), []string{"foo", "bar"})

	parameters := []string{task.Container.Docker.GetParameters()[0].GetValue(), task.Container.Docker.GetParameters()[1].GetValue()}
	sort.Strings(parameters)

	assert.Equal(t, len(parameters), 2)
	assert.Equal(t, parameters[0], "com.docker.swarm.mesos.name="+name)
	assert.Equal(t, parameters[1], "com.docker.swarm.mesos.task="+*task.TaskId.Value)

	assert.Equal(t, task.SlaveId.GetValue(), "slave-id")
}
func TestUnsupportedOperators(t *testing.T) {
	var (
		f      = ConstraintFilter{}
		nodes  = testFixtures()
		result []*node.Node
		err    error
	)

	result, err = f.Filter(cluster.BuildContainerConfig(dockerclient.ContainerConfig{Env: []string{"constraint:name=node0"}}), nodes)
	assert.Error(t, err)
	assert.Len(t, result, 0)

	result, err = f.Filter(cluster.BuildContainerConfig(dockerclient.ContainerConfig{Env: []string{"constraint:name=!node0"}}), nodes)
	assert.Error(t, err)
	assert.Len(t, result, 0)
}
Пример #12
0
func TestUnsupportedOperators(t *testing.T) {
	var (
		f      = ConstraintFilter{}
		nodes  = testFixtures()
		result []*node.Node
		err    error
	)

	result, err = f.Filter(cluster.BuildContainerConfig(containertypes.Config{Env: []string{"constraint:name=node0"}}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), nodes, true)
	assert.Error(t, err)
	assert.Len(t, result, 0)

	result, err = f.Filter(cluster.BuildContainerConfig(containertypes.Config{Env: []string{"constraint:name=!node0"}}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), nodes, true)
	assert.Error(t, err)
	assert.Len(t, result, 0)
}
Пример #13
0
// CreateNetwork creates a network in the cluster
func (c *Cluster) CreateNetwork(request *dockerclient.NetworkCreate) (response *dockerclient.NetworkCreateResponse, err error) {
	var (
		parts  = strings.SplitN(request.Name, "/", 2)
		config = &cluster.ContainerConfig{}
	)

	if len(parts) == 2 {
		// a node was specified, create the container only on this node
		request.Name = parts[1]
		config = cluster.BuildContainerConfig(dockerclient.ContainerConfig{Env: []string{"constraint:node==" + parts[0]}})
	}

	nodes, err := c.scheduler.SelectNodesForContainer(c.listNodes(), config)
	if err != nil {
		return nil, err
	}
	if nodes != nil {
		resp, err := c.engines[nodes[0].ID].CreateNetwork(request)
		if err == nil {
			if network := c.engines[nodes[0].ID].Networks().Get(resp.ID); network != nil && network.Scope == "global" {
				for id, engine := range c.engines {
					if id != nodes[0].ID {
						engine.AddNetwork(network)
					}
				}
			}
		}
		return resp, err
	}
	return nil, nil
}
Пример #14
0
// BuildImage build an image
func (c *Cluster) BuildImage(buildImage *dockerclient.BuildImage, out io.Writer) error {
	c.scheduler.Lock()

	// get an engine
	config := cluster.BuildContainerConfig(dockerclient.ContainerConfig{
		CpuShares: buildImage.CpuShares,
		Memory:    buildImage.Memory,
		Env:       convertMapToKVStrings(buildImage.BuildArgs),
	})
	buildImage.BuildArgs = convertKVStringsToMap(config.Env)
	nodes, err := c.scheduler.SelectNodesForContainer(c.listNodes(), config)
	c.scheduler.Unlock()
	if err != nil {
		return err
	}
	n := nodes[0]

	reader, err := c.engines[n.ID].BuildImage(buildImage)
	if err != nil {
		return err
	}

	if _, err := io.Copy(out, reader); err != nil {
		return err
	}

	c.engines[n.ID].RefreshImages()
	return nil
}
Пример #15
0
// CreateNetwork creates a network in the cluster
func (c *Cluster) CreateNetwork(request *dockerclient.NetworkCreate) (*dockerclient.NetworkCreateResponse, error) {
	var (
		parts  = strings.SplitN(request.Name, "/", 2)
		config = &cluster.ContainerConfig{}
	)

	if len(parts) == 2 {
		// a node was specified, create the container only on this node
		request.Name = parts[1]
		config = cluster.BuildContainerConfig(dockerclient.ContainerConfig{Env: []string{"constraint:node==" + parts[0]}})
	}

	c.scheduler.Lock()
	nodes, err := c.scheduler.SelectNodesForContainer(c.listNodes(), config)
	c.scheduler.Unlock()
	if err != nil {
		return nil, err
	}
	if nodes == nil {
		return nil, errors.New("cannot find node to create network")
	}
	n := nodes[0]
	s, ok := c.agents[n.ID]
	if !ok {
		return nil, fmt.Errorf("Unable to create network on agent %q", n.ID)
	}
	resp, err := s.engine.CreateNetwork(request)
	c.refreshNetworks()
	return resp, err
}
Пример #16
0
// POST /containers/create
func postContainersCreate(c *context, w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	var (
		config dockerclient.ContainerConfig
		name   = r.Form.Get("name")
	)

	if err := json.NewDecoder(r.Body).Decode(&config); err != nil {
		httpError(w, err.Error(), http.StatusBadRequest)
		return
	}

	container, err := c.cluster.CreateContainer(cluster.BuildContainerConfig(config), name)
	if err != nil {
		if strings.HasPrefix(err.Error(), "Conflict") {
			httpError(w, err.Error(), http.StatusConflict)
		} else {
			httpError(w, err.Error(), http.StatusInternalServerError)
		}
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusCreated)
	fmt.Fprintf(w, "{%q:%q}", "Id", container.Id)
	return
}
Пример #17
0
// BuildImage builds an image
func (c *Cluster) BuildImage(buildContext io.Reader, buildImage *types.ImageBuildOptions, out io.Writer) error {
	c.scheduler.Lock()

	// get an engine
	config := cluster.BuildContainerConfig(containertypes.Config{Env: convertMapToKVStrings(buildImage.BuildArgs)},
		containertypes.HostConfig{Resources: containertypes.Resources{CPUShares: buildImage.CPUShares, Memory: buildImage.Memory}},
		networktypes.NetworkingConfig{})
	buildImage.BuildArgs = convertKVStringsToMap(config.Env)
	nodes, err := c.scheduler.SelectNodesForContainer(c.listNodes(), config)
	c.scheduler.Unlock()
	if err != nil {
		return err
	}
	n := nodes[0]

	reader, err := c.engines[n.ID].BuildImage(buildContext, buildImage)
	if err != nil {
		return err
	}

	if _, err := io.Copy(out, reader); err != nil {
		return err
	}

	c.engines[n.ID].RefreshImages()
	return nil
}
Пример #18
0
func TestBuild(t *testing.T) {
	task, err := newTask(nil, cluster.BuildContainerConfig(dockerclient.ContainerConfig{
		Image:     "test-image",
		CpuShares: 42,
		Memory:    2097152,
		Cmd:       []string{"ls", "foo", "bar"},
	}), name)
	assert.NoError(t, err)

	task.build("slave-id", nil)

	assert.Equal(t, task.Container.GetType(), mesosproto.ContainerInfo_DOCKER)
	assert.Equal(t, task.Container.Docker.GetImage(), "test-image")
	assert.Equal(t, task.Container.Docker.GetNetwork(), mesosproto.ContainerInfo_DockerInfo_BRIDGE)

	assert.Equal(t, len(task.Resources), 2)
	assert.Equal(t, task.Resources[0], mesosutil.NewScalarResource("cpus", 42.0))
	assert.Equal(t, task.Resources[1], mesosutil.NewScalarResource("mem", 2))

	assert.Equal(t, task.Command.GetValue(), "ls")
	assert.Equal(t, task.Command.GetArguments(), []string{"foo", "bar"})

	parameters := []string{task.Container.Docker.GetParameters()[0].GetValue(), task.Container.Docker.GetParameters()[1].GetValue()}
	sort.Strings(parameters)

	assert.Equal(t, len(parameters), 2)
	assert.Equal(t, parameters[0], "com.docker.swarm.mesos.name="+name)
	assert.Equal(t, parameters[1], "com.docker.swarm.mesos.task="+*task.TaskId.Value)

	assert.Equal(t, task.SlaveId.GetValue(), "slave-id")
}
Пример #19
0
// POST /containers/create
func postContainersCreate(c *context, w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	var (
		defaultMemorySwappiness = int64(-1)
		name                    = r.Form.Get("name")
		config                  = cluster.ContainerConfig{
			HostConfig: containertypes.HostConfig{
				Resources: containertypes.Resources{
					MemorySwappiness: &(defaultMemorySwappiness),
				},
			},
		}
	)

	oldconfig := cluster.OldContainerConfig{
		ContainerConfig: config,
		Memory:          0,
		MemorySwap:      0,
		CPUShares:       0,
		CPUSet:          "",
	}

	if err := json.NewDecoder(r.Body).Decode(&oldconfig); err != nil {
		httpError(w, err.Error(), http.StatusBadRequest)
		return
	}

	// make sure HostConfig fields are consolidated before creating container
	cluster.ConsolidateResourceFields(&oldconfig)
	config = oldconfig.ContainerConfig

	// Pass auth information along if present
	var authConfig *apitypes.AuthConfig
	buf, err := base64.URLEncoding.DecodeString(r.Header.Get("X-Registry-Auth"))
	if err == nil {
		authConfig = &apitypes.AuthConfig{}
		json.Unmarshal(buf, authConfig)
	}
	containerConfig := cluster.BuildContainerConfig(config.Config, config.HostConfig, config.NetworkingConfig)
	if err := containerConfig.Validate(); err != nil {
		httpError(w, err.Error(), http.StatusInternalServerError)
		return
	}

	container, err := c.cluster.CreateContainer(containerConfig, name, authConfig)
	if err != nil {
		if strings.HasPrefix(err.Error(), "Conflict") {
			httpError(w, err.Error(), http.StatusConflict)
		} else {
			httpError(w, err.Error(), http.StatusInternalServerError)
		}
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusCreated)
	fmt.Fprintf(w, "{%q:%q}", "Id", container.ID)
	return
}
Пример #20
0
func TestApplyFilters(t *testing.T) {
	var (
		nodes = []*node.Node{
			{
				ID:   "node-0-id",
				Name: "node-0-name",
				Addr: "node-0",
				Containers: []*cluster.Container{
					{Container: dockerclient.Container{
						Id:    "container-n0-0-id",
						Names: []string{"/container-n0-0-name"},
					}},
					{Container: dockerclient.Container{
						Id:    "container-n0-1-id",
						Names: []string{"/container-n0-1-name"},
					}},
				},
				Images: []*cluster.Image{{Image: dockerclient.Image{
					Id:       "image-0-id",
					RepoTags: []string{"image-0:tag1", "image-0:tag2"},
				}}},
				HealthIndicator: 100,
			},
			{
				ID:   "node-1-id",
				Name: "node-1-name",
				Addr: "node-1",
				Containers: []*cluster.Container{
					{
						Container: dockerclient.Container{
							Id:    "container-n1-0-id",
							Names: []string{"/container-n1-0-name"},
						},
					},
					{
						Container: dockerclient.Container{
							Id:    "container-n1-1-id",
							Names: []string{"/container-n1-1-name"},
						},
					},
				},
				Images: []*cluster.Image{{Image: dockerclient.Image{
					Id:       "image-1-id",
					RepoTags: []string{"image-1:tag1", "image-0:tag3", "image-1:tag2"},
				}}},
				HealthIndicator: 0,
			},
		}
		result []*node.Node
		err    error
	)

	//Tests for Soft affinity, it should be considered as last
	config := cluster.BuildContainerConfig(dockerclient.ContainerConfig{Env: []string{"affinity:image==~image-0:tag3"}})
	result, err = ApplyFilters(filters, config, nodes)
	assert.NoError(t, err)
	assert.Len(t, result, 1)

}
Пример #21
0
func TestNewTask(t *testing.T) {
	task, err := NewTask(cluster.BuildContainerConfig(containertypes.Config{}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), name, 5*time.Second)
	assert.NoError(t, err)

	assert.Equal(t, *task.Name, name)
	assert.True(t, strings.HasPrefix(task.TaskId.GetValue(), name+"."))
	assert.Equal(t, len(task.TaskId.GetValue()), len(name)+1+12) //<name>+.+<shortId>
}
Пример #22
0
func TestNewTask(t *testing.T) {
	task, err := newTask(nil, cluster.BuildContainerConfig(dockerclient.ContainerConfig{}), name)
	assert.NoError(t, err)

	assert.Equal(t, *task.Name, name)
	assert.True(t, strings.HasPrefix(task.TaskId.GetValue(), name+"."))
	assert.Equal(t, len(task.TaskId.GetValue()), len(name)+1+12) //<name>+.+<shortId>
}
Пример #23
0
func createConfig(memory int64, cpus int64) *cluster.ContainerConfig {
	return cluster.BuildContainerConfig(containertypes.Config{}, containertypes.HostConfig{
		Resources: containertypes.Resources{
			Memory:    memory * 1024 * 1024 * 1024,
			CPUShares: cpus,
		},
	}, networktypes.NetworkingConfig{})
}
Пример #24
0
// CreateVolume creates a volume in the cluster
func (c *Cluster) CreateVolume(request *dockerclient.VolumeCreateRequest) (*cluster.Volume, error) {
	var (
		wg     sync.WaitGroup
		volume *cluster.Volume
		err    error
		parts  = strings.SplitN(request.Name, "/", 2)
		node   = ""
	)

	if request.Name == "" {
		request.Name = stringid.GenerateRandomID()
	} else if len(parts) == 2 {
		node = parts[0]
		request.Name = parts[1]
	}
	if node == "" {
		c.RLock()
		for _, e := range c.engines {
			wg.Add(1)

			go func(engine *cluster.Engine) {
				defer wg.Done()

				v, er := engine.CreateVolume(request)
				if v != nil {
					volume = v
					err = nil
				}
				if er != nil && volume == nil {
					err = er
				}
			}(e)
		}
		c.RUnlock()

		wg.Wait()
	} else {
		config := cluster.BuildContainerConfig(dockerclient.ContainerConfig{Env: []string{"constraint:node==" + parts[0]}})
		nodes, err := c.scheduler.SelectNodesForContainer(c.listNodes(), config)
		if err != nil {
			return nil, err
		}
		if nodes != nil {
			v, er := c.engines[nodes[0].ID].CreateVolume(request)
			if v != nil {
				volume = v
				err = nil
			}
			if er != nil && volume == nil {
				err = er
			}
		}
	}

	return volume, err
}
Пример #25
0
func TestSendGetStatus(t *testing.T) {
	task, err := newTask(nil, cluster.BuildContainerConfig(dockerclient.ContainerConfig{}), "")
	assert.NoError(t, err)

	status := mesosutil.NewTaskStatus(nil, mesosproto.TaskState_TASK_RUNNING)

	go func() { task.sendStatus(status) }()
	s := task.getStatus()

	assert.Equal(t, s, status)
}
Пример #26
0
func TestSendGetStatus(t *testing.T) {
	task, err := NewTask(cluster.BuildContainerConfig(containertypes.Config{}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), "", 5*time.Second)
	assert.NoError(t, err)

	status := mesosutil.NewTaskStatus(nil, mesosproto.TaskState_TASK_RUNNING)

	go func() { task.SendStatus(status) }()
	s := task.GetStatus()

	assert.Equal(t, s, status)
}
Пример #27
0
func TestRemoveTask(t *testing.T) {
	s := newAgent("SID", nil)

	assert.Empty(t, s.tasks)

	t1, err := newTask(nil, cluster.BuildContainerConfig(dockerclient.ContainerConfig{}), "task1")
	assert.NoError(t, err)
	s.addTask(t1)

	t2, err := newTask(nil, cluster.BuildContainerConfig(dockerclient.ContainerConfig{}), "task1")
	assert.NoError(t, err)
	s.addTask(t2)
	assert.Equal(t, len(s.tasks), 2)
	assert.Equal(t, len(s.getTasks()), 2)

	assert.True(t, s.removeTask(t1.TaskId.GetValue()))
	assert.Equal(t, len(s.tasks), 1)
	assert.Equal(t, len(s.getTasks()), 1)

	assert.False(t, s.removeTask(t1.TaskId.GetValue()))
}
Пример #28
0
func TestRemoveTask(t *testing.T) {
	s := newAgent("SID", nil)

	assert.Empty(t, s.tasks)

	t1, err := task.NewTask(cluster.BuildContainerConfig(containertypes.Config{}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), "task1", 5*time.Second)
	assert.NoError(t, err)
	s.addTask(t1)

	t2, err := task.NewTask(cluster.BuildContainerConfig(containertypes.Config{}, containertypes.HostConfig{}, networktypes.NetworkingConfig{}), "task1", 5*time.Second)
	assert.NoError(t, err)
	s.addTask(t2)
	assert.Equal(t, len(s.tasks), 2)
	assert.Equal(t, len(s.getTasks()), 2)

	assert.True(t, s.removeTask(t1.TaskId.GetValue()))
	assert.Equal(t, len(s.tasks), 1)
	assert.Equal(t, len(s.getTasks()), 1)

	assert.False(t, s.removeTask(t1.TaskId.GetValue()))
}
Пример #29
0
func TestAddTask(t *testing.T) {
	s := newAgent("SID", nil)

	assert.Empty(t, s.tasks)
	assert.True(t, s.empty())

	t1, err := task.NewTask(cluster.BuildContainerConfig(dockerclient.ContainerConfig{}), "task1", 5*time.Second)
	assert.NoError(t, err)
	s.addTask(t1)

	t2, err := task.NewTask(cluster.BuildContainerConfig(dockerclient.ContainerConfig{}), "task1", 5*time.Second)
	assert.NoError(t, err)
	s.addTask(t2)
	assert.Equal(t, len(s.tasks), 2)
	assert.Equal(t, len(s.getTasks()), 2)
	assert.False(t, s.empty())

	s.addTask(t1)
	assert.Equal(t, len(s.tasks), 2)
	assert.Equal(t, len(s.getTasks()), 2)
}
Пример #30
0
func TestAdd(t *testing.T) {
	q := NewTasks(&testLauncher{count: 1})

	task1, _ := NewTask(cluster.BuildContainerConfig(dockerclient.ContainerConfig{
		Image:     "test-image",
		CpuShares: 42,
		Memory:    2097152,
		Cmd:       []string{"ls", "foo", "bar"},
	}), "name1", 5*time.Second)

	task2, _ := NewTask(cluster.BuildContainerConfig(dockerclient.ContainerConfig{
		Image:     "test-image",
		CpuShares: 42,
		Memory:    2097152,
		Cmd:       []string{"ls", "foo", "bar"},
	}), "name2", 5*time.Second)
	q.Add(task1)
	assert.Equal(t, len(q.Tasks), 0)

	q.Add(task2)
	assert.Equal(t, len(q.Tasks), 1)

}