[Checkins] SVN: Sandbox/ctheune/buildbot/ - Integrate waterfall display with cruise control

Christian Theune ct at gocept.com
Wed Mar 12 11:56:29 EDT 2008


Log message for revision 84618:
  - Integrate waterfall display with cruise control
  - Integrate static resources (image, css) with HTTP server
  - Make configuration available as library
  

Changed:
  U   Sandbox/ctheune/buildbot/README.txt
  D   Sandbox/ctheune/buildbot/TODO
  A   Sandbox/ctheune/buildbot/__init__.py
  D   Sandbox/ctheune/buildbot/html2.py
  D   Sandbox/ctheune/buildbot/master.cfg
  A   Sandbox/ctheune/buildbot/master.py
  D   Sandbox/ctheune/buildbot/static/buildbot.css
  A   Sandbox/ctheune/buildbot/static/cruise.css
  A   Sandbox/ctheune/buildbot/status.py
  U   Sandbox/ctheune/buildbot/update-config.sh

-=-
Modified: Sandbox/ctheune/buildbot/README.txt
===================================================================
--- Sandbox/ctheune/buildbot/README.txt	2008-03-12 15:22:43 UTC (rev 84617)
+++ Sandbox/ctheune/buildbot/README.txt	2008-03-12 15:56:29 UTC (rev 84618)
@@ -1,5 +1,34 @@
-Some notes about setting this buildbot up:
+================================
+bsquare - buildbot for buildouts
+================================
 
-- The `static` directory needs to be made available through some webserver.
-  The CSS file pulls in the images relative to the place where the CSS is
-  located. The address of the CSS file is currently hard coded.
+This package provides a buildout configuration and utilities to automatically
+monitor a subversion repository defining zc.buildout-based projects.
+
+It also defines an alternative comprehensive view  (inspired by cruise control)
+accessiable via /cruise.
+
+Installation
+------------
+
+- Install this package using standard distutils functionality:
+
+      $ python setup.py install
+
+- Set up a buildbot master and configure the master.cfg like this:
+
+      $ cat > master.cfg
+      import bsquare.master
+
+      config = bsquare.master.configure('http://svn.example.com/repository')
+
+  You can then edit the config object like the normal buildout master's
+  configuration (adding the base URL, your contact information, slaves, etc ...)
+
+- Set up a cron-job to execute the `update-config.sh` script with two arguments:
+  your buildbot master`s directory and the subversion base url:
+
+  $ update-config.sh /home/foo/buildbot-master http://svn.example.com/repository/
+
+- In your master's `public_html` directory, you should
+  edit the `index.html` to allow access to the cruise-control-like interface.

Deleted: Sandbox/ctheune/buildbot/TODO
===================================================================
--- Sandbox/ctheune/buildbot/TODO	2008-03-12 15:22:43 UTC (rev 84617)
+++ Sandbox/ctheune/buildbot/TODO	2008-03-12 15:56:29 UTC (rev 84618)
@@ -1,17 +0,0 @@
-====
-TODO
-====
-
-Important
-=========
-
-- access to logs
-- display of current step when building
-- trigger builds
-- amount of projects currently building
-- redo green background (too small)
-
-Maybe
-=====
-
- - multi-slave environments

Added: Sandbox/ctheune/buildbot/__init__.py
===================================================================


Property changes on: Sandbox/ctheune/buildbot/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Deleted: Sandbox/ctheune/buildbot/html2.py
===================================================================
--- Sandbox/ctheune/buildbot/html2.py	2008-03-12 15:22:43 UTC (rev 84617)
+++ Sandbox/ctheune/buildbot/html2.py	2008-03-12 15:56:29 UTC (rev 84618)
@@ -1,223 +0,0 @@
-# -*- test-case-name: buildbot.test.test_web -*-
-
-from __future__ import generators
-
-from twisted.python import log, components
-import urllib, re
-import datetime
-
-from twisted.internet import defer, reactor
-from twisted.web.resource import Resource
-from twisted.web import static, html, server, distrib
-from twisted.web.error import NoResource
-from twisted.web.util import Redirect, DeferredResource
-from twisted.application import strports
-from twisted.spread import pb
-
-from buildbot.twcompat import implements, Interface
-
-import sys, string, types, time, os.path
-
-from buildbot import interfaces, util
-from buildbot import version
-from buildbot.sourcestamp import SourceStamp
-from buildbot.status import builder, base
-from buildbot.changes import changes
-from buildbot.process.base import BuildRequest
-
-NO_FILTER = object()
-
-class HtmlResource(Resource):
-    css = None
-    contentType = "text/html; charset=UTF-8"
-    title = "Dummy"
-
-    def render(self, request):
-        data = self.content(request)
-        if isinstance(data, unicode):
-            data = data.encode("utf-8")
-        request.setHeader("content-type", self.contentType)
-        if request.method == "HEAD":
-            request.setHeader("content-length", len(data))
-            return ''
-        return data
-
-    def content(self, request):
-        data = ('<!DOCTYPE html PUBLIC'
-                ' "-//W3C//DTD XHTML 1.0 Transitional//EN"\n'
-                '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n'
-                '<html'
-                ' xmlns="http://www.w3.org/1999/xhtml"'
-                ' lang="en"'
-                ' xml:lang="en">\n')
-        data += "<head>\n"
-        data += "  <title>" + self.title + "</title>\n"
-        data += '  <link href="http://uter.gocept.com/~ctheune/buildbot/buildbot.css" media="all" rel="Stylesheet" type="text/css" />'
-        if self.css:
-            # TODO: use some sort of relative link up to the root page, so
-            # this css can be used from child pages too
-            data += ('  <link href="%s" rel="stylesheet" type="text/css"/>\n'
-                     % "buildbot.css")
-        data += "</head>\n"
-        data += '<body>\n'
-        data += self.body(request)
-        data += "</body></html>\n"
-        return data
-
-    def body(self, request):
-        return "Dummy\n"
-
-
-class OverviewStatusResource(HtmlResource):
-    """This builds the main status page, with the waterfall display, and
-    all child pages."""
-    title = "BuildBot"
-    def __init__(self, status, changemaster):
-        HtmlResource.__init__(self)
-        self.status = status
-        self.changemaster = changemaster
-        p = self.status.getProjectName()
-        if p:
-            self.title = "BuildBot: %s" % p
-
-    def _builder_status(self, builder):
-        build = builder.getLastFinishedBuild()
-        if build is None:
-            stat = 'never'
-        else:
-            stat = build.getColor()
-        return stat
-
-    def body(self, request):
-        "This method builds the main waterfall display."
-
-        data = ''
-
-        data += """<script lang="javascript">
-        window.setTimeout("reload()", 10000);
-        function reload() {
-            document.forms['filter'].submit();
-        };
-        </script>
-        """
-
-        projectName = self.status.getProjectName()
-        projectURL = self.status.getProjectURL()
-
-        data += "<h1>%s &mdash; THIS IS STILL EXPERIMENTAL AND UNDER DEVELOPMENT!</h1>" % projectName
-
-        builders = [self.status.getBuilder(x) for x in 
-                self.status.getBuilderNames()]
-
-        # Setup filters
-        filters = []
-        filter_status = request.args.get('status', [None])[0] or 'red'
-        # Gah.
-        if filter_status == 'None':
-            filter_status = None
-        # Double-gah!
-        if filter_status != "any":
-            filters.append(lambda x:self._builder_status(x) == filter_status)
-
-        filter_prefix = request.args.get('prefix', [None])[0] or 'zope.'
-        filters.append(lambda x:x.getName().startswith(filter_prefix))
-
-        # Create totals
-        status = {}
-        for builder in builders:
-            stat = self._builder_status(builder)
-            if not stat in status:
-                status[stat] = []
-            status[stat].append(builder)
-
-        data += '<form id="filter" action=".">'
-        data += '<div id="status-blocks">'
-        for stat, affected in status.items():
-            if stat == filter_status:
-                selected = 'checked="checked"'
-            else:
-                selected = ""
-            data += '<div class="%s"><h3><label><input type="radio" name="status" value="%s" %s/> %s</label></h3><p>%s projects</p></div>' % (stat, stat, selected, stat, len(affected))
-
-        if filter_status == "any":
-            selected = 'checked="checked"'
-        else:
-            selected = ''
-        data += '<div><h3><label><input type="radio" name="status" value="any" %s/> Any</label></h3><p>&nbsp;</p></div>' % selected
-
-        data += "</div>"
-        data += '<div class="clear"/>'
-        data += '<div><label for="prefix">Show only projects starting with</label> <input type="text" name="prefix" value="%s"/> <input type="submit" value="Set filter"/></div>' % filter_prefix
-        data += '</form>'
-
-        # Apply filters on builders
-        for f in filters:
-            builders = filter(f, builders)
-        data += "<p>Showing %i projects matching the current filter.</p>" % len(builders)
-
-        # Create detail view panels
-        for builder in builders:
-            activity = builder.getState()[0]
-            data += '<div class="project %s %s"><h2>%s</h2>' % (self._builder_status(builder),
-                    activity, builder.getName())
-            data += '<p>This builder is currently %s.</p>' % activity
-            data += "<ul>"
-            for x in range(1,6):
-                build = builder.getBuild(-x)
-                if build is None:
-                    break
-                reason = build.reason
-                started = datetime.datetime.fromtimestamp(build.started)
-                started = started.strftime('%d %b, %H:%M')
-                if build.source.changes:
-                    change = build.source.changes[0]
-                    reason = "%s by %s: %s" % (change.revision, change.who, change.comments)
-                data += '<li style="color:%s;">%s &ndash; %s</li>' % (
-                        build.color, started, reason)
-            data += "</ul>"
-            data += "</div>"
-
-        return data
-
-class StatusResource(Resource):
-    status = None
-
-    def __init__(self, status, changemaster):
-        Resource.__init__(self)
-        self.status = status
-        self.changemaster = changemaster
-        overview = OverviewStatusResource(self.status, changemaster)
-        self.putChild("", overview)
-
-    def render(self, request):
-        request.redirect(request.prePathURL() + '/')
-        request.finish()
-
-
-class CompactOverview(base.StatusReceiverMultiService):
-
-    compare_attrs = ["http_port"]
-
-    def __init__(self, http_port=None):
-        base.StatusReceiverMultiService.__init__(self)
-        if type(http_port) is int:
-            http_port = "tcp:%d" % http_port
-        self.http_port = http_port
-
-    def __repr__(self):
-        return "<CompactOverview on port %s>" % self.http_port
-
-    def setServiceParent(self, parent):
-        """
-        @type  parent: L{buildbot.master.BuildMaster}
-        """
-        base.StatusReceiverMultiService.setServiceParent(self, parent)
-        self.setup()
-
-    def setup(self):
-        status = self.parent.getStatus()
-        change_svc = self.parent.change_svc
-        sr = StatusResource(status, change_svc)
-        self.site = server.Site(sr)
-        s = strports.service(self.http_port, self.site)
-        s.setServiceParent(self)

Deleted: Sandbox/ctheune/buildbot/master.cfg
===================================================================
--- Sandbox/ctheune/buildbot/master.cfg	2008-03-12 15:22:43 UTC (rev 84617)
+++ Sandbox/ctheune/buildbot/master.cfg	2008-03-12 15:56:29 UTC (rev 84618)
@@ -1,88 +0,0 @@
-# A buildbot master configuration for the Zope project
-#
-# This configuration 
-
-import os.path
-import subprocess
-from twisted.python import log
-
-from buildbot import locks
-from buildbot.changes.svnpoller import SVNPoller, split_file_branches
-from buildbot.process import step, factory
-from buildbot.process.base import Build
-from buildbot.status import html
-import html2
-from buildbot.scheduler import Scheduler, Nightly
-s = factory.s
-
-c = BuildmasterConfig = {}
-
-c['bots'] = [('local', 'local')]
-c['slavePortnum'] = 8989
-
-c['sources'] = []
-
-def split_file(path):
-    pieces = path.split("/")
-    if len(pieces) < 2:
-        return None
-    project, branch = pieces[0], pieces[1]
-    if branch != "trunk":
-        return None
-    return ("%s/%s" % (project, branch), "/".join(pieces[2:]))
-
-svn_url='svn://svn.zope.org/repos/main/'
-c['sources'].append(SVNPoller(svn_url, split_file=split_file, pollinterval=30))
-
-c['schedulers'] = [] 
-c['builders'] = []
-
-def make_steps(project):
-    return  [s(step.SVN,
-               baseURL=svn_url,
-               mode='clobber'),
-             s(step.Compile,
-               name='bootstrap',
-               command='buildout bootstrap .',
-               description=['bootstrapping'],
-               descriptionDone=['bootstrap']),
-             s(step.Compile,
-               name="buildout",
-               command='bin/buildout',
-               description=['building'],
-               descriptionDone=['build']),
-             s(step.Compile,
-               name="test",
-               command='bin/test --exit-with-status',
-               description=['testing'],
-               descriptionDone=['tests']),
-            ]
-
-slow_lock = locks.SlaveLock("cpu", maxCount=10)
-
-projects = open("projects", "rb").readlines()
-projects = [x.strip() for x in projects]
-for project in projects:
-    build_factory = factory.BuildFactory(make_steps(project))
-    build_factory.treeStableTimer = 300
-    c['builders'].append({
-        'name': project,
-        'slavename': 'local',
-        'builddir': project,
-        'factory': build_factory,
-        'locks': [slow_lock],
-    })
-    del build_factory
-    c['schedulers'].append(Scheduler(
-        project, "%s/trunk" % project, 30, [project]))
-    c['schedulers'].append(Nightly(
-        "%s nightly" % project, [project], hour=range(0,24,3),
-        branch="%s/trunk" % project))
-
-c['status'] = []
-c['status'].append(html2.CompactOverview(http_port=3333))
-c['status'].append(html.Waterfall(http_port=3334))
-
-c['projectName'] = "buildbot for zope.org projects"
-c['projectURL'] = "http://dev.zope.org/"
-c['buildbotURL'] = "http://zopebuildbot.whq.gocept.com/"

Added: Sandbox/ctheune/buildbot/master.py
===================================================================
--- Sandbox/ctheune/buildbot/master.py	                        (rev 0)
+++ Sandbox/ctheune/buildbot/master.py	2008-03-12 15:56:29 UTC (rev 84618)
@@ -0,0 +1,89 @@
+# A buildbot master configuration for buildout-based project repositories
+
+import os.path
+import subprocess
+from twisted.python import log
+
+from buildbot import locks
+
+from buildbot.changes.svnpoller import SVNPoller, split_file_branches
+from buildbot.steps.source import SVN
+from buildbot.steps.shell import Compile
+from buildbot.process.factory import BuildFactory
+
+from buildbot.process.base import Build
+from buildbot.status import html
+from buildbot.scheduler import Scheduler, Nightly
+
+import bsquare.status
+
+
+def split_file(path):
+    pieces = path.split("/")
+    if len(pieces) < 2:
+        return None
+    project, branch = pieces[0], pieces[1]
+    if branch != "trunk":
+        return None
+    return ("%s/%s" % (project, branch), "/".join(pieces[2:]))
+
+
+def make_factory(svn_url):
+    f = BuildFactory()
+    f.addStep(SVN(baseURL=svn_url, mode='clobber'))
+    f.addStep(Compile(name='bootstrap',
+                command='buildout bootstrap .',
+                description=['bootstrapping'],
+                descriptionDone=['bootstrap']))
+    f.addStep(Compile(name="buildout",
+                command='bin/buildout',
+                description=['building'],
+                descriptionDone=['build']))
+    f.addStep(Compile(name="test",
+                command='bin/test --exit-with-status',
+                description=['testing'],
+                descriptionDone=['tests']))
+
+    f.treeStableTimer = 300
+    return f
+
+
+def configure(svn_url, http_port=8010, allowForce=False):
+    """Creates a buildout master configuration.
+
+    The configuration returned is almost functional. You just need to add
+    slaves.
+
+    """
+    c = {}
+    c['slavePortnum'] = 8989
+    c['change_source'] = SVNPoller(svn_url, split_file=split_file, pollinterval=30)
+    c['schedulers'] = [] 
+    c['builders'] = []
+
+    slow_lock = locks.SlaveLock("cpu", maxCount=2)
+
+    projects = open("project-list.cfg", "rb").readlines()
+    projects = [x.strip() for x in projects]
+    for project in projects:
+        f = make_factory(svn_url)
+        c['builders'].append({
+            'name': project,
+            'slavename': 'local',
+            'builddir': project,
+            'factory': f,
+            'locks': [slow_lock],
+        })
+        del f
+
+        c['schedulers'].append(Scheduler(
+            project, "%s/trunk" % project, 30, [project]))
+        c['schedulers'].append(Nightly(
+            "%s nightly" % project, [project], hour=[3],
+            branch="%s/trunk" % project))
+
+    # Status display(s)
+    c['status'] = []
+    c['status'].append(bsquare.status.ExtendedWebStatus(http_port=http_port,
+                                                        allowForce=allowForce))
+    return c


Property changes on: Sandbox/ctheune/buildbot/master.py
___________________________________________________________________
Name: svn:eol-style
   + native

Deleted: Sandbox/ctheune/buildbot/static/buildbot.css
===================================================================
--- Sandbox/ctheune/buildbot/static/buildbot.css	2008-03-12 15:22:43 UTC (rev 84617)
+++ Sandbox/ctheune/buildbot/static/buildbot.css	2008-03-12 15:56:29 UTC (rev 84618)
@@ -1,65 +0,0 @@
-body {
-    background-color:#FFFFFF;
-    border:0pt none;
-    color:#000000;
-    font-family:"Lucida Grande","Lucida Sans",Verdana,Helvetica,Arial,sans-serif;
-    font-size:8pt;
-    margin:0pt;
-    padding:1em;
-}
-
-h1 {
-    background-image:url(headerbg.png);
-    background-position:center top;
-    background-repeat:repeat-x;
-    clear:both;
-    font-weight:normal;
-    margin:-0.5em;
-    margin-bottom:0pt;
-    padding:0.5em;
-}
-
-h2 {
-    padding:0.5em;
-}
-
-.project {
-    clear:both;
-    font-weight:normal;
-}
-
-.project p {
-    margin:1em;
-}
-.project, #status-blocks div {
-    background-image:url(greybg.png);
-    background-position:center top;
-    background-repeat:repeat-x;
-}
-
-.project.red, #status-blocks div.red {
-    background-image:url(errorbg.png);
-}
-.project.green, #status-blocks div.green {
-    background-image:url(headerbg2.png);
-}
-
-#status-blocks div {
-    float:left;
-    margin:1em;
-    padding:0.5em 1em;
-}
-
-#status-blocks div h3 {
-    margin:0;
-    padding:0;
-}
-
-.clear {
-    clear:both;
-}
-
-.building {
-    background-image:url(yellowbg.png) !important;
-}
-

Added: Sandbox/ctheune/buildbot/static/cruise.css
===================================================================
--- Sandbox/ctheune/buildbot/static/cruise.css	                        (rev 0)
+++ Sandbox/ctheune/buildbot/static/cruise.css	2008-03-12 15:56:29 UTC (rev 84618)
@@ -0,0 +1,68 @@
+body {
+    background-color:#FFFFFF;
+    border:0pt none;
+    color:#000000;
+    font-family:"Lucida Grande","Lucida Sans",Verdana,Helvetica,Arial,sans-serif;
+    font-size:8pt;
+    margin:0pt;
+    padding:1em;
+}
+
+h1 {
+    background-image:url(headerbg.png);
+    background-position:center top;
+    background-repeat:repeat-x;
+    clear:both;
+    font-weight:normal;
+    margin:-0.5em;
+    margin-bottom:0pt;
+    padding:0.5em;
+}
+
+h2 {
+    padding:0.5em;
+}
+
+.project {
+    clear:both;
+    font-weight:normal;
+}
+
+.project.offline {
+    background-color: inherit;
+}
+
+.project p {
+    margin:1em;
+}
+.project, #status-blocks div {
+    background-position:center top;
+    background-repeat:repeat-x;
+}
+
+.project.red, #status-blocks div.red {
+    background-image:url(errorbg.png);
+}
+.project.green, #status-blocks div.green {
+    background-image:url(headerbg2.png);
+}
+
+#status-blocks div {
+    float:left;
+    margin:1em;
+    padding:0.5em 1em;
+}
+
+#status-blocks div h3 {
+    margin:0;
+    padding:0;
+}
+
+.clear {
+    clear:both;
+}
+
+.building {
+    background-image:url(yellowbg.png) !important;
+}
+

Copied: Sandbox/ctheune/buildbot/status.py (from rev 82498, Sandbox/ctheune/buildbot/html2.py)
===================================================================
--- Sandbox/ctheune/buildbot/status.py	                        (rev 0)
+++ Sandbox/ctheune/buildbot/status.py	2008-03-12 15:56:29 UTC (rev 84618)
@@ -0,0 +1,130 @@
+# An extended web status display providing a cruise-control-like UI.
+
+import buildbot.status.web.base
+import datetime
+import os.path
+import twisted.web.static
+
+
+STATIC_DIR = os.path.join(os.path.dirname(__file__), 'static')
+
+
+class OverviewStatusResource(buildbot.status.web.base.HtmlResource):
+
+    title = "Buildbot Cruise-control"
+
+    def _builder_status(self, builder):
+        build = builder.getLastFinishedBuild()
+        if build is None:
+            stat = 'never'
+        else:
+            stat = build.getColor()
+        return stat
+
+    def head(self, request):
+        return ('<link href="%s" rel="stylesheet" type="text/css" />' % 
+                request.sibLink('cruise.css'))
+
+    def body(self, request):
+        "This method builds the main waterfall display."
+
+        data = ''
+
+        status = self.getStatus(request)
+
+        projectName = status.getProjectName()
+        projectURL = status.getProjectURL()
+
+        data += "<h1>%s</h1>" % projectName
+
+        builders = [status.getBuilder(x) for x in 
+                status.getBuilderNames()]
+
+        # Setup filters
+        filters = []
+        filter_status = request.args.get('status', [None])[0] or 'red'
+        # Gah.
+        if filter_status == 'None':
+            filter_status = None
+        # Double-gah!
+        if filter_status != "any":
+            filters.append(lambda x:self._builder_status(x) == filter_status)
+
+        filter_prefix = request.args.get('prefix', [None])[0] or ''
+        filters.append(lambda x:x.getName().startswith(filter_prefix))
+
+        # Create totals
+        status = {}
+        for builder in builders:
+            stat = self._builder_status(builder)
+            if not stat in status:
+                status[stat] = []
+            status[stat].append(builder)
+
+        data += '<form id="filter" action="%s">' % request.sibLink('cruise')
+        data += '<div id="status-blocks">'
+        for stat, affected in status.items():
+            if stat == filter_status:
+                selected = 'checked="checked"'
+            else:
+                selected = ""
+            data += '<div class="%s"><h3><label><input type="radio" name="status" value="%s" %s/> %s</label></h3><p>%s projects</p></div>' % (stat, stat, selected, stat, len(affected))
+
+        if filter_status == "any":
+            selected = 'checked="checked"'
+        else:
+            selected = ''
+        data += '<div><h3><label><input type="radio" name="status" value="any" %s/> Any</label></h3><p>&nbsp;</p></div>' % selected
+
+        data += "</div>"
+        data += '<div class="clear"/>'
+        data += '<div><label for="prefix">Show only projects starting with</label> <input type="text" name="prefix" value="%s"/> <input type="submit" value="Set filter"/></div>' % filter_prefix
+        data += '</form>'
+
+        # Apply filters on builders
+        for f in filters:
+            builders = filter(f, builders)
+        data += "<p>Showing %i projects matching the current filter.</p>" % len(builders)
+
+        # Create detail view panels
+        for builder in builders:
+            activity = builder.getState()[0]
+            data += '<div class="project %s %s"><h2>%s</h2>' % (self._builder_status(builder),
+                    activity, builder.getName())
+            data += '<p>This builder is currently %s.</p>' % activity
+            data += "<ul>"
+            for x in range(1,6):
+                build = builder.getBuild(-x)
+                if build is None:
+                    break
+                reason = build.reason
+                started = datetime.datetime.fromtimestamp(build.started)
+                started = started.strftime('%d %b, %H:%M')
+                if build.source.changes:
+                    change = build.source.changes[0]
+                    reason = "%s by %s: %s" % (change.revision, change.who, change.comments)
+                data += '<li style="color:%s;">%s &ndash; %s</li>' % (
+                        build.color, started, reason)
+            data += "</ul>"
+            data += "</div>"
+
+        return data
+
+
+
+class ExtendedWebStatus(buildbot.status.web.baseweb.WebStatus):
+
+    def __init__(self, *args, **kw):
+        buildbot.status.web.baseweb.WebStatus.__init__(self, *args, **kw)
+
+    def setupUsualPages(self):
+        buildbot.status.web.baseweb.WebStatus.setupUsualPages(self)
+        self.putChild('cruise', OverviewStatusResource())
+
+        css = open(os.path.join(STATIC_DIR, 'cruise.css')).read()
+        self.putChild('cruise.css', twisted.web.static.Data(css, 'text/css'))
+
+        for image in ['headerbg.png', 'headerbg2.png', 'errorbg.png']:
+            data = open(os.path.join(STATIC_DIR, image)).read()
+            self.putChild(image, twisted.web.static.Data(data, 'image/png'))
+

Modified: Sandbox/ctheune/buildbot/update-config.sh
===================================================================
--- Sandbox/ctheune/buildbot/update-config.sh	2008-03-12 15:22:43 UTC (rev 84617)
+++ Sandbox/ctheune/buildbot/update-config.sh	2008-03-12 15:56:29 UTC (rev 84618)
@@ -1,24 +1,23 @@
 #!/bin/bash
-# update-cruise.sh -- created 04-Mai-2007, <+NAME+>
-# @Last Change: 24-Dez-2004.
-# @Revision:    0.0
 
-HOME=/home/ctheune/buildbot/master
-BASE=svn://svn.zope.org/repos/main/
+HOME=$1
+BASE=$2
 
 cd $HOME
 rm -f project-updates
 for PROJECT in `svn ls $BASE`; do
-    svn ls $BASE/$PROJECT/trunk/buildout.cfg 2> /dev/null
+    svn ls $BASE/$PROJECT/trunk/buildout.cfg &> /dev/null
     if [ "$?" != "0" ]; then
         continue; 
     fi
     echo $PROJECT >> project-updates
 done
+
 # Remove trailing slashes
-cat project-updates | sed "s/\/*$//" > projects
+cat project-updates | sed "s/\/*$//" > project-list.cfg
+rm -f project-updates
 
 # Restart the master
-buildbot restart .
+make reconfig
 
 # vi: 



More information about the Checkins mailing list