func (s *S) TestContainerCreate(c *gocheck.C) {
	app := testing.NewFakeApp("app-name", "brainfuck", 1)
	app.Memory = 15
	rtesting.FakeRouter.AddBackend(app.GetName())
	defer rtesting.FakeRouter.RemoveBackend(app.GetName())
	dockerCluster().PullImage(
		docker.PullImageOptions{Repository: "tsuru/brainfuck"},
		docker.AuthConfiguration{},
	)
	cont := container{Name: "myName", AppName: app.GetName(), Type: app.GetPlatform(), Status: "created"}
	err := cont.create(app, getImage(app), []string{"docker", "run"})
	c.Assert(err, gocheck.IsNil)
	defer s.removeTestContainer(&cont)
	c.Assert(cont.ID, gocheck.Not(gocheck.Equals), "")
	c.Assert(cont, gocheck.FitsTypeOf, container{})
	c.Assert(cont.AppName, gocheck.Equals, app.GetName())
	c.Assert(cont.Type, gocheck.Equals, app.GetPlatform())
	u, _ := url.Parse(s.server.URL())
	host, _, _ := net.SplitHostPort(u.Host)
	c.Assert(cont.HostAddr, gocheck.Equals, host)
	user, err := config.GetString("docker:ssh:user")
	c.Assert(err, gocheck.IsNil)
	c.Assert(cont.User, gocheck.Equals, user)
	dcli, _ := docker.NewClient(s.server.URL())
	container, err := dcli.InspectContainer(cont.ID)
	c.Assert(err, gocheck.IsNil)
	c.Assert(container.Path, gocheck.Equals, "docker")
	c.Assert(container.Args, gocheck.DeepEquals, []string{"run"})
	c.Assert(container.Config.User, gocheck.Equals, user)
	c.Assert(container.Config.Memory, gocheck.Equals, int64(app.Memory*1024*1024))
}
Beispiel #2
0
func (s *S) TestContainerCreate(c *check.C) {
	config.Set("host", "my.cool.tsuru.addr:8080")
	defer config.Unset("host")
	app := provisiontest.NewFakeApp("app-name", "brainfuck", 1)
	app.Memory = 15
	app.Swap = 15
	app.CpuShare = 50
	app.SetEnv(bind.EnvVar{Name: "A", Value: "myenva"})
	app.SetEnv(bind.EnvVar{Name: "ABCD", Value: "other env"})
	routertest.FakeRouter.AddBackend(app.GetName())
	defer routertest.FakeRouter.RemoveBackend(app.GetName())
	img := "tsuru/brainfuck:latest"
	s.p.Cluster().PullImage(docker.PullImageOptions{Repository: img}, docker.AuthConfiguration{})
	cont := Container{
		Name:        "myName",
		AppName:     app.GetName(),
		Type:        app.GetPlatform(),
		Status:      "created",
		ProcessName: "myprocess1",
	}
	err := cont.Create(&CreateArgs{
		App:         app,
		ImageID:     img,
		Commands:    []string{"docker", "run"},
		Provisioner: s.p,
	})
	c.Assert(err, check.IsNil)
	defer s.removeTestContainer(&cont)
	c.Assert(cont.ID, check.Not(check.Equals), "")
	c.Assert(cont.AppName, check.Equals, app.GetName())
	c.Assert(cont.Type, check.Equals, app.GetPlatform())
	u, _ := url.Parse(s.server.URL())
	host, _, _ := net.SplitHostPort(u.Host)
	c.Assert(cont.HostAddr, check.Equals, host)
	user, err := config.GetString("docker:user")
	c.Assert(err, check.IsNil)
	c.Assert(cont.User, check.Equals, user)
	dcli, _ := docker.NewClient(s.server.URL())
	container, err := dcli.InspectContainer(cont.ID)
	c.Assert(err, check.IsNil)
	c.Assert(container.Path, check.Equals, "docker")
	c.Assert(container.Args, check.DeepEquals, []string{"run"})
	c.Assert(container.Config.User, check.Equals, user)
	c.Assert(container.Config.Memory, check.Equals, app.Memory)
	c.Assert(container.Config.MemorySwap, check.Equals, app.Memory+app.Swap)
	c.Assert(container.Config.CPUShares, check.Equals, int64(app.CpuShare))
	sort.Strings(container.Config.Env)
	c.Assert(container.Config.Env, check.DeepEquals, []string{
		"A=myenva",
		"ABCD=other env",
		"PORT=8888",
		"TSURU_HOST=my.cool.tsuru.addr:8080",
		"TSURU_PROCESSNAME=myprocess1",
		"port=8888",
	})
}
Beispiel #3
0
func (s *S) TestCreateContainerForward(c *check.C) {
	config.Set("docker:user", "ubuntu")
	defer config.Unset("docker:user")
	err := s.newFakeImage(s.p, "tsuru/python", nil)
	c.Assert(err, check.IsNil)
	client, err := docker.NewClient(s.server.URL())
	c.Assert(err, check.IsNil)
	images, err := client.ListImages(docker.ListImagesOptions{All: true})
	c.Assert(err, check.IsNil)
	cmds := []string{"ps", "-ef"}
	app := provisiontest.NewFakeApp("myapp", "python", 1)
	cont := container.Container{Name: "myName", AppName: app.GetName(), Type: app.GetPlatform(), Status: "created"}
	args := runContainerActionsArgs{
		app:           app,
		imageID:       images[0].ID,
		commands:      cmds,
		provisioner:   s.p,
		buildingImage: images[0].ID,
		isDeploy:      true,
	}
	context := action.FWContext{Previous: cont, Params: []interface{}{args}}
	r, err := createContainer.Forward(context)
	c.Assert(err, check.IsNil)
	cont = r.(container.Container)
	defer cont.Remove(s.p)
	c.Assert(cont, check.FitsTypeOf, container.Container{})
	c.Assert(cont.ID, check.Not(check.Equals), "")
	c.Assert(cont.HostAddr, check.Equals, "127.0.0.1")
	dcli, err := docker.NewClient(s.server.URL())
	c.Assert(err, check.IsNil)
	cc, err := dcli.InspectContainer(cont.ID)
	c.Assert(err, check.IsNil)
	c.Assert(cc.State.Running, check.Equals, false)
	c.Assert(cc.Config.User, check.Equals, "ubuntu")
	args = runContainerActionsArgs{
		app:         app,
		imageID:     images[0].ID,
		commands:    cmds,
		provisioner: s.p,
	}
	optsPull := docker.PullImageOptions{Repository: images[0].ID, OutputStream: nil}
	err = s.p.Cluster().PullImage(optsPull, docker.AuthConfiguration{})
	c.Assert(err, check.IsNil)
	cont = container.Container{Name: "myName2", AppName: app.GetName(), Type: app.GetPlatform(), Status: "created"}
	context = action.FWContext{Previous: cont, Params: []interface{}{args}}
	r, err = createContainer.Forward(context)
	c.Assert(err, check.IsNil)
	cont = r.(container.Container)
	defer cont.Remove(s.p)
	cc, err = dcli.InspectContainer(cont.ID)
	c.Assert(err, check.IsNil)
	c.Assert(cc.Config.User, check.Equals, "")
}
Beispiel #4
0
func (s *S) TestInsertEmptyContainerInDBForward(c *check.C) {
	app := provisiontest.NewFakeApp("myapp", "python", 1)
	args := runContainerActionsArgs{
		app:           app,
		imageID:       "image-id",
		buildingImage: "next-image",
		provisioner:   s.p,
	}
	context := action.FWContext{Params: []interface{}{args}}
	r, err := insertEmptyContainerInDB.Forward(context)
	c.Assert(err, check.IsNil)
	cont := r.(container.Container)
	c.Assert(cont, check.FitsTypeOf, container.Container{})
	c.Assert(cont.AppName, check.Equals, app.GetName())
	c.Assert(cont.Type, check.Equals, app.GetPlatform())
	c.Assert(cont.Name, check.Not(check.Equals), "")
	c.Assert(strings.HasPrefix(cont.Name, app.GetName()+"-"), check.Equals, true)
	c.Assert(cont.Name, check.HasLen, 26)
	c.Assert(cont.Status, check.Equals, "created")
	c.Assert(cont.Image, check.Equals, "image-id")
	c.Assert(cont.BuildingImage, check.Equals, "next-image")
	coll := s.p.Collection()
	defer coll.Close()
	defer coll.Remove(bson.M{"name": cont.Name})
	var retrieved container.Container
	err = coll.Find(bson.M{"name": cont.Name}).One(&retrieved)
	c.Assert(err, check.IsNil)
	c.Assert(retrieved.Name, check.Equals, cont.Name)
}
Beispiel #5
0
func (s *S) TestContainerCreateDoesNotAlocatesPortForDeploy(c *check.C) {
	s.server.CustomHandler("/images/.*/json", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		response := docker.Image{
			Config: &docker.Config{
				ExposedPorts: map[docker.Port]struct{}{},
			},
		}
		j, _ := json.Marshal(response)
		w.Write(j)
	}))
	app := provisiontest.NewFakeApp("app-name", "brainfuck", 1)
	app.Memory = 15
	routertest.FakeRouter.AddBackend(app.GetName())
	defer routertest.FakeRouter.RemoveBackend(app.GetName())
	img := "tsuru/brainfuck:latest"
	s.p.Cluster().PullImage(docker.PullImageOptions{Repository: img}, docker.AuthConfiguration{})
	cont := Container{
		Name:    "myName",
		AppName: app.GetName(),
		Type:    app.GetPlatform(),
		Status:  "created",
	}
	err := cont.Create(&CreateArgs{
		Deploy:      true,
		App:         app,
		ImageID:     img,
		Commands:    []string{"docker", "run"},
		Provisioner: s.p,
	})
	c.Assert(err, check.IsNil)
	defer s.removeTestContainer(&cont)
	info, err := cont.NetworkInfo(s.p)
	c.Assert(err, check.IsNil)
	c.Assert(info.HTTPHostPort, check.Equals, "")
}
Beispiel #6
0
func (s *S) TestContainerCreateSecurityOptions(c *check.C) {
	config.Set("docker:security-opts", []string{"label:type:svirt_apache", "ptrace peer=@unsecure"})
	defer config.Unset("docker:security-opts")
	app := provisiontest.NewFakeApp("app-name", "brainfuck", 1)
	app.Memory = 15
	app.Swap = 15
	app.CpuShare = 50
	routertest.FakeRouter.AddBackend(app.GetName())
	defer routertest.FakeRouter.RemoveBackend(app.GetName())
	img := "tsuru/brainfuck:latest"
	s.p.Cluster().PullImage(docker.PullImageOptions{Repository: img}, docker.AuthConfiguration{})
	cont := Container{
		Name:    "myName",
		AppName: app.GetName(),
		Type:    app.GetPlatform(),
		Status:  "created",
	}
	err := cont.Create(&CreateArgs{
		App:         app,
		ImageID:     img,
		Commands:    []string{"docker", "run"},
		Provisioner: s.p,
	})
	c.Assert(err, check.IsNil)
	defer s.removeTestContainer(&cont)
	dcli, _ := docker.NewClient(s.server.URL())
	container, err := dcli.InspectContainer(cont.ID)
	c.Assert(err, check.IsNil)
	c.Assert(container.Config.SecurityOpts, check.DeepEquals, []string{"label:type:svirt_apache", "ptrace peer=@unsecure"})
}
Beispiel #7
0
func (s *S) TestContainerCreateDoesNotAlocatesPortForDeploy(c *check.C) {
	app := provisiontest.NewFakeApp("app-name", "brainfuck", 1)
	app.Memory = 15
	routertest.FakeRouter.AddBackend(app.GetName())
	defer routertest.FakeRouter.RemoveBackend(app.GetName())
	img := "tsuru/brainfuck:latest"
	s.p.Cluster().PullImage(docker.PullImageOptions{Repository: img}, docker.AuthConfiguration{})
	cont := Container{
		Name:    "myName",
		AppName: app.GetName(),
		Type:    app.GetPlatform(),
		Status:  "created",
	}
	err := cont.Create(&CreateArgs{
		Deploy:      true,
		App:         app,
		ImageID:     img,
		Commands:    []string{"docker", "run"},
		Provisioner: s.p,
	})
	c.Assert(err, check.IsNil)
	defer s.removeTestContainer(&cont)
	info, err := cont.NetworkInfo(s.p)
	c.Assert(err, check.IsNil)
	c.Assert(info.HTTPHostPort, check.Equals, "")
}
Beispiel #8
0
func (s *S) TestContainerCreateUndefinedUser(c *check.C) {
	oldUser, _ := config.Get("docker:user")
	defer config.Set("docker:user", oldUser)
	config.Unset("docker:user")
	img := "tsuru/python:latest"
	s.p.Cluster().PullImage(docker.PullImageOptions{Repository: img}, docker.AuthConfiguration{})
	app := provisiontest.NewFakeApp("app-name", "python", 1)
	routertest.FakeRouter.AddBackend(app.GetName())
	defer routertest.FakeRouter.RemoveBackend(app.GetName())
	cont := Container{
		Name:    "myName",
		AppName: app.GetName(),
		Type:    app.GetPlatform(),
		Status:  "created",
	}
	err := cont.Create(&CreateArgs{
		App:         app,
		ImageID:     img,
		Commands:    []string{"docker", "run"},
		Provisioner: s.p,
	})
	c.Assert(err, check.IsNil)
	defer s.removeTestContainer(&cont)
	dcli, _ := docker.NewClient(s.server.URL())
	container, err := dcli.InspectContainer(cont.ID)
	c.Assert(err, check.IsNil)
	c.Assert(container.Config.User, check.Equals, "")
}
Beispiel #9
0
func (s *S) TestProvisionRemoveOldUnitForward(c *gocheck.C) {
	err := newImage("tsuru/python", s.server.URL())
	c.Assert(err, gocheck.IsNil)
	container, err := s.newContainer(nil)
	c.Assert(err, gocheck.IsNil)
	defer rtesting.FakeRouter.RemoveBackend(container.AppName)
	client, err := dockerClient.NewClient(s.server.URL())
	c.Assert(err, gocheck.IsNil)
	err = client.StartContainer(container.ID, nil)
	c.Assert(err, gocheck.IsNil)
	app := testing.NewFakeApp(container.AppName, "python", 0)
	unit := provision.Unit{
		Name:    container.ID,
		AppName: app.GetName(),
		Type:    app.GetPlatform(),
		Ip:      container.HostAddr,
		Status:  provision.StatusBuilding,
	}
	context := action.FWContext{Params: []interface{}{app, "", *container}, Previous: unit}
	result, err := provisionRemoveOldUnit.Forward(context)
	c.Assert(err, gocheck.IsNil)
	retUnit := result.(provision.Unit)
	c.Assert(retUnit, gocheck.DeepEquals, unit)
	_, err = getContainer(container.ID)
	c.Assert(err, gocheck.NotNil)
}
Beispiel #10
0
func (s *S) TestCreateContainerForward(c *gocheck.C) {
	cmutex.Lock()
	oldClusterNodes := clusterNodes
	clusterNodes = map[string]string{
		"server": "http://localhost:8081",
	}
	cmutex.Unlock()
	defer func() {
		cmutex.Lock()
		clusterNodes = oldClusterNodes
		cmutex.Unlock()
	}()
	err := newImage("tsuru/python", s.server.URL())
	c.Assert(err, gocheck.IsNil)
	client, err := dockerClient.NewClient(s.server.URL())
	c.Assert(err, gocheck.IsNil)
	images, err := client.ListImages(true)
	c.Assert(err, gocheck.IsNil)
	cmds := []string{"ps", "-ef"}
	app := testing.NewFakeApp("myapp", "python", 1)
	cont := container{Name: "myName", AppName: app.GetName(), Type: app.GetPlatform(), Status: "created"}
	context := action.FWContext{Previous: cont, Params: []interface{}{app, images[0].ID, cmds}}
	r, err := createContainer.Forward(context)
	c.Assert(err, gocheck.IsNil)
	cont = r.(container)
	defer cont.remove()
	c.Assert(cont, gocheck.FitsTypeOf, container{})
	c.Assert(cont.ID, gocheck.Not(gocheck.Equals), "")
	c.Assert(cont.HostAddr, gocheck.Equals, "localhost")
	dcli, err := dockerClient.NewClient(s.server.URL())
	c.Assert(err, gocheck.IsNil)
	cc, err := dcli.InspectContainer(cont.ID)
	c.Assert(err, gocheck.IsNil)
	c.Assert(cc.State.Running, gocheck.Equals, false)
}
Beispiel #11
0
func (s *S) TestCreateContainerForward(c *check.C) {
	err := s.newFakeImage(s.p, "tsuru/python", nil)
	c.Assert(err, check.IsNil)
	client, err := docker.NewClient(s.server.URL())
	c.Assert(err, check.IsNil)
	images, err := client.ListImages(docker.ListImagesOptions{All: true})
	c.Assert(err, check.IsNil)
	cmds := []string{"ps", "-ef"}
	app := provisiontest.NewFakeApp("myapp", "python", 1)
	cont := container.Container{Name: "myName", AppName: app.GetName(), Type: app.GetPlatform(), Status: "created"}
	args := runContainerActionsArgs{
		app:         app,
		imageID:     images[0].ID,
		commands:    cmds,
		provisioner: s.p,
	}
	context := action.FWContext{Previous: cont, Params: []interface{}{args}}
	r, err := createContainer.Forward(context)
	c.Assert(err, check.IsNil)
	cont = r.(container.Container)
	defer cont.Remove(s.p)
	c.Assert(cont, check.FitsTypeOf, container.Container{})
	c.Assert(cont.ID, check.Not(check.Equals), "")
	c.Assert(cont.HostAddr, check.Equals, "127.0.0.1")
	dcli, err := docker.NewClient(s.server.URL())
	c.Assert(err, check.IsNil)
	cc, err := dcli.InspectContainer(cont.ID)
	c.Assert(err, check.IsNil)
	c.Assert(cc.State.Running, check.Equals, false)
}
Beispiel #12
0
func (s *S) TestContainerCreateOverwriteEntrypoint(c *check.C) {
	config.Set("host", "my.cool.tsuru.addr:8080")
	defer config.Unset("host")
	app := provisiontest.NewFakeApp("app-name", "brainfuck", 1)
	img := "tsuru/brainfuck:latest"
	s.p.Cluster().PullImage(docker.PullImageOptions{Repository: img}, docker.AuthConfiguration{})
	cont := Container{
		Name:    "myName",
		AppName: app.GetName(),
		Type:    app.GetPlatform(),
		Status:  "created",
	}
	err := cont.Create(&CreateArgs{
		Deploy:      true,
		App:         app,
		ImageID:     img,
		Commands:    []string{"docker", "run"},
		Provisioner: s.p,
	})
	c.Assert(err, check.IsNil)
	defer s.removeTestContainer(&cont)
	dcli, err := docker.NewClient(s.server.URL())
	c.Assert(err, check.IsNil)
	container, err := dcli.InspectContainer(cont.ID)
	c.Assert(err, check.IsNil)
	c.Assert(container.Config.Entrypoint, check.DeepEquals, []string{})
}
Beispiel #13
0
func (s *S) TestContainerCreateCustomLog(c *check.C) {
	client, err := docker.NewClient(s.server.URL())
	c.Assert(err, check.IsNil)
	app := provisiontest.NewFakeApp("myapp", "python", 1)
	app.Pool = "mypool"
	img := "tsuru/brainfuck:latest"
	s.p.Cluster().PullImage(docker.PullImageOptions{Repository: img}, docker.AuthConfiguration{})
	testCases := []struct {
		name string
		opts map[string]string
	}{
		{"fluentd", map[string]string{
			"fluentd-address": "localhost:24224",
		}},
		{"syslog", map[string]string{
			"syslog-address": "udp://localhost:1514",
		}},
		{"fluentd", map[string]string{
			"fluentd-address": "somewhere:24224",
			"tag":             "x",
		}},
	}
	for i, testData := range testCases {
		c.Logf("test %d", i)
		cont := Container{
			Name:        fmt.Sprintf("myName-%d", i),
			AppName:     app.GetName(),
			Type:        app.GetPlatform(),
			Status:      "created",
			ProcessName: "myprocess1",
			ExposedPort: "8888/tcp",
		}
		conf := DockerLogConfig{Driver: testData.name, LogOpts: testData.opts}
		err = conf.Save(app.Pool)
		c.Assert(err, check.IsNil)
		err := cont.Create(&CreateArgs{
			App:         app,
			ImageID:     img,
			Commands:    []string{"docker", "run"},
			Provisioner: s.p,
		})
		c.Assert(err, check.IsNil)
		dockerContainer, err := client.InspectContainer(cont.ID)
		c.Assert(err, check.IsNil)
		c.Assert(dockerContainer.HostConfig.LogConfig.Type, check.Equals, testData.name)
		c.Assert(dockerContainer.HostConfig.LogConfig.Config, check.DeepEquals, testData.opts)
	}
}
Beispiel #14
0
func (s *S) TestContainerCreateForDeploy(c *check.C) {
	s.server.CustomHandler("/images/.*/json", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		response := docker.Image{
			Config: &docker.Config{
				ExposedPorts: map[docker.Port]struct{}{},
			},
		}
		j, _ := json.Marshal(response)
		w.Write(j)
	}))
	app := provisiontest.NewFakeApp("app-name", "brainfuck", 1)
	app.Memory = 15
	app.Swap = 15
	app.CpuShare = 50
	routertest.FakeRouter.AddBackend(app.GetName())
	defer routertest.FakeRouter.RemoveBackend(app.GetName())
	img := "tsuru/brainfuck:latest"
	s.p.Cluster().PullImage(docker.PullImageOptions{Repository: img}, docker.AuthConfiguration{})
	cont := Container{
		Name:    "myName",
		AppName: app.GetName(),
		Type:    app.GetPlatform(),
		Status:  "created",
	}
	err := cont.Create(&CreateArgs{
		Deploy:      true,
		App:         app,
		ImageID:     img,
		Commands:    []string{"docker", "run"},
		Provisioner: s.p,
	})
	c.Assert(err, check.IsNil)
	defer s.removeTestContainer(&cont)
	info, err := cont.NetworkInfo(s.p)
	c.Assert(err, check.IsNil)
	c.Assert(info.HTTPHostPort, check.Equals, "")
	client, err := docker.NewClient(s.server.URL())
	c.Assert(err, check.IsNil)
	dockerContainer, err := client.InspectContainer(cont.ID)
	c.Assert(err, check.IsNil)
	c.Assert(dockerContainer.HostConfig.RestartPolicy.Name, check.Equals, "")
	c.Assert(dockerContainer.HostConfig.LogConfig.Type, check.Equals, "")
	c.Assert(dockerContainer.HostConfig.Memory, check.Equals, int64(0))
	c.Assert(dockerContainer.HostConfig.MemorySwap, check.Equals, int64(0))
	c.Assert(dockerContainer.HostConfig.CPUShares, check.Equals, int64(50))
	c.Assert(dockerContainer.HostConfig.OomScoreAdj, check.Equals, 1000)
}
Beispiel #15
0
func (s *S) TestContainerCreateDoesNotSetEnvs(c *check.C) {
	s.server.CustomHandler("/images/.*/json", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		response := docker.Image{
			Config: &docker.Config{
				ExposedPorts: map[docker.Port]struct{}{},
			},
		}
		j, _ := json.Marshal(response)
		w.Write(j)
	}))
	config.Set("host", "my.cool.tsuru.addr:8080")
	defer config.Unset("host")
	app := provisiontest.NewFakeApp("app-name", "brainfuck", 1)
	app.SetEnv(bind.EnvVar{Name: "A", Value: "myenva"})
	app.SetEnv(bind.EnvVar{Name: "ABCD", Value: "other env"})
	routertest.FakeRouter.AddBackend(app.GetName())
	defer routertest.FakeRouter.RemoveBackend(app.GetName())
	img := "tsuru/brainfuck:latest"
	s.p.Cluster().PullImage(docker.PullImageOptions{Repository: img}, docker.AuthConfiguration{})
	cont := Container{
		Name:    "myName",
		AppName: app.GetName(),
		Type:    app.GetPlatform(),
		Status:  "created",
	}
	err := cont.Create(&CreateArgs{
		Deploy:      true,
		App:         app,
		ImageID:     img,
		Commands:    []string{"docker", "run"},
		Provisioner: s.p,
	})
	c.Assert(err, check.IsNil)
	defer s.removeTestContainer(&cont)
	dcli, err := docker.NewClient(s.server.URL())
	c.Assert(err, check.IsNil)
	container, err := dcli.InspectContainer(cont.ID)
	c.Assert(err, check.IsNil)
	sort.Strings(container.Config.Env)
	c.Assert(container.Config.Env, check.DeepEquals, []string{
		"PORT=",
		"TSURU_HOST=my.cool.tsuru.addr:8080",
		"port=",
	})
}
func (s *S) TestContainerCreateUndefinedUser(c *gocheck.C) {
	oldUser, _ := config.Get("docker:ssh:user")
	defer config.Set("docker:ssh:user", oldUser)
	config.Unset("docker:ssh:user")
	err := newImage("tsuru/python", s.server.URL())
	c.Assert(err, gocheck.IsNil)
	app := testing.NewFakeApp("app-name", "python", 1)
	rtesting.FakeRouter.AddBackend(app.GetName())
	defer rtesting.FakeRouter.RemoveBackend(app.GetName())
	cont := container{Name: "myName", AppName: app.GetName(), Type: app.GetPlatform(), Status: "created"}
	err = cont.create(app, getImage(app), []string{"docker", "run"})
	c.Assert(err, gocheck.IsNil)
	defer s.removeTestContainer(&cont)
	dcli, _ := docker.NewClient(s.server.URL())
	container, err := dcli.InspectContainer(cont.ID)
	c.Assert(err, gocheck.IsNil)
	c.Assert(container.Config.User, gocheck.Equals, "")
}
Beispiel #17
0
func (s *S) TestInsertEmptyContainerInDBForward(c *gocheck.C) {
	app := testing.NewFakeApp("myapp", "python", 1)
	context := action.FWContext{Params: []interface{}{app}}
	r, err := insertEmptyContainerInDB.Forward(context)
	c.Assert(err, gocheck.IsNil)
	cont := r.(container)
	c.Assert(cont, gocheck.FitsTypeOf, container{})
	c.Assert(cont.AppName, gocheck.Equals, app.GetName())
	c.Assert(cont.Type, gocheck.Equals, app.GetPlatform())
	c.Assert(cont.Name, gocheck.Not(gocheck.Equals), "")
	c.Assert(cont.Name, gocheck.HasLen, 20)
	c.Assert(cont.Status, gocheck.Equals, "created")
	coll := collection()
	defer coll.Close()
	defer coll.Remove(bson.M{"name": cont.Name})
	var retrieved container
	err = coll.Find(bson.M{"name": cont.Name}).One(&retrieved)
	c.Assert(err, gocheck.IsNil)
	c.Assert(retrieved.Name, gocheck.Equals, cont.Name)
}
Beispiel #18
0
func (s *S) TestProvisionAddUnitToHostBackward(c *gocheck.C) {
	err := newImage("tsuru/python", s.server.URL())
	c.Assert(err, gocheck.IsNil)
	container, err := s.newContainer(nil)
	c.Assert(err, gocheck.IsNil)
	defer s.removeTestContainer(container)
	app := testing.NewFakeApp(container.AppName, "python", 0)
	unit := provision.Unit{
		Name:    container.ID,
		AppName: app.GetName(),
		Type:    app.GetPlatform(),
		Ip:      container.HostAddr,
		Status:  provision.StatusBuilding,
	}
	context := action.BWContext{Params: []interface{}{app, "server"}, FWResult: unit}
	provisionAddUnitToHost.Backward(context)
	_, err = getContainer(container.ID)
	c.Assert(err, gocheck.NotNil)
	c.Assert(err.Error(), gocheck.Equals, "not found")
}
Beispiel #19
0
func (s *S) TestContainerCreateAllocatesPort(c *check.C) {
	s.server.CustomHandler("/images/.*/json", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		response := docker.Image{
			Config: &docker.Config{
				ExposedPorts: map[docker.Port]struct{}{"3000/tcp": {}},
			},
		}
		j, _ := json.Marshal(response)
		w.Write(j)
	}))
	config.Set("host", "my.cool.tsuru.addr:8080")
	defer config.Unset("host")
	app := provisiontest.NewFakeApp("app-name", "brainfuck", 1)
	app.Memory = 15
	app.Swap = 15
	app.CpuShare = 50
	routertest.FakeRouter.AddBackend(app.GetName())
	defer routertest.FakeRouter.RemoveBackend(app.GetName())
	img := "tsuru/brainfuck:latest"
	s.p.Cluster().PullImage(docker.PullImageOptions{Repository: img}, docker.AuthConfiguration{})
	cont := Container{
		Name:        "myName",
		AppName:     app.GetName(),
		Type:        app.GetPlatform(),
		Status:      "created",
		ProcessName: "myprocess1",
		ExposedPort: "3000/tcp",
	}
	err := cont.Create(&CreateArgs{
		App:         app,
		Commands:    []string{"docker", "run"},
		Provisioner: s.p,
		ImageID:     img,
	})
	c.Assert(err, check.IsNil)
	defer s.removeTestContainer(&cont)
	dcli, _ := docker.NewClient(s.server.URL())
	container, err := dcli.InspectContainer(cont.ID)
	c.Assert(err, check.IsNil)
	c.Assert(container.Config.ExposedPorts, check.DeepEquals, map[docker.Port]struct{}{"3000/tcp": {}})
}
Beispiel #20
0
func (s *S) TestContainerCreateAlocatesPort(c *check.C) {
	app := provisiontest.NewFakeApp("app-name", "brainfuck", 1)
	app.Memory = 15
	routertest.FakeRouter.AddBackend(app.GetName())
	defer routertest.FakeRouter.RemoveBackend(app.GetName())
	s.p.getCluster().PullImage(
		docker.PullImageOptions{Repository: "tsuru/brainfuck:latest"},
		docker.AuthConfiguration{},
	)
	cont := container{Name: "myName", AppName: app.GetName(), Type: app.GetPlatform(), Status: "created"}
	err := cont.create(runContainerActionsArgs{
		app:         app,
		imageID:     s.p.getBuildImage(app),
		commands:    []string{"docker", "run"},
		provisioner: s.p,
	})
	c.Assert(err, check.IsNil)
	defer s.removeTestContainer(&cont)
	info, err := cont.networkInfo(s.p)
	c.Assert(err, check.IsNil)
	c.Assert(info.HTTPHostPort, check.Not(check.Equals), "")
}
Beispiel #21
0
func (s *S) TestContainerCreateDontAllocatesPortToImageWithMoreThanOnePortExposed(c *check.C) {
	s.server.CustomHandler("/images/.*/json", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		response := docker.Image{
			Config: &docker.Config{
				ExposedPorts: map[docker.Port]struct{}{"3000/tcp": {}, "80/tcp": {}},
			},
		}
		j, _ := json.Marshal(response)
		w.Write(j)
	}))
	config.Set("host", "my.cool.tsuru.addr:8080")
	defer config.Unset("host")
	app := provisiontest.NewFakeApp("app-name", "brainfuck", 1)
	app.Memory = 15
	app.Swap = 15
	app.CpuShare = 50
	app.SetEnv(bind.EnvVar{Name: "A", Value: "myenva"})
	app.SetEnv(bind.EnvVar{Name: "ABCD", Value: "other env"})
	routertest.FakeRouter.AddBackend(app.GetName())
	defer routertest.FakeRouter.RemoveBackend(app.GetName())
	img := "tsuru/brainfuck:latest"
	s.p.Cluster().PullImage(docker.PullImageOptions{Repository: img}, docker.AuthConfiguration{})
	cont := Container{
		Name:        "myName",
		AppName:     app.GetName(),
		Type:        app.GetPlatform(),
		Status:      "created",
		ProcessName: "myprocess1",
	}
	err := cont.Create(&CreateArgs{
		App:         app,
		ImageID:     img,
		Commands:    []string{"docker", "run"},
		Provisioner: s.p,
	})
	c.Assert(err, check.NotNil)
	defer s.removeTestContainer(&cont)
}
Beispiel #22
0
func (s *S) TestContainerCreateUndefinedUser(c *check.C) {
	oldUser, _ := config.Get("docker:user")
	defer config.Set("docker:user", oldUser)
	config.Unset("docker:user")
	err := s.newFakeImage(s.p, "tsuru/python:latest", nil)
	c.Assert(err, check.IsNil)
	app := provisiontest.NewFakeApp("app-name", "python", 1)
	routertest.FakeRouter.AddBackend(app.GetName())
	defer routertest.FakeRouter.RemoveBackend(app.GetName())
	cont := container{Name: "myName", AppName: app.GetName(), Type: app.GetPlatform(), Status: "created"}
	err = cont.create(runContainerActionsArgs{
		app:         app,
		imageID:     s.p.getBuildImage(app),
		commands:    []string{"docker", "run"},
		provisioner: s.p,
	})
	c.Assert(err, check.IsNil)
	defer s.removeTestContainer(&cont)
	dcli, _ := docker.NewClient(s.server.URL())
	container, err := dcli.InspectContainer(cont.ID)
	c.Assert(err, check.IsNil)
	c.Assert(container.Config.User, check.Equals, "")
}
Beispiel #23
0
func (s *S) TestContainerCreateUndefinedUser(c *check.C) {
	s.server.CustomHandler("/images/.*/json", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		response := docker.Image{
			Config: &docker.Config{
				ExposedPorts: map[docker.Port]struct{}{},
			},
		}
		j, _ := json.Marshal(response)
		w.Write(j)
	}))
	oldUser, _ := config.Get("docker:user")
	defer config.Set("docker:user", oldUser)
	config.Unset("docker:user")
	img := "tsuru/python:latest"
	s.p.Cluster().PullImage(docker.PullImageOptions{Repository: img}, docker.AuthConfiguration{})
	app := provisiontest.NewFakeApp("app-name", "python", 1)
	routertest.FakeRouter.AddBackend(app.GetName())
	defer routertest.FakeRouter.RemoveBackend(app.GetName())
	cont := Container{
		Name:    "myName",
		AppName: app.GetName(),
		Type:    app.GetPlatform(),
		Status:  "created",
	}
	err := cont.Create(&CreateArgs{
		App:         app,
		ImageID:     img,
		Commands:    []string{"docker", "run"},
		Provisioner: s.p,
	})
	c.Assert(err, check.IsNil)
	defer s.removeTestContainer(&cont)
	dcli, _ := docker.NewClient(s.server.URL())
	container, err := dcli.InspectContainer(cont.ID)
	c.Assert(err, check.IsNil)
	c.Assert(container.Config.User, check.Equals, "")
}
Beispiel #24
0
func (s *S) TestContainerCreate(c *check.C) {
	s.server.CustomHandler("/images/.*/json", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		response := docker.Image{
			Config: &docker.Config{
				ExposedPorts: map[docker.Port]struct{}{},
			},
		}
		j, _ := json.Marshal(response)
		w.Write(j)
	}))
	config.Set("host", "my.cool.tsuru.addr:8080")
	defer config.Unset("host")
	app := provisiontest.NewFakeApp("app-name", "brainfuck", 1)
	app.Memory = 15
	app.Swap = 15
	app.CpuShare = 50
	app.SetEnv(bind.EnvVar{Name: "A", Value: "myenva"})
	app.SetEnv(bind.EnvVar{Name: "ABCD", Value: "other env"})
	routertest.FakeRouter.AddBackend(app.GetName())
	defer routertest.FakeRouter.RemoveBackend(app.GetName())
	img := "tsuru/brainfuck:latest"
	s.p.Cluster().PullImage(docker.PullImageOptions{Repository: img}, docker.AuthConfiguration{})
	cont := Container{
		Name:        "myName",
		AppName:     app.GetName(),
		Type:        app.GetPlatform(),
		Status:      "created",
		ProcessName: "myprocess1",
		ExposedPort: "8888/tcp",
	}
	err := cont.Create(&CreateArgs{
		App:         app,
		ImageID:     img,
		Commands:    []string{"docker", "run"},
		Provisioner: s.p,
	})
	c.Assert(err, check.IsNil)
	defer s.removeTestContainer(&cont)
	c.Assert(cont.ID, check.Not(check.Equals), "")
	c.Assert(cont.AppName, check.Equals, app.GetName())
	c.Assert(cont.Type, check.Equals, app.GetPlatform())
	u, _ := url.Parse(s.server.URL())
	host, _, _ := net.SplitHostPort(u.Host)
	c.Assert(cont.HostAddr, check.Equals, host)
	dcli, _ := docker.NewClient(s.server.URL())
	container, err := dcli.InspectContainer(cont.ID)
	c.Assert(err, check.IsNil)
	c.Assert(container.Path, check.Equals, "docker")
	c.Assert(container.Args, check.DeepEquals, []string{"run"})
	c.Assert(container.Config.Memory, check.Equals, app.Memory)
	c.Assert(container.Config.MemorySwap, check.Equals, app.Memory+app.Swap)
	c.Assert(container.Config.CPUShares, check.Equals, int64(app.CpuShare))
	sort.Strings(container.Config.Env)
	c.Assert(container.Config.Labels, check.DeepEquals, map[string]string{
		"tsuru.container":    "true",
		"tsuru.router.name":  "fake",
		"tsuru.router.type":  "fakeType",
		"tsuru.app.name":     "app-name",
		"tsuru.app.platform": "brainfuck",
		"tsuru.process.name": "myprocess1",
	})
	c.Assert(container.Config.Env, check.DeepEquals, []string{
		"A=myenva",
		"ABCD=other env",
		"PORT=8888",
		"TSURU_HOST=my.cool.tsuru.addr:8080",
		"TSURU_PROCESSNAME=myprocess1",
		"port=8888",
	})
	c.Assert(container.State.Running, check.Equals, false)
	expectedLogOptions := map[string]string{
		"syslog-address": "udp://localhost:1514",
	}
	expectedPortBindings := map[docker.Port][]docker.PortBinding{
		"8888/tcp": {{HostIP: "", HostPort: ""}},
	}
	c.Assert(container.HostConfig.RestartPolicy.Name, check.Equals, "always")
	c.Assert(container.HostConfig.LogConfig.Type, check.Equals, "syslog")
	c.Assert(container.HostConfig.LogConfig.Config, check.DeepEquals, expectedLogOptions)
	c.Assert(container.HostConfig.PortBindings, check.DeepEquals, expectedPortBindings)
	c.Assert(container.HostConfig.Memory, check.Equals, int64(15))
	c.Assert(container.HostConfig.MemorySwap, check.Equals, int64(30))
	c.Assert(container.HostConfig.CPUShares, check.Equals, int64(50))
	c.Assert(container.HostConfig.OomScoreAdj, check.Equals, 0)
	c.Assert(cont.Status, check.Equals, "created")
}
Beispiel #25
0
// title: app create
// path: /apps
// method: POST
// consume: application/x-www-form-urlencoded
// produce: application/json
// responses:
//   201: App created
//   400: Invalid data
//   401: Unauthorized
//   403: Quota exceeded
//   409: App already exists
func createApp(w http.ResponseWriter, r *http.Request, t auth.Token) (err error) {
	err = r.ParseForm()
	if err != nil {
		return &errors.HTTP{Code: http.StatusBadRequest, Message: err.Error()}
	}
	var ia inputApp
	dec := form.NewDecoder(nil)
	dec.IgnoreCase(true)
	dec.IgnoreUnknownKeys(true)
	dec.DecodeValues(&ia, r.Form)
	a := app.App{
		TeamOwner:   ia.TeamOwner,
		Platform:    ia.Platform,
		Plan:        app.Plan{Name: ia.Plan},
		Name:        ia.Name,
		Description: ia.Description,
		Pool:        ia.Pool,
		RouterOpts:  ia.RouterOpts,
	}
	if a.TeamOwner == "" {
		a.TeamOwner, err = permission.TeamForPermission(t, permission.PermAppCreate)
		if err != nil {
			if err != permission.ErrTooManyTeams {
				return err
			}
			teams, listErr := auth.ListTeams()
			if listErr != nil {
				return listErr
			}
			if len(teams) != 1 {
				return err
			}
			a.TeamOwner = teams[0].Name
		}
	}
	canCreate := permission.Check(t, permission.PermAppCreate,
		permission.Context(permission.CtxTeam, a.TeamOwner),
	)
	if !canCreate {
		return permission.ErrUnauthorized
	}
	u, err := t.User()
	if err != nil {
		return err
	}
	platform, err := app.GetPlatform(a.Platform)
	if err != nil {
		return err
	}
	if platform.Disabled {
		canUsePlat := permission.Check(t, permission.PermPlatformUpdate) ||
			permission.Check(t, permission.PermPlatformCreate)
		if !canUsePlat {
			return &errors.HTTP{Code: http.StatusBadRequest, Message: app.InvalidPlatformError.Error()}
		}
	}
	evt, err := event.New(&event.Opts{
		Target:     appTarget(a.Name),
		Kind:       permission.PermAppCreate,
		Owner:      t,
		CustomData: event.FormToCustomData(r.Form),
		Allowed:    event.Allowed(permission.PermAppReadEvents, contextsForApp(&a)...),
	})
	if err != nil {
		return err
	}
	defer func() { evt.Done(err) }()
	err = app.CreateApp(&a, u)
	if err != nil {
		log.Errorf("Got error while creating app: %s", err)
		if e, ok := err.(*errors.ValidationError); ok {
			return &errors.HTTP{Code: http.StatusBadRequest, Message: e.Message}
		}
		if _, ok := err.(app.NoTeamsError); ok {
			return &errors.HTTP{
				Code:    http.StatusBadRequest,
				Message: "In order to create an app, you should be member of at least one team",
			}
		}
		if e, ok := err.(*app.AppCreationError); ok {
			if e.Err == app.ErrAppAlreadyExists {
				return &errors.HTTP{Code: http.StatusConflict, Message: e.Error()}
			}
			if _, ok := e.Err.(*quota.QuotaExceededError); ok {
				return &errors.HTTP{
					Code:    http.StatusForbidden,
					Message: "Quota exceeded",
				}
			}
		}
		if err == app.InvalidPlatformError {
			return &errors.HTTP{Code: http.StatusBadRequest, Message: err.Error()}
		}
		return err
	}
	repo, err := repository.Manager().GetRepository(a.Name)
	if err != nil {
		return err
	}
	msg := map[string]string{
		"status":         "success",
		"repository_url": repo.ReadWriteURL,
		"ip":             a.Ip,
	}
	jsonMsg, err := json.Marshal(msg)
	if err != nil {
		return err
	}
	w.WriteHeader(http.StatusCreated)
	w.Header().Set("Content-Type", "application/json")
	w.Write(jsonMsg)
	return nil
}
Beispiel #26
0
	"github.com/tsuru/tsuru/log"
	"github.com/tsuru/tsuru/provision"
	"github.com/tsuru/tsuru/queue"
	"io"
	"labix.org/v2/mgo/bson"
)

var insertEmptyContainerInDB = action.Action{
	Name: "insert-empty-container",
	Forward: func(ctx action.FWContext) (action.Result, error) {
		app := ctx.Params[0].(provision.App)
		imageId := ctx.Params[1].(string)
		contName := containerName()
		cont := container{
			AppName: app.GetName(),
			Type:    app.GetPlatform(),
			Name:    contName,
			Status:  "created",
			Image:   imageId,
		}
		coll := collection()
		defer coll.Close()
		if err := coll.Insert(cont); err != nil {
			log.Errorf("error on inserting container into database %s - %s", cont.Name, err)
			return nil, err
		}
		return cont, nil
	},
	Backward: func(ctx action.BWContext) {
		c := ctx.FWResult.(container)
		coll := collection()
Beispiel #27
0
func createApp(w http.ResponseWriter, r *http.Request, t auth.Token) error {
	var a app.App
	defer r.Body.Close()
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		return err
	}
	if err = json.Unmarshal(body, &a); err != nil {
		return err
	}
	if a.TeamOwner == "" {
		a.TeamOwner, err = permission.TeamForPermission(t, permission.PermAppCreate)
		if err != nil {
			return err
		}
	}
	canCreate := permission.Check(t, permission.PermAppCreate,
		permission.Context(permission.CtxTeam, a.TeamOwner),
	)
	if !canCreate {
		return permission.ErrUnauthorized
	}
	u, err := t.User()
	if err != nil {
		return err
	}
	platform, err := app.GetPlatform(a.Platform)
	if err != nil {
		return err
	}
	if platform.Disabled {
		canUsePlat := permission.Check(t, permission.PermPlatformUpdate) ||
			permission.Check(t, permission.PermPlatformCreate)
		if !canUsePlat {
			return app.InvalidPlatformError{}
		}
	}
	rec.Log(u.Email, "create-app", "app="+a.Name, "platform="+a.Platform, "plan="+a.Plan.Name, "description="+a.Description)
	err = app.CreateApp(&a, u)
	if err != nil {
		log.Errorf("Got error while creating app: %s", err)
		if e, ok := err.(*errors.ValidationError); ok {
			return &errors.HTTP{Code: http.StatusBadRequest, Message: e.Message}
		}
		if _, ok := err.(app.NoTeamsError); ok {
			return &errors.HTTP{
				Code:    http.StatusBadRequest,
				Message: "In order to create an app, you should be member of at least one team",
			}
		}
		if e, ok := err.(*app.AppCreationError); ok {
			if e.Err == app.ErrAppAlreadyExists {
				return &errors.HTTP{Code: http.StatusConflict, Message: e.Error()}
			}
			if _, ok := e.Err.(*quota.QuotaExceededError); ok {
				return &errors.HTTP{
					Code:    http.StatusForbidden,
					Message: "Quota exceeded",
				}
			}
		}
		if e, ok := err.(app.InvalidPlatformError); ok {
			return &errors.HTTP{Code: http.StatusNotFound, Message: e.Error()}
		}
		return err
	}
	repo, _ := repository.Manager().GetRepository(a.Name)
	msg := map[string]string{
		"status":         "success",
		"repository_url": repo.ReadWriteURL,
		"ip":             a.Ip,
	}
	jsonMsg, err := json.Marshal(msg)
	if err != nil {
		return err
	}
	fmt.Fprintf(w, "%s", jsonMsg)
	return nil
}