// 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), }, }, ) }
// 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 }
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 }
// 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 }
// 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) }
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) }
// 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 }
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) }
// 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 }
// 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 }