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) }
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) }
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) }
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) }
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]) }
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") }
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) }
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") }
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) }
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) }
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) }
// 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 }
// 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 }
// 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 }
// 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 }
// 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 }
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") }
// 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 }
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) }
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> }
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> }
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{}) }
// 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 }
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) }
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) }
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())) }
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())) }
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) }
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) }