]> git.ipfire.org Git - people/jschlag/pbs.git/commitdiff
Redesign builders pages.
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 3 Dec 2012 10:51:46 +0000 (11:51 +0100)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 3 Dec 2012 10:51:46 +0000 (11:51 +0100)
backend/builders.py
data/templates/builder-detail.html
data/templates/builder-edit.html
data/templates/builder-list.html
web/__init__.py
web/handlers_builders.py
web/ui_modules.py

index 6ce1365e3d33f2e7968c41697226f7fe92e24468..9a8415bb0e38ed0825da065ef08ce5e880c0428a 100644 (file)
@@ -1,5 +1,7 @@
 #!/usr/bin/python
 
+from __future__ import division
+
 import datetime
 import hashlib
 import logging
@@ -69,17 +71,17 @@ class Builders(base.Object):
                return sorted(arches)
 
        def get_load(self):
-               slots = 1
-               running_jobs = 0
-
-               for builder in self.get_all():
-                       if not builder.state == "online":
-                               continue
+               res1 = self.db.get("SELECT SUM(max_jobs) AS max_jobs FROM builders \
+                       WHERE status = 'enabled'")
+               if not res1:
+                       return 0
 
-                       slots += builder.max_jobs
-                       running_jobs += len(builder.get_active_jobs(uploads=False))
+               res2 = self.db.get("SELECT COUNT(*) AS count FROM jobs \
+                       WHERE state = 'dispatching' OR state = 'running' OR state = 'uploading'")
+               if not res2:
+                       return 0
 
-               return int(running_jobs * 100 / slots)
+               return (res2.count * 100 / res1.max_jobs)
 
        def get_history(self, limit=None, offset=None, builder=None, user=None):
                query = "SELECT * FROM builders_history"
@@ -134,9 +136,8 @@ class Builder(base.Object):
        @property
        def data(self):
                if self._data is None:
-                       self._data = \
-                               self.db.get("SELECT *, NOW() - time_keepalive AS updated \
-                                       FROM builders WHERE id = %s", self.id)
+                       self._data = self.db.get("SELECT * FROM builders WHERE id = %s", self.id)
+                       assert self._data
 
                return self._data
 
@@ -531,11 +532,17 @@ class Builder(base.Object):
                if self.data.time_keepalive is None:
                        return "offline"
 
-               if self.data.updated >= 5*60:
-                       return "offline"
+               #if self.data.updated >= 5*60:
+               #       return "offline"
 
                return "online"
 
+       @property
+       def active_jobs(self):
+               jobs = self.get_active_jobs()
+
+               return len(jobs)
+
        def get_active_jobs(self, uploads=True):
                if self._active_jobs is None:
                        self._active_jobs = \
index 409eda11cfb97b8fc9c02937926ffa4ebfc1bfbd..8ea27c5053b273cbb9cbe94646ecb7ca85c1f58e 100644 (file)
                </li>
        </ul>
 
+       <div class="page-header">
+               <h2>{{ _("Builder") }}: {{ builder.name }}</h2>
+       </div>
+
        {% if builder.overload %}
-               <div class="alert alert-warning">
-                       <strong>{{ _("Warning") }}</strong>! {{ _("This builder is overloaded.") }}
-                       {{ _("That means it will take no additional jobs although it has not reached its threshold.") }}
-                       {{ _("If the load decreases new jobs will be added automatically.") }}
+               <div class="alert alert-block alert-warning">
+                       <h4 class="alert-heading">{{ _("Warning") }}!</h4>
+                       {{ _("This builder is overloaded.") }}
+                       {{ _("That means it will not take any additional jobs although it has not reached its threshold of running jobs, yet.") }}
+                       {{ _("New jobs will be started automatically after the load decreased.") }}
                </div>
        {% end %}
 
-       <div class="page-header">
-               <h1>{{ _("Builder") }}: {{ builder.name }}</h1>
-       </div>
-
        <div class="row">
-               <div class="span4 offset1">
-                       <table class="table">
+               <div class="span5">
+                       <table class="table table-striped table-hover">
                                <tbody>
                                        <tr>
                                                <td>{{ _("State") }}</td>
@@ -80,8 +81,8 @@
                        {% end %}
                </div>
 
-               <div class="span6">
-                       <table class="table">
+               <div class="span7">
+                       <table class="table table-striped table-hover">
                                <tbody>
                                        <tr>
                                                <td>{{ _("Pakfire version") }}</td>
        </div>
 
        {% if current_user and current_user.has_perm("maintain_builders") %}
-               <div class="row">
-                       <div class="span10 offset1">
-                               <div class="btn-toolbar">
-                                       <div class="btn-group pull-right">
-                                               {% if builder.enabled %}
-                                                       <a class="btn btn-danger" href="/builder/{{ builder.name }}/disable">
-                                                               {{ _("Disable") }}
-                                                       </a>
-                                               {% else %}
-                                                       <a class="btn btn-success" href="/builder/{{ builder.name }}/enable">
-                                                               {{ _("Enable") }}
-                                                       </a>
-                                               {% end %}
-
-                                               <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
-                                                       {{ _("Action") }}
-                                                       <span class="caret"></span>
-                                               </a>
-                                               <ul class="dropdown-menu">
-                                                       <li>
-                                                               <a href="/builder/{{ builder.name }}/edit">
-                                                                       <i class="icon-edit"></i>
-                                                                       {{ _("Edit settings") }}
-                                                               </a>
-                                                       </li>
-
-                                                       {% if not builder.enabled %}
-                                                               <li>
-                                                                       <a href="/builder/{{ builder.name }}/renew">
-                                                                               <i class="icon-refresh"></i>
-                                                                               {{ _("Renew passphrase") }}
-                                                                       </a>
-                                                               </li>
-                                                       {% end %}
+               <hr>
 
-                                                       <li class="divider"></li>
-                                                       <li>
-                                                               <a href="/builder/{{ builder.name }}/delete">
-                                                                       <i class="icon-trash"></i>
-                                                                       {{ _("Delete builder") }}
-                                                               </a>
-                                                       </li>
-                                               </ul>
-                                       </div>
-                               </div>
-                       </div>
-               </div>
-       {% end %}
+               <div class="btn-toolbar ac">
+                       {% if builder.enabled %}
+                               <a class="btn btn-danger" href="/builder/{{ builder.name }}/disable">
+                                       {{ _("Disable builder") }}
+                               </a>
+                       {% else %}
+                               <a class="btn btn-success" href="/builder/{{ builder.name }}/enable">
+                                       {{ _("Enable builder") }}
+                               </a>
+                       {% end %}
+
+                       <a class="btn" href="/builder/{{ builder.name }}/edit">
+                               <i class="icon-edit"></i>
+                               {{ _("Edit builder") }}
+                       </a>
+
+                       {% if not builder.enabled %}
+                               <a class="btn" href="/builder/{{ builder.name }}/renew">
+                                       <i class="icon-refresh"></i>
+                                       {{ _("Renew passphrase") }}
+                               </a>
+                       {% end %}
 
-       {% if builder.get_active_jobs() %}
-               <div class="row">
-                       <div class="span10 offset1">
-                               <h2>{{ _("Currently running builds on this host") }}</h2>
-                               {% module JobsList(builder.get_active_jobs()) %}
-                       </div>
+                       <a class="btn" href="/builder/{{ builder.name }}/delete">
+                               <i class="icon-trash"></i>
+                               {{ _("Delete builder") }}
+                       </a>
                </div>
        {% end %}
 
-       <div class="row">
-               <div class="span10 offset1">
-                       <h2>{{ _("Log") }}</h2>
-                       {% module Log(builder.get_history(limit=20)) %}
-               </div>
-       </div>
+       <hr>
+
+       <h3>{{ _("Log") }}</h3>
+       {% module Log(builder.get_history(limit=5)) %}
 {% end block %}
index e48dbdbb88bc9cc2a29bcf6e2a68f322db8a7b16..9ffc447e3c5415e7f15520085efd2a43cece96e8 100644 (file)
@@ -1,6 +1,6 @@
-{% extends "base-form1.html" %}
+{% extends "base.html" %}
 
-{% block title %}{{ _("Edit builder %s") % builder.hostname }}{% end block %}
+{% block title %}{{ _("Manage builder %s") % builder.hostname }}{% end block %}
 
 {% block body %}
        <ul class="breadcrumb">
        </ul>
 
        <div class="page-header">
-               <h1>{{ _("Manage builder:") }} {{ builder.hostname }}</h1>
+               <h2>{{ _("Builder: %s") % builder.hostname }} <small>{{ _("Manage") }}</small></h2>
        </div>
 
-       <div class="row">
-               <div class="span8">
-                       <form class="form-horizontal" method="POST" action="">
-                               {% raw xsrf_form_html() %}
-                               <fieldset>
-                                       <div class="control-group">
-                                               <label class="control-label">{{ _("Hostname") }}</label>
-                                               <div class="controls">
-                                                       <span class="input-xlarge uneditable-input">{{ builder.hostname }}</span>
-                                                       <p class="help-block">
-                                                               {{ _("The hostname cannot be changed.") }}
-                                                       </p>
-                                               </div>
-                                       </div>
+       <form class="form-horizontal" method="POST" action="">
+               {% raw xsrf_form_html() %}
+               <fieldset>
+                       <div class="control-group">
+                               <label class="control-label">{{ _("Hostname") }}</label>
+                               <div class="controls">
+                                       <span class="input-xlarge uneditable-input">{{ builder.hostname }}</span>
+                                       <p class="help-block">
+                                               {{ _("The hostname cannot be changed.") }}
+                                       </p>
+                               </div>
+                       </div>
 
-                                       <div class="control-group">
-                                               <label class="control-label" for="enabled">{{ _("Enabled") }}</label>
-                                               <div class="controls">
-                                                       <label class="checkbox">
-                                                               <input type="checkbox" id="enabled" name="enabled" {% if builder.enabled %}checked="checked"{% end %}>
-                                                               {{ _("The builder must be enabled in order to process build jobs.") }}
-                                                       </label>
-                                               </div>
-                                       </div>
-                               </fieldset>
+                       <div class="control-group">
+                               <label class="control-label" for="enabled">{{ _("Enabled") }}</label>
+                               <div class="controls">
+                                       <label class="checkbox">
+                                               <input type="checkbox" id="enabled" name="enabled" {% if builder.enabled %}checked="checked"{% end %}>
+                                               {{ _("The builder must be enabled in order to process build jobs.") }}
+                                       </label>
+                               </div>
+                       </div>
+               </fieldset>
 
-                               <fieldset>
-                                       <legend>{{ _("Build job settings") }}</legend>
+               <fieldset>
+                       <legend>{{ _("Build job settings") }}</legend>
 
-                                       <div class="control-group">
-                                               <label class="control-label" for="max_jobs">{{ _("Maximum number of parallel build jobs") }}</label>
-                                               <div class="controls">
-                                                       <select id="max_jobs" name="max_jobs">
-                                                               {% for i in range(1, (2 * builder.cpu_count) + 1) %}
-                                                                       <option value="{{ i }}" {% if i == builder.max_jobs %}selected="selected"{% end %}>{{ i }}</option>
-                                                               {% end %}
-                                                       </select>
+                       <div class="control-group">
+                               <label class="control-label" for="max_jobs">{{ _("Maximum number of parallel build jobs") }}</label>
+                               <div class="controls">
+                                       <select id="max_jobs" name="max_jobs">
+                                               {% for i in range(1, (2 * builder.cpu_count) + 1) %}
+                                                       <option value="{{ i }}" {% if i == builder.max_jobs %}selected="selected"{% end %}>{{ i }}</option>
+                                               {% end %}
+                                       </select>
 
-                                                       <p class="help-block">
-                                                               {{ _("This is the number of build jobs that are started in parallel.") }}
-                                                       </p>
-                                               </div>
-                                       </div>
+                                       <p class="help-block">
+                                               {{ _("This is the number of build jobs that are started in parallel.") }}
+                                       </p>
+                               </div>
+                       </div>
 
-                                       <div class="control-group">
-                                               <div class="controls">
-                                                       <label class="checkbox">
-                                                               <input type="checkbox" id="build_release" name="build_release" {%if builder.build_release %}checked="checked"{% end %}>
-                                                               {{ _("Authorized to build release builds.") }}
-                                                       </label>
-                                               </div>
-                                       </div>
+                       <div class="control-group">
+                               <div class="controls">
+                                       <label class="checkbox">
+                                               <input type="checkbox" id="build_release" name="build_release" {%if builder.build_release %}checked="checked"{% end %}>
+                                               {{ _("Authorized to build release builds.") }}
+                                       </label>
+                               </div>
+                       </div>
 
-                                       <div class="control-group">
-                                               <div class="controls">
-                                                       <label class="checkbox">
-                                                               <input type="checkbox" id="build_scratch" name="build_scratch" {%if builder.build_scratch %}checked="checked"{% end %}>
-                                                               {{ _("Authorized to build scratch builds.") }}
-                                                       </label>
-                                               </div>
-                                       </div>
+                       <div class="control-group">
+                               <div class="controls">
+                                       <label class="checkbox">
+                                               <input type="checkbox" id="build_scratch" name="build_scratch" {%if builder.build_scratch %}checked="checked"{% end %}>
+                                               {{ _("Authorized to build scratch builds.") }}
+                                       </label>
+                               </div>
+                       </div>
 
-                                       <div class="control-group">
-                                               <div class="controls">
-                                                       <label class="checkbox">
-                                                               <input type="checkbox" id="build_test" name="build_test" {%if builder.build_test %}checked="checked"{% end %}>
-                                                               {{ _("Authorized to build test builds.") }}
-                                                       </label>
-                                               </div>
-                                       </div>
+                       <div class="control-group">
+                               <div class="controls">
+                                       <label class="checkbox">
+                                               <input type="checkbox" id="build_test" name="build_test" {%if builder.build_test %}checked="checked"{% end %}>
+                                               {{ _("Authorized to build test builds.") }}
+                                       </label>
+                               </div>
+                       </div>
 
-                                       <div class="control-group">
-                                               <label class="control-label" for="arches">{{ _("Enable host for these architectures") }}</label>
-                                               <div class="controls">
-                                                       <select multiple="multiple" id="arches" name="arches">
-                                                               {% for arch in builder.get_arches() %}
-                                                                       <option value="{{ arch.name }}" {% if arch in builder.arches %}selected="selected"{% end %}>{{ arch.name }}</option>
-                                                               {% end %}
-                                                       </select>
+                       <div class="control-group">
+                               <label class="control-label" for="arches">{{ _("Enable host for these architectures") }}</label>
+                               <div class="controls">
+                                       <select multiple="multiple" id="arches" name="arches">
+                                               {% for arch in builder.get_arches() %}
+                                                       <option value="{{ arch.name }}" {% if arch in builder.arches %}selected="selected"{% end %}>{{ arch.name }}</option>
+                                               {% end %}
+                                       </select>
 
-                                                       <p class="help-block">
-                                                               {{ _("Select or deselect the architectures, this builder should build or not.") }}
-                                                       </p>
-                                               </div>
-                                       </div>
+                                       <p class="help-block">
+                                               {{ _("Select or deselect the architectures, this builder should build or not.") }}
+                                       </p>
+                               </div>
+                       </div>
 
-                                       <div class="form-actions">
-                                               <button type="submit" class="btn btn-primary">{{ _("Save changes") }}</button>
-                                       </div>
-                               </fieldset>
-                       </form>
-               </div>
-       </div>
+                       <div class="form-actions">
+                               <button type="submit" class="btn btn-primary">{{ _("Save changes") }}</button>
+                       </div>
+               </fieldset>
+       </form>
 {% end block %}
index 11a7c3dda3e86daf0d1f5250a305fa1c3546d5de..4154017f3a2a78bd107620051d4f672a6df4d977 100644 (file)
@@ -1,6 +1,6 @@
 {% extends "base.html" %}
 
-{% block title %}{{ _("Build servers") }}{% end block %}
+{% block title %}{{ _("Builders") }}{% end block %}
 
 {% block body %}
        <ul class="breadcrumb">
        </ul>
 
        <div class="page-header">
-               <h1>{{ _("Build servers") }}</h1>
+               <h2>{{ _("Builders") }}</h2>
        </div>
 
-       <div class="row">
-               <div class="span12">
-                       <p>
-                               {{ _("Builders are those, that do all the hard work.") }}
-                               {{ _("Build jobs are scheduled to these hosts that they process and send back the result.") }}
-                       </p>
-               </div>
-       </div>
+       {% module BuildersLoad() %}
+
+       <hr>
 
        <div class="row">
-               <div class="span6 offset3">
+               <div class="span12">
                        <table class="table table-striped table-hover">
                                <thead>
                                        <tr>
                                                <th>&nbsp;</th>
                                                <th>{{ _("Hostname") }}</th>
-                                               <th>{{ _("Load") }}</th>
-                                               <th>{{ _("Running jobs") }}</th>
+                                               <th>{{ _("Architectures") }}</th>
+                                               <th>{{ _("Jobs") }}</th>
                                        </tr>
                                </thead>
                                <tbody>
                                        {% for builder in builders %}
                                                <tr>
-                                                       <td>
-                                                               <img src="{{ static_url("images/icons/builder-%s.png" % builder.state.lower()) }}"
-                                                                       alt="{{ _("State %s") % builder.state }}" />
+                                                       <td class="lead">
+                                                               {% if builder.state == "disabled" %}
+                                                                       <i class="icon-stop text-error"></i>
+                                                               {% elif builder.state == "offline" %}
+                                                                       <i class="icon-pause text-warning"></i>
+                                                               {% elif builder.state == "online" %}
+                                                                       <i class="icon-play text-success"></i>
+                                                               {% end %}
                                                        </td>
                                                        <td>
                                                                <a href="/builder/{{ builder.name }}">{{ builder.name }}</a>
                                                                {% if builder.overload %}
-                                                                               <span class="label label-important">{{ _("Overload") }}</span>
+                                                                               <span class="label label-important pull-right">{{ _("Overload") }}</span>
                                                                {% end %}
-                                                               <br />
-                                                               {{ locale.list([a.name for a in builder.arches]) }}
+                                                               <br>
+                                                               {{ builder.cpu_model or _("Unknown CPU") }} - {{ format_size(builder.memory) }}
                                                        </td>
                                                        <td>
-                                                               {{ builder.load1 or _("N/A") }}
+                                                               {% if builder.arches %}
+                                                                       {{ locale.list([a.name for a in builder.arches]) }}
+                                                               {% else %}
+                                                                       {{ _("N/A") }}
+                                                               {% end %}
                                                        </td>
                                                        <td>
-                                                               {{ len(builder.get_active_jobs()) }}/{{ builder.max_jobs }}
+                                                               <p class="{% if builder.active_jobs == 0 %}text-success{% elif builder.active_jobs >= builder.max_jobs %}text-error{% else %}text-warning{% end %}">
+                                                                       {{ len(builder.get_active_jobs()) }}/{{ builder.max_jobs }}
+                                                               </p>
                                                        </td>
                                                </tr>
                                        {% end %}
-
-                                       <tr>
-                                               <td colspan="3">
-                                                       <div class="progress progress-info">
-                                                               <div class="bar" style="width: {{ load }}%;"></div>
-                                                       </div>
-                                               </td>
-                                               <td>
-                                                       {% if current_user and current_user.is_admin() %}
-                                                               <div class="btn-group pull-right">
-                                                                       <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
-                                                                               {{ _("Action") }}
-                                                                               <span class="caret"></span>
-                                                                       </a>
-                                                                       <ul class="dropdown-menu">
-                                                                               <li>
-                                                                                       <a href="/builder/new">{{ _("Create new builder") }}</a>
-                                                                               </li>
-                                                                       </ul>
-                                                               </div>
-                                                       {% end %}
-                                               </td>
-                                       </tr>
                                </tbody>
                        </table>
-               </div>
-       </div>
 
-       <div class="row">
-               <div class="span12">
-                       {% if log %}
-                               <h2>{{ _("Log") }}</h2>
-                               {% module Log(log) %}
+                       {% if current_user and current_user.is_admin() %}
+                               <div class="btn-group pull-right">
+                                       <a class="btn" href="/builder/new">{{ _("Create new builder") }}</a>
+                               </div>
                        {% end %}
                </div>
        </div>
index 73be54c8ef8910c0f70ac5ffd519d7adbddf0248..71a687539b2864ff62e540e9a212871e21263aac 100644 (file)
@@ -35,6 +35,9 @@ class Application(tornado.web.Application):
                                "LogEntry"           : LogEntryModule,
                                "LogEntryComment"    : LogEntryCommentModule,
 
+                               # Builders
+                               "BuildersLoad"       : BuildersLoadModule,
+
                                "BuildHeadline"      : BuildHeadlineModule,
                                "BuildStateWarnings" : BuildStateWarningsModule,
 
index aa9ba6d558d27ab877ba80c776e6836623566ab8..eaab382ea3ff7323f0682d7a8e844bde1202ff25 100644 (file)
@@ -9,11 +9,8 @@ from handlers_base import *
 class BuilderListHandler(BaseHandler):
        def get(self):
                builders = self.pakfire.builders.get_all()
-               load = self.pakfire.builders.get_load()
 
-               log = self.pakfire.builders.get_history(limit=10)
-
-               self.render("builder-list.html", builders=builders, load=load, log=log)
+               self.render("builder-list.html", builders=builders)
 
 
 class BuilderDetailHandler(BaseHandler):
index 5f386852fe0f3fa0c182aa2e0f5d1f48f8d22a29..a5b593cb941e6f10fa0e8b5fce98697287178d0f 100644 (file)
@@ -96,6 +96,13 @@ class BuildHeadlineModule(UIModule):
                        prefix=prefix, build=build, pkg=build.pkg, short=short, shorter=shorter)
 
 
+class BuildersLoadModule(UIModule):
+       def render(self):
+               load = self.pakfire.builders.get_load()
+
+               return self.render_string("modules/builders/load.html", load=load)
+
+
 class BugsTableModule(UIModule):
        def render(self, pkg, bugs):
                return self.render_string("modules/bugs-table.html",