# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
from xml.dom.minidom import *
+from datetime import datetime
import string
import time
import xml.sax.saxutils
import os
import urllib
import cgi
+import pytz
+import tempfile
import util
import log
def escape(s):
return xml.sax.saxutils.escape(s)
+# return date in iso8601 format
+def iso8601(ts, timezone='UTC'):
+ tz = pytz.timezone(timezone)
+ dt = datetime.fromtimestamp(ts, tz)
+ return dt.isoformat()
+
def is_blank(e):
return e.nodeType == Element.TEXT_NODE and string.strip(e.nodeValue) == ""
def dump_html(self, f):
f.write(
- "<div id=\"%(no)d\" class=\"%(flags)s\">\n"
- "<a href=\"#%(no)d\">%(no)d</a>. <span id=\"tz\">%(time)s</span> from <b>%(requester)s</b> "
+ "<div id=\"%(no)d\" class=\"request %(flags)s\">\n"
+ "<a href=\"#%(no)d\">%(no)d</a>. "
+ "<time class=\"timeago\" datetime=\"%(datetime)s\">%(time)s</time> "
+ "from <b class=requester>%(requester)s</b> "
"<small>%(id)s, prio=%(priority)d, jobs=%(max_jobs)d, %(flags)s</small>\n"
% {
'no': self.no,
'id': '<a href="srpms/%(id)s">%(id)s</a>' % {'id': self.id},
'time': escape(time.strftime("%a %b %d %Y %H:%M:%S %z", time.localtime(self.time))),
+ 'datetime': escape(iso8601(self.time)),
'requester': escape(self.requester),
'priority': self.priority,
'max_jobs': self.max_jobs,
'flags': string.join(self.flags)
})
- f.write("<ul>\n")
+ f.write("<ol>\n")
for b in self.batches:
b.dump_html(f, self.id)
- f.write("</ul>\n")
+ f.write("</ol>\n")
f.write("</div>\n")
def write_to(self, f):
self.builders_status_time = {}
self.builders_status_buildtime = {}
self.kernel = ""
+ self.defines = {}
self.target = []
self.branch = ""
self.src_rpm = ""
self.b_id = attr(e, "id")
self.depends_on = string.split(attr(e, "depends-on"))
self.upgraded = True
+
+ self.parse_xml(e)
+
+ self.__topdir = None
+
+ def get_topdir(self):
+ if not self.__topdir:
+ self.__topdir = tempfile.mkdtemp(prefix='B.', dir='/tmp')
+ return self.__topdir
+
+ def parse_xml(self, e):
for c in e.childNodes:
if is_blank(c): continue
self.info = text(c)
elif c.nodeName == "kernel":
self.kernel = text(c)
+ elif c.nodeName == "define":
+ define = attr(c, "name")
+ self.defines[define] = text(c)
elif c.nodeName == "target":
self.target.append(text(c))
elif c.nodeName == "skip":
else:
log.panic("xml: evil batch child (%s)" % c.nodeName)
+ def get_package_name(self):
+ if len(self.spec) <= 5:
+ return None
+ return self.spec[:-5]
+
+ def tmpdir(self):
+ """
+ return tmpdir for this batch job building
+ """
+ # it's better to have TMPDIR and BUILD dir on same partition:
+ # + /usr/bin/bzip2 -dc /home/services/builder/rpm/packages/kernel/patch-2.6.27.61.bz2
+ # patch: **** Can't rename file /tmp/B.a1b1d3/poKWwRlp to drivers/scsi/hosts.c : No such file or directory
+ path = os.path.join(self.get_topdir(), 'BUILD', 'tmp')
+ return path
+
def is_done(self):
ok = 1
for b in self.builders:
f.write(" batch: %s/%s\n" % (self.src_rpm, self.spec))
f.write(" info: %s\n" % self.info)
f.write(" kernel: %s\n" % self.kernel)
+ f.write(" defines: %s\n" % self.defines_string())
f.write(" target: %s\n" % self.target_string())
f.write(" branch: %s\n" % self.branch)
f.write(" bconds: %s\n" % self.bconds_string())
if self.is_command():
desc = "SH: <pre>%s</pre> flags: [%s]" % (self.command, ' '.join(self.command_flags))
else:
- cmd = "/usr/bin/git ls-remote --heads git://git.tld-linux.org/packages/%s 1>/dev/null 2>&1" % (self.spec[:-5])
- r = call(cmd, shell=True)
- if r == 0:
- dist = "tld"
- else:
- dist = "pld"
- package_url = "http://git.%(dist)s-linux.org/?p=packages/%(package)s.git;a=blob;f=%(spec)s;hb=%(branch)s" % {
- 'dist': dist,
- 'spec': self.spec,
- 'branch': self.branch,
- 'package': self.spec[:-5],
+ cmd = "/usr/bin/git ls-remote --heads git://git.tld-linux.org/packages/%s 1>/dev/null 2>&1" % (self.spec[:-5])
+ r = call(cmd, shell=True)
+ if r == 0:
+ dist = "tld"
+ else:
+ dist = "pld"
+ package_url = "http://git.%(dist)s-linux.org/?p=packages/%(package)s.git;a=blob;f=%(spec)s;hb=%(branch)s" % {
+ 'dist': dist,
+ 'spec': urllib.quote(self.spec),
+ 'branch': urllib.quote(self.branch),
+ 'package': urllib.quote(self.spec[:-5]),
}
- desc = "%(src_rpm)s (<a href=\"%(package_url)s\">%(spec)s -r %(branch)s</a>%(bconds)s)" % {
+ desc = "%(src_rpm)s (<a href=\"%(package_url)s\">%(spec)s -r %(branch)s</a>%(rpmopts)s)" % {
'src_rpm': self.src_rpm,
'spec': self.spec,
'branch': self.branch,
- 'bconds': self.bconds_string() + self.kernel_string() + self.target_string(),
+ 'rpmopts': self.bconds_string() + self.kernel_string() + self.target_string() + self.defines_string(),
'package_url': package_url,
}
f.write("%s <small>[" % desc)
bld = lin_ar.split('-')
tree_name = '-'.join(bld[:-1])
tree_arch = '-'.join(bld[-1:])
- link_pre = "<a href=\"http://buildlogs.tld-linux.org/index.php?dist=%s&arch=%s&name=%s&id=%s&action=download\">" \
- % (urllib.quote(tree_name), urllib.quote(tree_arch), urllib.quote(bl_name), urllib.quote(rid))
+ link_pre = "<a href=\"http://buildlogs.tld-linux.org/index.php?dist=%s&arch=%s&name=%s&id=%s&action=download\">" \
+ % (urllib.quote(tree_name), urllib.quote(tree_arch), urllib.quote(bl_name), urllib.quote(rid))
link_post = "</a>"
def ftime(s):
"""
return all rpmbuild options related to this build
"""
- bconds = self.bconds_string() + self.kernel_string() + self.target_string()
+ rpmopts = self.bconds_string() + self.kernel_string() + self.target_string() + self.defines_string()
rpmdefs = \
- "--define '_topdir %(echo $HOME/rpm)' " \
- "--define '_specdir %{_topdir}/packages/%{name}' " \
+ "--define '_topdir %s' " % self.get_topdir() + \
+ "--define '_specdir %{_topdir}' " \
"--define '_sourcedir %{_specdir}' " \
- "--define '_builddir %{_topdir}/BUILD/%{name}' "
- return rpmdefs + bconds
+ "--define '_rpmdir %{_topdir}/RPMS' " \
+ "--define '_builddir %{_topdir}/BUILD' "
+ return rpmdefs + rpmopts
+
+ def php_ignores(self):
+ # transform php package name (52) to version (5.2)
+ def php_name_to_ver(v):
+ return '.'.join(list(v))
+
+ # transform php version (5.2) to package name (52)
+ def php_ver_to_name(v):
+ return v.replace('.', '')
+
+ # available php versions in distro
+ php_versions = ['4', '5.2', '5.3', '5.4', '5.5', '5.6', '7.0']
+
+ # current version if -D php_suffix is present
+ php_version = php_name_to_ver(self.defines['php_suffix'])
+
+ # remove current php version
+ try:
+ php_versions.remove(php_version)
+ except ValueError:
+ log.notice("Attempt to remove inexistent key '%s' from %s" % (php_version, php_versions))
+ pass
+
+ # map them to poldek ignores
+ # always ignore hhvm
+ res = ['hhvm-*']
+ for v in map(php_ver_to_name, php_versions):
+ res.append("php%s-*" % v)
+
+ return res
+
+ # build ignore package list
+ # currently only php ignore is filled based on build context
+ def ignores(self):
+ ignores = []
+
+ # add php version based ignores
+ if self.defines.has_key('php_suffix'):
+ ignores.extend(self.php_ignores())
+
+ # return empty string if the list is empty
+ if len(ignores) == 0:
+ return ""
+
+ def add_ignore(s):
+ return "--ignore=%s" % s
+
+ return " ".join(map(add_ignore, ignores))
def kernel_string(self):
r = ""
r = r + " --without " + b
return r
+ def defines_string(self):
+ r = ""
+ for key,value in self.defines.items():
+ r += " --define '%s %s'" % (key, value)
+ return r
+
+ def defines_xml(self):
+ r = ""
+ for key,value in self.defines.items():
+ r += "<define name='%s'>%s</define>\n" % (escape(key), escape(value))
+ return r
+
def default_target(self, arch):
self.target.append("%s-tld-linux" % arch)
f.write(" <target>%s</target>\n" % escape(b))
for b in self.bconds_without:
f.write(" <without>%s</without>\n" % escape(b))
+ if self.defines:
+ f.write(" %s\n" % self.defines_xml())
for b in self.builders:
if self.builders_status_buildtime.has_key(b):
t = self.builders_status_buildtime[b]