예제 #1
0
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)
}
예제 #2
0
파일: app.go 프로젝트: janqii/tsuru
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
}
예제 #3
0
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)
}
예제 #4
0
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")
}
예제 #5
0
파일: auth.go 프로젝트: rpeterson/tsuru
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)
}
예제 #6
0
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)
}
예제 #7
0
파일: app.go 프로젝트: janqii/tsuru
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
}
예제 #8
0
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)
}
예제 #9
0
파일: app.go 프로젝트: janqii/tsuru
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
}
예제 #10
0
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)
}
예제 #11
0
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"])
	}
}
예제 #12
0
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)
}
예제 #13
0
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)
	}
}
예제 #14
0
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)
}
예제 #15
0
		}
		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()