xaizek / rocketgit (License: AGPLv3+) (since 2018-12-09)
Light and fast Git hosting solution suitable to serve both as a hub or as a personal code storage with its tickets, pull requests, API and much more.
<root> / inc / builder.inc.php (c5a5b88fe59ff6e58cead9df32b171db1d7f1b02) (4,110B) (mode 100644) [raw]
<?php
$INC = isset($INC) ? $INC : dirname(__FILE__);

/*
 * 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);
	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);

		$res = rg_sql_commit($db);
		if ($res === FALSE)
			break;

		$rollback = FALSE;

		$ret = TRUE;
		break;
	}

	if ($rollback)
		rg_sql_rollback($db);

	rg_log_exit();
}

/*
 * Returns a list of possible environments
 * TODO: think about a lot of architecures, bits, OSes!
 */
function rg_builder_env_list($db)
{
	return array('fedora23-server-x86_64');
}

?>
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/rocketgit

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/rocketgit

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master