| |
@@ -17,7 +17,7 @@
|
| |
# Authors:
|
| |
# Josef Skladanka <jskladan@redhat.com>
|
| |
|
| |
- from flask import Blueprint, render_template, request, jsonify
|
| |
+ from flask import Blueprint, render_template, request, jsonify, current_app
|
| |
import werkzeug.exceptions
|
| |
from sqlalchemy.orm import exc as orm_exc
|
| |
|
| |
@@ -26,18 +26,21 @@
|
| |
from werkzeug.exceptions import BadRequest as JSONBadRequest
|
| |
|
| |
|
| |
- from execdb import app, db
|
| |
+ #from execdb import app, db
|
| |
+ #from execdb import db
|
| |
+ from execdb.models import db
|
| |
from execdb.models.job import Job, BuildStep
|
| |
from sqlalchemy import desc
|
| |
|
| |
import json
|
| |
import re
|
| |
+ from datetime import datetime
|
| |
|
| |
from pprint import pformat
|
| |
|
| |
main = Blueprint('main', __name__)
|
| |
- BB_URL = app.config['BUILDBOT_FRONTPAGE_URL']
|
| |
- RESULTSDB_URL = app.config['RESULTSDB_FRONTPAGE_URL']
|
| |
+ #BB_URL = current_app.config['BUILDBOT_FRONTPAGE_URL']
|
| |
+ #RESULTSDB_URL = current_app.config['RESULTSDB_FRONTPAGE_URL']
|
| |
|
| |
RE_PAGE = re.compile(r"([?&])page=([0-9]+)")
|
| |
RP = {}
|
| |
@@ -110,7 +113,8 @@
|
| |
|
| |
return render_template('index.html',
|
| |
jobs=jobs,
|
| |
- buildbot_url=BB_URL,
|
| |
+ # buildbot_url=BB_URL,
|
| |
+ buildbot_url=current_app.config['BUILDBOT_FRONTPAGE_URL'],
|
| |
prev=prev,
|
| |
next=next)
|
| |
|
| |
@@ -124,9 +128,11 @@
|
| |
job.t_triggered = str(job.t_triggered).split('.')[0]
|
| |
return render_template('show_job.html',
|
| |
job=job,
|
| |
- buildbot_url=BB_URL,
|
| |
- resultsdb_url=RESULTSDB_URL,
|
| |
- artifacts_base_url=app.config['ARTIFACTS_BASE_URL'])
|
| |
+ #buildbot_url=BB_URL,
|
| |
+ buildbot_url=current_app.config['BUILDBOT_FRONTPAGE_URL'],
|
| |
+ #resultsdb_url=RESULTSDB_URL,
|
| |
+ resultsdb_url=current_app.config['RESULTSDB_FRONTPAGE_URL'],
|
| |
+ artifacts_base_url=current_app.config['ARTIFACTS_BASE_URL'])
|
| |
|
| |
|
| |
@main.route('/jobs/<uuid>/steps', methods=['GET'])
|
| |
@@ -137,7 +143,8 @@
|
| |
return 'UUID not found', 404
|
| |
|
| |
steps = dict(
|
| |
- buildbot_url=BB_URL,
|
| |
+ #buildbot_url=BB_URL,
|
| |
+ buildbot_url=current_app.config['BUILDBOT_FRONTPAGE_URL'],
|
| |
steps=[],
|
| |
job_status=job.current_state,
|
| |
job_duration=str(job.build_took),
|
| |
@@ -213,7 +220,7 @@
|
| |
if event not in known_events:
|
| |
# FIXME remove
|
| |
if 'uuid' in json.dumps(data):
|
| |
- app.logger.debug("UUID found in %s", event)
|
| |
+ current_app.logger.debug("UUID found in %s", event)
|
| |
|
| |
return 'Skipping event', 204
|
| |
|
| |
@@ -261,7 +268,7 @@
|
| |
# app.logger.debug("%s: %s" % (uuid, data['payload']['build']['steps']))
|
| |
# app.logger.debug("%s - Build Started" % uuid)
|
| |
for step_info in data['payload']['build']['steps']:
|
| |
- # app.logger.debug("%s -- adding step %s"% (uuid, step_info['name']))
|
| |
+ # current_app.logger.debug("%s -- adding step %s"% (uuid, step_info['name']))
|
| |
step = BuildStep(name=step_info['name'])
|
| |
step.job = job
|
| |
db.session.add(step)
|
| |
@@ -270,11 +277,11 @@
|
| |
|
| |
elif event == 'stepStarted' and job.current_state == 'Running':
|
| |
step_info = data['payload']['step']
|
| |
- # app.logger.debug("%s - Step Started - %s"% (uuid, step_info['name']))
|
| |
+ # current_app.logger.debug("%s - Step Started - %s"% (uuid, step_info['name']))
|
| |
try:
|
| |
step = job.get_build_step(step_info['name'])
|
| |
except KeyError:
|
| |
- app.logger.debug("Job %s had missing step %s", job.uuid, step_info)
|
| |
+ current_app.logger.debug("Job %s had missing step %s", job.uuid, step_info)
|
| |
step = BuildStep(name=step_info['name'])
|
| |
step.job = job
|
| |
|
| |
@@ -283,11 +290,11 @@
|
| |
step.data = json.dumps(data['payload']) # FIXME - store sensible subset of data
|
| |
db.session.add(step)
|
| |
db.session.commit()
|
| |
- # app.logger.debug("%s - Step Started - %s - written to db"% (uuid, step_info['name']))
|
| |
+ # current_app.logger.debug("%s - Step Started - %s - written to db"% (uuid, step_info['name']))
|
| |
|
| |
elif event == 'stepFinished' and job.current_state == 'Running':
|
| |
step_info = data['payload']['step']
|
| |
- # app.logger.debug("%s - Step Finished - %s"% (uuid, step_info['name']))
|
| |
+ # current_app.logger.debug("%s - Step Finished - %s"% (uuid, step_info['name']))
|
| |
try:
|
| |
step = job.get_build_step(step_info['name'])
|
| |
except KeyError:
|
| |
@@ -303,36 +310,104 @@
|
| |
|
| |
db.session.add(step)
|
| |
db.session.commit()
|
| |
- # app.logger.debug("%s - Step Finished - %s - written to db" % (uuid, step_info['name']))
|
| |
+ # current_app.logger.debug("%s - Step Finished - %s - written to db" % (uuid, step_info['name']))
|
| |
|
| |
elif event == 'buildFinished' and job.current_state == 'Running':
|
| |
job.finish()
|
| |
db.session.add(job)
|
| |
db.session.commit()
|
| |
- # app.logger.debug("%s - Build Finished " % uuid)
|
| |
+ # current_app.logger.debug("%s - Build Finished " % uuid)
|
| |
|
| |
+ def process_bb_status(status_data):
|
| |
+ # grab uuid, build state, properties
|
| |
+ build_properties = status_data['properties']
|
| |
+ uuid = build_properties['uuid'][0]
|
| |
+ build_complete = status_data['complete']
|
| |
|
| |
- @main.route('/buildbottest', methods=['POST'])
|
| |
+ current_app.logger.info("Processing data for job {} (complete: {})".format(uuid, build_complete))
|
| |
+
|
| |
+ # find job in db
|
| |
+ try:
|
| |
+ job = db.session.query(Job).filter(Job.uuid == uuid).one()
|
| |
+ except orm_exc.NoResultFound:
|
| |
+ current_app.logger.info("UUID {} not found".format(uuid))
|
| |
+ return 'UUID not found', 400
|
| |
+
|
| |
+ # if 'complete' is false, create job
|
| |
+ if not build_complete:
|
| |
+ current_app.logger.debug("%s -- adding job %s"% (uuid, status_data['number']))
|
| |
+
|
| |
+ job.t_build_started = datetime.fromtimestamp(status_data['started_at'])
|
| |
+ job.t_triggered = datetime.fromtimestamp(status_data['started_at'])
|
| |
+
|
| |
+ job.taskname = build_properties['taskname'][0]
|
| |
+ job.item = build_properties['item'][0]
|
| |
+ job.item_type = build_properties['item_type'][0]
|
| |
+ job.arch = build_properties['arch'][0]
|
| |
+ job.slavename = build_properties['slavename'][0]
|
| |
+ job.link_build_log = '/builders/%s/builds/%s' % (
|
| |
+ status_data['buildrequest']['builderid'],
|
| |
+ status_data['number'])
|
| |
+
|
| |
+ db.session.add(job)
|
| |
+
|
| |
+ db.session.commit()
|
| |
+
|
| |
+ # if 'complete' is true, fill in buildsteps, finish job
|
| |
+ else:
|
| |
+ # add the completed time and state
|
| |
+
|
| |
+ job.t_build_ended = datetime.fromtimestamp(status_data['complete_at'])
|
| |
+ # add the build steps
|
| |
+ for step_info in status_data['steps']:
|
| |
+
|
| |
+ current_app.logger.debug("%s -- adding step %s"% (uuid, step_info['name']))
|
| |
+
|
| |
+ step = BuildStep(name=step_info['name'])
|
| |
+ step.job = job
|
| |
+ step.started_at = datetime.fromtimestamp(step_info['started_at'])
|
| |
+ step.finished_at = datetime.fromtimestamp(step_info['complete_at'])
|
| |
+ step.data = step_info['state_string']
|
| |
+
|
| |
+ # there doesn't seem to be a really reasonable way to tell if a step has failed but
|
| |
+ # this should work well enough for now
|
| |
+ if 'failed' in step_info['state_string']:
|
| |
+ step.status = 'NOT OK'
|
| |
+ else:
|
| |
+ step.status = 'OK'
|
| |
+
|
| |
+ db.session.add(step)
|
| |
+
|
| |
+ db.session.commit()
|
| |
+
|
| |
+
|
| |
+ @main.route('/buildbot', methods=['POST'])
|
| |
def bb_push():
|
| |
"""
|
| |
Receives the post-push notifications from buildbot and fills in
|
| |
the steps for the job.
|
| |
"""
|
| |
- # data are embedded in form field 'packets'
|
| |
- data = request.form
|
| |
- try:
|
| |
- data = request.form['packets']
|
| |
- except werkzeug.exceptions.BadRequestKeyError:
|
| |
- return 'Field `packets` missing in request form.', 400
|
| |
- data = json.loads(data)
|
| |
-
|
| |
- # app.logger.debug(pformat(data))
|
| |
+ from pprint import pprint
|
| |
|
| |
- # multiple messages may be present in one 'packet'
|
| |
- for entry in data:
|
| |
- process_event(entry)
|
| |
- # app.logger.debug("%s %s, %s", entry['id'], entry['event'], process_event(entry))
|
| |
+ data = request.get_json()
|
| |
+ # pprint(data)
|
| |
|
| |
+ process_bb_status(data)
|
| |
+ # data are embedded in form field 'packets'
|
| |
+ # data = request.form
|
| |
+ # try:
|
| |
+ # data = request.form['packets']
|
| |
+ # except werkzeug.exceptions.BadRequestKeyError:
|
| |
+ # return 'Field `packets` missing in request form.', 400
|
| |
+ # data = json.loads(data)
|
| |
+ #
|
| |
+ # # current_app.logger.debug(pformat(data))
|
| |
+ #
|
| |
+ # # multiple messages may be present in one 'packet'
|
| |
+ # for entry in data:
|
| |
+ # process_event(entry)
|
| |
+ ## current_app.logger.debug("%s %s, %s", entry['id'], entry['event'], process_event(entry))
|
| |
+ #
|
| |
# plain 200 code needs to be returned - otherwise buildbot is
|
| |
# endlessly trying to re-send the message.
|
| |
# FIXME - add logging for non-200 responses
|
| |
This is a WIP for discussion purposes. It does work with the new buildbot, though.
I started off wanting to test the changes I was going to make which led me down a path of modifying the application structure to use a factory pattern but didn't question whether that was wise until later on.
As we don't know how much longer execdb is going to be a thing, does it make sense to be making changes to the application like this? It is more easily testable this way, though and could be a decent reference for new Flask apps going forward?
Either way, it still needs a bit of cleanup but I wanted to start the discussion before putting any more time into this