blob: b1300f9f6a62b5e615a5a1ad21b8abdc3a0db8bd [file] [log] [blame]
import flask
from flask import abort
from flask import jsonify
from flask import redirect
from flask import render_template
from flask import request
from flask import session
from flask import url_for
from flask import current_app
ci = flask.Module(__name__, url_prefix='/ci', name='ci')
from llvmlab import util
@ci.route('/')
def dashboard():
return render_template("dashboard.html",
ci_config=current_app.config.summary.config)
@ci.route('/phase/<int:index>/<source_stamp>')
def phase_popup(index, source_stamp):
cfg = current_app.config.summary.config
# Validate the phase.
if index >= len(cfg.phases):
abort(404)
# Get the phase.
phase = cfg.phases[index]
# Lookup the latest builds associated with this revision.
phased_builds = dict(
(builder, [b for b in current_app.config.status.builders.get(builder,[])
if b.source_stamp == source_stamp])
for builder in phase.builder_names)
return render_template("phase_popup.html",
ci_config=current_app.config.summary.config,
phase = phase, source_stamp = source_stamp,
phased_builds = phased_builds)
@ci.route('/latest_release')
def latest_release():
return render_template("latest_release.html",
ci_config=current_app.config.summary.config)
@ci.route('/monitor')
def buildbot_monitor():
return render_template("buildbot_monitor.html",
bb_status=current_app.config.status)
@ci.route('/build_chart')
def build_chart():
import time
# Determine the render constants.
k_days_data = int(request.args.get('days', 1))
k_pixels_per_minute = float(request.args.get('pixels_per_minute', .5))
# Aggregate builds by slave, for completed builds within the desired time
# frame.
current_time = time.time()
builders = current_app.config.status.builders
slave_builders = util.multidict(
(build.slave, build)
for builds in builders.values()
for build in builds
if build.end_time is not None
if current_time - build.start_time < 60 * 60 * 24 * k_days_data)
# Compute the build chart.
class ChartItem(object):
def __init__(self, build, color, left, width):
self.build = build
self.color = color
self.left = left
self.width = width
builder_colors = dict((name, util.make_dark_color(float(i) / len(builders)))
for i,name in enumerate(builders))
build_chart_data = {}
max_x = 0
min_time = min(build.start_time
for builds in slave_builders.values()
for build in builds)
for slave, builders in slave_builders.items():
# Order the builders by time.
builders.sort(key = lambda b: b.start_time)
# Aggregate builds by builder type.
builds_by_type = util.multidict(
(build.name, build)
for build in builders)
# Create the char items.
rows = []
for name,builds in util.sorted(builds_by_type.items()):
color = builder_colors[name]
hex_color = '%02x%02x%02x' % tuple(int(x*255)
for x in color)
rows.append([])
for build in builds:
elapsed = build.end_time - build.start_time
width = max(1, int(k_pixels_per_minute * elapsed / 60))
left = int(k_pixels_per_minute *
(build.start_time - min_time) / 60)
max_x = max(max_x, left + width)
rows[-1].append(ChartItem(build, hex_color, left, width))
build_chart_data[slave] = rows
build_chart = { 'data' : build_chart_data,
'max_x' : max_x }
return render_template("build_chart.html",
bb_status = current_app.config.status,
build_chart = build_chart)
@ci.route('/phase_description/<int:index>')
def phase_description(index):
cfg = current_app.config.summary.config
# Validate the phase.
if index >= len(cfg.phases):
abort(404)
# Get the phase.
phase = cfg.phases[index]
return render_template("phase_description.html", phase=phase)
@ci.route('/times')
@ci.route('/times/<int:index>')
def phase_timing(index=None):
cfg = current_app.config.summary.config
# Determine what we are timing.
if index is not None:
# Validate the phase.
if index >= len(cfg.phases):
abort(404)
# Get the phase.
phase = cfg.phases[index]
else:
phase = None
# Get the list of builders to time.
builder_to_time = []
if phase is None:
builders_to_time = [p.phase_builder
for p in cfg.phases]
else:
builders_to_time = phase.builder_names
# Get the builds to report timing information for.
status = current_app.config.status
builders = dict((name, [b for b in status.builders.get(name, [])
if b.end_time is not None])
for name in builders_to_time)
# Return the timing data as a json object.
data = []
for i,(name,builds) in enumerate(util.sorted(builders.items())):
color = list(util.make_dark_color(float(i) / len(builders)))
hex_color = '%02x%02x%02x' % tuple(int(x*255)
for x in color)
points = [(float(i) / len(builds), b.end_time - b.start_time)
for i,b in enumerate(builds)]
data.append((name, points, color, hex_color))
return flask.jsonify(data = data)