func (s segregatedScheduler) Schedule(opts docker.CreateContainerOptions) (string, *docker.Container, error) { conn, err := db.Conn() if err != nil { return "", nil, err } defer conn.Close() var cont container coll := collection() defer coll.Close() err = coll.Find(bson.M{"name": opts.Name}).One(&cont) if err != nil { return "", nil, err } app, err := app.GetByName(cont.AppName) if err != nil { return s.fallback(opts) } var nodes []node query := bson.M{"teams": bson.M{"$in": app.Teams}} err = conn.Collection(schedulerCollection).Find(query).All(&nodes) if err != nil || len(nodes) < 1 { return s.fallback(opts) } return s.handle(opts, nodes) }
func addLog(w http.ResponseWriter, r *http.Request, t *auth.Token) error { queryValues := r.URL.Query() app, err := app.GetByName(queryValues.Get(":app")) if err != nil { return err } defer r.Body.Close() body, err := ioutil.ReadAll(r.Body) if err != nil { return err } var logs []string err = json.Unmarshal(body, &logs) source := queryValues.Get("source") if len(source) == 0 { source = "app" } for _, log := range logs { err := app.Log(log, source) if err != nil { return err } } w.WriteHeader(http.StatusOK) return nil }
func (s *S) TestUpdateTwice(c *gocheck.C) { a := getApp(s.conn, c) defer s.conn.Apps().Remove(bson.M{"name": a.Name}) out := getOutput() update(out) a, err := app.GetByName(a.Name) c.Assert(err, gocheck.IsNil) c.Assert(a.Units[0].Ip, gocheck.Equals, "192.168.0.11") c.Assert(a.Units[0].Machine, gocheck.Equals, 1) c.Assert(a.Units[0].InstanceId, gocheck.Equals, "i-0800") c.Assert(a.Units[0].State, gocheck.Equals, provision.StatusStarted.String()) update(out) a, err = app.GetByName(a.Name) c.Assert(err, gocheck.IsNil) c.Assert(len(a.Units), gocheck.Equals, 1) }
func (s *S) TestUpdateWithMultipleUnits(c *gocheck.C) { a := getApp(s.conn, c) out := getOutput() u := provision.Unit{ Name: "i-00000zz9", AppName: "umaappqq", Type: "python", Machine: 2, InstanceId: "i-0900", Ip: "192.168.0.12", Status: provision.StatusStarted, } out = append(out, u) update(out) a, err := app.GetByName(a.Name) c.Assert(err, gocheck.IsNil) c.Assert(len(a.Units), gocheck.Equals, 2) var unit app.Unit for _, unit = range a.Units { if unit.Machine == 2 { break } } c.Assert(unit.Name, gocheck.Equals, "i-00000zz9") c.Assert(unit.Ip, gocheck.Equals, "192.168.0.12") c.Assert(unit.InstanceId, gocheck.Equals, "i-0900") c.Assert(unit.State, gocheck.Equals, provision.StatusStarted.String()) addr, _ := s.provisioner.Addr(a) c.Assert(a.Ip, gocheck.Equals, addr) c.Assert(a.State, gocheck.Equals, "ready") }
func generateAppToken(w http.ResponseWriter, r *http.Request, t *auth.Token) error { var body jToken defer r.Body.Close() err := json.NewDecoder(r.Body).Decode(&body) if err != nil { return err } if body.Client == "" { return &errors.HTTP{ Code: http.StatusBadRequest, Message: "Missing client name in JSON body", } } token, err := auth.CreateApplicationToken(body.Client) if err != nil { return err } if body.Export { if a, err := app.GetByName(body.Client); err == nil { envs := []bind.EnvVar{ { Name: "TSURU_APP_TOKEN", Value: token.Token, Public: false, }, } a.SetEnvs(envs, false) } } return json.NewEncoder(w).Encode(token) }
func (s *S) TestSaveUnitsForwardShouldMaintainData(c *gocheck.C) { a := app.App{ Name: "otherapp", Platform: "zend", Deploys: 10, } conn, err := db.Conn() c.Assert(err, gocheck.IsNil) defer conn.Close() err = conn.Apps().Insert(a) c.Assert(err, gocheck.IsNil) a.Deploys = 0 defer conn.Apps().Remove(bson.M{"name": a.Name}) container := container{ ID: "id", Type: "python", HostAddr: "", AppName: a.Name, } coll := collection() c.Assert(err, gocheck.IsNil) coll.Insert(&container) context := action.FWContext{Params: []interface{}{&a}} _, err = saveUnits.Forward(context) c.Assert(err, gocheck.IsNil) app, err := app.GetByName(a.Name) c.Assert(err, gocheck.IsNil) c.Assert(app.Units[0].Name, gocheck.Equals, "id") c.Assert(int(app.Deploys), gocheck.Equals, 10) }
func appIsAvailable(w http.ResponseWriter, r *http.Request, t *auth.Token) error { app, err := app.GetByName(r.URL.Query().Get(":appname")) if err != nil { return err } if !app.Available() { return fmt.Errorf("App must be available to receive pushs.") } w.WriteHeader(http.StatusOK) return nil }
func (s *S) TestUnbindRemovesEnvironmentVariableFromApp(c *gocheck.C) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNoContent) })) defer ts.Close() srvc := service.Service{Name: "mysql", Endpoint: map[string]string{"production": ts.URL}} err := srvc.Create() c.Assert(err, gocheck.IsNil) defer s.conn.Services().Remove(bson.M{"_id": "mysql"}) instance := service.ServiceInstance{ Name: "my-mysql", ServiceName: "mysql", Teams: []string{s.team.Name}, Apps: []string{"painkiller"}, } err = instance.Create() c.Assert(err, gocheck.IsNil) defer s.conn.ServiceInstances().Remove(bson.M{"name": "my-mysql"}) a := app.App{ Name: "painkiller", Teams: []string{s.team.Name}, Env: map[string]bind.EnvVar{ "DATABASE_HOST": { Name: "DATABASE_HOST", Value: "arrea", Public: false, InstanceName: instance.Name, }, "MY_VAR": { Name: "MY_VAR", Value: "123", }, }, Units: []app.Unit{ { Ip: "10.10.10.10", }, }, } err = s.conn.Apps().Insert(&a) c.Assert(err, gocheck.IsNil) defer s.conn.Apps().Remove(bson.M{"name": a.Name}) err = instance.UnbindApp(&a) c.Assert(err, gocheck.IsNil) newApp, err := app.GetByName(a.Name) c.Assert(err, gocheck.IsNil) expected := map[string]bind.EnvVar{ "MY_VAR": { Name: "MY_VAR", Value: "123", }, } c.Assert(newApp.Env, gocheck.DeepEquals, expected) }
func getApp(name string, u *auth.User) (app.App, error) { a, err := app.GetByName(name) if err != nil { return app.App{}, &errors.HTTP{Code: http.StatusNotFound, Message: fmt.Sprintf("App %s not found.", name)} } if u.IsAdmin() { return *a, nil } if !auth.CheckUserAccess(a.Teams, u) { return *a, &errors.HTTP{Code: http.StatusForbidden, Message: "User does not have access to this app"} } return *a, nil }
func deploy(w http.ResponseWriter, r *http.Request, t *auth.Token) error { version := r.PostFormValue("version") if version == "" { return &errors.HTTP{Code: http.StatusBadRequest, Message: "Missing parameter version"} } w.Header().Set("Content-Type", "text") appName := r.URL.Query().Get(":appname") instance, err := app.GetByName(appName) if err != nil { return &errors.HTTP{Code: http.StatusNotFound, Message: fmt.Sprintf("App %s not found.", appName)} } return app.DeployApp(instance, version, w) }
func (s *S) TestUpdateWithMultipleApps(c *gocheck.C) { appDicts := []map[string]string{ { "name": "andrewzito3", "ip": "10.10.10.163", }, { "name": "flaviapp", "ip": "10.10.10.208", }, { "name": "mysqlapi", "ip": "10.10.10.131", }, { "name": "teste_api_semantica", "ip": "10.10.10.189", }, { "name": "xikin", "ip": "10.10.10.168", }, } apps := make([]app.App, len(appDicts)) units := make([]provision.Unit, len(appDicts)) for i, appDict := range appDicts { a := app.App{Name: appDict["name"]} err := s.conn.Apps().Insert(&a) c.Assert(err, gocheck.IsNil) apps[i] = a units[i] = provision.Unit{ Name: "i-00000", AppName: appDict["name"], Machine: i + 1, Type: "python", Ip: appDict["ip"], Status: provision.StatusBuilding, } } update(units) for _, appDict := range appDicts { a, err := app.GetByName(appDict["name"]) c.Assert(err, gocheck.IsNil) c.Assert(a.Units[0].Ip, gocheck.Equals, appDict["ip"]) } }
func (s *S) TestUpdateWithDownMachine(c *gocheck.C) { a := app.App{Name: "barduscoapp"} err := s.conn.Apps().Insert(&a) c.Assert(err, gocheck.IsNil) units := []provision.Unit{ { Name: "i-00000zz8", AppName: "barduscoapp", Type: "python", Machine: 2, Ip: "", Status: provision.StatusBuilding, }, } update(units) _, err = app.GetByName(a.Name) c.Assert(err, gocheck.IsNil) }
func update(units []provision.Unit) { log.Debug("updating status from provisioner") var l AppList var err error for _, unit := range units { a, index := l.Search(unit.AppName) if index > -1 { a, err = app.GetByName(unit.AppName) if err != nil { log.Errorf("collector: app %q not found. Skipping.\n", unit.AppName) continue } a.Units = nil l.Add(a, index) } u := app.Unit{} u.Name = unit.Name u.Type = unit.Type u.Machine = unit.Machine u.InstanceId = unit.InstanceId u.Ip = unit.Ip if unit.Status == provision.StatusStarted && a.State == "" { a.State = "ready" } u.State = string(unit.Status) a.AddUnit(&u) } conn, err := db.Conn() if err != nil { log.Errorf("collector failed to connect to the database: %s", err) return } defer conn.Close() for _, a := range l { a.Ip, err = app.Provisioner.Addr(a) if err != nil { log.Errorf("collector failed to get app (%q) address: %s", a.Name, err) } conn.Apps().Update(bson.M{"name": a.Name}, a) } }
func (s *S) TestBindCallTheServiceAPIAndSetsEnvironmentVariableReturnedFromTheCall(c *gocheck.C) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte(`{"DATABASE_USER":"******","DATABASE_PASSWORD":"******"}`)) })) defer ts.Close() srvc := service.Service{Name: "mysql", Endpoint: map[string]string{"production": ts.URL}} err := srvc.Create() c.Assert(err, gocheck.IsNil) defer s.conn.Services().Remove(bson.M{"_id": "mysql"}) instance := service.ServiceInstance{ Name: "my-mysql", ServiceName: "mysql", Teams: []string{s.team.Name}, } err = instance.Create() c.Assert(err, gocheck.IsNil) defer s.conn.ServiceInstances().Remove(bson.M{"name": "my-mysql"}) a, err := createTestApp(s.conn, "painkiller", "", []string{s.team.Name}, []app.Unit{{Ip: "127.0.0.1"}}) c.Assert(err, gocheck.IsNil) defer s.conn.Apps().Remove(bson.M{"name": a.Name}) err = instance.BindApp(&a) c.Assert(err, gocheck.IsNil) newApp, err := app.GetByName(a.Name) c.Assert(err, gocheck.IsNil) expectedEnv := map[string]bind.EnvVar{ "DATABASE_USER": { Name: "DATABASE_USER", Value: "root", Public: false, InstanceName: instance.Name, }, "DATABASE_PASSWORD": { Name: "DATABASE_PASSWORD", Value: "s3cr3t", Public: false, InstanceName: instance.Name, }, } c.Assert(newApp.Env, gocheck.DeepEquals, expectedEnv) }
} go injectEnvsAndRestart(app) return nil, nil }, Backward: func(ctx action.BWContext) { }, } var saveUnits = action.Action{ Name: "save-units", Forward: func(ctx action.FWContext) (action.Result, error) { a, ok := ctx.Params[0].(*app.App) if !ok { return nil, errors.New("First parameter must be a *app.App.") } a, err := app.GetByName(a.Name) if err != nil { return nil, err } containers, err := listAppContainers(a.GetName()) if err != nil { return nil, err } for _, c := range containers { var status string addr := strings.Replace(c.getAddress(), "http://", "", 1) conn, err := net.Dial("tcp", addr) if err != nil { status = provision.StatusUnreachable.String() } else { conn.Close()