func main() { var ( configFile string dry bool ) logger, err := syslog.NewLogger(syslog.LOG_INFO, stdlog.LstdFlags) if err != nil { stdlog.Fatal(err) } log.SetLogger(logger) flag.StringVar(&configFile, "config", "/etc/tsuru/tsuru.conf", "tsuru config file") flag.BoolVar(&dry, "dry", false, "dry-run: does not start the agent (for testing purposes)") flag.Parse() err = config.ReadConfigFile(configFile) if err != nil { fatal(err) } connString, err := config.GetString("database:url") if err != nil { fatal(err) } dbName, err := config.GetString("database:name") if err != nil { fatal(err) } db.Session, err = db.Open(connString, dbName) if err != nil { fatal(err) } defer db.Session.Close() fmt.Printf("Connected to MongoDB server at %s.\n", connString) fmt.Printf("Using the database %q.\n\n", dbName) if !dry { provisioner, err := config.GetString("provisioner") if err != nil { fmt.Printf("Warning: %q didn't declare a provisioner, using default provisioner.\n", configFile) provisioner = "juju" } app.Provisioner, err = provision.Get(provisioner) if err != nil { fatal(err) } fmt.Printf("Using %q provisioner.\n\n", provisioner) qServer, err := config.GetString("queue-server") if err != nil { fatal(err) } fmt.Printf("Connected to queue server at %s.\n", qServer) go handleMessages() ticker := time.Tick(time.Minute) fmt.Println("tsuru collector agent started...") jujuCollect(ticker) } }
func (s *S) TestPosRestartWhenAppConfDoesNotExists(c *C) { a := App{Name: "something", Framework: "django"} w := new(bytes.Buffer) l := stdlog.New(w, "", stdlog.LstdFlags) log.SetLogger(l) err := a.posRestart(w) c.Assert(err, IsNil) st := strings.Split(w.String(), "\n") c.Assert(st[len(st)-2], Matches, ".*Skipping pos-restart hooks...") }
func (s *S) TestPreRestartWhenAppConfDoesNotExist(c *gocheck.C) { a := App{Name: "something", Framework: "django"} w := new(bytes.Buffer) l := stdlog.New(w, "", stdlog.LstdFlags) log.SetLogger(l) err := a.preRestart(w) c.Assert(err, gocheck.IsNil) st := strings.Split(w.String(), "\n") regexp := ".*Skipping pre-restart hooks..." c.Assert(st[0], gocheck.Matches, regexp) }
func (s *S) TestNewContainerReturnsContainerWithoutIdAndLogsOnError(c *gocheck.C) { w := new(bytes.Buffer) l := stdlog.New(w, "", stdlog.LstdFlags) log.SetLogger(l) tmpdir, err := commandmocker.Error("docker", "cool error", 1) c.Assert(err, gocheck.IsNil) defer commandmocker.Remove(tmpdir) app := testing.NewFakeApp("myapp", "python", 1) container, err := newContainer(app, deployContainerCmd) c.Assert(err, gocheck.NotNil) c.Assert(container.id, gocheck.Equals, "") c.Assert(w.String(), gocheck.Matches, "(?s).*Error creating container myapp.*") }
func (s *S) TestNewContainerReturnsNilAndLogsOnError(c *gocheck.C) { w := new(bytes.Buffer) l := stdlog.New(w, "", stdlog.LstdFlags) log.SetLogger(l) tmpdir, err := commandmocker.Error("docker", "cool error", 1) c.Assert(err, gocheck.IsNil) defer commandmocker.Remove(tmpdir) app := testing.NewFakeApp("myapp", "python", 1) container, err := newContainer(app) c.Assert(err, gocheck.NotNil) defer s.conn.Collection(s.collName).Remove(bson.M{"appname": app.GetName()}) c.Assert(container, gocheck.IsNil) c.Assert(w.String(), gocheck.Matches, `(?s).*Error creating container for the app "myapp".*`) }
func (s *S) TestProvisionerDestroyEmptyUnit(c *gocheck.C) { fexec := &etesting.FakeExecutor{} setExecut(fexec) defer setExecut(nil) w := new(bytes.Buffer) l := stdlog.New(w, "", stdlog.LstdFlags) log.SetLogger(l) app := testing.NewFakeApp("myapp", "python", 0) app.AddUnit(&testing.FakeUnit{}) var p dockerProvisioner p.Provision(app) err := p.Destroy(app) c.Assert(err, gocheck.IsNil) }
func (s *S) TestProvisionerDestroy(c *gocheck.C) { fexec := &etesting.FakeExecutor{} execut = fexec defer func() { execut = nil }() w := new(bytes.Buffer) l := stdlog.New(w, "", stdlog.LstdFlags) log.SetLogger(l) app := testing.NewFakeApp("myapp", "python", 1) u := provision.Unit{ Name: app.ProvisionUnits()[0].GetName(), AppName: app.GetName(), Machine: app.ProvisionUnits()[0].GetMachine(), InstanceId: app.ProvisionUnits()[0].GetInstanceId(), Status: provision.StatusCreating, } err := s.conn.Collection(s.collName).Insert(&u) c.Assert(err, gocheck.IsNil) img := image{Name: app.GetName()} err = s.conn.Collection(s.imageCollName).Insert(&img) c.Assert(err, gocheck.IsNil) var p DockerProvisioner c.Assert(p.Destroy(app), gocheck.IsNil) ok := make(chan bool, 1) go func() { for { coll := s.conn.Collection(s.collName) ct, err := coll.Find(bson.M{"name": u.Name}).Count() if err != nil { c.Fatal(err) } if ct == 0 { ok <- true return } runtime.Gosched() } }() select { case <-ok: case <-time.After(10e9): c.Error("Timed out waiting for the container to be destroyed (10 seconds)") } args := []string{"stop", "i-01"} c.Assert(fexec.ExecutedCmd("docker", args), gocheck.Equals, true) args = []string{"rm", "i-01"} c.Assert(fexec.ExecutedCmd("docker", args), gocheck.Equals, true) }
func (s *S) TestSkipsPosRestartWhenPosRestartSectionDoesNotExists(c *C) { a := App{ Name: "something", Framework: "django", Units: []Unit{{State: string(provision.StatusStarted), Machine: 1}}, hooks: &conf{PreRestart: []string{"somescript.sh"}}, } w := new(bytes.Buffer) l := stdlog.New(w, "", stdlog.LstdFlags) log.SetLogger(l) err := a.posRestart(w) c.Assert(err, IsNil) st := strings.Split(w.String(), "\n") c.Assert(st[len(st)-2], Matches, ".*Skipping pos-restart hooks...") }
func (s *S) TestProvisionerDestroy(c *gocheck.C) { fexec := &etesting.FakeExecutor{} setExecut(fexec) defer setExecut(nil) w := new(bytes.Buffer) l := stdlog.New(w, "", stdlog.LstdFlags) log.SetLogger(l) app := testing.NewFakeApp("myapp", "python", 1) cont := container{ Id: app.ProvisionUnits()[0].GetName(), AppName: app.GetName(), } err := s.conn.Collection(s.collName).Insert(cont) c.Assert(err, gocheck.IsNil) defer s.conn.Collection(s.collName).RemoveId(cont.Id) s.conn.Collection(s.collName).Insert(container{Id: "something-01", AppName: app.GetName()}) defer s.conn.Collection(s.collName).RemoveId("something-01") img := image{Name: app.GetName()} err = s.conn.Collection(s.imageCollName).Insert(&img) c.Assert(err, gocheck.IsNil) var p dockerProvisioner p.Provision(app) c.Assert(p.Destroy(app), gocheck.IsNil) ok := make(chan bool, 1) go func() { coll := s.conn.Collection(s.collName) for { ct, err := coll.Find(bson.M{"appname": cont.AppName}).Count() if err != nil { c.Fatal(err) } if ct == 0 { ok <- true return } runtime.Gosched() } }() select { case <-ok: case <-time.After(10e9): c.Fatal("Timed out waiting for the container to be destroyed (10 seconds)") } args := []string{"rm", "myapp/0"} c.Assert(fexec.ExecutedCmd("docker", args), gocheck.Equals, true) c.Assert(rtesting.FakeRouter.HasBackend("myapp"), gocheck.Equals, false) }
func Run(flags map[string]interface{}) { logger, err := syslog.NewLogger(syslog.LOG_INFO, stdlog.LstdFlags) if err != nil { stdlog.Fatal(err) } log.SetLogger(logger) configFile, ok := flags["config"].(string) if !ok { configFile = "/etc/tsuru/tsuru.conf" } dry, ok := flags["dry"].(bool) if !ok { dry = false } err = config.ReadAndWatchConfigFile(configFile) if err != nil { fatal(err) } connString, err := config.GetString("database:url") if err != nil { fatal(err) } dbName, err := config.GetString("database:name") if err != nil { fatal(err) } fmt.Printf("Using the database %q from the server %q.\n\n", dbName, connString) if !dry { provisioner, err := config.GetString("provisioner") if err != nil { fmt.Printf("Warning: %q didn't declare a provisioner, using default provisioner.\n", configFile) provisioner = "juju" } app.Provisioner, err = provision.Get(provisioner) if err != nil { fatal(err) } fmt.Printf("Using %q provisioner.\n\n", provisioner) ticker := time.Tick(time.Minute) fmt.Println("tsuru collector agent started...") collect(ticker) } }
func main() { logger, err := syslog.NewLogger(syslog.LOG_INFO, stdlog.LstdFlags) if err != nil { stdlog.Fatal(err) } log.SetLogger(logger) configFile := flag.String("config", "/etc/tsuru/tsuru.conf", "tsuru config file") dry := flag.Bool("dry", false, "dry-run: does not start the server (for testing purpose)") flag.Parse() err = config.ReadAndWatchConfigFile(*configFile) if err != nil { fatal(err) } connString, err := config.GetString("database:url") if err != nil { fatal(err) } dbName, err := config.GetString("database:name") if err != nil { fatal(err) } fmt.Printf("Using the database %q from the server %q.\n\n", dbName, connString) m := pat.New() m.Get("/services/instances", AuthorizationRequiredHandler(ServicesInstancesHandler)) m.Post("/services/instances", AuthorizationRequiredHandler(CreateInstanceHandler)) m.Put("/services/instances/:instance/:app", AuthorizationRequiredHandler(BindHandler)) m.Del("/services/instances/:instance/:app", AuthorizationRequiredHandler(UnbindHandler)) m.Del("/services/c/instances/:name", AuthorizationRequiredHandler(RemoveServiceInstanceHandler)) m.Get("/services/instances/:instance/status", AuthorizationRequiredHandler(ServiceInstanceStatusHandler)) m.Get("/services", AuthorizationRequiredHandler(ServicesHandler)) m.Post("/services", AuthorizationRequiredHandler(CreateHandler)) m.Put("/services", AuthorizationRequiredHandler(UpdateHandler)) m.Del("/services/:name", AuthorizationRequiredHandler(DeleteHandler)) m.Get("/services/:name", AuthorizationRequiredHandler(ServiceInfoHandler)) m.Get("/services/c/:name/doc", AuthorizationRequiredHandler(Doc)) m.Get("/services/:name/doc", AuthorizationRequiredHandler(GetDocHandler)) m.Put("/services/:name/doc", AuthorizationRequiredHandler(AddDocHandler)) m.Put("/services/:service/:team", AuthorizationRequiredHandler(GrantServiceAccessToTeamHandler)) m.Del("/services/:service/:team", AuthorizationRequiredHandler(RevokeServiceAccessFromTeamHandler)) m.Del("/apps/:name", AuthorizationRequiredHandler(appDelete)) m.Get("/apps/:name/repository/clone", Handler(CloneRepositoryHandler)) m.Get("/apps/:name/avaliable", Handler(AppIsAvailableHandler)) m.Get("/apps/:name", AuthorizationRequiredHandler(AppInfo)) m.Post("/apps/:name", AuthorizationRequiredHandler(setCName)) m.Post("/apps/:name/run", AuthorizationRequiredHandler(RunCommand)) m.Get("/apps/:name/restart", AuthorizationRequiredHandler(RestartHandler)) m.Get("/apps/:name/env", AuthorizationRequiredHandler(GetEnv)) m.Post("/apps/:name/env", AuthorizationRequiredHandler(SetEnv)) m.Del("/apps/:name/env", AuthorizationRequiredHandler(UnsetEnv)) m.Get("/apps", AuthorizationRequiredHandler(AppList)) m.Post("/apps", AuthorizationRequiredHandler(CreateAppHandler)) m.Put("/apps/:name/units", AuthorizationRequiredHandler(AddUnitsHandler)) m.Del("/apps/:name/units", AuthorizationRequiredHandler(RemoveUnitsHandler)) m.Put("/apps/:app/:team", AuthorizationRequiredHandler(GrantAccessToTeamHandler)) m.Del("/apps/:app/:team", AuthorizationRequiredHandler(RevokeAccessFromTeamHandler)) m.Get("/apps/:name/log", AuthorizationRequiredHandler(appLog)) m.Post("/apps/:name/log", Handler(AddLogHandler)) m.Post("/users", Handler(CreateUser)) m.Post("/users/:email/tokens", Handler(Login)) m.Put("/users/password", AuthorizationRequiredHandler(ChangePassword)) m.Del("/users", AuthorizationRequiredHandler(RemoveUser)) m.Post("/users/keys", AuthorizationRequiredHandler(AddKeyToUser)) m.Del("/users/keys", AuthorizationRequiredHandler(RemoveKeyFromUser)) m.Get("/teams", AuthorizationRequiredHandler(ListTeams)) m.Post("/teams", AuthorizationRequiredHandler(CreateTeam)) m.Del("/teams/:name", AuthorizationRequiredHandler(RemoveTeam)) m.Put("/teams/:team/:user", AuthorizationRequiredHandler(AddUserToTeam)) m.Del("/teams/:team/:user", AuthorizationRequiredHandler(RemoveUserFromTeam)) m.Get("/healers", Handler(healers)) m.Get("/healers/:healer", Handler(healer)) if !*dry { provisioner, err := config.GetString("provisioner") if err != nil { fmt.Printf("Warning: %q didn't declare a provisioner, using default provisioner.\n", configFile) provisioner = "juju" } app.Provisioner, err = provision.Get(provisioner) if err != nil { fatal(err) } fmt.Printf("Using %q provisioner.\n\n", provisioner) listen, err := config.GetString("listen") if err != nil { fatal(err) } tls, _ := config.GetBool("use-tls") if tls { certFile, err := config.GetString("tls-cert-file") if err != nil { fatal(err) } keyFile, err := config.GetString("tls-key-file") if err != nil { fatal(err) } fmt.Printf("tsuru HTTP/TLS server listening at %s...\n", listen) fatal(http.ListenAndServeTLS(listen, certFile, keyFile, m)) } else { fmt.Printf("tsuru HTTP server listening at %s...\n", listen) fatal(http.ListenAndServe(listen, m)) } } }
func (s *S) TestHandleMessageErrors(c *C) { var data = []struct { action string args []string unitName string expectedLog string visits int }{ { action: "unknown-action", args: []string{"does not matter"}, expectedLog: `Error handling "unknown-action": invalid action.`, }, { action: app.StartApp, args: []string{"nemesis"}, expectedLog: `Error handling "start-app" for the app "nemesis":` + ` The status of the app and all units should be "started" (the app is "pending").`, }, { action: app.StartApp, args: []string{"totem", "totem/0", "totem/1"}, expectedLog: `Error handling "start-app" for the app "totem":` + ` The status of the app and all units should be "started" (the app is "started").`, }, { action: app.RegenerateApprc, args: []string{"nemesis"}, expectedLog: `Error handling "regenerate-apprc" for the app "nemesis":` + ` The status of the app and all units should be "started" (the app is "pending").`, }, { action: app.RegenerateApprc, args: []string{"totem", "totem/0", "totem/1"}, expectedLog: `Error handling "regenerate-apprc" for the app "totem":` + ` The status of the app and all units should be "started" (the app is "started").`, }, { action: app.RegenerateApprc, args: []string{"unknown-app"}, expectedLog: `Error handling "regenerate-apprc": app "unknown-app" does not exist.`, }, { action: app.RegenerateApprc, expectedLog: `Error handling "regenerate-apprc": this action requires at least 1 argument.`, }, { action: "does not matter", args: []string{"does not matter"}, expectedLog: `Error handling "does not matter": this message has been visited more than 50 times.`, visits: MaxVisits, }, { action: app.RegenerateApprc, args: []string{"marathon"}, expectedLog: `Error handling "regenerate-apprc" for the app "marathon":` + ` the app is in "error" state.`, }, { action: app.RegenerateApprc, args: []string{"territories"}, expectedLog: `Error handling "regenerate-apprc" for the app "territories":` + ` the app is down.`, }, } var buf bytes.Buffer a := app.App{Name: "nemesis", State: "pending"} err := db.Session.Apps().Insert(a) c.Assert(err, IsNil) defer db.Session.Apps().Remove(bson.M{"name": a.Name}) a = app.App{ Name: "totem", State: "started", Units: []app.Unit{ {Name: "totem/0", State: "pending"}, {Name: "totem/1", State: "started"}, }, } err = db.Session.Apps().Insert(a) c.Assert(err, IsNil) defer db.Session.Apps().Remove(bson.M{"name": a.Name}) a = app.App{Name: "marathon", State: "error"} err = db.Session.Apps().Insert(a) c.Assert(err, IsNil) defer db.Session.Apps().Remove(bson.M{"name": a.Name}) a = app.App{Name: "territories", State: "down"} err = db.Session.Apps().Insert(a) c.Assert(err, IsNil) defer db.Session.Apps().Remove(bson.M{"name": a.Name}) log.SetLogger(stdlog.New(&buf, "", 0)) handler := MessageHandler{} handler.start() handler.closed = 1 defer handler.stop() for _, d := range data { message := queue.Message{ Action: d.action, Visits: d.visits, } if len(d.args) > 0 { message.Args = d.args } handler.handle(message) } content := buf.String() lines := strings.Split(content, "\n") for i, d := range data { var found bool for j := i; j < len(lines); j++ { if lines[j] == d.expectedLog { found = true break } } if !found { c.Errorf("\nWant: %q.\nGot:\n%s", d.expectedLog, content) } } }
func main() { logger, err := syslog.NewLogger(syslog.LOG_INFO, stdlog.LstdFlags) if err != nil { stdlog.Fatal(err) } log.SetLogger(logger) configFile := flag.String("config", "/etc/tsuru/tsuru.conf", "tsuru config file") dry := flag.Bool("dry", false, "dry-run: does not start the server (for testing purpose)") flag.Parse() err = config.ReadConfigFile(*configFile) if err != nil { fatal(err) } connString, err := config.GetString("database:url") if err != nil { fatal(err) } dbName, err := config.GetString("database:name") if err != nil { fatal(err) } db.Session, err = db.Open(connString, dbName) if err != nil { fatal(err) } defer db.Session.Close() fmt.Printf("Connected to MongoDB server at %s.\n", connString) fmt.Printf("Using the database %q.\n\n", dbName) m := pat.New() m.Get("/services/instances", AuthorizationRequiredHandler(consumption.ServicesInstancesHandler)) m.Post("/services/instances", AuthorizationRequiredHandler(consumption.CreateInstanceHandler)) m.Put("/services/instances/:instance/:app", AuthorizationRequiredHandler(api.BindHandler)) m.Del("/services/instances/:instance/:app", AuthorizationRequiredHandler(api.UnbindHandler)) m.Del("/services/c/instances/:name", AuthorizationRequiredHandler(consumption.RemoveServiceInstanceHandler)) m.Get("/services/instances/:instance/status", AuthorizationRequiredHandler(consumption.ServiceInstanceStatusHandler)) m.Get("/services", AuthorizationRequiredHandler(service_provision.ServicesHandler)) m.Post("/services", AuthorizationRequiredHandler(service_provision.CreateHandler)) m.Put("/services", AuthorizationRequiredHandler(service_provision.UpdateHandler)) m.Del("/services/:name", AuthorizationRequiredHandler(service_provision.DeleteHandler)) m.Get("/services/:name", AuthorizationRequiredHandler(consumption.ServiceInfoHandler)) m.Get("/services/c/:name/doc", AuthorizationRequiredHandler(consumption.Doc)) m.Get("/services/:name/doc", AuthorizationRequiredHandler(service_provision.GetDocHandler)) m.Put("/services/:name/doc", AuthorizationRequiredHandler(service_provision.AddDocHandler)) m.Put("/services/:service/:team", AuthorizationRequiredHandler(service_provision.GrantAccessToTeamHandler)) m.Del("/services/:service/:team", AuthorizationRequiredHandler(service_provision.RevokeAccessFromTeamHandler)) m.Del("/apps/:name", AuthorizationRequiredHandler(api.AppDelete)) m.Get("/apps/:name/repository/clone", Handler(api.CloneRepositoryHandler)) m.Get("/apps/:name/avaliable", Handler(api.AppIsAvaliableHandler)) m.Get("/apps/:name", AuthorizationRequiredHandler(api.AppInfo)) m.Post("/apps/:name/run", AuthorizationRequiredHandler(api.RunCommand)) m.Get("/apps/:name/restart", AuthorizationRequiredHandler(api.RestartHandler)) m.Get("/apps/:name/env", AuthorizationRequiredHandler(api.GetEnv)) m.Post("/apps/:name/env", AuthorizationRequiredHandler(api.SetEnv)) m.Del("/apps/:name/env", AuthorizationRequiredHandler(api.UnsetEnv)) m.Get("/apps", AuthorizationRequiredHandler(api.AppList)) m.Post("/apps", AuthorizationRequiredHandler(api.CreateAppHandler)) m.Put("/apps/:name/units", AuthorizationRequiredHandler(api.AddUnitsHandler)) m.Put("/apps/:app/:team", AuthorizationRequiredHandler(api.GrantAccessToTeamHandler)) m.Del("/apps/:app/:team", AuthorizationRequiredHandler(api.RevokeAccessFromTeamHandler)) m.Get("/apps/:name/log", AuthorizationRequiredHandler(api.AppLog)) m.Post("/apps/:name/log", Handler(api.AddLogHandler)) m.Post("/users", Handler(auth.CreateUser)) m.Post("/users/:email/tokens", Handler(auth.Login)) m.Put("/users/password", AuthorizationRequiredHandler(auth.ChangePassword)) m.Del("/users", AuthorizationRequiredHandler(auth.RemoveUser)) m.Post("/users/keys", AuthorizationRequiredHandler(auth.AddKeyToUser)) m.Del("/users/keys", AuthorizationRequiredHandler(auth.RemoveKeyFromUser)) m.Get("/teams", AuthorizationRequiredHandler(auth.ListTeams)) m.Post("/teams", AuthorizationRequiredHandler(auth.CreateTeam)) m.Del("/teams/:name", AuthorizationRequiredHandler(auth.RemoveTeam)) m.Put("/teams/:team/:user", AuthorizationRequiredHandler(auth.AddUserToTeam)) m.Del("/teams/:team/:user", AuthorizationRequiredHandler(auth.RemoveUserFromTeam)) if !*dry { provisioner, err := config.GetString("provisioner") if err != nil { fmt.Printf("Warning: %q didn't declare a provisioner, using default provisioner.\n", configFile) provisioner = "juju" } app.Provisioner, err = provision.Get(provisioner) if err != nil { fatal(err) } fmt.Printf("Using %q provisioner.\n\n", provisioner) listen, err := config.GetString("listen") if err != nil { fatal(err) } fmt.Printf("tsuru HTTP server listening at %s...\n", listen) fatal(http.ListenAndServe(listen, m)) } }
func (s *S) TestHandleMessageErrors(c *gocheck.C) { var data = []struct { action string args []string unitName string expectedLog string }{ { action: "unknown-action", args: []string{"does not matter"}, expectedLog: `Error handling "unknown-action": invalid action.`, }, { action: startApp, args: []string{"nemesis"}, expectedLog: `Error handling "start-app" for the app "nemesis":` + ` all units must be started.`, }, { action: startApp, args: []string{"totem", "totem/0", "totem/1"}, expectedLog: `Error handling "start-app" for the app "totem":` + ` all units must be started.`, }, { action: regenerateApprc, args: []string{"nemesis"}, expectedLog: `Error handling "regenerate-apprc" for the app "nemesis":` + ` all units must be started.`, }, { action: regenerateApprc, args: []string{"totem", "totem/0", "totem/1"}, expectedLog: `Error handling "regenerate-apprc" for the app "totem":` + ` all units must be started.`, }, { action: regenerateApprc, args: []string{"unknown-app"}, expectedLog: `Error handling "regenerate-apprc": app "unknown-app" does not exist.`, }, { action: regenerateApprc, expectedLog: `Error handling "regenerate-apprc": this action requires at least 1 argument.`, }, { action: regenerateApprc, args: []string{"marathon", "marathon/0"}, expectedLog: `Error handling "regenerate-apprc" for the app "marathon":` + ` units are in "error" state.`, }, { action: regenerateApprc, args: []string{"territories", "territories/0"}, expectedLog: `Error handling "regenerate-apprc" for the app "territories":` + ` units are in "down" state.`, }, } var buf bytes.Buffer a := App{Name: "nemesis"} err := s.conn.Apps().Insert(a) c.Assert(err, gocheck.IsNil) defer s.conn.Apps().Remove(bson.M{"name": a.Name}) a = App{ Name: "totem", Units: []Unit{ {Name: "totem/0", State: "pending"}, {Name: "totem/1", State: "started"}, }, } err = s.conn.Apps().Insert(a) c.Assert(err, gocheck.IsNil) defer s.conn.Apps().Remove(bson.M{"name": a.Name}) a = App{Name: "marathon", Units: []Unit{{Name: "marathon/0", State: "error"}}} err = s.conn.Apps().Insert(a) c.Assert(err, gocheck.IsNil) defer s.conn.Apps().Remove(bson.M{"name": a.Name}) a = App{Name: "territories", Units: []Unit{{Name: "territories/0", State: "down"}}} err = s.conn.Apps().Insert(a) c.Assert(err, gocheck.IsNil) defer s.conn.Apps().Remove(bson.M{"name": a.Name}) log.SetLogger(stdlog.New(&buf, "", 0)) for _, d := range data { message := queue.Message{Action: d.action} if len(d.args) > 0 { message.Args = d.args } handle(&message) defer message.Delete() // Sanity } content := buf.String() lines := strings.Split(content, "\n") for i, d := range data { var found bool for j := i; j < len(lines); j++ { if lines[j] == d.expectedLog { found = true break } } if !found { c.Errorf("\nWant: %q.\nGot:\n%s", d.expectedLog, content) } } }
func NewFakeLogger() log.Logger { l := &FakeLogger{Buf: bytes.Buffer{}} log.SetLogger(l) return l }
func NewFakeLogger() log.Logger { var buf safe.Buffer l := &FakeLogger{Buf: buf} log.SetLogger(l) return l }
func RunServer(flags map[string]interface{}) { logger, err := syslog.NewLogger(syslog.LOG_INFO, stdlog.LstdFlags) if err != nil { stdlog.Fatal(err) } log.SetLogger(logger) configFile, ok := flags["config"].(string) if !ok { configFile = "/etc/tsuru/tsuru.conf" } dry, ok := flags["dry"].(bool) if !ok { dry = false } err = config.ReadAndWatchConfigFile(configFile) if err != nil { fatal(err) } connString, err := config.GetString("database:url") if err != nil { fatal(err) } dbName, err := config.GetString("database:name") if err != nil { fatal(err) } fmt.Printf("Using the database %q from the server %q.\n\n", dbName, connString) m := pat.New() m.Get("/schema/app", authorizationRequiredHandler(appSchema)) m.Get("/services/instances", authorizationRequiredHandler(serviceInstances)) m.Post("/services/instances", authorizationRequiredHandler(createServiceInstance)) m.Put("/services/instances/:instance/:app", authorizationRequiredHandler(bindServiceInstance)) m.Del("/services/instances/:instance/:app", authorizationRequiredHandler(unbindServiceInstance)) m.Del("/services/c/instances/:name", authorizationRequiredHandler(removeServiceInstance)) m.Get("/services/instances/:instance/status", authorizationRequiredHandler(serviceInstanceStatus)) m.Get("/services", authorizationRequiredHandler(serviceList)) m.Post("/services", authorizationRequiredHandler(serviceCreate)) m.Put("/services", authorizationRequiredHandler(serviceUpdate)) m.Del("/services/:name", authorizationRequiredHandler(serviceDelete)) m.Get("/services/:name", authorizationRequiredHandler(serviceInfo)) m.Get("/services/:name/doc", authorizationRequiredHandler(serviceDoc)) m.Put("/services/:name/doc", authorizationRequiredHandler(serviceAddDoc)) m.Put("/services/:service/:team", authorizationRequiredHandler(grantServiceAccess)) m.Del("/services/:service/:team", authorizationRequiredHandler(revokeServiceAccess)) m.Del("/apps/:app", authorizationRequiredHandler(appDelete)) m.Get("/apps/:app", authorizationRequiredHandler(appInfo)) m.Post("/apps/:app", authorizationRequiredHandler(setCName)) m.Post("/apps/:app/run", authorizationRequiredHandler(runCommand)) m.Get("/apps/:app/restart", authorizationRequiredHandler(restart)) m.Get("/apps/:app/env", authorizationRequiredHandler(getEnv)) m.Post("/apps/:app/env", authorizationRequiredHandler(setEnv)) m.Del("/apps/:app/env", authorizationRequiredHandler(unsetEnv)) m.Get("/apps", authorizationRequiredHandler(appList)) m.Post("/apps", authorizationRequiredHandler(createApp)) m.Put("/apps/:app/units", authorizationRequiredHandler(addUnits)) m.Del("/apps/:app/units", authorizationRequiredHandler(removeUnits)) m.Put("/apps/:app/:team", authorizationRequiredHandler(grantAppAccess)) m.Del("/apps/:app/:team", authorizationRequiredHandler(revokeAppAccess)) m.Get("/apps/:app/log", authorizationRequiredHandler(appLog)) m.Post("/apps/:app/log", authorizationRequiredHandler(addLog)) m.Get("/platforms", authorizationRequiredHandler(platformList)) // These handlers don't use :app on purpose. Using :app means that only // the token generate for the given app is valid, but these handlers // use a token generated for Gandalf. m.Get("/apps/:appname/available", authorizationRequiredHandler(appIsAvailable)) m.Get("/apps/:appname/repository/clone", authorizationRequiredHandler(cloneRepository)) if registrationEnabled, _ := config.GetBool("auth:user-registration"); registrationEnabled { m.Post("/users", handler(createUser)) } m.Post("/users/:email/password", handler(resetPassword)) m.Post("/users/:email/tokens", handler(login)) m.Del("/users/tokens", authorizationRequiredHandler(logout)) m.Put("/users/password", authorizationRequiredHandler(changePassword)) m.Del("/users", authorizationRequiredHandler(removeUser)) m.Post("/users/keys", authorizationRequiredHandler(addKeyToUser)) m.Del("/users/keys", authorizationRequiredHandler(removeKeyFromUser)) m.Post("/tokens", adminRequiredHandler(generateAppToken)) m.Get("/teams", authorizationRequiredHandler(teamList)) m.Post("/teams", authorizationRequiredHandler(createTeam)) m.Del("/teams/:name", authorizationRequiredHandler(removeTeam)) m.Put("/teams/:team/:user", authorizationRequiredHandler(addUserToTeam)) m.Del("/teams/:team/:user", authorizationRequiredHandler(removeUserFromTeam)) m.Get("/healers", authorizationRequiredHandler(healers)) m.Get("/healers/:healer", authorizationRequiredHandler(healer)) if !dry { provisioner, err := config.GetString("provisioner") if err != nil { fmt.Printf("Warning: %q didn't declare a provisioner, using default provisioner.\n", configFile) provisioner = "juju" } app.Provisioner, err = provision.Get(provisioner) if err != nil { fatal(err) } fmt.Printf("Using %q provisioner.\n\n", provisioner) listen, err := config.GetString("listen") if err != nil { fatal(err) } tls, _ := config.GetBool("use-tls") if tls { certFile, err := config.GetString("tls-cert-file") if err != nil { fatal(err) } keyFile, err := config.GetString("tls-key-file") if err != nil { fatal(err) } fmt.Printf("tsuru HTTP/TLS server listening at %s...\n", listen) fatal(http.ListenAndServeTLS(listen, certFile, keyFile, m)) } else { listener, err := net.Listen("tcp", listen) if err != nil { fatal(err) } fmt.Printf("tsuru HTTP server listening at %s...\n", listen) http.Handle("/", m) fatal(http.Serve(listener, nil)) } } }