addServer(); $worker->addFunction("invoke_image_build", "image_build"); $worker->addFunction("invoke_start_image", "start_image"); while ($worker->work()); function update_result($handle, $returncode, $result) { $result = trim($result); echo "A job finished with return code ".$returncode.": ".$result."\n"; $db = mysql_connect("localhost", "gentoaster", ""); if(!$db) die("Could not connect to database ".mysql_error()); mysql_select_db("gentoaster"); $result = mysql_real_escape_string($result); $query = "UPDATE builds". " SET result = '".$result."', returncode = '".$returncode. "' WHERE handle = '".mysql_real_escape_string($handle)."'"; mysql_query($query); return serialize(array($returncode, $result)); } function check_pid($pid) { $cmd = "ps $pid"; exec($cmd, $output, $result); if(count($output) >= 2){ return true; } return false; } function image_build($job) { global $configurationsPath, $gentoasterPath, $buildToolName, $progressMagic; $handle = $job->handle(); $handlehash = md5($handle); echo "Processing job handle hash ".$handlehash."\n"; $configurationString = $job->workload(); $configurationArray = parse_ini_string($configurationString); if ($configurationArray !== FALSE) { if (isset($configurationArray["BUILD_ID"])) { $buildID = $configurationArray["BUILD_ID"]; $buildPath = $configurationsPath."/".$buildID; @mkdir($buildPath, 0777, true); if (is_writable($buildPath)) { chdir($buildPath); file_put_contents("config.ini", $configurationString); $toolArgs = "--config config.ini --compress"; $cmd = $gentoasterPath."/".$buildToolName." ".$toolArgs; $processHandle = popen($cmd." 2>&1", "r"); $nonstatusOutput = ""; while (!feof($processHandle)) { $progressLine = fgets($processHandle); preg_match("/Step (.+):/", $progressLine, $matches); if (sizeof($matches) > 0) { $job->sendStatus($matches[1], $progressMagic); } else { $nonstatusOutput .= $progressLine; } } $returncode = pclose($processHandle); unlink("config.ini"); return update_result($handle, $returncode, $nonstatusOutput); } else { $error = "Configured build path is not writable"; return update_result($handle, -2, $error); } } else { $error = "Configuration file is incomplete"; return update_result($handle, -3, $error); } } else { $error = "Configuration string is not valid"; return update_result($handle, -4, $error); } } function start_image($job) { global $configurationsPath, $gentoasterPath, $wrapToolName; global $externalHost, $lowPort, $highPort; $buildID = $job->workload(); $running = false; $insert = false; $update = false; $db = mysql_connect("localhost", "gentoaster", ""); if(!$db) die("Could not connect to database ".mysql_error()); mysql_select_db("gentoaster"); $query = "SELECT port FROM ports ORDER BY port DESC LIMIT 1"; $result = mysql_query($query); if(mysql_num_rows($result) == 0) { // no ports! assign a new one $port = $lowPort; $insert = true; echo "No ports! Assigning ".$port."\n"; } else { // we have a port! let's check if our vm has one $ports = mysql_fetch_array($result); $lastport = $ports[0]; $query = "SELECT port, pid FROM ports WHERE id = '".$buildID."'"; $result = mysql_query($query); if (mysql_num_rows($result) == 0) { // vm doesn't have one, assign one! $port = $lastport+1; if ($port > $highPort) { $port = $lowPort; } $insert = true; echo "Assigning new port ".$port."\n"; } else { // vm already has one, return it $ports = mysql_fetch_array($result); $port = $ports[0]; $pid = $ports[1]; $running = true; if(!check_pid($pid)) { $running = false; $update = true; echo "VM is not running, PID ".$pid." is dead!\n"; } else { echo "VM is running on PID ".$pid."\n"; } echo "VM already has port ".$port."\n"; } } if (!$running || $update) { $cmd = $gentoasterPath."/".$wrapToolName." ". $configurationsPath."/".$buildID."/".$buildID.".image ". $port." &"; $handle = proc_open($cmd, array(), $foo); $status = proc_get_status($handle); $pid = $status["pid"]; echo "New process spawned with PID ".$pid."\n"; proc_close($handle); } // qemu pid is two up $pid = $pid + 2; if ($insert) { $query = "DELETE FROM ports WHERE port = ".$port; $result = mysql_query($query); $query = "INSERT INTO ports (id, port, pid) VALUES('".mysql_real_escape_string($buildID)."', ".$port.", ".$pid.")"; $result = mysql_query($query); echo "Doing insert!\n"; } elseif($update) { $query = "UPDATE ports SET pid = ".$pid." WHERE id = '".$buildID."'"; $result = mysql_query($query); echo "Doing update\n"; } $port = $port+1000; return serialize(array($externalHost, $port)); }