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