Esempio n. 1
0
func (s *S) TestGetImageCustomDataLegacyProcesses(c *check.C) {
	data := image.ImageMetadata{
		Name: "tsuru/app-myapp:v1",
		LegacyProcesses: map[string]string{
			"worker1": "python myapp.py",
			"worker2": "worker2",
		},
	}
	err := data.Save()
	c.Assert(err, check.IsNil)
	dbMetadata, err := image.GetImageCustomData(data.Name)
	c.Assert(err, check.IsNil)
	c.Assert(dbMetadata.Processes, check.DeepEquals, map[string][]string{
		"worker1": {"python myapp.py"},
		"worker2": {"worker2"},
	})
	data.Name = "tsuru/app-myapp:v2"
	data.Processes = map[string][]string{
		"w1": {"has", "priority"},
	}
	err = data.Save()
	c.Assert(err, check.IsNil)
	dbMetadata, err = image.GetImageCustomData(data.Name)
	c.Assert(err, check.IsNil)
	c.Assert(dbMetadata.Processes, check.DeepEquals, map[string][]string{
		"w1": {"has", "priority"},
	})
}
Esempio n. 2
0
func (p *dockerProvisioner) deploy(a provision.App, imageId string, evt *event.Event) error {
	if err := checkCanceled(evt); err != nil {
		return err
	}
	containers, err := p.listContainersByApp(a.GetName())
	if err != nil {
		return err
	}
	imageData, err := image.GetImageCustomData(imageId)
	if err != nil {
		return err
	}
	if len(containers) == 0 {
		toAdd := make(map[string]*containersToAdd, len(imageData.Processes))
		for processName := range imageData.Processes {
			_, ok := toAdd[processName]
			if !ok {
				ct := containersToAdd{Quantity: 0}
				toAdd[processName] = &ct
			}
			toAdd[processName].Quantity++
		}
		if err = setQuota(a, toAdd); err != nil {
			return err
		}
		_, err = p.runCreateUnitsPipeline(evt, a, toAdd, imageId, imageData.ExposedPort)
	} else {
		toAdd := getContainersToAdd(imageData, containers)
		if err = setQuota(a, toAdd); err != nil {
			return err
		}
		_, err = p.runReplaceUnitsPipeline(evt, a, toAdd, containers, imageId)
	}
	return err
}
Esempio n. 3
0
func (s *S) TestSavePortInImageCustomData(c *check.C) {
	img1 := "tsuru/app-myapp:v1"
	customData1 := map[string]interface{}{
		"exposedPort": "3434",
	}
	err := image.SaveImageCustomData(img1, customData1)
	c.Assert(err, check.IsNil)
	imageMetaData, err := image.GetImageCustomData(img1)
	c.Check(err, check.IsNil)
	c.Check(imageMetaData.ExposedPort, check.Equals, "3434")
}
Esempio n. 4
0
func deployProcesses(client *docker.Client, a provision.App, newImg string, updateSpec processSpec) error {
	curImg, err := image.AppCurrentImageName(a.GetName())
	if err != nil {
		return err
	}
	currentImageData, err := image.GetImageCustomData(curImg)
	if err != nil {
		return err
	}
	currentSpec := processSpec{}
	for p := range currentImageData.Processes {
		currentSpec[p] = processState{}
	}
	newImageData, err := image.GetImageCustomData(newImg)
	if err != nil {
		return err
	}
	if len(newImageData.Processes) == 0 {
		return errors.Errorf("no process information found deploying image %q", newImg)
	}
	newSpec := processSpec{}
	for p := range newImageData.Processes {
		newSpec[p] = processState{start: true}
		if updateSpec != nil {
			newSpec[p] = updateSpec[p]
		}
	}
	pipeline := action.NewPipeline(
		updateServices,
		updateImageInDB,
		removeOldServices,
	)
	return pipeline.Execute(&pipelineArgs{
		client:           client,
		app:              a,
		newImage:         newImg,
		newImageSpec:     newSpec,
		currentImage:     curImg,
		currentImageSpec: currentSpec,
	})
}
Esempio n. 5
0
func (s *S) TestPrepareImageForDeployNoProcfile(c *check.C) {
	srv, err := testing.NewServer("0.0.0.0:0", nil, nil)
	c.Assert(err, check.IsNil)
	defer srv.Stop()
	a := &app.App{Name: "myapp"}
	cli, err := docker.NewClient(srv.URL())
	c.Assert(err, check.IsNil)
	baseImgName := "baseImg"
	err = cli.PullImage(docker.PullImageOptions{Repository: baseImgName}, docker.AuthConfiguration{})
	c.Assert(err, check.IsNil)
	srv.CustomHandler(fmt.Sprintf("/images/%s/json", baseImgName), http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		response := docker.Image{
			Config: &docker.Config{
				Entrypoint:   []string{"/bin/sh"},
				Cmd:          []string{"python", "test file.py"},
				ExposedPorts: map[docker.Port]struct{}{"3000/tcp": {}},
			},
		}
		j, _ := json.Marshal(response)
		w.Write(j)
	}))
	buf := bytes.Buffer{}
	args := PrepareImageArgs{
		Client:      cli,
		App:         a,
		ProcfileRaw: "",
		ImageId:     baseImgName,
		Out:         &buf,
	}
	newImg, err := PrepareImageForDeploy(args)
	c.Assert(err, check.IsNil)
	c.Assert(newImg, check.Equals, "my.registry/tsuru/app-myapp:v1")
	c.Assert(buf.String(), check.Equals, `---- Inspecting image "baseImg" ----
  ---> Procfile not found, using entrypoint and cmd
  ---> Process "web" found with commands: ["/bin/sh" "python" "test file.py"]
---- Pushing image "my.registry/tsuru/app-myapp:v1" to tsuru ----
Pushing...
Pushed
`)
	imd, err := image.GetImageCustomData(newImg)
	c.Assert(err, check.IsNil)
	c.Assert(imd, check.DeepEquals, image.ImageMetadata{
		Name:            "my.registry/tsuru/app-myapp:v1",
		Processes:       map[string][]string{"web": {"/bin/sh", "python", "test file.py"}},
		CustomData:      map[string]interface{}{},
		LegacyProcesses: map[string]string{},
		ExposedPort:     "3000/tcp",
	})
}
Esempio n. 6
0
func allAppProcesses(appName string) ([]string, error) {
	var processes []string
	imgID, err := image.AppCurrentImageName(appName)
	if err != nil {
		return nil, errors.WithStack(err)
	}
	data, err := image.GetImageCustomData(imgID)
	if err != nil {
		return nil, errors.WithStack(err)
	}
	for procName := range data.Processes {
		processes = append(processes, procName)
	}
	return processes, nil
}
Esempio n. 7
0
func (s *S) TestSaveImageCustomDataProcfile(c *check.C) {
	img1 := "tsuru/app-myapp:v1"
	customData1 := map[string]interface{}{
		"exposedPort": "3434",
		"procfile":    "worker1: python myapp.py\nworker2: someworker",
	}
	err := image.SaveImageCustomData(img1, customData1)
	c.Assert(err, check.IsNil)
	imageMetaData, err := image.GetImageCustomData(img1)
	c.Check(err, check.IsNil)
	c.Check(imageMetaData.ExposedPort, check.Equals, "3434")
	c.Check(imageMetaData.Processes, check.DeepEquals, map[string][]string{
		"worker1": {"python myapp.py"},
		"worker2": {"someworker"},
	})
}
Esempio n. 8
0
func ProcessCmdForImage(processName, imageId string) ([]string, string, error) {
	data, err := image.GetImageCustomData(imageId)
	if err != nil {
		return nil, "", err
	}
	if processName == "" {
		if len(data.Processes) == 0 {
			return nil, "", nil
		}
		if len(data.Processes) > 1 {
			return nil, "", provision.InvalidProcessError{Msg: "no process name specified and more than one declared in Procfile"}
		}
		for name := range data.Processes {
			processName = name
		}
	}
	processCmd := data.Processes[processName]
	if len(processCmd) == 0 {
		return nil, "", provision.InvalidProcessError{Msg: fmt.Sprintf("no command declared in Procfile for process %q", processName)}
	}
	return processCmd, processName, nil
}
Esempio n. 9
0
func (p *dockerProvisioner) AddUnits(a provision.App, units uint, process string, w io.Writer) error {
	if a.GetDeploys() == 0 {
		return errors.New("New units can only be added after the first deployment")
	}
	if units == 0 {
		return errors.New("Cannot add 0 units")
	}
	if w == nil {
		w = ioutil.Discard
	}
	writer := io.MultiWriter(w, &app.LogWriter{App: a})
	imageId, err := image.AppCurrentImageName(a.GetName())
	if err != nil {
		return err
	}
	imageData, err := image.GetImageCustomData(imageId)
	if err != nil {
		return err
	}
	_, err = p.runCreateUnitsPipeline(writer, a, map[string]*containersToAdd{process: {Quantity: int(units)}}, imageId, imageData.ExposedPort)
	return err
}
Esempio n. 10
0
func (s *S) TestPrepareImageForDeploy(c *check.C) {
	srv, err := testing.NewServer("0.0.0.0:0", nil, nil)
	c.Assert(err, check.IsNil)
	defer srv.Stop()
	a := &app.App{Name: "myapp"}
	cli, err := docker.NewClient(srv.URL())
	c.Assert(err, check.IsNil)
	baseImgName := "baseImg"
	err = cli.PullImage(docker.PullImageOptions{Repository: baseImgName}, docker.AuthConfiguration{})
	c.Assert(err, check.IsNil)
	buf := bytes.Buffer{}
	args := PrepareImageArgs{
		Client:      cli,
		App:         a,
		ProcfileRaw: "web: myapp run",
		ImageId:     baseImgName,
		Out:         &buf,
	}
	newImg, err := PrepareImageForDeploy(args)
	c.Assert(err, check.IsNil)
	c.Assert(newImg, check.Equals, "my.registry/tsuru/app-myapp:v1")
	c.Assert(buf.String(), check.Equals, `---- Inspecting image "baseImg" ----
  ---> Process "web" found with commands: ["myapp run"]
---- Pushing image "my.registry/tsuru/app-myapp:v1" to tsuru ----
Pushing...
Pushed
`)
	imd, err := image.GetImageCustomData(newImg)
	c.Assert(err, check.IsNil)
	c.Assert(imd, check.DeepEquals, image.ImageMetadata{
		Name:            "my.registry/tsuru/app-myapp:v1",
		Processes:       map[string][]string{"web": {"myapp run"}},
		CustomData:      map[string]interface{}{},
		LegacyProcesses: map[string]string{},
	})
}