Example #1
0
File: app.go Project: tsuru/tsuru
// RemoveUnits removes n units from the app. It's a process composed of
// multiple steps:
//
//     1. Remove units from the provisioner
//     2. Update quota
func (app *App) RemoveUnits(n uint, process string, writer io.Writer) error {
	prov, err := app.getProvisioner()
	if err != nil {
		return err
	}
	err = prov.RemoveUnits(app, n, process, writer)
	rebuild.RoutesRebuildOrEnqueue(app.Name)
	if err != nil {
		return err
	}
	conn, err := db.Conn()
	if err != nil {
		return err
	}
	defer conn.Close()
	units, err := app.Units()
	if err != nil {
		return err
	}
	return conn.Apps().Update(
		bson.M{"name": app.Name},
		bson.M{
			"$set": bson.M{
				"quota.inuse": len(units),
			},
		},
	)
}
Example #2
0
File: app.go Project: tsuru/tsuru
// AddUnits creates n new units within the provisioner, saves new units in the
// database and enqueues the apprc serialization.
func (app *App) AddUnits(n uint, process string, writer io.Writer) error {
	if n == 0 {
		return errors.New("Cannot add zero units.")
	}
	err := action.NewPipeline(
		&reserveUnitsToAdd,
		&provisionAddUnits,
	).Execute(app, n, writer, process)
	rebuild.RoutesRebuildOrEnqueue(app.Name)
	return err
}
Example #3
0
File: app.go Project: tsuru/tsuru
func (app *App) RemoveCName(cnames ...string) error {
	actions := []*action.Action{
		&checkCNameExists,
		&unsetCNameFromProvisioner,
		&removeCNameFromDatabase,
		&removeCNameFromApp,
	}
	err := action.NewPipeline(actions...).Execute(app, cnames)
	rebuild.RoutesRebuildOrEnqueue(app.Name)
	return err
}
Example #4
0
File: app.go Project: tsuru/tsuru
// AddCName adds a CName to app. It updates the attribute,
// calls the SetCName function on the provisioner and saves
// the app in the database, returning an error when it cannot save the change
// in the database or add the CName on the provisioner.
func (app *App) AddCName(cnames ...string) error {
	actions := []*action.Action{
		&validateNewCNames,
		&setNewCNamesToProvisioner,
		&saveCNames,
		&updateApp,
	}
	err := action.NewPipeline(actions...).Execute(app, cnames)
	rebuild.RoutesRebuildOrEnqueue(app.Name)
	return err
}
Example #5
0
File: app.go Project: tsuru/tsuru
// Swap calls the Router.Swap and updates the app.CName in the database.
func Swap(app1, app2 *App, cnameOnly bool) error {
	r1, err := app1.Router()
	if err != nil {
		return err
	}
	r2, err := app2.Router()
	if err != nil {
		return err
	}
	defer rebuild.RoutesRebuildOrEnqueue(app1.Name)
	defer rebuild.RoutesRebuildOrEnqueue(app2.Name)
	err = r1.Swap(app1.Name, app2.Name, cnameOnly)
	if err != nil {
		return err
	}
	conn, err := db.Conn()
	if err != nil {
		return err
	}
	defer conn.Close()
	app1.CName, app2.CName = app2.CName, app1.CName
	updateCName := func(app *App, r router.Router) error {
		app.Ip, err = r.Addr(app.Name)
		if err != nil {
			return err
		}
		return conn.Apps().Update(
			bson.M{"name": app.Name},
			bson.M{"$set": bson.M{"cname": app.CName, "ip": app.Ip}},
		)
	}
	err = updateCName(app1, r1)
	if err != nil {
		return err
	}
	return updateCName(app2, r2)
}
Example #6
0
func (s *S) TestRoutesRebuildOrEnqueueNoError(c *check.C) {
	a := &app.App{
		Name:      "almah",
		Platform:  "static",
		TeamOwner: s.team.Name,
	}
	err := app.CreateApp(a, s.user)
	c.Assert(err, check.IsNil)
	invalidAddr, err := url.Parse("http://invalid.addr")
	c.Assert(err, check.IsNil)
	err = routertest.FakeRouter.AddRoute(a.GetName(), invalidAddr)
	c.Assert(err, check.IsNil)
	rebuild.RoutesRebuildOrEnqueue(a.GetName())
	c.Assert(routertest.FakeRouter.HasRoute(a.GetName(), invalidAddr.String()), check.Equals, false)
}
Example #7
0
File: app.go Project: tsuru/tsuru
// Start starts the app calling the provisioner.Start method and
// changing the units state to StatusStarted.
func (app *App) Start(w io.Writer, process string) error {
	msg := fmt.Sprintf("\n ---> Starting the process %q\n", process)
	if process == "" {
		msg = fmt.Sprintf("\n ---> Starting the app %q\n", app.Name)
	}
	log.Write(w, []byte(msg))
	prov, err := app.getProvisioner()
	if err != nil {
		return err
	}
	err = prov.Start(app, process)
	if err != nil {
		log.Errorf("[start] error on start the app %s - %s", app.Name, err)
		return err
	}
	rebuild.RoutesRebuildOrEnqueue(app.Name)
	return err
}
Example #8
0
func (s *S) TestRoutesRebuildOrEnqueueForceEnqueue(c *check.C) {
	a := &app.App{
		Name:      "almah",
		Platform:  "static",
		TeamOwner: s.team.Name,
	}
	err := app.CreateApp(a, s.user)
	c.Assert(err, check.IsNil)
	invalidAddr, err := url.Parse("http://invalid.addr")
	c.Assert(err, check.IsNil)
	err = routertest.FakeRouter.AddRoute(a.GetName(), invalidAddr)
	c.Assert(err, check.IsNil)
	routertest.FakeRouter.FailForIp(invalidAddr.String())
	rebuild.RoutesRebuildOrEnqueue(a.GetName())
	c.Assert(routertest.FakeRouter.HasRoute(a.GetName(), invalidAddr.String()), check.Equals, true)
	routertest.FakeRouter.RemoveFailForIp(invalidAddr.String())
	err = queue.TestingWaitQueueTasks(1, 10*time.Second)
	c.Assert(err, check.IsNil)
	c.Assert(routertest.FakeRouter.HasRoute(a.GetName(), invalidAddr.String()), check.Equals, false)
}
Example #9
0
File: app.go Project: tsuru/tsuru
// Restart runs the restart hook for the app, writing its output to w.
func (app *App) Restart(process string, w io.Writer) error {
	msg := fmt.Sprintf("---- Restarting process %q ----\n", process)
	if process == "" {
		msg = fmt.Sprintf("---- Restarting the app %q ----\n", app.Name)
	}
	err := log.Write(w, []byte(msg))
	if err != nil {
		log.Errorf("[restart] error on write app log for the app %s - %s", app.Name, err)
		return err
	}
	prov, err := app.getProvisioner()
	if err != nil {
		return err
	}
	err = prov.Restart(app, process, w)
	if err != nil {
		log.Errorf("[restart] error on restart the app %s - %s", app.Name, err)
		return err
	}
	rebuild.RoutesRebuildOrEnqueue(app.Name)
	return nil
}
Example #10
0
// Deploy runs a deployment of an application. It will first try to run an
// archive based deploy (if opts.ArchiveURL is not empty), and then fallback to
// the Git based deployment.
func Deploy(opts DeployOptions) (string, error) {
	if opts.Event == nil {
		return "", errors.Errorf("missing event in deploy opts")
	}
	if opts.Rollback && !regexp.MustCompile(":v[0-9]+$").MatchString(opts.Image) {
		validImages, err := findValidImages(*opts.App)
		if err == nil {
			inputImage := opts.Image
			for img := range validImages {
				if strings.HasSuffix(img, opts.Image) {
					opts.Image = img
					break
				}
			}
			if opts.Image == inputImage {
				return "", errors.Errorf("invalid version: %q", inputImage)
			}
		}
	}
	logWriter := LogWriter{App: opts.App}
	logWriter.Async()
	defer logWriter.Close()
	opts.Event.SetLogWriter(io.MultiWriter(&tsuruIo.NoErrorWriter{Writer: opts.OutputStream}, &logWriter))
	imageId, err := deployToProvisioner(&opts, opts.Event)
	rebuild.RoutesRebuildOrEnqueue(opts.App.Name)
	if err != nil {
		return "", err
	}
	err = incrementDeploy(opts.App)
	if err != nil {
		log.Errorf("WARNING: couldn't increment deploy count, deploy opts: %#v", opts)
	}
	if opts.App.UpdatePlatform {
		opts.App.SetUpdatePlatform(false)
	}
	return imageId, nil
}