Add support for the remaining events to the frontend and the backend

This commit is contained in:
Joseph Schorr 2014-07-18 15:58:18 -04:00
parent f7c154abb5
commit af31bde997
7 changed files with 269 additions and 40 deletions

View file

@ -9,7 +9,7 @@ from flask.ext.principal import identity_changed
from random import SystemRandom
from data import model
from app import app, login_manager, dockerfile_build_queue
from app import app, login_manager, dockerfile_build_queue, notification_queue
from auth.permissions import QuayDeferredPermissionUser
from auth import scopes
from endpoints.api.discovery import swagger_route_data
@ -21,6 +21,7 @@ from external_libraries import get_external_javascript, get_external_css
import features
logger = logging.getLogger(__name__)
profile = logging.getLogger('application.profiler')
route_data = None
@ -207,6 +208,7 @@ def start_build(repository, dockerfile_id, tags, build_name, subdir, manual,
'pull_credentials': model.get_pull_credentials(pull_robot_name) if pull_robot_name else None
}), retries_remaining=1)
# Add the build to the repo's log.
metadata = {
'repo': repository.name,
'namespace': repository.namespace,
@ -223,4 +225,47 @@ def start_build(repository, dockerfile_id, tags, build_name, subdir, manual,
ip=request.remote_addr, metadata=metadata,
repository=repository)
# Add notifications for the build queue.
profile.debug('Adding notifications for repository')
event_data = {
'build_id': build_request.uuid,
'build_name': build_name,
'docker_tags': tags,
'is_manual': manual,
'trigger_id': trigger.uuid,
'trigger_kind': trigger.service.name
}
spawn_notification(repository, 'build_queued', event_data,
subpage='build?current=' % build_request.uuid,
pathargs=['build', build_request.uuid])
return build_request
def spawn_notification(repository, event_name, extra_data={}, subpage=None, pathargs=[]):
homepage = 'https://quay.io/repository/%s' % repo_string
if subpage:
homepage = homepage + subpage
repo_string = '%s/%s' % (repo.namespace, repo.name)
event_data = {
'repository': repo_string,
'namespace': repo.namespace,
'name': repo.name,
'docker_url': 'quay.io/%s' % repo_string,
'homepage': homepage,
'visibility': repo.visibility.name
}
event_data.update(extra_data)
notifications = model.list_repo_notifications(repo.namespace, repo.name, event_name=event_name)
for notification in notifications:
notification_data = {
'notification_id': notification.id,
'repository_id': repository.id,
'event_data': event_data
}
path = [namespace, repository, 'notification', event_name] + pathargs
notification_queue.put(path, json.dumps(notification_data))

View file

@ -17,6 +17,7 @@ from auth.permissions import (ModifyRepositoryPermission, UserAdminPermission,
ReadRepositoryPermission, CreateRepositoryPermission)
from util.http import abort
from endpoints.common import spawn_notification
logger = logging.getLogger(__name__)
@ -307,7 +308,7 @@ def update_images(namespace, repository):
'action': 'pushed_repo',
'repository': repository,
'namespace': namespace
}
}
event = userevents.get_event(username)
event.publish_event_data('docker-cli', user_data)
@ -318,28 +319,13 @@ def update_images(namespace, repository):
# Generate a job for each notification that has been added to this repo
profile.debug('Adding notifications for repository')
repo_string = '%s/%s' % (namespace, repository)
event_data = {
'repository': repo_string,
'namespace': namespace,
'name': repository,
'docker_url': 'quay.io/%s' % repo_string,
'homepage': 'https://quay.io/repository/%s' % repo_string,
'visibility': repo.visibility.name,
'updated_tags': updated_tags,
'pushed_image_count': len(image_with_checksums),
'pruned_image_count': num_removed
}
notifications = model.list_repo_notifications(namespace, repository, event_name='repo_push')
for notification in notifications:
notification_data = {
'notification_id': notification.id,
'repository_id': repository.id,
'event_data': event_data
}
notification_queue.put([namespace, repository, 'repo_push'], json.dumps(notification_data))
spawn_notification(repo, 'repo_push', event_data)
return make_response('Updated', 204)
abort(403)

View file

@ -13,13 +13,13 @@ class NotificationEvent(object):
def __init__(self):
pass
def get_summary(self, notification_data):
def get_summary(self, event_data, notification_data):
"""
Returns a human readable one-line summary for the given notification data.
"""
raise NotImplementedError
def get_message(self, notification_data):
def get_message(self, event_data, notification_data):
"""
Returns a human readable HTML message for the given notification data.
"""
@ -53,19 +53,27 @@ class RepoPushEvent(NotificationEvent):
def event_name(cls):
return 'repo_push'
def get_summary(self, notification_data):
return 'Repository %s updated' % (notification_data['event_data']['repository'])
def get_summary(self, event_data, notification_data):
return 'Repository %s updated' % (event_data['repository'])
def get_message(self, notification_data):
event_data = notification_data['event_data']
def get_message(self, event_data, notification_data):
if not event_data.get('updated_tags', []):
return '%s images pushed for repository %s (%s)' % (event_data['pushed_image_count'],
event_data['repository'], event_data['homepage'])
html = """
Repository <a href="%s">%s</a> has been updated via a push.
""" % (event_data['homepage'],
event_data['repository'])
else:
html = """
Repository <a href="%s">%s</a> has been updated via a push.
<br><br>
Tags Updated: %s
""" % (event_data['homepage'],
event_data['repository'],
event_data['updated_tags'])
return 'Tags %s updated for repository %s (%s)' % (event_data['updated_tags'],
event_data['repository'], event_data['homepage'])
return html
def get_sample_data(self, repository=None):
def get_sample_data(self, repository):
repo_string = '%s/%s' % (repository.namespace, repository.name)
event_data = {
'repository': repo_string,
@ -81,22 +89,117 @@ class RepoPushEvent(NotificationEvent):
return event_data
class BuildQueueEvent(NotificationEvent):
@classmethod
def event_name(cls):
return 'build_queued'
def get_sample_data(self, repository):
build_uuid = 'fake-build-id'
repo_string = '%s/%s' % (repository.namespace, repository.name)
event_data = {
'repository': repo_string,
'namespace': repository.namespace,
'name': repository.name,
'docker_url': 'quay.io/%s' % repo_string,
'homepage': 'https://quay.io/repository/%s/build/%s' % (repo_string, build_uuid),
'is_manual': False,
'build_id': build_uuid,
'build_name': 'some-fake-build',
'docker_tags': ['latest', 'foo', 'bar'],
'trigger_kind': 'GitHub'
}
return event_data
def get_summary(self, event_data, notification_data):
return 'Build queued for repository %s' % (event_data['repository'])
def get_message(self, event_data, notification_data):
is_manual = event_data['is_manual']
if is_manual:
html = """
A <a href="%s">new build</a> has been manually queued to start on repository %s.
<br><br>
Build ID: %s
""" % (event_data['homepage'], event_data['repository'], event_data['build_id'])
else:
html = """
A <a href="%s">new build</a> has been queued via a %s trigger to start on repository %s.
<br><br>
Build ID: %s
""" % (event_data['homepage'], event_data['repository'],
event_data['trigger_kind'], event_data['build_id'])
return html
class BuildStartEvent(NotificationEvent):
@classmethod
def event_name(cls):
return 'build_start'
def get_sample_data(self, repository=None):
pass
def get_sample_data(self, repository):
build_uuid = 'fake-build-id'
repo_string = '%s/%s' % (repository.namespace, repository.name)
event_data = {
'repository': repo_string,
'namespace': repository.namespace,
'name': repository.name,
'docker_url': 'quay.io/%s' % repo_string,
'homepage': 'https://quay.io/repository/%s/build?current=%s' % (repo_string, build_uuid),
'build_id': build_uuid,
'build_name': 'some-fake-build',
'docker_tags': ['latest', 'foo', 'bar'],
'trigger_kind': 'GitHub'
}
return event_data
def get_summary(self, event_data, notification_data):
return 'Build started for repository %s' % (event_data['repository'])
def get_message(self, event_data, notification_data):
html = """
A <a href="%s">new build</a> has started on repository %s.
<br><br>
Build ID: %s
""" % (event_data['homepage'], event_data['repository'], event_data['build_id'])
return html
class BuildSuccessEvent(NotificationEvent):
@classmethod
def event_name(cls):
return 'build_success'
def get_sample_data(self, repository=None):
pass
def get_sample_data(self, repository):
build_uuid = 'fake-build-id'
repo_string = '%s/%s' % (repository.namespace, repository.name)
event_data = {
'repository': repo_string,
'namespace': repository.namespace,
'name': repository.name,
'docker_url': 'quay.io/%s' % repo_string,
'homepage': 'https://quay.io/repository/%s/build?current=%s' % (repo_string, build_uuid),
'build_id': build_uuid,
'build_name': 'some-fake-build',
'docker_tags': ['latest', 'foo', 'bar'],
'trigger_kind': 'GitHub'
}
return event_data
def get_summary(self, event_data, notification_data):
return 'Build succeeded for repository %s' % (event_data['repository'])
def get_message(self, event_data, notification_data):
html = """
A <a href="%s">build</a> has finished on repository %s.
<br><br>
Build ID: %s
""" % (event_data['homepage'], event_data['repository'], event_data['build_id'])
return html
class BuildFailureEvent(NotificationEvent):
@ -104,5 +207,33 @@ class BuildFailureEvent(NotificationEvent):
def event_name(cls):
return 'build_failure'
def get_sample_data(self, repository=None):
pass
def get_sample_data(self, repository):
build_uuid = 'fake-build-id'
repo_string = '%s/%s' % (repository.namespace, repository.name)
event_data = {
'repository': repo_string,
'namespace': repository.namespace,
'name': repository.name,
'docker_url': 'quay.io/%s' % repo_string,
'homepage': 'https://quay.io/repository/%s/build?current=%s' % (repo_string, build_uuid),
'build_id': build_uuid,
'build_name': 'some-fake-build',
'docker_tags': ['latest', 'foo', 'bar'],
'trigger_kind': 'GitHub',
'error_message': 'This is a fake error message'
}
return event_data
def get_summary(self, event_data, notification_data):
return 'Build failure for repository %s' % (event_data['repository'])
def get_message(self, event_data, notification_data):
html = """
A <a href="%s">build</a> has failed on repository %s.
<br><br>
Reason: %s<br>
Build ID: %s<br>
""" % (event_data['homepage'], event_data['repository'],
event_data['error_message'], event_data['build_id'])
return html

View file

@ -98,10 +98,10 @@ class EmailMethod(NotificationMethod):
if not email:
return False
msg = Message(event_handler.get_summary(notification_data),
msg = Message(event_handler.get_summary(notification_data['event_data'], notification_data),
sender='support@quay.io',
recipients=[email])
msg.html = event_handler.get_message(notification_data)
msg.html = event_handler.get_message(notification_data['event_data'], notification_data)
try:
with app.app_context():