Пример #1
0
func (s *S) TestRollbackWithWrongVersionImage(c *check.C) {
	a := App{
		Name:      "otherapp",
		Plan:      Plan{Router: "fake"},
		Platform:  "zend",
		Teams:     []string{s.team.Name},
		TeamOwner: s.team.Name,
	}
	err := CreateApp(&a, s.user)
	c.Assert(err, check.IsNil)
	err = image.AppendAppImageName("otherapp", "registry.somewhere/tsuru/app-example:v1")
	c.Assert(err, check.IsNil)
	err = image.AppendAppImageName("otherapp", "registry.somewhere/tsuru/app-example:v2")
	c.Assert(err, check.IsNil)
	err = image.AppendAppImageName("invalid", "127.0.0.1:5000/tsuru/app-tsuru-dashboard:v2")
	c.Assert(err, check.IsNil)
	writer := &bytes.Buffer{}
	evt, err := event.New(&event.Opts{
		Target:   event.Target{Type: "app", Value: a.Name},
		Kind:     permission.PermAppDeploy,
		RawOwner: event.Owner{Type: event.OwnerTypeUser, Name: s.user.Email},
		Allowed:  event.Allowed(permission.PermApp),
	})
	c.Assert(err, check.IsNil)
	imgID, err := Deploy(DeployOptions{
		App:          &a,
		OutputStream: writer,
		Image:        "v20",
		Rollback:     true,
		Event:        evt,
	})
	c.Assert(err, check.NotNil)
	c.Assert(err, check.ErrorMatches, `^invalid version: "v20"$`)
	c.Assert(imgID, check.Equals, "")
}
Пример #2
0
func (s *S) TestDeleteAllAppImageNamesSimilarApps(c *check.C) {
	data := map[string]interface{}{"healthcheck": map[string]interface{}{"path": "/test"}}
	err := image.AppendAppImageName("myapp", "tsuru/app-myapp:v1")
	c.Assert(err, check.IsNil)
	err = image.SaveImageCustomData("tsuru/app-myapp:v1", data)
	c.Assert(err, check.IsNil)
	err = image.AppendAppImageName("myapp-dev", "tsuru/app-myapp-dev:v1")
	c.Assert(err, check.IsNil)
	err = image.SaveImageCustomData("tsuru/app-myapp-dev:v1", data)
	c.Assert(err, check.IsNil)
	err = image.DeleteAllAppImageNames("myapp")
	c.Assert(err, check.IsNil)
	_, err = image.ListAppImages("myapp")
	c.Assert(err, check.ErrorMatches, "not found")
	_, err = image.ListAppImages("myapp-dev")
	c.Assert(err, check.IsNil)
	yamlData, err := image.GetImageTsuruYamlData("tsuru/app-myapp:v1")
	c.Assert(err, check.IsNil)
	c.Assert(yamlData, check.DeepEquals, provision.TsuruYamlData{})
	yamlData, err = image.GetImageTsuruYamlData("tsuru/app-myapp-dev:v1")
	c.Assert(err, check.IsNil)
	c.Assert(yamlData, check.DeepEquals, provision.TsuruYamlData{
		Healthcheck: provision.TsuruYamlHealthcheck{Path: "/test"},
	})
}
Пример #3
0
func (s *S) TestListAppImages(c *check.C) {
	err := image.AppendAppImageName("myapp", "tsuru/app-myapp:v1")
	c.Assert(err, check.IsNil)
	err = image.AppendAppImageName("myapp", "tsuru/app-myapp:v2")
	c.Assert(err, check.IsNil)
	images, err := image.ListAppImages("myapp")
	c.Assert(err, check.IsNil)
	c.Assert(images, check.DeepEquals, []string{"tsuru/app-myapp:v1", "tsuru/app-myapp:v2"})
}
Пример #4
0
func (s *S) TestDeleteAllAppImageNames(c *check.C) {
	err := image.AppendAppImageName("myapp", "tsuru/app-myapp:v1")
	c.Assert(err, check.IsNil)
	err = image.AppendAppImageName("myapp", "tsuru/app-myapp:v2")
	c.Assert(err, check.IsNil)
	err = image.DeleteAllAppImageNames("myapp")
	c.Assert(err, check.IsNil)
	_, err = image.ListAppImages("myapp")
	c.Assert(err, check.ErrorMatches, "not found")
}
Пример #5
0
func (s *S) TestAppCurrentImageName(c *check.C) {
	err := image.AppendAppImageName("myapp", "tsuru/app-myapp:v1")
	c.Assert(err, check.IsNil)
	img1, err := image.AppCurrentImageName("myapp")
	c.Assert(err, check.IsNil)
	c.Assert(img1, check.Equals, "tsuru/app-myapp:v1")
	err = image.AppendAppImageName("myapp", "tsuru/app-myapp:v2")
	c.Assert(err, check.IsNil)
	img2, err := image.AppCurrentImageName("myapp")
	c.Assert(err, check.IsNil)
	c.Assert(img2, check.Equals, "tsuru/app-myapp:v2")
}
Пример #6
0
func (s *S) TestValidListAppImages(c *check.C) {
	config.Set("docker:image-history-size", 2)
	defer config.Unset("docker:image-history-size")
	err := image.AppendAppImageName("myapp", "tsuru/app-myapp:v1")
	c.Assert(err, check.IsNil)
	err = image.AppendAppImageName("myapp", "tsuru/app-myapp:v2")
	c.Assert(err, check.IsNil)
	err = image.AppendAppImageName("myapp", "tsuru/app-myapp:v3")
	c.Assert(err, check.IsNil)
	images, err := image.ListValidAppImages("myapp")
	c.Assert(err, check.IsNil)
	c.Assert(images, check.DeepEquals, []string{"tsuru/app-myapp:v2", "tsuru/app-myapp:v3"})
}
Пример #7
0
func (s *S) TestSwarmNodeUnits(c *check.C) {
	srv, err := testing.NewServer("127.0.0.1:0", nil, nil)
	c.Assert(err, check.IsNil)
	defer srv.Stop()
	opts := provision.AddNodeOptions{Address: srv.URL()}
	err = s.p.AddNode(opts)
	c.Assert(err, check.IsNil)
	nodes, err := s.p.ListNodes(nil)
	c.Assert(err, check.IsNil)
	c.Assert(nodes, check.HasLen, 1)
	units, err := nodes[0].Units()
	c.Assert(err, check.IsNil)
	c.Assert(units, check.HasLen, 0)
	a := &app.App{Name: "myapp", TeamOwner: s.team.Name, Deploys: 1}
	err = app.CreateApp(a, s.user)
	c.Assert(err, check.IsNil)
	imgName := "myapp:v1"
	err = image.SaveImageCustomData(imgName, map[string]interface{}{
		"processes": map[string]interface{}{
			"web": "python myapp.py",
		},
	})
	c.Assert(err, check.IsNil)
	err = image.AppendAppImageName(a.GetName(), imgName)
	c.Assert(err, check.IsNil)
	err = s.p.AddUnits(a, 1, "web", nil)
	c.Assert(err, check.IsNil)
	units, err = nodes[0].Units()
	c.Assert(err, check.IsNil)
	c.Assert(units, check.HasLen, 1)
}
Пример #8
0
func (s *S) TestPullAppImageNamesRemovesCustomData(c *check.C) {
	img1Name := "tsuru/app-myapp:v1"
	err := image.AppendAppImageName("myapp", img1Name)
	c.Assert(err, check.IsNil)
	err = image.AppendAppImageName("myapp", "tsuru/app-myapp:v2")
	c.Assert(err, check.IsNil)
	err = image.AppendAppImageName("myapp", "tsuru/app-myapp:v3")
	c.Assert(err, check.IsNil)
	data := map[string]interface{}{"healthcheck": map[string]interface{}{"path": "/test"}}
	err = image.SaveImageCustomData(img1Name, data)
	c.Assert(err, check.IsNil)
	err = image.PullAppImageNames("myapp", []string{img1Name})
	c.Assert(err, check.IsNil)
	images, err := image.ListAppImages("myapp")
	c.Assert(err, check.IsNil)
	c.Assert(images, check.DeepEquals, []string{"tsuru/app-myapp:v2", "tsuru/app-myapp:v3"})
	yamlData, err := image.GetImageTsuruYamlData(img1Name)
	c.Assert(err, check.IsNil)
	c.Assert(yamlData, check.DeepEquals, provision.TsuruYamlData{})
}
Пример #9
0
func (s *S) TestDeleteAllAppImageNamesRemovesCustomData(c *check.C) {
	imgName := "tsuru/app-myapp:v1"
	err := image.AppendAppImageName("myapp", imgName)
	c.Assert(err, check.IsNil)
	data := map[string]interface{}{"healthcheck": map[string]interface{}{"path": "/test"}}
	err = image.SaveImageCustomData(imgName, data)
	c.Assert(err, check.IsNil)
	err = image.DeleteAllAppImageNames("myapp")
	c.Assert(err, check.IsNil)
	_, err = image.ListAppImages("myapp")
	c.Assert(err, check.ErrorMatches, "not found")
	yamlData, err := image.GetImageTsuruYamlData(imgName)
	c.Assert(err, check.IsNil)
	c.Assert(yamlData, check.DeepEquals, provision.TsuruYamlData{})
}
Пример #10
0
func (s *DeploySuite) TestDeployRollbackHandlerWithOnlyVersionImage(c *check.C) {
	user, _ := s.token.User()
	a := app.App{Name: "otherapp", Platform: "python", TeamOwner: s.team.Name}
	err := app.CreateApp(&a, user)
	c.Assert(err, check.IsNil)
	err = image.AppendAppImageName("otherapp", "127.0.0.1:5000/tsuru/app-tsuru-dashboard:v1")
	c.Assert(err, check.IsNil)
	v := url.Values{}
	v.Set("origin", "rollback")
	v.Set("image", "v1")
	u := fmt.Sprintf("/apps/%s/deploy/rollback", a.Name)
	request, err := http.NewRequest("POST", u, strings.NewReader(v.Encode()))
	c.Assert(err, check.IsNil)
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	recorder := httptest.NewRecorder()
	request.Header.Set("Authorization", "bearer "+s.token.GetValue())
	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")
	c.Assert(recorder.Code, check.Equals, http.StatusOK)
	c.Assert(recorder.Body.String(), check.Equals, "{\"Message\":\"Rollback deploy called\"}\n")
	c.Assert(eventtest.EventDesc{
		Target: appTarget(a.Name),
		Owner:  s.token.GetUserName(),
		Kind:   "app.deploy",
		StartCustomData: map[string]interface{}{
			"app.name":   a.Name,
			"commit":     "",
			"filesize":   0,
			"kind":       "rollback",
			"archiveurl": "",
			"user":       s.token.GetUserName(),
			"image":      "v1",
			"origin":     "rollback",
			"build":      false,
			"rollback":   true,
		},
		EndCustomData: map[string]interface{}{
			"image": "127.0.0.1:5000/tsuru/app-tsuru-dashboard:v1",
		},
		LogMatches: `Rollback deploy called`,
	}, eventtest.HasEvent)
}
Пример #11
0
func (s *S) TestListFilteredDeploys(c *check.C) {
	team := &auth.Team{Name: "team"}
	err := s.conn.Teams().Insert(team)
	c.Assert(err, check.IsNil)
	a := App{
		Name:      "g1",
		Platform:  "zend",
		TeamOwner: s.team.Name,
	}
	err = CreateApp(&a, s.user)
	c.Assert(err, check.IsNil)
	a = App{
		Name:      "ge",
		Platform:  "zend",
		TeamOwner: team.Name,
	}
	err = CreateApp(&a, s.user)
	c.Assert(err, check.IsNil)
	err = image.AppendAppImageName("ge", "app-image")
	c.Assert(err, check.IsNil)
	insert := []DeployData{
		{App: "g1", Timestamp: time.Now().Add(-3600 * time.Second)},
		{App: "ge", Timestamp: time.Now(), Image: "app-image"},
	}
	insertDeploysAsEvents(insert, c)
	expected := []DeployData{insert[1], insert[0]}
	expected[0].CanRollback = true
	normalizeTS(expected)
	f := &Filter{}
	f.ExtraIn("teams", team.Name)
	deploys, err := ListDeploys(f, 0, 0)
	c.Assert(err, check.IsNil)
	normalizeTS(deploys)
	c.Assert(deploys, check.DeepEquals, []DeployData{expected[0]})
	f = &Filter{}
	f.ExtraIn("name", "g1")
	deploys, err = ListDeploys(f, 0, 0)
	c.Assert(err, check.IsNil)
	normalizeTS(deploys)
	c.Assert(deploys, check.DeepEquals, []DeployData{expected[1]})
}
Пример #12
0
func (s *S) TestRemoveOldRoutesForwardNoImageData(c *check.C) {
	app := provisiontest.NewFakeApp("myapp", "python", 1)
	err := image.AppendAppImageName(app.GetName(), "img1")
	c.Assert(err, check.IsNil)
	err = image.PullAppImageNames(app.GetName(), []string{"img1"})
	c.Assert(err, check.IsNil)
	routertest.FakeRouter.AddBackend(app.GetName())
	defer routertest.FakeRouter.RemoveBackend(app.GetName())
	cont1 := container.Container{ID: "ble-1", AppName: app.GetName(), ProcessName: "", HostAddr: "127.0.0.1", HostPort: ""}
	args := changeUnitsPipelineArgs{
		app:         app,
		toRemove:    []container.Container{cont1},
		provisioner: s.p,
	}
	context := action.FWContext{Previous: []container.Container{}, Params: []interface{}{args}}
	r, err := removeOldRoutes.Forward(context)
	c.Assert(err, check.IsNil)
	hasRoute := routertest.FakeRouter.HasRoute(app.GetName(), cont1.Address().String())
	c.Assert(hasRoute, check.Equals, false)
	containers := r.([]container.Container)
	c.Assert(containers, check.DeepEquals, []container.Container{})
	c.Assert(args.toRemove[0].Routable, check.Equals, false)
}
Пример #13
0
	},
	Backward: func(ctx action.BWContext) {
	},
	MinParams: 1,
}

var updateAppImage = action.Action{
	Name: "update-app-image",
	Forward: func(ctx action.FWContext) (action.Result, error) {
		args := ctx.Params[0].(changeUnitsPipelineArgs)
		if err := checkCanceled(args.event); err != nil {
			return nil, err
		}
		currentImageName, _ := image.AppCurrentImageName(args.app.GetName())
		if currentImageName != args.imageId {
			err := image.AppendAppImageName(args.app.GetName(), args.imageId)
			if err != nil {
				return nil, errors.Wrap(err, "unable to save image name")
			}
		}
		imgHistorySize := image.ImageHistorySize()
		allImages, err := image.ListAppImages(args.app.GetName())
		if err != nil {
			log.Errorf("Couldn't list images for cleaning: %s", err)
			return ctx.Previous, nil
		}
		for i, imgName := range allImages {
			if i > len(allImages)-imgHistorySize-1 {
				err := args.provisioner.Cluster().RemoveImageIgnoreLast(imgName)
				if err != nil {
					log.Debugf("Ignored error removing old image %q: %s", imgName, err.Error())
Пример #14
0
			return nil, err
		}
		return deployedProcesses, nil
	},
	Backward: func(ctx action.BWContext) {
		args := ctx.Params[0].(*pipelineArgs)
		deployedProcesses := ctx.FWResult.([]string)
		rollbackAddedProcesses(args, deployedProcesses)
	},
}

var updateImageInDB = &action.Action{
	Name: "update-image-in-db",
	Forward: func(ctx action.FWContext) (action.Result, error) {
		args := ctx.Params[0].(*pipelineArgs)
		err := image.AppendAppImageName(args.app.GetName(), args.newImage)
		if err != nil {
			return nil, errors.WithStack(err)
		}
		return ctx.Previous, nil
	},
}

var removeOldServices = &action.Action{
	Name: "remove-old-services",
	Forward: func(ctx action.FWContext) (action.Result, error) {
		args := ctx.Params[0].(*pipelineArgs)
		old := set.FromMap(args.currentImageSpec)
		new := set.FromMap(args.newImageSpec)
		for processName := range old.Difference(new) {
			err := removeService(args.client, args.app, processName)