import logging import os import json from flask import Flask, Config, request, Request from flask.ext.principal import Principal from flask.ext.login import LoginManager from flask.ext.mail import Mail import features from storage import Storage from data import model from data import database from data.userfiles import Userfiles from data.users import UserAuthentication from data.buildlogs import BuildLogs from data.archivedlogs import LogArchive from data.queue import WorkQueue from data.userevent import UserEventsBuilderModule from avatars.avatars import Avatar from util.analytics import Analytics from data.billing import Billing from util.config.provider import FileConfigProvider, TestConfigProvider from util.exceptionlog import Sentry from util.names import urn_generator from util.oauth import GoogleOAuthConfig, GithubOAuthConfig from util.queuemetrics import QueueMetrics from util.config.configutil import generate_secret_key app = Flask(__name__) logger = logging.getLogger(__name__) profile = logging.getLogger('profile') CONFIG_PROVIDER = FileConfigProvider('conf/stack/', 'config.yaml', 'config.py') # Instantiate the default configuration (for test or for normal operation). if 'TEST' in os.environ: CONFIG_PROVIDER = TestConfigProvider() from test.testconfig import TestConfig logger.debug('Loading test config.') app.config.from_object(TestConfig()) else: from config import DefaultConfig logger.debug('Loading default config.') app.config.from_object(DefaultConfig()) app.teardown_request(database.close_db_filter) # Load the override config via the provider. CONFIG_PROVIDER.update_app_config(app.config) # Update any configuration found in the override environment variable. OVERRIDE_CONFIG_KEY = 'QUAY_OVERRIDE_CONFIG' environ_config = json.loads(os.environ.get(OVERRIDE_CONFIG_KEY, '{}')) app.config.update(environ_config) class RequestWithId(Request): request_gen = staticmethod(urn_generator(['request'])) def __init__(self, *args, **kwargs): super(RequestWithId, self).__init__(*args, **kwargs) self.request_id = self.request_gen() @app.before_request def _request_start(): profile.debug('Starting request: %s', request.path) @app.after_request def _request_end(r): profile.debug('Ending request: %s', request.path) return r class InjectingFilter(logging.Filter): def filter(self, record): record.msg = '[%s] %s' % (request.request_id, record.msg) return True profile.addFilter(InjectingFilter()) app.request_class = RequestWithId features.import_features(app.config) Principal(app, use_sessions=False) avatar = Avatar(app) login_manager = LoginManager(app) mail = Mail(app) storage = Storage(app) userfiles = Userfiles(app, storage) log_archive = LogArchive(app, storage) analytics = Analytics(app) billing = Billing(app) sentry = Sentry(app) build_logs = BuildLogs(app) queue_metrics = QueueMetrics(app) authentication = UserAuthentication(app) userevents = UserEventsBuilderModule(app) github_login = GithubOAuthConfig(app.config, 'GITHUB_LOGIN_CONFIG') github_trigger = GithubOAuthConfig(app.config, 'GITHUB_TRIGGER_CONFIG') google_login = GoogleOAuthConfig(app.config, 'GOOGLE_LOGIN_CONFIG') oauth_apps = [github_login, github_trigger, google_login] tf = app.config['DB_TRANSACTION_FACTORY'] image_diff_queue = WorkQueue(app.config['DIFFS_QUEUE_NAME'], tf) dockerfile_build_queue = WorkQueue(app.config['DOCKERFILE_BUILD_QUEUE_NAME'], tf, reporter=queue_metrics.report) notification_queue = WorkQueue(app.config['NOTIFICATION_QUEUE_NAME'], tf) database.configure(app.config) model.config.app_config = app.config model.config.store = storage # Generate a secret key if none was specified. if app.config['SECRET_KEY'] is None: logger.debug('Generating in-memory secret key') app.config['SECRET_KEY'] = generate_secret_key() def get_app_url(): return '%s://%s' % (app.config['PREFERRED_URL_SCHEME'], app.config['SERVER_HOSTNAME'])