func swap(w http.ResponseWriter, r *http.Request, t auth.Token) error { u, err := t.User() if err != nil { return err } app1Name := r.URL.Query().Get("app1") app2Name := r.URL.Query().Get("app2") locked1, err := app.AcquireApplicationLock(app1Name, t.GetUserName(), "/swap") if err != nil { return err } defer app.ReleaseApplicationLock(app1Name) locked2, err := app.AcquireApplicationLock(app2Name, t.GetUserName(), "/swap") if err != nil { return err } defer app.ReleaseApplicationLock(app2Name) app1, err := getApp(app1Name, u) if err != nil { return err } if !locked1 { return &errors.HTTP{Code: http.StatusConflict, Message: fmt.Sprintf("%s: %s", app1.Name, &app1.Lock)} } app2, err := getApp(app2Name, u) if err != nil { return err } if !locked2 { return &errors.HTTP{Code: http.StatusConflict, Message: fmt.Sprintf("%s: %s", app2.Name, &app2.Lock)} } rec.Log(u.Email, "swap", app1Name, app2Name) return app.Swap(&app1, &app2) }
func (p *dockerProvisioner) runningContainersByNode(nodes []*cluster.Node) (map[string][]container.Container, error) { appNames, err := p.listAppsForNodes(nodes) if err != nil { return nil, err } for _, appName := range appNames { locked, err := app.AcquireApplicationLock(appName, app.InternalAppName, "node auto scale") if err != nil { return nil, err } if !locked { return nil, fmt.Errorf("unable to lock app %s, aborting", appName) } defer app.ReleaseApplicationLock(appName) } result := map[string][]container.Container{} for _, n := range nodes { nodeConts, err := p.listRunningContainersByHost(urlToHost(n.Address)) if err != nil { return nil, err } result[n.Address] = nodeConts } return result, nil }
func (s *S) TestRoutesRebuildOrEnqueueLocked(c *check.C) { err := s.p.Initialize() c.Assert(err, check.IsNil) coll := s.storage.Apps() a := &app.App{ Name: "almah", Platform: "static", } err = coll.Insert(a) c.Assert(err, check.IsNil) locked, err := app.AcquireApplicationLock(a.Name, "me", "mine") c.Assert(err, check.IsNil) c.Assert(locked, check.Equals, true) err = s.p.Provision(a) 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) lockedRoutesRebuildOrEnqueue(a.GetName()) c.Assert(routertest.FakeRouter.HasRoute(a.GetName(), invalidAddr.String()), check.Equals, true) app.ReleaseApplicationLock(a.Name) err = queue.TestingWaitQueueTasks(1, 10*time.Second) c.Assert(err, check.IsNil) c.Assert(routertest.FakeRouter.HasRoute(a.GetName(), invalidAddr.String()), check.Equals, false) }
func swap(w http.ResponseWriter, r *http.Request, t auth.Token) error { u, err := t.User() if err != nil { return err } app1Name := r.URL.Query().Get("app1") app2Name := r.URL.Query().Get("app2") forceSwap := r.URL.Query().Get("force") if forceSwap == "" { forceSwap = "false" } locked1, err := app.AcquireApplicationLock(app1Name, t.GetUserName(), "/swap") if err != nil { return err } defer app.ReleaseApplicationLock(app1Name) locked2, err := app.AcquireApplicationLock(app2Name, t.GetUserName(), "/swap") if err != nil { return err } defer app.ReleaseApplicationLock(app2Name) app1, err := getApp(app1Name, u) if err != nil { return err } if !locked1 { return &errors.HTTP{Code: http.StatusConflict, Message: fmt.Sprintf("%s: %s", app1.Name, &app1.Lock)} } app2, err := getApp(app2Name, u) if err != nil { return err } if !locked2 { return &errors.HTTP{Code: http.StatusConflict, Message: fmt.Sprintf("%s: %s", app2.Name, &app2.Lock)} } // compare apps by platform type and number of units if forceSwap == "false" && ((len(app1.Units()) != len(app2.Units())) || (app1.Platform != app2.Platform)) { return app.ErrAppNotEqual } rec.Log(u.Email, "swap", app1Name, app2Name) return app.Swap(&app1, &app2) }
func (l *appLocker) lock(appName string) bool { appDBMutex.Lock() defer appDBMutex.Unlock() if l.refCount == nil { l.refCount = make(map[string]int) } if l.refCount[appName] > 0 { l.refCount[appName]++ return true } ok, err := app.AcquireApplicationLock(appName, app.InternalAppName, "container-move") if err != nil || !ok { return false } l.refCount[appName]++ return true }
func (s *S) TestRoutesRebuildOrEnqueueLocked(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) locked, err := app.AcquireApplicationLock(a.Name, "me", "mine") c.Assert(err, check.IsNil) c.Assert(locked, check.Equals, true) 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.LockedRoutesRebuildOrEnqueue(a.GetName()) c.Assert(routertest.FakeRouter.HasRoute(a.GetName(), invalidAddr.String()), check.Equals, true) app.ReleaseApplicationLock(a.Name) err = queue.TestingWaitQueueTasks(1, 10*time.Second) c.Assert(err, check.IsNil) c.Assert(routertest.FakeRouter.HasRoute(a.GetName(), invalidAddr.String()), check.Equals, false) }
func runRoutesRebuildOnce(appName string, lock bool) bool { if lock { locked, err := app.AcquireApplicationLock(appName, app.InternalAppName, "rebuild-routes-task") if err != nil || !locked { return false } defer app.ReleaseApplicationLock(appName) } a, err := app.GetByName(appName) if err == app.ErrAppNotFound { return true } if err != nil { log.Errorf("[routes-rebuild-task] error getting app: %s", err) return false } _, err = a.RebuildRoutes() if err != nil { log.Errorf("[routes-rebuild-task] error rebuilding: %s", err) return false } return true }
func (m *appLockMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { if r.Method == "GET" { next(w, r) return } currentHandler := context.GetDelayedHandler(r) if currentHandler != nil { currentHandlerPtr := reflect.ValueOf(currentHandler).Pointer() for _, h := range m.excludedHandlers { if reflect.ValueOf(h).Pointer() == currentHandlerPtr { next(w, r) return } } } appName := r.URL.Query().Get(":app") if appName == "" { appName = r.URL.Query().Get(":appname") } if appName == "" { next(w, r) return } t := context.GetAuthToken(r) var owner string if t != nil { if t.IsAppToken() { owner = t.GetAppName() } else { owner = t.GetUserName() } } ok, err := app.AcquireApplicationLock(appName, owner, fmt.Sprintf("%s %s", r.Method, r.URL.Path)) if err != nil { context.AddRequestError(r, fmt.Errorf("Error trying to acquire application lock: %s", err)) return } if ok { defer func() { if !context.IsPreventUnlock(r) { app.ReleaseApplicationLock(appName) } }() next(w, r) return } a, err := app.GetByName(appName) httpErr := &errors.HTTP{Code: http.StatusInternalServerError} if err != nil { if err == app.ErrAppNotFound { httpErr.Code = http.StatusNotFound httpErr.Message = err.Error() } else { httpErr.Message = fmt.Sprintf("Error to get application: %s", err) } } else { httpErr.Code = http.StatusConflict if a.Lock.Locked { httpErr.Message = fmt.Sprintf("%s", &a.Lock) } else { httpErr.Message = "Not locked anymore, please try again." } } context.AddRequestError(r, httpErr) }