Fix exception handling in the registry health check and make sure the user_loader is registered before the process is forked

This commit is contained in:
Joseph Schorr 2015-01-16 22:41:54 -05:00
parent e7054a8690
commit 2a89accc49
4 changed files with 58 additions and 43 deletions

26
app.py
View file

@ -5,7 +5,7 @@ import yaml
from flask import Flask as BaseFlask, Config as BaseConfig, request, Request
from flask.ext.principal import Principal
from flask.ext.login import LoginManager
from flask.ext.login import LoginManager, UserMixin
from flask.ext.mail import Mail
import features
@ -150,5 +150,29 @@ database.configure(app.config)
model.config.app_config = app.config
model.config.store = storage
@login_manager.user_loader
def load_user(user_uuid):
logger.debug('User loader loading deferred user with uuid: %s' % user_uuid)
return LoginWrappedDBUser(user_uuid)
class LoginWrappedDBUser(UserMixin):
def __init__(self, user_uuid, db_user=None):
self._uuid = user_uuid
self._db_user = db_user
def db_user(self):
if not self._db_user:
self._db_user = model.get_user_by_uuid(self._uuid)
return self._db_user
def is_authenticated(self):
return self.db_user() is not None
def is_active(self):
return self.db_user().verified
def get_id(self):
return unicode(self._uuid)
def get_app_url():
return '%s://%s' % (app.config['PREFERRED_URL_SCHEME'], app.config['SERVER_HOSTNAME'])

View file

@ -4,14 +4,17 @@ import json
import string
import datetime
# Register the various exceptions via decorators.
import endpoints.decorated
from flask import make_response, render_template, request, abort, session
from flask.ext.login import login_user, UserMixin
from flask.ext.login import login_user
from flask.ext.principal import identity_changed
from random import SystemRandom
from data import model
from data.database import db
from app import app, login_manager, oauth_apps, dockerfile_build_queue
from app import app, oauth_apps, dockerfile_build_queue, LoginWrappedDBUser
from auth.permissions import QuayDeferredPermissionUser
from auth import scopes
@ -21,7 +24,6 @@ from functools import wraps
from config import getFrontendVisibleConfig
from external_libraries import get_external_javascript, get_external_css
from endpoints.notificationhelper import spawn_notification
from util.useremails import CannotSendEmailException
import features
@ -84,34 +86,8 @@ def param_required(param_name):
return wrapper
@login_manager.user_loader
def load_user(user_uuid):
logger.debug('User loader loading deferred user with uuid: %s' % user_uuid)
return _LoginWrappedDBUser(user_uuid)
class _LoginWrappedDBUser(UserMixin):
def __init__(self, user_uuid, db_user=None):
self._uuid = user_uuid
self._db_user = db_user
def db_user(self):
if not self._db_user:
self._db_user = model.get_user_by_uuid(self._uuid)
return self._db_user
def is_authenticated(self):
return self.db_user() is not None
def is_active(self):
return self.db_user().verified
def get_id(self):
return unicode(self._uuid)
def common_login(db_user):
if login_user(_LoginWrappedDBUser(db_user.uuid, db_user)):
if login_user(LoginWrappedDBUser(db_user.uuid, db_user)):
logger.debug('Successfully signed in as: %s (%s)' % (db_user.username, db_user.uuid))
new_identity = QuayDeferredPermissionUser(db_user.uuid, 'user_uuid', {scopes.DIRECT_LOGIN})
identity_changed.send(app, identity=new_identity)
@ -121,17 +97,6 @@ def common_login(db_user):
logger.debug('User could not be logged in, inactive?.')
return False
@app.errorhandler(model.DataModelException)
def handle_dme(ex):
logger.exception(ex)
return make_response(json.dumps({'message': ex.message}), 400)
@app.errorhandler(CannotSendEmailException)
def handle_emailexception(ex):
message = 'Could not send email. Please contact an administrator and report this problem.'
return make_response(json.dumps({'message': message}), 400)
def random_string():
random = SystemRandom()
return ''.join([random.choice(string.ascii_uppercase + string.digits) for _ in range(8)])

19
endpoints/decorated.py Normal file
View file

@ -0,0 +1,19 @@
import logging
import json
from flask import make_response
from app import app
from util.useremails import CannotSendEmailException
from data import model
logger = logging.getLogger(__name__)
@app.errorhandler(model.DataModelException)
def handle_dme(ex):
logger.exception(ex)
return make_response(json.dumps({'message': ex.message}), 400)
@app.errorhandler(CannotSendEmailException)
def handle_emailexception(ex):
message = 'Could not send email. Please contact an administrator and report this problem.'
return make_response(json.dumps({'message': message}), 400)

View file

@ -27,6 +27,9 @@ import features
logger = logging.getLogger(__name__)
# Capture the unverified SSL errors.
logging.captureWarnings(True)
web = Blueprint('web', __name__)
STATUS_TAGS = app.config['STATUS_TAGS']
@ -167,7 +170,11 @@ def health():
port = ':' + hostname_parts[1]
registry_url = '%s://localhost%s/v1/_internal_ping' % (app.config['PREFERRED_URL_SCHEME'], port)
registry_healthy = client.get(registry_url, verify=False, timeout=2).status_code == 200
registry_healthy = False
try:
registry_healthy = client.get(registry_url, verify=False, timeout=2).status_code == 200
except Exception:
logger.exception('Exception when checking registry health: %s', registry_url)
check = HealthCheck.get_check(app.config['HEALTH_CHECKER'][0], app.config['HEALTH_CHECKER'][1])
(data, is_healthy) = check.conduct_healthcheck(db_healthy, buildlogs_healthy, registry_healthy)