# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+import ConfigParser
import os
import re
import time
return s2["value"] - s1["value"]
+class Tree(object):
+ """A tree to build."""
+
+ def __init__(self, name, scm, repo, branch, subdir="", srcdir=""):
+ self.name = name
+ self.repo = repo
+ self.branch = branch
+ self.subdir = subdir
+ self.srcdir = srcdir
+
+ def __repr__(self):
+ return "<%s %r>" % (self.__class__.__name__, self.name)
+
+
+def read_trees_from_conf(path):
+ ret = {}
+ cfp = ConfigParser.ConfigParser()
+ cfp.readfp(open(path))
+ for s in cfp.sections():
+ ret[s] = Tree(name=s, **dict(cfp.items(s)))
+ return s
+
+
class BuildfarmDatabase(object):
+ """The build farm build result database."""
OLDAGE = 60*60*4,
DEADAGE = 60*60*24*4
LCOVHOST = "magni"
def __init__(self, basedir, readonly=False):
+ """Open the database.
+
+ :param basedir: Build result base directory
+ :param readonly: Whether to avoid saving cache files
+ """
self.basedir = basedir
check_dir_exists("base", self.basedir)
self.readonly = readonly
self.compilers = util.load_list(os.path.join(self.webdir, "compilers.list"))
self.hosts = util.load_hash(os.path.join(self.webdir, "hosts.list"))
- self.trees = {
- 'ccache': {
- 'scm': 'git',
- 'repo': 'ccache',
- 'branch': 'master',
- 'subdir': '',
- 'srcdir': ''
- },
- 'ccache-maint': {
- 'scm': 'git',
- 'repo': 'ccache',
- 'branch': 'maint',
- 'subdir': '',
- 'srcdir': ''
- },
- 'ppp': {
- 'scm': 'git',
- 'repo': 'ppp',
- 'branch': 'master',
- 'subdir': '',
- 'srcdir': ''
- },
- 'build_farm': {
- 'scm': 'svn',
- 'repo': 'build-farm',
- 'branch': 'trunk',
- 'subdir': '',
- 'srcdir': ''
- },
- 'samba-web': {
- 'scm': 'svn',
- 'repo': 'samba-web',
- 'branch': 'trunk',
- 'subdir': '',
- 'srcdir': ''
- },
- 'samba-docs': {
- 'scm': 'svn',
- 'repo': 'samba-docs',
- 'branch': 'trunk',
- 'subdir': '',
- 'srcdir': ''
- },
- 'lorikeet': {
- 'scm': 'svn',
- 'repo': 'lorikeeet',
- 'branch': 'trunk',
- 'subdir': '',
- 'srcdir': ''
- },
- 'samba_3_current': {
- 'scm': 'git',
- 'repo': 'samba.git',
- 'branch': 'v3-5-test',
- 'subdir': '',
- 'srcdir': 'source'
- },
- 'samba_3_next': {
- 'scm': 'git',
- 'repo': 'samba.git',
- 'branch': 'v3-6-test',
- 'subdir': '',
- 'srcdir': 'source'
- },
- 'samba_3_master': {
- 'scm': 'git',
- 'repo': 'samba.git',
- 'branch': 'master',
- 'subdir': '',
- 'srcdir': 'source'
- },
- 'samba_4_0_test': {
- 'scm': 'git',
- 'repo': 'samba.git',
- 'branch': 'master',
- 'subdir': '',
- 'srcdir': 'source4'
- },
- 'libreplace': {
- 'scm': 'git',
- 'repo': 'samba.git',
- 'branch': 'master',
- 'subdir': 'lib/replace/',
- 'srcdir': ''
- },
- 'talloc': {
- 'scm': 'git',
- 'repo': 'samba.git',
- 'branch': 'master',
- 'subdir': 'lib/talloc/',
- 'srcdir': ''
- },
- 'tdb': {
- 'scm': 'git',
- 'repo': 'samba.git',
- 'branch': 'master',
- 'subdir': 'lib/tdb/',
- 'srcdir': ''
- },
- 'ldb': {
- 'scm': 'git',
- 'repo': 'samba.git',
- 'branch': 'master',
- 'subdir': 'lib/ldb/',
- 'srcdir': ''
- },
- 'pidl': {
- 'scm': 'git',
- 'repo': 'samba.git',
- 'branch': 'master',
- 'subdir': 'pidl/',
- 'srcdir': ''
- },
- 'rsync': {
- 'scm': 'git',
- 'repo': 'rsync.git',
- 'branch': 'HEAD',
- 'subdir': '',
- 'srcdir': ''
- }
- }
+ self.trees = read_trees_from_conf(os.path.join(self.webdir, "trees.conf"))
def cache_fname(self, tree, host, compiler, rev=None):
if rev is not None:
# on a host.
# the ctime age is used to determine when the last real build happened
- ##############################################
def build_age_mtime(self, host, tree, compiler, rev):
"""get the age of build from mtime"""
file = self.build_fname(tree, host, compiler, rev)
if rev:
if tree not in self.trees:
return rev
- if self.trees[tree]["scm"] != "git":
+ if self.trees[tree].scm != "git":
return rev
try:
cstatus, bstatus, istatus, tstatus, sstatus, dstatus, tostatus)
def build_status(self, host, tree, compiler, rev):
- """get status of build"""
+ """get status of build
+
+ :param host: Host name
+ :param tree: Tree name
+ :param compiler: Compiler name
+ :param rev: Revision
+ :return: string with build status
+ """
+ # FIXME: This should return a tuple
+
file = self.build_fname(tree, host, compiler, rev)
cachefile = self.cache_fname(tree, host, compiler, rev)+".status"
try:
TIMEOFFSET = 0
UNPACKED_DIR = "/home/ftp/pub/unpacked"
-CVSWEB_BASE = "http://pserver.samba.org/cgi-bin/cvsweb"
-VIEWCVS_BASE = "http://websvn.samba.org/cgi-bin/viewcvs.cgi"
-UNPACKED_BASE = "http://svn.samba.org/ftp/unpacked"
-GITWEB_BASE = "http://gitweb.samba.org"
-
-
class History(object):
def __init__(self, db):
# validate the tree
t = self.db.trees[tree]
- if t["scm"] == "cvs":
+ if t.scm == "cvs":
self._cvs_diff(t, author, date, tree)
- elif t["scm"] == "svn":
+ elif t.scm == "svn":
self._svn_diff(t, revision, tree)
- elif t["scm"] == "git":
+ elif t.scm == "git":
self._git_diff(t, revision, tree)
else:
- raise Exception("Unknown VCS %s" % t["scm"])
+ raise Exception("Unknown VCS %s" % t.scm)
def _svn_diff(self, t, revision, tree):
"""show recent svn entries"""
# get information about the current diff
title = "SVN Diff in %s:%s for revision r%s" % (
- tree, t["branch"], revision)
+ tree, t.branch, revision)
old_revision = revision - 1
cmd = "svn diff -r %s:%s" % (old_revision, revision)
t1 = time.ctime(date-60+(TIMEOFFSET*60*60)).strip()
t2 = time.ctime(date+60+(TIMEOFFSET*60*60)).strip()
- title = "CVS Diff in %s:%s for %s" % (tree, t["branch"], t1)
+ title = "CVS Diff in %s:%s for %s" % (tree, t.branch, t1)
if entry["TAG"] != "" and entry["REVISIONS"] != "":
raise Exception("sorry, cvs diff on branches not currently possible due to a limitation in cvs")
# get information about the current diff
title = "GIT Diff in %s:%s for revision %s" % (
- tree, t["branch"], revision)
+ tree, t.branch, revision)
cmd = "git diff %s^ %s ./" % (revision, revision)
return (title, entry, tree, [(cmd, commands.getoutput("%s 2> /dev/null" % cmd))])
finally:
f.close()
+ def write_trees(self, trees):
+ f = open(os.path.join(self.path, "web", "trees.conf"), "w")
+ try:
+ for t in trees:
+ f.write("[%s]\n" % t)
+ for k, v in trees[t].iteritems():
+ f.write("%s = %s\n" % (k, v))
+ f.write("\n")
+ finally:
+ f.close()
+
def setUp(self):
super(BuildFarmTestCase, self).setUp()
self.path = tempfile.mkdtemp()
self.write_compilers(["cc"])
self.write_hosts(["gwenhwyvar", "charis"])
+ self.write_trees({"tdb": {"scm": "git", "repo": "tdb", "branch": "master"}})
self.x = data.BuildfarmDatabase(self.path)
trees = db.trees
OLDAGE = db.OLDAGE
+CVSWEB_BASE = "http://pserver.samba.org/cgi-bin/cvsweb"
+VIEWCVS_BASE = "http://websvn.samba.org/cgi-bin/viewcvs.cgi"
+UNPACKED_BASE = "http://svn.samba.org/ftp/unpacked"
+GITWEB_BASE = "http://gitweb.samba.org"
+
# this is automatically filled in
deadhosts = []
sorturl = "%s?tree=%s;function=Recent+Builds" % (myself, tree)
yield "<div id='recent-builds' class='build-section'>"
- yield "<h2>Recent builds of %s (%s branch %s)</h2>" % (tree, t["scm"], t["branch"])
+ yield "<h2>Recent builds of %s (%s branch %s)</h2>" % (tree, t.scm, t.branch)
yield "<table class='real'>"
yield "<thead>"
yield "<tr>"
yield "</select>"
yield "<select name='tree'>"
for tree, t in trees.iteritems():
- yield "<option value='%s'>%s:%s</option>" % (tree, tree, t["branch"])
+ yield "<option value='%s'>%s:%s</option>" % (tree, tree, t.branch)
yield "</select>"
yield "<select name='compiler'>"
for compiler in compilers:
fmt = None
- if t["scm"] == "cvs":
- fmt = " <a href=\"%s/%s/%%s\">%%s</a>" % (CVSWEB_BASE, t["repo"])
- elif t["scm"] == "svn":
- fmt = " <a href=\"%s/%s/%%s?root=%s\">%%s</a>" % (VIEWCVS_BASE, t["branch"], t["repo"])
- elif t["scm"] == "git":
- r = t["repo"]
- s = t["subdir"]
- b = t["branch"]
+ if t.scm == "cvs":
+ fmt = " <a href=\"%s/%s/%%s\">%%s</a>" % (CVSWEB_BASE, t.repo)
+ elif t.scm == "svn":
+ fmt = " <a href=\"%s/%s/%%s?root=%s\">%%s</a>" % (VIEWCVS_BASE, t.branch, t.repo)
+ elif t.scm == "git":
+ r = t.repo
+ s = t.subdir
+ b = t.branch
fmt = " <a href=\"%s/?p=%s;a=history;f=%s%%s;h=%s;hb=%s\">%%s</a>" % (GITWEB_BASE, r, s, b, b)
else:
return paths
authors.update(history.authors(tree))
yield "<h2>Recent checkins for %s (%s branch %s)</h2>\n" % (
- tree, t["scm"], t["branch"])
+ tree, t.scm, t.branch)
yield "<form method='GET'>"
yield "Select Author: "
yield "<select name='author'>"
--- /dev/null
+[ccache]
+scm = git
+repo = ccache
+branch = master
+
+[ccache-maint]
+scm = git
+repo = ccache
+branch = maint
+
+[ppp]
+scm = git
+repo = ppp
+branch = master
+
+[build_farm]
+scm = svn
+repo = build-farm
+branch = trunk
+
+[samba-web]
+scm = svn
+repo = samba-web
+branch = trunk
+
+[samba-docs]
+scm = svn
+repo = samba-docs
+branch = trunk
+
+[lorikeet]
+scm = svn
+repo = lorikeeet
+branch = trunk
+
+[samba_3_current]
+scm = git
+repo = samba.git
+branch = v3-5-test
+srcdir = source
+
+[samba_3_next]
+scm = git
+repo = samba.git
+branch = v3-6-test
+srcdir = source
+
+[samba_3_master]
+scm = git
+repo = samba.git
+branch = master
+srcdir = source
+
+[samba_4_0_test]
+scm = git
+repo = samba.git
+branch = master
+srcdir = source4
+
+[libreplace]
+scm = git
+repo = samba.git
+branch = master
+subdir = lib/replace/
+
+[talloc]
+scm = git
+repo = samba.git
+branch = master
+subdir = lib/talloc/
+
+[tdb]
+scm = git
+repo = samba.git
+branch = master
+subdir = lib/tdb/
+
+[ldb]
+scm = git
+repo = samba.git
+branch = master
+subdir = lib/ldb/
+
+[pidl]
+scm = git
+repo = samba.git
+branch = master
+subdir = pidl/
+
+[rsync]
+scm = git
+repo = rsync.git
+branch = HEAD