1)
return "s";
}
/**
* Return timestamp from package key
* @param string $key package submission key
*
* @return integer
*/
function key2timestamp($key) {
global $tz;
$date = DateTime::createFromFormat("YmdHis", $key+0, $tz);
if ($date <= 0)
return null;
return $date->getTimestamp();
}
function timediff($start, $end) {
/**
* Return human-readable time difference
*
* @param integer $start timestamp
* @param integer $end timestamp, defaults to now
*
* @return string
*/
if (is_null($end)) {
$end = time();
}
$diff = $end - $start;
if ($diff<60)
return $diff . " second" . plural($diff);
$diff = round($diff/60);
if ($diff<60)
return $diff . " minute" . plural($diff);
$diff = round($diff/60);
if ($diff<24)
return $diff . " hour" . plural($diff);
$diff = round($diff/24);
return $diff . " day" . plural($diff);
}
$g_user = isset($_GET['user']) ? htmlentities(strip_tags($_GET['user'])) : null;
$upload_dir = '/home/schedbot/uploads';
$max_modified = 2;
$title = 'Mageia build system status';
$robots = 'index,nofollow,nosnippet,noarchive';
if ($g_user) {
$title .= ' for ' . $g_user . "'s packages";
$robots = 'no' . $robots;
}
$tz = new DateTimeZone('UTC');
$date_gen = date('c');
chdir($upload_dir);
$all_files = shell_exec("find \( -name '*.rpm' -o -name '*.src.rpm.info' -o -name '*.lock' -o -name '*.done' -o -name '*.upload' \) -ctime -$max_modified -printf \"%p\t%T@\\n\"");
$re = "!^\./(\w+)/((\w+)/(\w+)/(\w+)/(\d+)\.(\w+)\.(\w+)\.(\d+))_?(.*)(\.src\.rpm(?:\.info)?|\.lock|\.done|\.upload)\s+(\d+\.\d+)$!m";
$r = preg_match_all($re,
$all_files,
$matches,
PREG_SET_ORDER);
$pkgs = array();
$hosts = array();
$buildtime_total = array();
$buid_dates = array();
foreach ($matches as $val) {
if ($_GET['user'] && ($_GET['user'] != $val[7])) {
continue;
}
$key = $val[6] . $val[7];
if (!is_array($pkgs[$key])) {
$pkgs[$key] = array(
'status' => array(),
'path' => $val[2],
'version' => $val[3],
'media' => $val[4],
'section' => $val[5],
'user' => $val[7],
'host' => $val[8],
'job' => $val[9]
);
}
$status = $val[1];
$data = $val[10];
if (preg_match("/@(\d+):/", $data, $revision)) {
$pkgs[$key]['revision'] = $revision[1];
}
$pkgs[$key]['status'][$status] = 1;
$ext = $val[11];
if ($ext == '.src.rpm.info') {
preg_match("!^(?:@\d+:)?(.*)!", $data, $name);
$pkgs[$key]['package'] = $name[1];
} else if ($ext == '.src.rpm') {
$pkgs[$key]['status']['src'] = 1;
} else if ($ext == '.upload') {
$pkgs[$key]['status']['upload'] = 1;
} else if ($ext == '.lock') {
preg_match("!(.*)\.iurt\.(.*)\.\d+\.\d+!", $data, $buildhost);
if (!$hosts[$buildhost[2]]) {
$hosts[$buildhost[2]]= array();
}
$hosts[$buildhost[2]][$buildhost[1]] = $key;
if ($pkgs[$key]['status']['build'])
array_push($pkgs[$key]['status']['build'], $buildhost[2]);
else
$pkgs[$key]['status']['build'] = array($buildhost[2]);
} else if ($ext == '.done') {
// beware! this block is called twice for a given $key
$pkgs[$key]['buildtime']['start'] = key2timestamp($val[6]);
$pkgs[$key]['buildtime']['end'] = round($val[12]);
$pkgs[$key]['buildtime']['diff'] = $pkgs[$key]['buildtime']['end'] - $pkgs[$key]['buildtime']['start'];
@$build_dates[date('H', $pkgs[$key]['buildtime']['start'])] += 1;
// keep obviously dubious values out of there
// 12 hours is be an acceptable threshold given current BS global perfs
// as of April 2011
if ($pkgs[$key]['buildtime']['diff'] < 43200) {
$buildtime_total[$key] = $pkgs[$key]['buildtime']['diff'];
}
}
}
// filter packages if a package name was provided
if ($_GET['package']) {
foreach ($pkgs as $key => $pkg) {
preg_match("/^(.*)-[^-]*-[^-]*$/", $pkg['package'], $name);
if ($_GET['package'] != $name[1]) {
unset($pkgs[$key]);
}
}
}
// sort by key in reverse order to have more recent pkgs first
krsort($pkgs);
ksort($build_dates);
$build_count = count($buildtime_total);
$buildtime_total = array_sum($buildtime_total);
// count all packages statuses
$stats = array(
'uploaded' => 0,
'failure' => 0,
'todo' => 0,
'building' => 0,
'partial' => 0
);
$total = count($pkgs);
// count users' packages
$users = array();
if ($total > 0) {
foreach ($pkgs as $key => $p) {
$pkgs[$key]['type'] = pkg_gettype($p);
$stats[$pkgs[$key]['type']] += 1;
if (!array_key_exists($p['user'], $users))
$users[$p['user']] = 1;
else
$users[$p['user']] += 1;
}
}
// check if emi is running
$stat = stat("/var/lib/schedbot/tmp/upload");
if ($stat) {
$upload_time = $stat['mtime'];
}
// publish stats as headers
foreach ($stats as $k => $v) {
Header("X-BS-Queue-$k: $v");
}
$w = $stats['todo'] - 10;
if($w < 0)
$w = 0;
$w = $w * 60;
Header("X-BS-Throttle: $w");
if ($_GET['last'] && $total > 0) {
reset($pkgs);
$last = current($pkgs);
Header("X-BS-Package-Status: ".$last['type']);
}
$buildtime_total = $buildtime_total / 60;
header(sprintf('X-BS-Buildtime: %d', round($buildtime_total)));
$buildtime_avg = round($buildtime_total / $build_count, 2);
header(sprintf('X-BS-Buildtime-Average: %5.2f', $buildtime_avg));
?>
« Back to full list';
if (!$_GET['package']) {
$missing_deps_count = preg_match_all("/- /m", file_get_contents("http://check.mageia.org/cauldron/dependencies.rss"), $matches);
$unmaintained_count = count(file(__DIR__ . '/data/unmaintained.txt'));
if ($missing_deps_count > 0 || $unmaintained_count > 0) {
echo "
";
if ($missing_deps_count > 0)
echo "$missing_deps_count broken dependencies. ";
if ($unmaintained_count > 0)
echo "$unmaintained_count unmaintained packages. ";
echo 'You can help!
';
}
if ($upload_time) {
echo sprintf('Upload in progress for %s.
', timediff($upload_time));
}
$buildtime_stats = array();
// Builds in progress
$s = '';
$tmpl = <<
%s |
%s |
%s |
%s |
%s |
%s/%s |
TB;
foreach ($hosts as $machine => $b) {
foreach ($b as $arch => $key) {
$s .= sprintf($tmpl,
$machine,
$arch,
$pkgs[$key]['user'], $pkgs[$key]['user'],
$pkgs[$key]['package'],
$pkgs[$key]['version'],
$pkgs[$key]['media'], $pkgs[$key]['section']);
}
}
echo '',
'', count($hosts), ' builds in progress.',
'Machine | Arch | User | Package | Target | Media |
',
$s,
'
';
echo '';
}
// Build queue
$s = '';
$tmpl = <<
%s |
%s |
%s |
%s |
%s/%s |
|
T;
if ($total > 0) {
foreach ($pkgs as $key => $p) {
$s .= sprintf($tmpl,
$p['type'],
timediff(key2timestamp($key)) . ' ago',
$p['user'], $p['user'],
$p['revision'],
addslashes($p['summary']),
$p['package'],
$p['version'],
$p['media'], $p['section']
);
$typelink = '';
if ($p['type'] == 'failure') {
$typelink = '/uploads/' . $p['type'] . '/' . $p['path'];
} elseif ($p['type'] == 'rejected') {
$typelink = '/uploads/' . $p['type'] . '/' . $p['path'] . '.youri';
} else {
$typelink = '/uploads/done/' . $p['path'];
if (!is_dir("..$typelink")) {
$typelink = '';
}
}
$typestr = $p['type'];
if ($p['status']['build']) {
$typealt = 'Building on';
foreach ($p['status']['build'] as $h)
$typealt .= " $h";
$typestr = "$typestr";
}
$s .= '';
$s .= ($typelink != '') ?
sprintf('%s', $typelink, $typestr) :
$typestr;
$s .= ' | ';
if ($p['type'] == 'uploaded') {
$tdiff = timediff($p['buildtime']['start'], $p['buildtime']['end']); // use $p['buildtime']['diff']; instead?
$s .= $tdiff;
$tdiff = floor(($p['buildtime']['end'] - $p['buildtime']['start']) / 60)*60;
@$buildtime_stats[timediff(0, $tdiff)] += 1;
}
$s .= ' | ';
$s .= '';
}
// Table
echo '',
'', $total, ' packages submitted in the past ', $max_modified * 24, ' hours.',
'Submitted | User |
Package | Target | Media |
Status | Build time |
',
$s,
'
';
// Stats
$s = '';
$score = round($stats['uploaded']/$total * 100);
$s .= sprintf('
',
$score, $score);
$s .= '
Stats.Status | Count | % |
';
foreach ($stats as $k => $v) {
$s .= sprintf(' | %s | %d | %d%% |
',
$k, $k, $v, round($v/$total*100));
}
$s .= '
';
$s .= '
PackagersUser | Packages |
';
arsort($users);
foreach ($users as $k => $v)
$s .= sprintf('%s | %d |
',
$k, $k, $v);
$s .= '
';
/**
*/
function timesort($a, $b)
{
$a = explode(' ', trim($a));
$b = explode(' ', trim($b));
if ($a[1] == 'hour' || $a[1] == 'hours')
$a[0] *= 3600;
if ($b[1] == 'hour' || $b[1] == 'hours')
$b[0] *= 3600;
if ($a[0] > $b[0])
return 1;
elseif ($a[0] < $b[0])
return -1;
return 0;
}
uksort($buildtime_stats, "timesort");
$bts = '';
$max = max($buildtime_stats);
foreach ($buildtime_stats as $time => $count) {
$bts .= sprintf('
%s | |
',
$time == "0 second" ? "< 1 minute" : $time,
round($count/$max*100),
$count);
$tmp = explode(' ', $time);
}
$s .= '
Build time';
$s .= sprintf('Total time | %s hours |
Average | %s minutes |
Builds count | %s |
',
round($buildtime_total / 60, 2),
$buildtime_avg,
$buildtime_cnt);
$s .= 'Duration | Pack. nb. |
';
$s .= $bts;
$s .= '
Does not take
build failures
into account.';
$s .= '
Build times';
$max = max($build_dates);
foreach ($build_dates as $time => $count)
$s .= sprintf('%d | |
',
$time,
round($count / $max * 100),
$count);
$s .= '
';
$s .= '
';
echo $s;
}
else
{
echo sprintf('No package has been submitted in the past %d hours.
',
$max_modified * 24);
}
?>
Generated at .
Code for this page is in http://svnweb.mageia.org/soft/build_system/web/.