Example #1
0
func (s *S) TestNodeContainerDelete(c *check.C) {
	err := nodecontainer.AddNewContainer("", &nodecontainer.NodeContainerConfig{
		Name: "c1",
		Config: docker.Config{
			Image: "img1",
			Env:   []string{"A=1"},
		},
	})
	c.Assert(err, check.IsNil)
	err = nodecontainer.AddNewContainer("p1", &nodecontainer.NodeContainerConfig{
		Name: "c1",
		Config: docker.Config{
			Env: []string{"A=2"},
		},
	})
	c.Assert(err, check.IsNil)
	request, err := http.NewRequest("DELETE", "/1.2/nodecontainers/c1", nil)
	c.Assert(err, check.IsNil)
	request.Header.Set("Authorization", "bearer "+s.token.GetValue())
	recorder := httptest.NewRecorder()
	server := RunServer(true)
	server.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusOK)
	all, err := nodecontainer.AllNodeContainers()
	c.Assert(err, check.IsNil)
	c.Assert(all, check.DeepEquals, []nodecontainer.NodeContainerConfigGroup{
		{Name: "c1", ConfigPools: map[string]nodecontainer.NodeContainerConfig{
			"p1": {Name: "c1", Config: docker.Config{Env: []string{"A=2"}}},
		}},
	})
	c.Assert(eventtest.EventDesc{
		Target: event.Target{Type: event.TargetTypeNodeContainer, Value: "c1"},
		Owner:  s.token.GetUserName(),
		Kind:   "nodecontainer.delete",
		StartCustomData: []map[string]interface{}{
			{"name": ":name", "value": "c1"},
		},
	}, eventtest.HasEvent)
	s.provisioner.UpgradeNodeContainer("c1", "p1", ioutil.Discard)
	request, err = http.NewRequest("DELETE", "/1.2/nodecontainers/c1?pool=p1", nil)
	c.Assert(err, check.IsNil)
	request.Header.Set("Authorization", "bearer "+s.token.GetValue())
	recorder = httptest.NewRecorder()
	server.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusOK)
	all, err = nodecontainer.AllNodeContainers()
	c.Assert(err, check.IsNil)
	c.Assert(all, check.DeepEquals, []nodecontainer.NodeContainerConfigGroup{})
	c.Assert(s.provisioner.HasNodeContainer("c1", "p1"), check.Equals, true)
}
Example #2
0
func (s *S) TestNodeContainerUpgradeNotFound(c *check.C) {
	err := nodecontainer.AddNewContainer("otherpool", &nodecontainer.NodeContainerConfig{
		Name:        "c2",
		PinnedImage: "tsuru/c1@sha256:abcef384829283eff",
		Config: docker.Config{
			Image: "img1",
			Env:   []string{"A=1"},
		},
	})
	c.Assert(err, check.IsNil)
	tt := []struct {
		name string
		pool string
	}{
		{"c1", ""},
		{"c2", "theonepool"},
	}
	server := RunServer(true)
	for _, t := range tt {
		recorder := httptest.NewRecorder()
		form := url.Values{}
		if t.pool != "" {
			form.Set("pool", t.pool)
		}
		request, errReq := http.NewRequest("POST", "/docker/nodecontainers/"+t.name+"/upgrade", strings.NewReader(form.Encode()))
		c.Assert(errReq, check.IsNil)
		request.Header.Set("Authorization", "bearer "+s.token.GetValue())
		request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
		server.ServeHTTP(recorder, request)
		c.Assert(recorder.Code, check.Equals, http.StatusNotFound)
	}
}
Example #3
0
func (s *S) TestNodeContainerUpgrade(c *check.C) {
	err := nodecontainer.AddNewContainer("", &nodecontainer.NodeContainerConfig{
		Name:        "c1",
		PinnedImage: "tsuru/c1@sha256:abcef384829283eff",
		Config: docker.Config{
			Image: "img1",
			Env:   []string{"A=1"},
		},
	})
	c.Assert(err, check.IsNil)
	recorder := httptest.NewRecorder()
	request, err := http.NewRequest("POST", "/docker/nodecontainers/c1/upgrade", nil)
	c.Assert(err, check.IsNil)
	request.Header.Set("Authorization", "bearer "+s.token.GetValue())
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	server := RunServer(true)
	server.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusOK)
	c.Assert(recorder.Header().Get("Content-Type"), check.Equals, "application/x-json-stream")
	all, err := nodecontainer.AllNodeContainers()
	c.Assert(err, check.IsNil)
	c.Assert(all, check.DeepEquals, []nodecontainer.NodeContainerConfigGroup{
		{Name: "c1", ConfigPools: map[string]nodecontainer.NodeContainerConfig{
			"": {Name: "c1", Config: docker.Config{Env: []string{"A=1"}, Image: "img1"}},
		}},
	})
	c.Assert(eventtest.EventDesc{
		Target: event.Target{Type: event.TargetTypeNodeContainer, Value: "c1"},
		Owner:  s.token.GetUserName(),
		Kind:   "nodecontainer.update.upgrade",
		StartCustomData: []map[string]interface{}{
			{"name": ":name", "value": "c1"},
		},
	}, eventtest.HasEvent)
}
Example #4
0
func (s *S) TestNodeContainerUpdateLimited(c *check.C) {
	err := nodecontainer.AddNewContainer("p1", &nodecontainer.NodeContainerConfig{Name: "c1", Config: docker.Config{Image: "img1"}})
	c.Assert(err, check.IsNil)
	t := userWithPermission(c, permission.Permission{
		Scheme:  permission.PermNodecontainerUpdate,
		Context: permission.Context(permission.CtxPool, "p1"),
	})
	values, err := form.EncodeToValues(nodecontainer.NodeContainerConfig{Name: "c1"})
	c.Assert(err, check.IsNil)
	reader := strings.NewReader(values.Encode())
	request, err := http.NewRequest("POST", "/1.2/nodecontainers/c1", reader)
	c.Assert(err, check.IsNil)
	request.Header.Set("Authorization", "bearer "+t.GetValue())
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	recorder := httptest.NewRecorder()
	server := RunServer(true)
	server.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusForbidden)
	values.Set("pool", "p1")
	reader = strings.NewReader(values.Encode())
	request, err = http.NewRequest("POST", "/1.2/nodecontainers/c1", reader)
	c.Assert(err, check.IsNil)
	request.Header.Set("Authorization", "bearer "+t.GetValue())
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	recorder = httptest.NewRecorder()
	server.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusOK)
}
Example #5
0
func (s *S) TestEnsureContainersStartedOnlyChild(c *check.C) {
	err := nodecontainer.AddNewContainer("p1", &nodecontainer.NodeContainerConfig{
		Name: "c1",
		Config: docker.Config{
			Image: "myregistry/tsuru/bs",
		},
	})
	c.Assert(err, check.IsNil)
	p, err := dockertest.StartMultipleServersCluster()
	c.Assert(err, check.IsNil)
	defer p.Destroy()
	clust := p.Cluster()
	nodes, err := clust.Nodes()
	c.Assert(err, check.IsNil)
	c.Assert(nodes, check.HasLen, 2)
	nodes[0].Metadata["pool"] = "p1"
	_, err = p.Cluster().UpdateNode(nodes[0])
	c.Assert(err, check.IsNil)
	nodes[1].Metadata["pool"] = "p2"
	_, err = p.Cluster().UpdateNode(nodes[1])
	c.Assert(err, check.IsNil)
	buf := safe.NewBuffer(nil)
	err = ensureContainersStarted(p, buf, true, nil)
	c.Assert(err, check.IsNil)
	client, err := docker.NewClient(nodes[0].Address)
	c.Assert(err, check.IsNil)
	containers, err := client.ListContainers(docker.ListContainersOptions{All: true})
	c.Assert(err, check.IsNil)
	c.Assert(containers, check.HasLen, 1)
	client2, err := docker.NewClient(nodes[1].Address)
	c.Assert(err, check.IsNil)
	containers2, err := client2.ListContainers(docker.ListContainersOptions{All: true})
	c.Assert(err, check.IsNil)
	c.Assert(containers2, check.HasLen, 0)
}
Example #6
0
func (s *S) TestNodeContainerListLimited(c *check.C) {
	err := nodecontainer.AddNewContainer("", &nodecontainer.NodeContainerConfig{
		Name: "c1",
		Config: docker.Config{
			Image: "img1",
			Env:   []string{"A=1"},
		},
	})
	c.Assert(err, check.IsNil)
	err = nodecontainer.AddNewContainer("p1", &nodecontainer.NodeContainerConfig{
		Name: "c1",
		Config: docker.Config{
			Env: []string{"A=2"},
		},
	})
	c.Assert(err, check.IsNil)
	err = nodecontainer.AddNewContainer("p3", &nodecontainer.NodeContainerConfig{
		Name: "c1",
		Config: docker.Config{
			Env: []string{"A=3"},
		},
	})
	c.Assert(err, check.IsNil)
	t := userWithPermission(c, permission.Permission{
		Scheme:  permission.PermNodecontainerRead,
		Context: permission.Context(permission.CtxPool, "p3"),
	})
	request, err := http.NewRequest("GET", "/1.2/nodecontainers", nil)
	c.Assert(err, check.IsNil)
	request.Header.Set("Authorization", "bearer "+t.GetValue())
	recorder := httptest.NewRecorder()
	server := RunServer(true)
	server.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusOK)
	var configEntries []nodecontainer.NodeContainerConfigGroup
	json.Unmarshal(recorder.Body.Bytes(), &configEntries)
	sort.Sort(nodecontainer.NodeContainerConfigGroupSlice(configEntries))
	c.Assert(configEntries, check.DeepEquals, []nodecontainer.NodeContainerConfigGroup{
		{Name: "c1", ConfigPools: map[string]nodecontainer.NodeContainerConfig{
			"":   {Name: "c1", Config: docker.Config{Image: "img1", Env: []string{"A=1"}}},
			"p3": {Name: "c1", Config: docker.Config{Env: []string{"A=3"}}},
		}},
	})
}
Example #7
0
func (s *S) TestEnsureContainersStartedPinImgInChild(c *check.C) {
	err := nodecontainer.AddNewContainer("", &nodecontainer.NodeContainerConfig{
		Name: "c1",
		Config: docker.Config{
			Image: "myrootimg",
		},
	})
	c.Assert(err, check.IsNil)
	err = nodecontainer.AddNewContainer("p1", &nodecontainer.NodeContainerConfig{
		Name: "c1",
		Config: docker.Config{
			Image: "myregistry/tsuru/bs",
		},
	})
	c.Assert(err, check.IsNil)
	server, err := testing.NewServer("127.0.0.1:0", nil, nil)
	c.Assert(err, check.IsNil)
	defer server.Stop()
	server.CustomHandler("/images/create", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		w.WriteHeader(http.StatusOK)
		server.DefaultHandler().ServeHTTP(w, r)
		w.Write([]byte(pullOutputDigest))
	}))
	p, err := dockertest.NewFakeDockerProvisioner(server.URL())
	c.Assert(err, check.IsNil)
	defer p.Destroy()
	node, err := p.Cluster().GetNode(server.URL())
	c.Assert(err, check.IsNil)
	node.Metadata["pool"] = "p1"
	_, err = p.Cluster().UpdateNode(node)
	c.Assert(err, check.IsNil)
	buf := safe.NewBuffer(nil)
	err = ensureContainersStarted(p, buf, true, nil)
	c.Assert(err, check.IsNil)
	all, err := nodecontainer.LoadNodeContainersForPoolsMerge("c1", false)
	c.Assert(err, check.IsNil)
	c.Assert(all, check.DeepEquals, map[string]nodecontainer.NodeContainerConfig{
		"":   {Name: "c1", PinnedImage: "", Config: docker.Config{Image: "myrootimg"}},
		"p1": {Name: "c1", PinnedImage: "myregistry/tsuru/bs@" + digest, Config: docker.Config{Image: "myregistry/tsuru/bs"}},
	})
}
Example #8
0
func (s *S) TestNodeContainerInfo(c *check.C) {
	err := nodecontainer.AddNewContainer("", &nodecontainer.NodeContainerConfig{
		Name: "c1",
		Config: docker.Config{
			Image: "img1",
			Env:   []string{"A=1"},
		},
	})
	c.Assert(err, check.IsNil)
	err = nodecontainer.AddNewContainer("p1", &nodecontainer.NodeContainerConfig{
		Name: "c1",
		Config: docker.Config{
			Env: []string{"A=2"},
		},
	})
	c.Assert(err, check.IsNil)
	err = nodecontainer.AddNewContainer("", &nodecontainer.NodeContainerConfig{
		Name: "c2",
		Config: docker.Config{
			Image: "img1",
			Env:   []string{"B=1"},
		},
	})
	c.Assert(err, check.IsNil)
	request, err := http.NewRequest("GET", "/1.2/nodecontainers/c1", nil)
	c.Assert(err, check.IsNil)
	request.Header.Set("Authorization", "bearer "+s.token.GetValue())
	recorder := httptest.NewRecorder()
	server := RunServer(true)
	server.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusOK)
	var configEntries map[string]nodecontainer.NodeContainerConfig
	json.Unmarshal(recorder.Body.Bytes(), &configEntries)
	c.Assert(configEntries, check.DeepEquals, map[string]nodecontainer.NodeContainerConfig{
		"":   {Name: "c1", Config: docker.Config{Image: "img1", Env: []string{"A=1"}}},
		"p1": {Name: "c1", Config: docker.Config{Env: []string{"A=2"}}},
	})
}
Example #9
0
func (s *S) TestEnsureContainersStartedAlreadyPinned(c *check.C) {
	config.Set("docker:bs:image", "myregistry/tsuru/bs")
	_, err := nodecontainer.InitializeBS()
	c.Assert(err, check.IsNil)
	cont, err := nodecontainer.LoadNodeContainer("", nodecontainer.BsDefaultName)
	c.Assert(err, check.IsNil)
	cont.PinnedImage = "myregistry/tsuru/bs@" + digest
	err = nodecontainer.AddNewContainer("", cont)
	c.Assert(err, check.IsNil)
	server, err := testing.NewServer("127.0.0.1:0", nil, nil)
	c.Assert(err, check.IsNil)
	defer server.Stop()
	server.CustomHandler("/images/create", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		w.WriteHeader(http.StatusOK)
		server.DefaultHandler().ServeHTTP(w, r)
		w.Write([]byte(pullOutputDigest))
	}))
	p, err := dockertest.NewFakeDockerProvisioner(server.URL())
	c.Assert(err, check.IsNil)
	defer p.Destroy()
	client, err := docker.NewClient(server.URL())
	c.Assert(err, check.IsNil)
	err = client.PullImage(docker.PullImageOptions{
		Repository: "base",
	}, docker.AuthConfiguration{})
	c.Assert(err, check.IsNil)
	_, err = client.CreateContainer(docker.CreateContainerOptions{
		Name:       nodecontainer.BsDefaultName,
		Config:     &docker.Config{Image: "base"},
		HostConfig: &docker.HostConfig{},
	})
	c.Assert(err, check.IsNil)
	buf := safe.NewBuffer(nil)
	err = ensureContainersStarted(p, buf, true, nil)
	c.Assert(err, check.IsNil)
	containers, err := client.ListContainers(docker.ListContainersOptions{All: true})
	c.Assert(err, check.IsNil)
	c.Assert(containers, check.HasLen, 1)
	container, err := client.InspectContainer(containers[0].ID)
	c.Assert(err, check.IsNil)
	c.Assert(container.Name, check.Equals, nodecontainer.BsDefaultName)
	c.Assert(container.Config.Image, check.Equals, "myregistry/tsuru/bs@"+digest)
	c.Assert(container.HostConfig.RestartPolicy, check.Equals, docker.AlwaysRestart())
	c.Assert(container.State.Running, check.Equals, true)
	nodeContainer, err := nodecontainer.LoadNodeContainer("", nodecontainer.BsDefaultName)
	c.Assert(err, check.IsNil)
	c.Assert(nodeContainer.PinnedImage, check.Equals, "myregistry/tsuru/bs@"+digest)
}
Example #10
0
// title: node container create
// path: /docker/nodecontainers
// method: POST
// consume: application/x-www-form-urlencoded
// responses:
//   200: Ok
//   400: Invald data
//   401: Unauthorized
func nodeContainerCreate(w http.ResponseWriter, r *http.Request, t auth.Token) (err error) {
	err = r.ParseForm()
	if err != nil {
		return err
	}
	dec := form.NewDecoder(nil)
	dec.IgnoreUnknownKeys(true)
	dec.IgnoreCase(true)
	var config nodecontainer.NodeContainerConfig
	err = dec.DecodeValues(&config, r.Form)
	if err != nil {
		return err
	}
	poolName := r.FormValue("pool")
	var ctxs []permission.PermissionContext
	if poolName != "" {
		ctxs = append(ctxs, permission.Context(permission.CtxPool, poolName))
	}
	if !permission.Check(t, permission.PermNodecontainerCreate, ctxs...) {
		return permission.ErrUnauthorized
	}
	evt, err := event.New(&event.Opts{
		Target:     event.Target{Type: event.TargetTypeNodeContainer, Value: config.Name},
		Kind:       permission.PermNodecontainerCreate,
		Owner:      t,
		CustomData: event.FormToCustomData(r.Form),
		Allowed:    event.Allowed(permission.PermPoolReadEvents, ctxs...),
	})
	if err != nil {
		return err
	}
	defer func() { evt.Done(err) }()
	err = nodecontainer.AddNewContainer(poolName, &config)
	if err != nil {
		if _, ok := err.(nodecontainer.ValidationErr); ok {
			return &tsuruErrors.HTTP{
				Code:    http.StatusBadRequest,
				Message: err.Error(),
			}
		}
		return err
	}
	return nil
}
Example #11
0
func (s *S) TestLoadNodeContainersForPools(c *check.C) {
	err := nodecontainer.AddNewContainer("p1", &nodecontainer.NodeContainerConfig{
		Name: "c1",
		Config: docker.Config{
			Image: "myregistry/tsuru/bs",
		},
	})
	c.Assert(err, check.IsNil)
	result, err := nodecontainer.LoadNodeContainersForPools("c1")
	c.Assert(err, check.IsNil)
	c.Assert(result, check.DeepEquals, map[string]nodecontainer.NodeContainerConfig{
		"p1": {
			Name: "c1",
			Config: docker.Config{
				Image: "myregistry/tsuru/bs",
			},
		},
	})
}
Example #12
0
func (s *S) TestNodeContainerDeleteKillsRunningContainers(c *check.C) {
	err := nodecontainer.AddNewContainer("p1", &nodecontainer.NodeContainerConfig{
		Name: "c1",
		Config: docker.Config{
			Image: "img",
			Env:   []string{"A=2"},
		},
	})
	c.Assert(err, check.IsNil)
	s.provisioner.UpgradeNodeContainer("c1", "p1", ioutil.Discard)
	c.Assert(s.provisioner.HasNodeContainer("c1", "p1"), check.Equals, true)
	request, err := http.NewRequest("DELETE", "/1.2/nodecontainers/c1?pool=p1&kill=1", nil)
	c.Assert(err, check.IsNil)
	request.Header.Set("Authorization", "bearer "+s.token.GetValue())
	recorder := httptest.NewRecorder()
	server := RunServer(true)
	server.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusOK)
	c.Assert(s.provisioner.HasNodeContainer("c1", "p1"), check.Equals, false)
}
Example #13
0
func (s *S) TestNodeContainerDeleteNotFound(c *check.C) {
	err := nodecontainer.AddNewContainer("p1", &nodecontainer.NodeContainerConfig{
		Name: "c1",
		Config: docker.Config{
			Image: "img1",
			Env:   []string{"A=1"},
		},
	})
	c.Assert(err, check.IsNil)
	request, err := http.NewRequest("DELETE", "/1.2/nodecontainers/c1", nil)
	c.Assert(err, check.IsNil)
	request.Header.Set("Authorization", "bearer "+s.token.GetValue())
	recorder := httptest.NewRecorder()
	server := RunServer(true)
	server.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusNotFound)
	c.Assert(recorder.Body.String(), check.Equals, "node container \"c1\" not found for pool \"\"\n")
	request, err = http.NewRequest("DELETE", "/1.2/nodecontainers/c1?pool=p1", nil)
	c.Assert(err, check.IsNil)
	request.Header.Set("Authorization", "bearer "+s.token.GetValue())
	recorder = httptest.NewRecorder()
	server.ServeHTTP(recorder, request)
	c.Assert(recorder.Code, check.Equals, http.StatusOK)
}
Example #14
0
func (s *S) TestServiceSpecForNodeContainer(c *check.C) {
	c1 := nodecontainer.NodeContainerConfig{
		Name: "swarmbs",
		Config: docker.Config{
			Image: "bsimg",
			Env: []string{
				"A=1",
				"B=2",
			},
			Labels: map[string]string{"label1": "val1"},
		},
		HostConfig: docker.HostConfig{
			RestartPolicy: docker.AlwaysRestart(),
			Privileged:    true,
			Binds:         []string{"/xyz:/abc:ro"},
		},
	}
	err := nodecontainer.AddNewContainer("", &c1)
	c.Assert(err, check.IsNil)
	serviceSpec, err := serviceSpecForNodeContainer("swarmbs", "")
	c.Assert(err, check.IsNil)
	expectedLabels := map[string]string{
		"label1":                   "val1",
		"tsuru.nodecontainer.name": "swarmbs",
		"tsuru.nodecontainer":      "true",
		"tsuru.node.pool":          "",
		"tsuru.node.provisioner":   "swarm",
	}
	expected := &swarm.ServiceSpec{
		Annotations: swarm.Annotations{
			Name:   "node-container-swarmbs-all",
			Labels: expectedLabels,
		},
		Mode: swarm.ServiceMode{Global: &swarm.GlobalService{}},
		TaskTemplate: swarm.TaskSpec{
			ContainerSpec: swarm.ContainerSpec{
				Image:  "bsimg",
				Env:    []string{"A=1", "B=2"},
				Labels: expectedLabels,
				Mounts: []mount.Mount{
					{
						Type:     mount.TypeBind,
						Source:   "/xyz",
						Target:   "/abc",
						ReadOnly: true,
					},
				},
			},
			Placement: &swarm.Placement{Constraints: []string(nil)},
		},
	}
	c.Assert(serviceSpec, check.DeepEquals, expected)
	err = nodecontainer.AddNewContainer("p1", &c1)
	c.Assert(err, check.IsNil)
	err = nodecontainer.AddNewContainer("p2", &c1)
	c.Assert(err, check.IsNil)
	serviceSpec, err = serviceSpecForNodeContainer("swarmbs", "p1")
	c.Assert(err, check.IsNil)
	c.Assert(serviceSpec.TaskTemplate.Placement.Constraints, check.DeepEquals, []string{"node.labels.pool == p1"})
	serviceSpec, err = serviceSpecForNodeContainer("swarmbs", "")
	c.Assert(err, check.IsNil)
	constraints := sort.StringSlice(serviceSpec.TaskTemplate.Placement.Constraints)
	constraints.Sort()
	c.Assert([]string(constraints), check.DeepEquals, []string{"node.labels.pool != p1", "node.labels.pool != p2"})
}
Example #15
0
func (s *S) TestEnsureContainersStarted(c *check.C) {
	c1 := nodecontainer.NodeContainerConfig{
		Name: "bs",
		Config: docker.Config{
			Image: "bsimg",
			Env: []string{
				"A=1",
				"B=2",
			},
		},
		HostConfig: docker.HostConfig{
			RestartPolicy: docker.AlwaysRestart(),
			Privileged:    true,
			Binds:         []string{"/xyz:/abc:rw"},
		},
	}
	err := nodecontainer.AddNewContainer("", &c1)
	c.Assert(err, check.IsNil)
	c2 := c1
	c2.Name = "sysdig"
	c2.Config.Image = "sysdigimg"
	c2.Config.Env = []string{"X=Z"}
	err = nodecontainer.AddNewContainer("", &c2)
	c.Assert(err, check.IsNil)
	p, err := dockertest.StartMultipleServersCluster()
	c.Assert(err, check.IsNil)
	nodes, err := p.Cluster().Nodes()
	c.Assert(err, check.IsNil)
	for i, n := range nodes {
		n.Metadata["pool"] = fmt.Sprintf("p-%d", i)
		_, err = p.Cluster().UpdateNode(n)
		c.Assert(err, check.IsNil)
	}
	var createBodies []string
	var names []string
	var mut sync.Mutex
	server := p.Servers()[0]
	server.CustomHandler("/containers/create", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		mut.Lock()
		defer mut.Unlock()
		data, _ := ioutil.ReadAll(r.Body)
		createBodies = append(createBodies, string(data))
		names = append(names, r.URL.Query().Get("name"))
		r.Body = ioutil.NopCloser(bytes.NewBuffer(data))
		server.DefaultHandler().ServeHTTP(w, r)
	}))
	defer p.Destroy()
	buf := safe.NewBuffer(nil)
	err = ensureContainersStarted(p, buf, true, nil)
	c.Assert(err, check.IsNil)
	parts := strings.Split(buf.String(), "\n")
	c.Assert(parts, check.HasLen, 5)
	sort.Strings(parts)
	c.Assert(parts[1], check.Matches, `relaunching node container "bs" in the node http://127.0.0.1:\d+/ \[p-0\]`)
	c.Assert(parts[2], check.Matches, `relaunching node container "bs" in the node http://localhost:\d+/ \[p-1\]`)
	c.Assert(parts[3], check.Matches, `relaunching node container "sysdig" in the node http://127.0.0.1:\d+/ \[p-0\]`)
	c.Assert(parts[4], check.Matches, `relaunching node container "sysdig" in the node http://localhost:\d+/ \[p-1\]`)
	c.Assert(createBodies, check.HasLen, 2)
	c.Assert(names, check.HasLen, 2)
	sort.Strings(names)
	c.Assert(names, check.DeepEquals, []string{"bs", "sysdig"})
	sort.Strings(createBodies)
	result := make([]struct {
		docker.Config
		HostConfig docker.HostConfig
	}, 2)
	err = json.Unmarshal([]byte(createBodies[0]), &result[0])
	c.Assert(err, check.IsNil)
	err = json.Unmarshal([]byte(createBodies[1]), &result[1])
	c.Assert(err, check.IsNil)
	c.Assert(result, check.DeepEquals, []struct {
		docker.Config
		HostConfig docker.HostConfig
	}{
		{
			Config: docker.Config{Env: []string{"DOCKER_ENDPOINT=" + server.URL(), "A=1", "B=2"}, Image: "bsimg",
				Labels: map[string]string{
					"tsuru.node.address":     server.URL(),
					"tsuru.node.pool":        "p-0",
					"tsuru.node.provisioner": "fake",
					"tsuru.nodecontainer":    "true",
				}},
			HostConfig: docker.HostConfig{
				Binds:         []string{"/xyz:/abc:rw"},
				Privileged:    true,
				RestartPolicy: docker.RestartPolicy{Name: "always"},
				LogConfig:     docker.LogConfig{},
			},
		},
		{
			Config: docker.Config{Env: []string{"DOCKER_ENDPOINT=" + server.URL(), "X=Z"}, Image: "sysdigimg",
				Labels: map[string]string{
					"tsuru.node.address":     server.URL(),
					"tsuru.node.pool":        "p-0",
					"tsuru.node.provisioner": "fake",
					"tsuru.nodecontainer":    "true",
				}},
			HostConfig: docker.HostConfig{
				Binds:         []string{"/xyz:/abc:rw"},
				Privileged:    true,
				RestartPolicy: docker.RestartPolicy{Name: "always"},
				LogConfig:     docker.LogConfig{},
			},
		},
	})
	nodeContainer, err := nodecontainer.LoadNodeContainer("", nodecontainer.BsDefaultName)
	c.Assert(err, check.IsNil)
	c.Assert(nodeContainer.PinnedImage, check.Equals, "")
	client, err := docker.NewClient(p.Servers()[0].URL())
	c.Assert(err, check.IsNil)
	containers, err := client.ListContainers(docker.ListContainersOptions{All: true})
	c.Assert(err, check.IsNil)
	c.Assert(containers, check.HasLen, 2)
	client, err = docker.NewClient(p.Servers()[1].URL())
	c.Assert(err, check.IsNil)
	containers, err = client.ListContainers(docker.ListContainersOptions{All: true})
	c.Assert(err, check.IsNil)
	c.Assert(containers, check.HasLen, 2)
}
Example #16
0
func migrateBSEnvs() error {
	scheme, err := config.GetString("auth:scheme")
	if err != nil {
		scheme = nativeSchemeName
	}
	app.AuthScheme, err = auth.GetScheme(scheme)
	if err != nil {
		return err
	}
	_, err = nodecontainer.InitializeBS()
	if err != nil {
		return err
	}
	conn, err := db.Conn()
	if err != nil {
		return err
	}
	defer conn.Close()
	var entry map[string]interface{}
	err = conn.Collection("bsconfig").FindId("bs").One(&entry)
	if err != nil {
		if err == mgo.ErrNotFound {
			return nil
		}
		return err
	}
	image, _ := entry["image"].(string)
	envs, _ := entry["envs"].([]interface{})
	var baseEnvs []string
	for _, envEntry := range envs {
		mapEntry, _ := envEntry.(map[string]interface{})
		if mapEntry == nil {
			continue
		}
		name, _ := mapEntry["name"].(string)
		value, _ := mapEntry["value"].(string)
		baseEnvs = append(baseEnvs, fmt.Sprintf("%s=%s", name, value))
	}
	bsNodeContainer, err := nodecontainer.LoadNodeContainer("", nodecontainer.BsDefaultName)
	if err != nil {
		return err
	}
	if len(baseEnvs) > 0 {
		bsNodeContainer.Config.Env = append(bsNodeContainer.Config.Env, baseEnvs...)
	}
	bsNodeContainer.PinnedImage = image
	err = nodecontainer.AddNewContainer("", bsNodeContainer)
	if err != nil {
		return err
	}
	pools, _ := entry["pools"].([]interface{})
	for _, poolData := range pools {
		poolMap, _ := poolData.(map[string]interface{})
		if poolMap == nil {
			continue
		}
		poolName, _ := poolMap["name"].(string)
		if poolName == "" {
			continue
		}
		envs, _ := poolMap["envs"].([]interface{})
		var toAdd []string
		for _, envEntry := range envs {
			mapEntry, _ := envEntry.(map[string]interface{})
			if mapEntry == nil {
				continue
			}
			name, _ := mapEntry["name"].(string)
			value, _ := mapEntry["value"].(string)
			toAdd = append(toAdd, fmt.Sprintf("%s=%s", name, value))
		}
		if len(toAdd) > 0 {
			bsCont := nodecontainer.NodeContainerConfig{Name: nodecontainer.BsDefaultName}
			bsCont.Config.Env = append(bsCont.Config.Env, toAdd...)
			err = nodecontainer.AddNewContainer(poolName, &bsCont)
			if err != nil {
				return err
			}
		}
	}
	return nil
}
Example #17
0
func (s *S) TestNodeContainerUpdate(c *check.C) {
	doReq := func(cont nodecontainer.NodeContainerConfig, expected map[string]nodecontainer.NodeContainerConfig, pool ...string) {
		values, err := form.EncodeToValues(cont)
		c.Assert(err, check.IsNil)
		if len(pool) > 0 {
			values.Set("pool", pool[0])
		}
		reader := strings.NewReader(values.Encode())
		request, err := http.NewRequest("POST", "/1.2/nodecontainers/"+cont.Name, reader)
		c.Assert(err, check.IsNil)
		request.Header.Set("Authorization", "bearer "+s.token.GetValue())
		request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
		recorder := httptest.NewRecorder()
		server := RunServer(true)
		server.ServeHTTP(recorder, request)
		c.Assert(recorder.Code, check.Equals, http.StatusOK)
		request, err = http.NewRequest("GET", "/1.2/nodecontainers/"+cont.Name, nil)
		c.Assert(err, check.IsNil)
		request.Header.Set("Authorization", "bearer "+s.token.GetValue())
		recorder = httptest.NewRecorder()
		server.ServeHTTP(recorder, request)
		c.Assert(recorder.Code, check.Equals, http.StatusOK)
		var configEntries map[string]nodecontainer.NodeContainerConfig
		json.Unmarshal(recorder.Body.Bytes(), &configEntries)
		if len(pool) > 0 {
			for _, p := range pool {
				sort.Strings(configEntries[p].Config.Env)
				sort.Strings(expected[p].Config.Env)
			}
		}
		sort.Strings(configEntries[""].Config.Env)
		sort.Strings(expected[""].Config.Env)
		c.Assert(configEntries, check.DeepEquals, expected)
	}
	err := nodecontainer.AddNewContainer("", &nodecontainer.NodeContainerConfig{Name: "c1", Config: docker.Config{Image: "img1"}})
	c.Assert(err, check.IsNil)
	err = nodecontainer.AddNewContainer("", &nodecontainer.NodeContainerConfig{Name: "c2", Config: docker.Config{Image: "img2"}})
	c.Assert(err, check.IsNil)
	doReq(nodecontainer.NodeContainerConfig{Name: "c1"}, map[string]nodecontainer.NodeContainerConfig{
		"": {Name: "c1", Config: docker.Config{Image: "img1"}},
	})
	c.Assert(eventtest.EventDesc{
		Target: event.Target{Type: event.TargetTypeNodeContainer, Value: "c1"},
		Owner:  s.token.GetUserName(),
		Kind:   "nodecontainer.update",
		StartCustomData: []map[string]interface{}{
			{"name": "Name", "value": "c1"},
		},
	}, eventtest.HasEvent)
	doReq(nodecontainer.NodeContainerConfig{
		Name:       "c2",
		Config:     docker.Config{Env: []string{"A=1"}},
		HostConfig: docker.HostConfig{Memory: 256, Privileged: true},
	}, map[string]nodecontainer.NodeContainerConfig{
		"": {Name: "c2", Config: docker.Config{Env: []string{"A=1"}, Image: "img2"}, HostConfig: docker.HostConfig{Memory: 256, Privileged: true}},
	})
	doReq(nodecontainer.NodeContainerConfig{
		Name:       "c2",
		Config:     docker.Config{Env: []string{"Z=9"}},
		HostConfig: docker.HostConfig{Memory: 256},
	}, map[string]nodecontainer.NodeContainerConfig{
		"": {Name: "c2", Config: docker.Config{Env: []string{"A=1", "Z=9"}, Image: "img2"}, HostConfig: docker.HostConfig{Memory: 256, Privileged: true}},
	})
	err = nodecontainer.AddNewContainer("p1", &nodecontainer.NodeContainerConfig{Name: "c2"})
	c.Assert(err, check.IsNil)
	doReq(nodecontainer.NodeContainerConfig{
		Name:   "c2",
		Config: docker.Config{Env: []string{"X=1"}},
	}, map[string]nodecontainer.NodeContainerConfig{
		"":   {Name: "c2", Config: docker.Config{Env: []string{"A=1", "Z=9"}, Image: "img2"}, HostConfig: docker.HostConfig{Memory: 256, Privileged: true}},
		"p1": {Name: "c2", Config: docker.Config{Env: []string{"X=1"}}},
	}, "p1")
}