app/app.go
func Delete(app *App, evt *event.Event, requestID string) error {
	w := evt
	isSwapped, swappedWith, err := router.IsSwapped(app.GetName())
	if err != nil {
		return errors.Wrap(err, "unable to check if app is swapped")
	}
	if isSwapped {
		return errors.Errorf("application is swapped with %q, cannot remove it", swappedWith)
	}
	appName := app.Name
	fmt.Fprintf(w, "---- Removing application %q...\n", appName)
	var hasErrors bool
	defer func() {
		var problems string
		if hasErrors {
			problems = " Some errors occurred during removal."
		}
		fmt.Fprintf(w, "---- Done removing application.%s\n", problems)
	}()
	logErr := func(msg string, err error) {
		msg = fmt.Sprintf("%s: %s", msg, err)
		fmt.Fprintf(w, "%s\n", msg)
		log.Errorf("[delete-app: %s] %s", appName, msg)
		hasErrors = true
	}
	prov, err := app.getProvisioner()
	if err != nil {
		return err
	}
	err = prov.Destroy(app)
	if err != nil {
		logErr("Unable to destroy app in provisioner", err)
	}
	err = registry.RemoveAppImages(appName)
	if err != nil {
		log.Errorf("failed to remove images from registry for app %s: %s", appName, err)
	}
	if cleanProv, ok := prov.(provision.CleanImageProvisioner); ok {
		var imgs []string
		imgs, err = image.ListAppImages(appName)
		if err != nil {
			log.Errorf("failed to list images for app %s: %s", appName, err)
		}
		var imgsBuild []string
		imgsBuild, err = image.ListAppBuilderImages(appName)
		if err != nil {
			log.Errorf("failed to list build images for app %s: %s", appName, err)
		}
		for _, img := range append(imgs, imgsBuild...) {
			err = cleanProv.CleanImage(appName, img)
			if err != nil {
				log.Errorf("failed to remove image from provisioner %s: %s", appName, err)
			}
		}
	}
	err = image.DeleteAllAppImageNames(appName)
	if err != nil {
		log.Errorf("failed to remove image names from storage for app %s: %s", appName, err)
	}
	err = app.unbind(evt, requestID)
	if err != nil {
		logErr("Unable to unbind app", err)
	}
	routers := app.GetRouters()
	for _, appRouter := range routers {
		var r router.Router
		r, err = router.Get(appRouter.Name)
		if err == nil {
			err = r.RemoveBackend(app.Name)
		}
		if err != nil {
			logErr("Failed to remove router backend", err)
		}
	}
	err = router.Remove(app.Name)
	if err != nil {
		logErr("Failed to remove router backend from database", err)
	}
	err = app.unbindVolumes()
	if err != nil {
		logErr("Unable to unbind volumes", err)
	}
	err = repository.Manager().RemoveRepository(appName)
	if err != nil {
		logErr("Unable to remove app from repository manager", err)
	}
	token := app.Env["TSURU_APP_TOKEN"].Value
	err = AuthScheme.AppLogout(token)
	if err != nil {
		logErr("Unable to remove app token in destroy", err)
	}
	owner, err := auth.GetUserByEmail(app.Owner)
	if err == nil {
		err = servicemanager.UserQuota.Inc(owner.Email, -1)
	}
	if err != nil {
		logErr("Unable to release app quota", err)
	}
	logConn, err := db.LogConn()
	if err == nil {
		defer logConn.Close()
		err = logConn.AppLogCollection(appName).DropCollection()
	}
	if err != nil {
		logErr("Unable to remove logs collection", err)
	}
	conn, err := db.Conn()
	if err == nil {
		defer conn.Close()
		err = conn.Apps().Remove(bson.M{"name": appName})
	}
	if err != nil {
		logErr("Unable to remove app from db", err)
	}
	err = event.MarkAsRemoved(event.Target{Type: event.TargetTypeApp, Value: appName})
	if err != nil {
		logErr("Unable to mark old events as removed", err)
	}
	return nil
}
func Delete(app *App, evt *event.Event, requestID string) error {
	w := evt
	isSwapped, swappedWith, err := router.IsSwapped(app.GetName())
	if err != nil {
		return errors.Wrap(err, "unable to check if app is swapped")
	}
	if isSwapped {
		return errors.Errorf("application is swapped with %q, cannot remove it", swappedWith)
	}
	appName := app.Name
	fmt.Fprintf(w, "---- Removing application %q...\n", appName)
	var hasErrors bool
	defer func() {
		var problems string
		if hasErrors {
			problems = " Some errors occurred during removal."
		}
		fmt.Fprintf(w, "---- Done removing application.%s\n", problems)
	}()
	logErr := func(msg string, err error) {
		msg = fmt.Sprintf("%s: %s", msg, err)
		fmt.Fprintf(w, "%s\n", msg)
		log.Errorf("[delete-app: %s] %s", appName, msg)
		hasErrors = true
	}
	prov, err := app.getProvisioner()
	if err != nil {
		return err
	}
	err = prov.Destroy(app)
	if err != nil {
		logErr("Unable to destroy app in provisioner", err)
	}
	err = registry.RemoveAppImages(appName)
	if err != nil {
		log.Errorf("failed to remove images from registry for app %s: %s", appName, err)
	}
	if cleanProv, ok := prov.(provision.CleanImageProvisioner); ok {
		var imgs []string
		imgs, err = image.ListAppImages(appName)
		if err != nil {
			log.Errorf("failed to list images for app %s: %s", appName, err)
		}
		var imgsBuild []string
		imgsBuild, err = image.ListAppBuilderImages(appName)
		if err != nil {
			log.Errorf("failed to list build images for app %s: %s", appName, err)
		}
		for _, img := range append(imgs, imgsBuild...) {
			err = cleanProv.CleanImage(appName, img)
			if err != nil {
				log.Errorf("failed to remove image from provisioner %s: %s", appName, err)
			}
		}
	}
	err = image.DeleteAllAppImageNames(appName)
	if err != nil {
		log.Errorf("failed to remove image names from storage for app %s: %s", appName, err)
	}
	err = app.unbind(evt, requestID)
	if err != nil {
		logErr("Unable to unbind app", err)
	}
	routers := app.GetRouters()
	for _, appRouter := range routers {
		var r router.Router
		r, err = router.Get(appRouter.Name)
		if err == nil {
			err = r.RemoveBackend(app.Name)
		}
		if err != nil {
			logErr("Failed to remove router backend", err)
		}
	}
	err = router.Remove(app.Name)
	if err != nil {
		logErr("Failed to remove router backend from database", err)
	}
	err = app.unbindVolumes()
	if err != nil {
		logErr("Unable to unbind volumes", err)
	}
	err = repository.Manager().RemoveRepository(appName)
	if err != nil {
		logErr("Unable to remove app from repository manager", err)
	}
	token := app.Env["TSURU_APP_TOKEN"].Value
	err = AuthScheme.AppLogout(token)
	if err != nil {
		logErr("Unable to remove app token in destroy", err)
	}
	owner, err := auth.GetUserByEmail(app.Owner)
	if err == nil {
		err = servicemanager.UserQuota.Inc(owner.Email, -1)
	}
	if err != nil {
		logErr("Unable to release app quota", err)
	}
	logConn, err := db.LogConn()
	if err == nil {
		defer logConn.Close()
		err = logConn.AppLogCollection(appName).DropCollection()
	}
	if err != nil {
		logErr("Unable to remove logs collection", err)
	}
	conn, err := db.Conn()
	if err == nil {
		defer conn.Close()
		err = conn.Apps().Remove(bson.M{"name": appName})
	}
	if err != nil {
		logErr("Unable to remove app from db", err)
	}
	err = event.MarkAsRemoved(event.Target{Type: event.TargetTypeApp, Value: appName})
	if err != nil {
		logErr("Unable to mark old events as removed", err)
	}
	return nil
}
// Delete deletes an app.