Recent Builds
</h1>
</div>
-{{build_mru}}
{% for build in mru %}
<div class="alert {%if build.outcome == build.SUCCEEDED%}alert-success{%elif build.outcome == build.FAILED%}alert-error{%else%}alert-info{%endif%}">
<div class="row-fluid">
</tr>
{% for build in objects %}
<tr class="data">
- <td class="outcome"><a href="{% url "configuration" build.id %}">{%if build.outcome == build.SUCCEEDED%}<i class="icon-ok-sign success"></i>{%elif build.outcome == build.FAILED%}<i class="icon-minus-sign error"></i>{%else%}{%endif%}</a></td>
+ <td class="outcome"><a href="{% url "builddashboard" build.id %}">{%if build.outcome == build.SUCCEEDED%}<i class="icon-ok-sign success"></i>{%elif build.outcome == build.FAILED%}<i class="icon-minus-sign error"></i>{%else%}{%endif%}</a></td>
<td class="target">{% for t in build.target_set.all %}{%if t.is_image %}<a href="{% url "target" build.id t.id %}">{% endif %}{{t.target}}{% if t.is_image %}</a>{% endif %}<br/>{% endfor %}</td>
- <td class="machine">{{build.machine}}</td>
- <td class="started_on">{{build.started_on}}</td>
- <td class="completed_on">{{build.completed_on}}</td>
+ <td class="machine"><a href="{% url "builddashboard" build.id %}">{{build.machine}}</a></td>
+ <td class="started_on"><a href="{% url "builddashboard" build.id %}">{{build.started_on}}</a></td>
+ <td class="completed_on"><a href="{% url "builddashboard" build.id %}">{{build.completed_on}}</a></td>
<td class="failed_tasks"></td>
- <td class="errors">{% if build.errors_no %}<a class="error" href="#">{{build.errors_no}} error{{build.errors_no|pluralize}}</a>{%endif%}</td>
- <td class="warnings">{% if build.warnings_no %}<a class="warning" href="#">{{build.warnings_no}} warning{{build.warnings_no|pluralize}}</a>{%endif%}</td>
- <td class="time">{{build|timespent}}</td>
+ <td class="errors">{% if build.errors_no %}<a class="error" href="{% url "builddashboard" build.id %}#errors">{{build.errors_no}} error{{build.errors_no|pluralize}}</a>{%endif%}</td>
+ <td class="warnings">{% if build.warnings_no %}<a class="warning" href="{% url "builddashboard" build.id %}#warnings">{{build.warnings_no}} warning{{build.warnings_no|pluralize}}</a>{%endif%}</td>
+ <td class="time"><a href="{% url "buildtime" build.id %}">{{build|timespent}}</a></td>
<td class="log">{{build.log}}</td>
- <td class="output">{% if build.outcome == 0 %}{% for t in build.target_set.all %}{% if t.is_image %}{{build.image_fstypes}}{% endif %}{% endfor %}{% endif %}</td>
+ <td class="output">{% if build.outcome == 0 %}{% for t in build.target_set.all %}{% if t.is_image %}<a href="{%url "builddashboard" build.id%}#images">{{build.image_fstypes}}</a>{% endif %}{% endfor %}{% endif %}</td>
</tr>
{% endfor %}
{% extends "basebuildpage.html" %}
+{% load humanize %}
+{% load projecttags %}
{% block localbreadcrumb %}
<li>Dashboard</li>
{% endblock %}
{% block buildinfomain %}
+<!-- page title -->
+<div class="row-fluid span10">
+ <div class="page-header">
+ <h1>{{build.target_set.all|join:" "}} {{build.machine}}</h1>
+ </div>
+</div>
+
+<!-- build result bar -->
+<div class="row-fluid span10 pull-right">
+ <div class="alert {%if build.outcome == build.SUCCEEDED%}alert-success{%elif build.outcome == build.FAILED%}alert-error{%else%}alert-info{%endif%}">
+ <div class="row-fluid lead">
+ <span class="pull-left"><strong>{%if build.outcome == build.SUCCEEDED%}Completed{%elif build.outcome == build.FAILED%}Failed{%else%}{%endif%}</strong> {{build.completed_on|naturaltime}} with </span>{%if build.outcome == build.SUCCEEDED or build.outcome == build.FAILED %}{% if build.errors_no %}
+ <span class="span2"><i class="icon-minus-sign red"></i><strong><a href="{%url 'builddashboard' build.pk%}" class="error"> {{build.errors_no}} error{{build.errors_no|pluralize}}</a></strong></span>
+{% endif %}
+{% if build.warnings_no %}
+ <span class="span2"><i class="icon-warning-sign yellow"></i><strong><a href="{%url 'builddashboard' build.pk%}" class="warning"> {{build.warnings_no}} warning{{build.warnings_no|pluralize}}</a></strong></span>
+{% endif %}
+ <span class="pull-right">Build time: <a href="build-time.html">{{ build|timespent }}</a></span>
+{%endif%}
+ </div>
+ </div>
+</div>
+
+{%if build.outcome == build.SUCCEEDED%}
+<!-- built images -->
+<div class="row-fluid span10 pull-right">
+ <h2>Images</h2>
+
+<div class="well" style="background-color:transparent;">
+</div>
+</div>
+
+{%else%}
+<!-- error dump -->
+{%endif%}
+
+<!-- build summary -->
+<div class="row-fluid span10 pull-right">
+<h2>Build summary</h2>
+ <div class="well span4" style="margin-left:0px; background-color:transparent;">
+ <h4><a href="{%url 'configuration' build.pk%}">Configuration</a></h4>
+ <dl>
+ <dt>Machine</dt><dd>{{build.machine}}</dd>
+ <dt>Distro</dt><dd></dd>
+ <dt>Layers</dt>{% for i in build.layer_version_build.all %}<dd>{{i.layer.name}}</dd>{%endfor%}
+ </dl>
+ </div>
+ <div class="well span4" style="background-color:transparent;">
+ <h4><a href="{%url 'tasks' build.pk%}">Tasks</a></h4>
+ <dl>
+ <dt>Total number of tasks</dt><dd>{{build.task_build.all.count}}</dd>
+ <dt>Tasks executed</dt><dd>{% query build.task_build task_executed=1 order__gt=0 as exectask%}{{exectask.count}}</dd>
+ <dt>Tasks prebuilt</dt><dd>{% query build.task_build task_executed=0 order__gt=0 as noexectask%}{{noexectask.count}}</dd>
+ <dt>Reuse</dt><dd>{% query build.task_build order__gt=0 as texec %}{{noexectask.count|multiply:100|divide:texec.count}}%</dd>
+ </dl>
+ </div>
+ <div class="well span4" style="background-color:transparent;">
+ <h4><a href="{% url 'recipes' build.pk %}">Recipes</a> & <a href="{% url 'packages' build.pk %}">Packages</a></h4>
+ <dl>
+ <dt>Recipes used</dt><dd>{{recipecount}}</dd>
+ <dt>Packages built</dt><dd>{{build.package_set.all.count}}</dd>
+ </dl>
+ </div>
+</div>
{% endblock %}
return miss
return None
-def _redirect_parameters(view, g, mandatory_parameters):
+def _redirect_parameters(view, g, mandatory_parameters, *args, **kwargs):
import urllib
from django.core.urlresolvers import reverse
- url = reverse(view)
+ url = reverse(view, kwargs=kwargs)
params = {}
for i in g:
params[i] = g[i]
if not i in params:
params[i] = mandatory_parameters[i]
- return redirect(url + "?%s" % urllib.urlencode(params))
+ return redirect(url + "?%s" % urllib.urlencode(params), *args, **kwargs)
# shows the "all builds" page
mandatory_parameters = { 'count': 10, 'page' : 1};
retval = _verify_parameters( request.GET, mandatory_parameters )
if retval:
- return _redirect_parameters( builds, request.GET, mandatory_parameters)
+ return _redirect_parameters( 'all-builds', request.GET, mandatory_parameters)
# retrieve the objects that will be displayed in the table
build_info = _build_page_range(Paginator(Build.objects.exclude(outcome = Build.IN_PROGRESS).order_by("-id"), request.GET.get('count', 10)),request.GET.get('page', 1))
return redirect(builds)
context = {
'build' : Build.objects.filter(pk=build_id)[0],
+ 'recipecount' : Recipe.objects.filter(layer_version__id__in=Layer_Version.objects.filter(build=build_id)).count()
}
return render(request, template, context)
def tasks(request, build_id):
template = 'task.html'
+ mandatory_parameters = { 'count': 100, 'page' : 1};
+ retval = _verify_parameters( request.GET, mandatory_parameters )
+ if retval:
+ return _redirect_parameters( 'tasks', request.GET, mandatory_parameters, build_id = build_id)
- tasks = _build_page_range(Paginator(Task.objects.filter(build=build_id), 100),request.GET.get('page', 1))
+ tasks = _build_page_range(Paginator(Task.objects.filter(build=build_id, order__gt=0), request.GET.get('count', 100)),request.GET.get('page', 1))
for t in tasks:
if t.outcome == Task.OUTCOME_COVERED:
def recipes(request, build_id):
template = 'recipe.html'
+ mandatory_parameters = { 'count': 100, 'page' : 1};
+ retval = _verify_parameters( request.GET, mandatory_parameters )
+ if retval:
+ return _redirect_parameters( 'recipes', request.GET, mandatory_parameters, build_id = build_id)
- recipes = _build_page_range(Paginator(Recipe.objects.filter(build_recipe=build_id), 100),request.GET.get('page', 1))
+ recipes = _build_page_range(Paginator(Recipe.objects.filter(layer_version__id__in=Layer_Version.objects.filter(build=build_id)), request.GET.get('count', 100)),request.GET.get('page', 1))
- context = {'build': Build.objects.filter(pk=build_id)[0], 'objects': recipes}
+ context = {'build': Build.objects.filter(pk=build_id)[0], 'objects': recipes, }
return render(request, template, context)
def configuration(request, build_id):
template = 'configuration.html'
+ mandatory_parameters = { 'count': 100, 'page' : 1};
+ retval = _verify_parameters( request.GET, mandatory_parameters )
+ if retval:
+ return _redirect_parameters( 'configuration', request.GET, mandatory_parameters, build_id = build_id)
+
variables = _build_page_range(Paginator(Variable.objects.filter(build=build_id), 50), request.GET.get('page', 1))
context = {'build': Build.objects.filter(pk=build_id)[0], 'objects' : variables}
return render(request, template, context)
def bpackage(request, build_id):
template = 'bpackage.html'
- packages = Package.objects.filter(build = build_id)
+ mandatory_parameters = { 'count': 100, 'page' : 1};
+ retval = _verify_parameters( request.GET, mandatory_parameters )
+ if retval:
+ return _redirect_parameters( 'packages', request.GET, mandatory_parameters, build_id = build_id)
+
+ packages = _build_page_range(Paginator(Package.objects.filter(build = build_id), request.GET.get('count', 100)),request.GET.get('page', 1))
+
context = {'build': Build.objects.filter(pk=build_id)[0], 'objects' : packages}
return render(request, template, context)