func (s *S) TestAppLocker(c *gocheck.C) { appName := "myapp" conn, err := db.Conn() c.Assert(err, gocheck.IsNil) defer conn.Close() appDB := &app.App{Name: appName} defer conn.Apps().Remove(bson.M{"name": appName}) err = conn.Apps().Insert(appDB) c.Assert(err, gocheck.IsNil) locker := &appLocker{} hasLock := locker.lock(appName) c.Assert(hasLock, gocheck.Equals, true) c.Assert(locker.refCount[appName], gocheck.Equals, 1) appDB, err = app.GetByName(appName) c.Assert(err, gocheck.IsNil) c.Assert(appDB.Lock.Locked, gocheck.Equals, true) c.Assert(appDB.Lock.Owner, gocheck.Equals, app.InternalAppName) c.Assert(appDB.Lock.Reason, gocheck.Equals, "container-move") hasLock = locker.lock(appName) c.Assert(hasLock, gocheck.Equals, true) c.Assert(locker.refCount[appName], gocheck.Equals, 2) locker.unlock(appName) c.Assert(locker.refCount[appName], gocheck.Equals, 1) appDB, err = app.GetByName(appName) c.Assert(err, gocheck.IsNil) c.Assert(appDB.Lock.Locked, gocheck.Equals, true) locker.unlock(appName) c.Assert(locker.refCount[appName], gocheck.Equals, 0) appDB, err = app.GetByName(appName) c.Assert(err, gocheck.IsNil) c.Assert(appDB.Lock.Locked, gocheck.Equals, false) }
func (s *S) TestAppLocker(c *check.C) { appName := "myapp" appDB := &app.App{Name: appName} err := s.storage.Apps().Insert(appDB) c.Assert(err, check.IsNil) locker := &appLocker{} hasLock := locker.Lock(appName) c.Assert(hasLock, check.Equals, true) c.Assert(locker.refCount[appName], check.Equals, 1) appDB, err = app.GetByName(appName) c.Assert(err, check.IsNil) c.Assert(appDB.Lock.Locked, check.Equals, true) c.Assert(appDB.Lock.Owner, check.Equals, app.InternalAppName) c.Assert(appDB.Lock.Reason, check.Equals, "container-move") hasLock = locker.Lock(appName) c.Assert(hasLock, check.Equals, true) c.Assert(locker.refCount[appName], check.Equals, 2) locker.Unlock(appName) c.Assert(locker.refCount[appName], check.Equals, 1) appDB, err = app.GetByName(appName) c.Assert(err, check.IsNil) c.Assert(appDB.Lock.Locked, check.Equals, true) locker.Unlock(appName) c.Assert(locker.refCount[appName], check.Equals, 0) appDB, err = app.GetByName(appName) c.Assert(err, check.IsNil) c.Assert(appDB.Lock.Locked, check.Equals, false) }
func (s *HandlerSuite) TestLocksAppDuringAppRequests(c *check.C) { myApp := app.App{ Name: "my-app", } err := s.conn.Apps().Insert(myApp) c.Assert(err, check.IsNil) defer s.conn.Apps().Remove(bson.M{"name": myApp.Name}) recorder := httptest.NewRecorder() request, err := http.NewRequest("POST", "/apps/my-app/", nil) c.Assert(err, check.IsNil) request.Header.Set("Authorization", "bearer "+s.token.GetValue()) handler := func(w http.ResponseWriter, r *http.Request, t auth.Token) error { a, appErr := app.GetByName(r.URL.Query().Get(":app")) c.Assert(appErr, check.IsNil) c.Assert(a.Lock.Reason, check.Equals, "POST /apps/my-app/") c.Assert(a.Lock.Owner, check.Equals, s.token.GetUserName()) c.Assert(a.Lock.Locked, check.Equals, true) c.Assert(a.Lock.AcquireDate, check.NotNil) return nil } RegisterHandler("/apps/{app}/", "POST", authorizationRequiredHandler(handler)) defer resetHandlers() m := RunServer(true) m.ServeHTTP(recorder, request) c.Assert(recorder.Code, check.Equals, http.StatusOK) a, err := app.GetByName(request.URL.Query().Get(":app")) c.Assert(err, check.IsNil) c.Assert(a.Lock.Locked, check.Equals, false) }
func (s *S) TestRebuildRoutesTCPRoutes(c *check.C) { a := app.App{Name: "my-test-app", TeamOwner: s.team.Name} err := app.CreateApp(&a, s.user) c.Assert(err, check.IsNil) err = provisiontest.ProvisionerInstance.AddUnits(&a, 3, "web", nil) c.Assert(err, check.IsNil) units, err := a.Units() c.Assert(err, check.IsNil) for _, u := range units { routertest.FakeRouter.RemoveRoute(a.Name, u.Address) routertest.FakeRouter.AddRoute(a.Name, &url.URL{Scheme: "tcp", Host: u.Address.Host}) } changes, err := rebuild.RebuildRoutes(&a) c.Assert(err, check.IsNil) c.Assert(changes.Added, check.IsNil) c.Assert(changes.Removed, check.IsNil) routes, err := routertest.FakeRouter.Routes(a.Name) c.Assert(err, check.IsNil) c.Assert(routes, check.HasLen, 3) c.Assert(routertest.FakeRouter.HasRoute(a.Name, units[0].Address.Host), check.Equals, true) c.Assert(routertest.FakeRouter.HasRoute(a.Name, units[1].Address.Host), check.Equals, true) c.Assert(routertest.FakeRouter.HasRoute(a.Name, units[2].Address.Host), check.Equals, true) app, err := app.GetByName(a.Name) c.Assert(err, check.IsNil) addr, err := routertest.FakeRouter.Addr(app.Name) c.Assert(err, check.IsNil) c.Assert(app.Ip, check.Equals, addr) }
func listContainersHandler(w http.ResponseWriter, r *http.Request, t auth.Token) error { address := r.URL.Query().Get(":address") if address != "" { node, err := mainDockerProvisioner.Cluster().GetNode(address) if err != nil { return err } hasAccess := permission.Check(t, permission.PermNodeRead, permission.Context(permission.CtxPool, node.Metadata["pool"])) if !hasAccess { return permission.ErrUnauthorized } containerList, err := mainDockerProvisioner.listContainersByHost(address) if err != nil { return err } return json.NewEncoder(w).Encode(containerList) } appName := r.URL.Query().Get(":appname") a, err := app.GetByName(appName) if err != nil { return err } hasAccess := permission.Check(t, permission.PermNodeRead, permission.Context(permission.CtxPool, a.Pool)) if !hasAccess { return permission.ErrUnauthorized } containerList, err := mainDockerProvisioner.listContainersByApp(appName) if err != nil { return err } return json.NewEncoder(w).Encode(containerList) }
func getApp(name string) (*app.App, error) { a, err := app.GetByName(name) if err != nil { return nil, &errors.HTTP{Code: http.StatusNotFound, Message: fmt.Sprintf("App %s not found.", name)} } return a, nil }
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" } unit := queryValues.Get("unit") for _, log := range logs { err := app.Log(log, source, unit) if err != nil { return err } } w.WriteHeader(http.StatusOK) return nil }
func registerUnit(w http.ResponseWriter, r *http.Request, t auth.Token) error { appName := r.URL.Query().Get(":app") data, err := ioutil.ReadAll(r.Body) if err != nil { return err } val, err := url.ParseQuery(string(data)) if err != nil { return err } hostname := val.Get("hostname") var customData map[string]interface{} rawCustomData := val.Get("customdata") if rawCustomData != "" { err = json.Unmarshal([]byte(rawCustomData), &customData) if err != nil { return err } } a, err := app.GetByName(appName) if err != nil { return err } err = a.RegisterUnit(hostname, customData) if err != nil { if _, ok := err.(*provision.UnitNotFoundError); ok { return &errors.HTTP{Code: http.StatusNotFound, Message: err.Error()} } return err } return writeEnvVars(w, a) }
func (s *segregatedScheduler) Schedule(c *cluster.Cluster, opts docker.CreateContainerOptions, schedulerOpts cluster.SchedulerOptions) (cluster.Node, error) { schedOpts, _ := schedulerOpts.([]string) if len(schedOpts) != 2 { return cluster.Node{}, fmt.Errorf("invalid scheduler opts: %#v", schedulerOpts) } appName := schedOpts[0] processName := schedOpts[1] a, _ := app.GetByName(appName) nodes, err := s.provisioner.Nodes(a) if err != nil { return cluster.Node{}, err } nodes, err = s.filterByMemoryUsage(a, nodes, s.maxMemoryRatio, s.TotalMemoryMetadata) if err != nil { return cluster.Node{}, err } node, err := s.chooseNode(nodes, opts.Name, appName, processName) if err != nil { return cluster.Node{}, err } var pool string if len(nodes) > 0 { pool = nodes[0].Metadata["pool"] } err = bs.CreateContainer(node, pool, mainDockerProvisioner, false) if err != nil && err != docker.ErrContainerAlreadyExists { return cluster.Node{Address: node}, err } return cluster.Node{Address: node}, nil }
func deploy(w http.ResponseWriter, r *http.Request, t auth.Token) error { version := r.PostFormValue("version") archiveURL := r.PostFormValue("archive-url") if version == "" && archiveURL == "" { return &errors.HTTP{ Code: http.StatusBadRequest, Message: "you must specify either the version or the archive-url", } } if version != "" && archiveURL != "" { return &errors.HTTP{ Code: http.StatusBadRequest, Message: "you must specify either the version or the archive-url, but not both", } } commit := r.PostFormValue("commit") 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.Deploy(app.DeployOptions{ App: instance, Version: version, Commit: commit, ArchiveURL: archiveURL, OutputStream: w, }) }
func (s *QuotaSuite) TestChangeAppQuota(c *check.C) { conn, err := db.Conn() c.Assert(err, check.IsNil) defer conn.Close() a := &app.App{ Name: "shangrila", Quota: quota.Quota{Limit: 4, InUse: 2}, Teams: []string{s.team.Name}, } err = conn.Apps().Insert(a) c.Assert(err, check.IsNil) defer conn.Apps().Remove(bson.M{"name": a.Name}) body := bytes.NewBufferString("limit=40") request, _ := http.NewRequest("PUT", "/apps/shangrila/quota", body) request.Header.Set("Content-Type", "application/x-www-form-urlencoded") request.Header.Set("Authorization", "bearer "+s.token.GetValue()) recorder := httptest.NewRecorder() handler := RunServer(true) handler.ServeHTTP(recorder, request) c.Assert(recorder.Code, check.Equals, http.StatusOK) a, err = app.GetByName(a.Name) c.Assert(err, check.IsNil) c.Assert(a.Quota.InUse, check.Equals, 2) c.Assert(a.Quota.Limit, check.Equals, 40) c.Assert(eventtest.EventDesc{ Target: event.Target{Type: event.TargetTypeApp, Value: a.Name}, Owner: s.token.GetUserName(), Kind: "app.admin.quota", StartCustomData: []map[string]interface{}{ {"name": ":appname", "value": a.Name}, {"name": "limit", "value": "40"}, }, }, eventtest.HasEvent) }
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 (s *S) SetUpTest(c *check.C) { queue.ResetQueue() err := rebuild.RegisterTask(func(appName string) (rebuild.RebuildApp, error) { a, err := app.GetByName(appName) if err == app.ErrAppNotFound { return nil, nil } return a, err }) c.Assert(err, check.IsNil) routertest.FakeRouter.Reset() provisiontest.ProvisionerInstance.Reset() err = dbtest.ClearAllCollections(s.conn.Apps().Database) c.Assert(err, check.IsNil) s.user = &auth.User{Email: "*****@*****.**", Password: "******", Quota: quota.Unlimited} nativeScheme := auth.ManagedScheme(native.NativeScheme{}) app.AuthScheme = nativeScheme _, err = nativeScheme.Create(s.user) c.Assert(err, check.IsNil) s.team = &auth.Team{Name: "admin"} c.Assert(err, check.IsNil) err = s.conn.Teams().Insert(s.team) c.Assert(err, check.IsNil) err = provision.AddPool(provision.AddPoolOptions{ Name: "p1", Default: true, Provisioner: "fake", }) c.Assert(err, check.IsNil) }
func (p *dockerProvisioner) fixContainer(container *container.Container, info container.NetworkInfo) error { if info.HTTPHostPort == "" { return nil } appInstance, err := app.GetByName(container.AppName) if err != nil { return err } r, err := getRouterForApp(appInstance) if err != nil { return err } err = r.RemoveRoute(container.AppName, container.Address()) if err != nil && err != router.ErrRouteNotFound { return err } container.IP = info.IP container.HostPort = info.HTTPHostPort err = r.AddRoute(container.AppName, container.Address()) if err != nil && err != router.ErrRouteExists { return err } coll := p.Collection() defer coll.Close() return coll.Update(bson.M{"id": container.ID}, container) }
func (s *segregatedScheduler) Schedule(c *cluster.Cluster, opts docker.CreateContainerOptions, schedulerOpts cluster.SchedulerOptions) (cluster.Node, error) { schedOpts, ok := schedulerOpts.(*container.SchedulerOpts) if !ok { return cluster.Node{}, &container.SchedulerError{ Base: errors.Errorf("invalid scheduler opts: %#v", schedulerOpts), } } a, _ := app.GetByName(schedOpts.AppName) nodes, err := s.provisioner.Nodes(a) if err != nil { return cluster.Node{}, &container.SchedulerError{Base: err} } nodes, err = s.filterByMemoryUsage(a, nodes, s.maxMemoryRatio, s.TotalMemoryMetadata) if err != nil { return cluster.Node{}, &container.SchedulerError{Base: err} } node, err := s.chooseNodeToAdd(nodes, opts.Name, schedOpts.AppName, schedOpts.ProcessName) if err != nil { return cluster.Node{}, &container.SchedulerError{Base: err} } if schedOpts.ActionLimiter != nil { schedOpts.LimiterDone = schedOpts.ActionLimiter.Start(net.URLToHost(node)) } return cluster.Node{Address: node}, nil }
func (s *QuotaSuite) TestChangeAppQuota(c *check.C) { conn, err := db.Conn() c.Assert(err, check.IsNil) defer conn.Close() a := &app.App{ Name: "shangrila", Quota: quota.Quota{Limit: 4, InUse: 2}, Teams: []string{s.team.Name}, } err = conn.Apps().Insert(a) c.Assert(err, check.IsNil) defer conn.Apps().Remove(bson.M{"name": a.Name}) body := bytes.NewBufferString("limit=40") request, _ := http.NewRequest("PUT", "/apps/shangrila/quota", body) request.Header.Set("Content-Type", "application/x-www-form-urlencoded") request.Header.Set("Authorization", "bearer "+s.token.GetValue()) recorder := httptest.NewRecorder() handler := RunServer(true) handler.ServeHTTP(recorder, request) c.Assert(recorder.Code, check.Equals, http.StatusOK) a, err = app.GetByName(a.Name) c.Assert(err, check.IsNil) c.Assert(a.Quota.InUse, check.Equals, 2) c.Assert(a.Quota.Limit, check.Equals, 40) }
func moveOneContainer(c container, toHost string, errors chan error, wg *sync.WaitGroup, encoder *json.Encoder) { a, err := app.GetByName(c.AppName) defer wg.Done() if err != nil { errors <- err return } logProgress(encoder, "Moving unit %s for %q: %s -> %s...", c.ID, c.AppName, c.HostAddr, toHost) pipeline := action.NewPipeline( &provisionAddUnitToHost, &provisionRemoveOldUnit, ) err = pipeline.Execute(a, toHost, c) if err != nil { errors <- err return } logProgress(encoder, "Finished moving unit %s for %q.", c.ID, c.AppName) addedUnit := pipeline.Result().(provision.Unit) err = moveOneContainerInDB(a, c, addedUnit) if err != nil { errors <- err return } logProgress(encoder, "Moved unit %s -> %s for %s in DB.", c.ID, addedUnit.Name, c.AppName) }
func nodesForAppName(c *cluster.Cluster, appName string) ([]cluster.Node, error) { a, err := app.GetByName(appName) if err != nil { return nil, err } return nodesForApp(c, a) }
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 (a *memoryScaler) nodesMemoryData(prov *dockerProvisioner, nodes []*cluster.Node) (map[string]*nodeMemoryData, error) { nodesMemoryData := make(map[string]*nodeMemoryData) containersMap, err := prov.runningContainersByNode(nodes) if err != nil { return nil, err } for _, node := range nodes { totalMemory, _ := strconv.ParseFloat(node.Metadata[a.totalMemoryMetadata], 64) if totalMemory == 0.0 { return nil, fmt.Errorf("no value found for memory metadata (%s) in node %s", a.totalMemoryMetadata, node.Address) } maxMemory := int64(float64(a.maxMemoryRatio) * totalMemory) data := &nodeMemoryData{ containersMemory: make(map[string]int64), node: node, maxMemory: maxMemory, } nodesMemoryData[node.Address] = data for _, cont := range containersMap[node.Address] { a, err := app.GetByName(cont.AppName) if err != nil { return nil, fmt.Errorf("couldn't find container app (%s): %s", cont.AppName, err) } data.containersMemory[cont.ID] = a.Plan.Memory data.reserved += a.Plan.Memory } data.available = data.maxMemory - data.reserved } return nodesMemoryData, nil }
func setUnitStatus(w http.ResponseWriter, r *http.Request, t auth.Token) error { unitName := r.URL.Query().Get(":unit") if unitName == "" { return &errors.HTTP{ Code: http.StatusBadRequest, Message: "missing unit", } } postStatus := r.FormValue("status") status, err := provision.ParseStatus(postStatus) if err != nil { return &errors.HTTP{ Code: http.StatusBadRequest, Message: err.Error(), } } appName := r.URL.Query().Get(":app") a, err := app.GetByName(appName) if err != nil { return &errors.HTTP{Code: http.StatusNotFound, Message: err.Error()} } err = a.SetUnitStatus(unitName, status) if _, ok := err.(*provision.UnitNotFoundError); ok { return &errors.HTTP{Code: http.StatusNotFound, Message: err.Error()} } if err == nil { w.WriteHeader(http.StatusOK) } return err }
func deployRollback(w http.ResponseWriter, r *http.Request, t auth.Token) error { 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)} } image := r.PostFormValue("image") if image == "" { return &errors.HTTP{ Code: http.StatusBadRequest, Message: "you cannot rollback without an image name", } } w.Header().Set("Content-Type", "application/json") writer := &io.SimpleJsonMessageEncoderWriter{Encoder: json.NewEncoder(w)} err = app.Deploy(app.DeployOptions{ App: instance, OutputStream: writer, Image: image, User: t.GetUserName(), }) if err != nil { writer.Encode(io.SimpleJsonMessage{Error: err.Error()}) } return nil }
func (s *S) TestChangePlan(c *check.C) { config.Set("docker:router", "fake") defer config.Unset("docker:router") plans := []app.Plan{ {Name: "hiperplan", Memory: 536870912, Swap: 536870912, CpuShare: 100}, {Name: "superplan", Memory: 268435456, Swap: 268435456, CpuShare: 100}, } for _, plan := range plans { err := plan.Save() c.Assert(err, check.IsNil) defer app.PlanRemove(plan.Name) } a := app.App{Name: "someapp", Platform: "zend", TeamOwner: s.team.Name, Plan: plans[1]} err := app.CreateApp(&a, s.user) c.Assert(err, check.IsNil) defer s.logConn.Logs(a.Name).DropCollection() request, err := http.NewRequest("POST", "/apps/someapp/plan", strings.NewReader(`{"name":"hiperplan"}`)) c.Assert(err, check.IsNil) request.Header.Set("Authorization", "bearer "+s.token.GetValue()) recorder := httptest.NewRecorder() m := RunServer(true) m.ServeHTTP(recorder, request) c.Assert(recorder.Code, check.Equals, http.StatusOK) app, err := app.GetByName(a.Name) c.Assert(err, check.IsNil) c.Assert(app.Plan, check.DeepEquals, plans[0]) c.Assert(s.provisioner.Restarts(&a, ""), check.Equals, 1) }
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) }
// title: app log // path: /apps/{app}/log // method: POST // consume: application/x-www-form-urlencoded // responses: // 200: Ok // 400: Invalid data // 401: Unauthorized // 404: App not found func addLog(w http.ResponseWriter, r *http.Request, t auth.Token) error { a, err := app.GetByName(r.URL.Query().Get(":app")) if err != nil { return err } err = r.ParseForm() if err != nil { return &errors.HTTP{Code: http.StatusBadRequest, Message: err.Error()} } if t.GetAppName() != app.InternalAppName { allowed := permission.Check(t, permission.PermAppUpdateLog, contextsForApp(a)..., ) if !allowed { return permission.ErrUnauthorized } } logs := r.Form["message"] source := r.FormValue("source") if source == "" { source = "app" } unit := r.FormValue("unit") for _, log := range logs { err := a.Log(log, source, unit) if err != nil { return err } } return nil }
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") }
// title: set unit status // path: /apps/{app}/units/{unit} // method: POST // consume: application/x-www-form-urlencoded // responses: // 200: Ok // 400: Invalid data // 401: Unauthorized // 404: App or unit not found func setUnitStatus(w http.ResponseWriter, r *http.Request, t auth.Token) error { unitName := r.URL.Query().Get(":unit") if unitName == "" { return &errors.HTTP{ Code: http.StatusBadRequest, Message: "missing unit", } } postStatus := r.FormValue("status") status, err := provision.ParseStatus(postStatus) if err != nil { return &errors.HTTP{ Code: http.StatusBadRequest, Message: err.Error(), } } appName := r.URL.Query().Get(":app") a, err := app.GetByName(appName) if err != nil { return &errors.HTTP{Code: http.StatusNotFound, Message: err.Error()} } allowed := permission.Check(t, permission.PermAppUpdateUnitStatus, contextsForApp(a)..., ) if !allowed { return permission.ErrUnauthorized } err = a.SetUnitStatus(unitName, status) if _, ok := err.(*provision.UnitNotFoundError); ok { return &errors.HTTP{Code: http.StatusNotFound, Message: err.Error()} } return err }
func (s segregatedScheduler) Schedule(opts docker.CreateContainerOptions, schedulerOpts cluster.SchedulerOptions) (cluster.Node, error) { conn, err := db.Conn() if err != nil { return cluster.Node{}, 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 cluster.Node{}, err } app, err := app.GetByName(cont.AppName) if err != nil { return s.fallback(opts, cont) } var nodes []node var query bson.M if app.TeamOwner != "" { query = bson.M{"teams": app.TeamOwner} } else { 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, cont) } return s.handle(opts, nodes, cont) }
func deployRollback(w http.ResponseWriter, r *http.Request, t auth.Token) error { 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)} } image := r.PostFormValue("image") if image == "" { return &errors.HTTP{ Code: http.StatusBadRequest, Message: "you cannot rollback without an image name", } } w.Header().Set("Content-Type", "application/json") keepAliveWriter := io.NewKeepAliveWriter(w, 30*time.Second, "") defer keepAliveWriter.Stop() writer := &io.SimpleJsonMessageEncoderWriter{Encoder: json.NewEncoder(keepAliveWriter)} if !regexp.MustCompile(":v[0-9]+$").MatchString(image) { img, err := getImage(appName, image) //err is not handled because it is treated in funcion app.Deploy() if err == nil { image = img } } err = app.Deploy(app.DeployOptions{ App: instance, OutputStream: writer, Image: image, User: t.GetUserName(), }) if err != nil { writer.Encode(io.SimpleJsonMessage{Error: err.Error()}) } return nil }
func (s *S) TestRebuildRoutes(c *check.C) { a := app.App{Name: "my-test-app", TeamOwner: s.team.Name} err := app.CreateApp(&a, s.user) c.Assert(err, check.IsNil) err = provisiontest.ProvisionerInstance.AddUnits(&a, 3, "web", nil) c.Assert(err, check.IsNil) units, err := a.Units() c.Assert(err, check.IsNil) routertest.FakeRouter.RemoveRoute(a.Name, units[2].Address) routertest.FakeRouter.AddRoute(a.Name, &url.URL{Scheme: "http", Host: "invalid:1234"}) changes, err := rebuild.RebuildRoutes(&a) c.Assert(err, check.IsNil) c.Assert(changes.Added, check.DeepEquals, []string{units[2].Address.String()}) c.Assert(changes.Removed, check.DeepEquals, []string{"http://invalid:1234"}) routes, err := routertest.FakeRouter.Routes(a.Name) c.Assert(err, check.IsNil) c.Assert(routes, check.HasLen, 3) c.Assert(routertest.FakeRouter.HasRoute(a.Name, units[0].Address.String()), check.Equals, true) c.Assert(routertest.FakeRouter.HasRoute(a.Name, units[1].Address.String()), check.Equals, true) c.Assert(routertest.FakeRouter.HasRoute(a.Name, units[2].Address.String()), check.Equals, true) app, err := app.GetByName(a.Name) c.Assert(err, check.IsNil) addr, err := routertest.FakeRouter.Addr(app.Name) c.Assert(err, check.IsNil) c.Assert(app.Ip, check.Equals, addr) }