<?php
$INC = isset($INC) ? $INC : dirname(__FILE__);
require_once($INC . '/workers.inc.php');
/*
* Function to load job list
*/
function rg_builder_load_jobs($db)
{
rg_log_enter('builder_load_jobs');
$ret = array();
$ret['ok'] = 0;
$ret['list'] = array();
while (1) {
$sql = 'SELECT * FROM build_jobs'
. ' WHERE done = 0'
. ' ORDER BY prio DESC';
$res = rg_sql_query($db, $sql);
if ($res === FALSE)
break;
while (($row = rg_sql_fetch_array($res))) {
$jid = $row['id'];
// TODO: set 'url' when adding the job in queue!
$final = @unserialize($row['request']);
if ($final === FALSE) {
rg_internal_error('cannot unserialize!');
continue;
}
$final['id'] = $jid;
$final['repo_id'] = $row['repo_id'];
$final['itime'] = $row['itime'];
$final['prio'] = $row['prio'];
$ret['list'][$jid] = $final;
}
rg_sql_free_result($res);
$ret['ok'] = 1;
break;
}
rg_log_exit();
return $ret;
}
/*
* Add a build job in queue
*/
function rg_builder_add($db, $repo_id, $d)
{
$ret = array('ok' => 0);
rg_log_ml('builder_add: ' . print_r($d, TRUE));
while (1) {
$params = array(
'repo_id' => $repo_id,
'prio' => 10, // TODO
'itime' => time(),
'request' => serialize($d)
);
$sql = 'INSERT INTO build_jobs (repo_id, prio, itime'
. ', request)'
. ' VALUES (@@repo_id@@, @@prio@@, @@itime@@'
. ', @@request@@)';
$res = rg_sql_query_params($db, $sql, $params);
if ($res === FALSE)
break;
// TODO: notify build system to not poll?
$ret['ok'] = 1;
break;
}
return $ret;
}
/*
* List virtual machines
* TODO: for now, only libvirt
*/
function rg_builder_vm_list()
{
$cmd = 'virsh list --name';
$r = rg_exec($cmd, '', FALSE, FALSE);
if ($r['ok'] != 1) {
rg_log('Cannot find out virtual machines: ' . $r['errmsg']);
return FALSE;
}
return explode("\n", trim($r['data']));
}
/*
* Function executed when a job is done
*/
function rg_builder_done($db, $job, $s)
{
rg_log_enter('builder_done');
rg_log_ml('DEBUG: builder_done: job: ' . print_r($job, TRUE));
rg_log_ml('DEBUG: builder_done: status: ' . print_r($s, TRUE));
$job['done'] = time();
$ret = FALSE;
$rollback = FALSE;
while (1) {
$res = rg_sql_begin($db);
if ($res === FALSE)
break;
$rollback = TRUE;
$labels = $s['labels'];
// Some cosmetic stuff
$env = $job['env'];
$labels[] = 'worker_elap/' . ($s['done'] - $s['start']) . 's';
$labels[] = 'wait_time/' . ($job['worker_sent'] - $job['itime']) . 's';
$labels[] = 'date/' . gmdate('Y-m-d', $job['itime']);
$labels[] = 'time/' . gmdate('H:i', $job['itime']);
// add labels to the commit
$params = array(
'repo_id' => $job['repo_id'],
'head' => $job['head'],
'type' => 'build',
'misc' => $env,
'labels' => serialize($labels),
'itime' => time()
);
$sql = 'DELETE FROM commit_labels'
. ' WHERE repo_id = @@repo_id@@'
. ' AND type = @@type@@'
. ' AND misc = @@misc@@'
. ' AND head = @@head@@';
$res = rg_sql_query_params($db, $sql, $params);
if ($res === FALSE)
break;
rg_sql_free_result($res);
$sql = 'INSERT INTO commit_labels (repo_id, head, type, misc'
. ', labels, itime)'
. ' VALUES (@@repo_id@@, @@head@@, @@type@@'
. ', @@misc@@, @@labels@@, @@itime@@)';
$res = rg_sql_query_params($db, $sql, $params);
if ($res === FALSE)
break;
rg_sql_free_result($res);
rg_cache_unset('repo_commit_labels' . '::' . $job['repo_id']
. '::' . $job['head'], RG_SOCKET_NO_WAIT);
$params = array(
'id' => $job['id'],
'done' => $job['done'],
'status' => serialize($s)
);
$sql = 'UPDATE build_jobs SET done = @@done@@'
. ', status = @@status@@'
. ' WHERE id = @@id@@';
$res = rg_sql_query_params($db, $sql, $params);
if ($res === FALSE)
break;
rg_sql_free_result($res);
$ev = array(
'category' => 'wh_build_job_done',
'prio' => 100,
'ui' => array('uid' => $job['uid']),
'job' => $job,
'status' => $s
);
$r = rg_event_add($db, $ev);
if ($r !== TRUE) {
rg_repo_set_error('cannot add event'
. ' (' . rg_event_error() . ')');
break;
}
$res = rg_sql_commit($db);
if ($res === FALSE)
break;
$rollback = FALSE;
rg_event_signal_daemon('', 0);
$ret = TRUE;
break;
}
if ($rollback)
rg_sql_rollback($db);
rg_log_exit();
}
?>