summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'shared/classes/build.php')
-rw-r--r--shared/classes/build.php168
1 files changed, 118 insertions, 50 deletions
diff --git a/shared/classes/build.php b/shared/classes/build.php
index 64730fe..10b2043 100644
--- a/shared/classes/build.php
+++ b/shared/classes/build.php
@@ -36,18 +36,25 @@ class sql_build extends conf_build_common {
),
'status' => array (
'type' => 'ENUM',
- 'length' => '\'queued\',\'uploading\',\'cancel\',\'complete\',\'upload_failed\',\'canceled\',\'failed\',\'got_signal\',\'building\',\'bundling\'',
+ 'length' => '\'queued\',\'uploading\',\'cancel\',\'complete\',\'canceled\',\'building\',\'bundling\'',
'not_null' => true
),
- 'details' => array (
+ 'build_step' => array (
'type' => 'TINYINT',
- 'length' => 4
+ 'length' => 4,
+ 'unsigned' => true
),
- 'build_step' => array (
+ 'num_steps' => array (
'type' => 'TINYINT',
- 'length' => 3,
+ 'length' => 4,
'unsigned' => true
),
+ 'failed' => array (
+ 'type' => 'ENUM',
+ 'length' => '\'false\',\'true\'',
+ 'not_null' => true,
+ 'default' => 'false'
+ ),
'ctime' => array (
'type' => 'INT',
'length' => 10,
@@ -71,49 +78,52 @@ class sql_build extends conf_build_common {
$perms=$this->visibility == 'public' || owner_or_admin($this->id);
$html='<div class="build"><span class="name">'.(isset($this->name) && strlen($this->name)?htmlentities($this->name):'Unnamed Build').'</span> ';
$links=array();
- if ($this->status == 'queued') {
+ switch ($this->status) {
+ case 'queued':
$total=query('SELECT COUNT(*) FROM `builds` WHERE `status`="queued"')->fetch(PDO::FETCH_COLUMN);
$num=query('SELECT COUNT(*) FROM `builds` WHERE `status`="queued" AND `ctime` <= '.$this->ctime)->fetch(PDO::FETCH_COLUMN);
$html.="<span class=\"status queued\">[queued ($num/$total)]</span>";
- } elseif ($this->status == 'uploading') {
+ break;
+ case 'uploading':
$html.='<span class="status successful">[uploading]</span>';
if ($perms) $links['Build log']="build/$this->id";
- } elseif ($this->status == 'cancel') {
+ break;
+ case 'cancel':
$html.='<span class="status queued">[pending cancellation]</span>';
if ($perms) $links['Build log']="build/$this->id";
- } elseif ($this->status == 'building') {
- // TODO stage x/y
- $html.='<span class="status building">[building ('.$this->build_step.'/'.$this->details.')]</span>';
+ break;
+ case 'building':
+ case 'bundling':
+ $html.='<span class="status building">['.$this->status.' ('.$this->build_step.'/'.$this->num_steps.')]</span>';
if ($perms) {
//$links['Watch']="build/$this->id/live";
$links['Build Log']="build/$this->id";
}
- } elseif ($this->status == 'complete') {
- $r=query('SELECT COUNT(*) as `count`, MAX(`time`) as `time` FROM `downloads` WHERE `build`="'.$this->id.'"')->fetch(PDO::FETCH_ASSOC);
- $d=($perms && $r['count']?'<a href="'.url("build/$this->id/history").'">':'').$r['count'].' download'.($r['count'] != 1?'s':'').($r['count']?($perms?'</a>':'').'<br/><span class="time">(last at '.date($format, $r['time']).')</span>':'');
+ break;
+ case 'complete':
+ $url="build/$this->id/history";
+ if ($perms && $S['request'] != $url) {
+ $r=query('SELECT COUNT(*) as `count`, MAX(`time`) as `time` FROM `downloads` WHERE `build`="'.$this->id.'"')->fetch(PDO::FETCH_ASSOC);
+ $d=($r['count']?'<a href="'.url($url).'">':'').$r['count'].' download'.($r['count'] != 1?'s':'').($r['count']?($perms?'</a>':'').'<br/><span class="time">(last at '.date($format, $r['time']).')</span>':'');
+ } else
+ $d='';
$html.='<span class="downloads">'.$d.'</span><span class="status successful">[successful]</span>';
$links['Download image']="build/$this->id/download";
if ($perms) $links['Build log']="build/$this->id";
- } elseif ($this->status == 'upload_failed') {
- $html.='<span class="status failed">[upload failed]</span>';
- if ($perms) $links['Build log']="build/$this->id";
- } elseif ($this->status == 'failed') {
- $html.='<span class="status failed">[failed after step '.$this->build_step.']</span>';
- if ($perms) {
- //$links['View output of failed command']="build/$this->id/failure";
- $links['Build log']="build/$this->id";
- }
- } elseif ($this->status == 'canceled') {
+ break;
+ case 'canceled':
$html.='<span class="status failed">[canceled]</span>';
if ($perms) $links['Build log']="build/$this->id";
- } elseif ($this->status == 'got_signal') {
- $html.='<span class="status failed">[failed: got signal '.$this->details.' after step '.$this->build_step.']</span>';
- if ($perms) $links['Build log']="build/$this->id";
- } else {
+ break;
+ default:
$html.='<span class="status failed">[UNKNOWN STATUS: '.$this->status.']</span>';
}
- if ($perms && ($this->status == 'upload_failed' || $this->status == 'failed' || $this->status == 'canceled' || $this->status == 'queued' || $this->status == 'complete' || $this->status == 'got_signal'))
- $links['Delete']="build/$this->id/delete";
+ if ($perms) {
+ if ($this->status == 'canceled' || $this->status == 'queued' || $this->status == 'complete' || $this->failed == 'true')
+ $links['Delete']="build/$this->id/delete";
+ elseif ($this->status != 'cancel')
+ $links['Cancel']="build/$this->id/cancel";
+ }
if ($links) {
foreach ($links as $label => $url) {
if ($S['request'] == $url)
@@ -141,13 +151,6 @@ class sql_build extends conf_build_common {
$html.='</div>';
return $html;
}
- public function queued_tasks() {
- global $S;
- static $cache;
- if (!isset($cache))
- $cache=query('SELECT COUNT(`order`) FROM `tasks` WHERE `start` IS NULL AND `build`="'.$this->id.'"')->fetch(PDO::FETCH_COLUMN);
- return $cache;
- }
public function delete() {
global $S;
query('DELETE FROM `buildlogs` WHERE `build`="'.$this->id.'"');
@@ -161,43 +164,108 @@ class sql_build extends conf_build_common {
public function build($workdir) {
global $S;
try {
- if (!is_dir($workdir))
- log_status('Create work directory '.$workdir, mkdir($workdir, 0700));
$opts=$this->get_opts();
$S['build_steps']=array();
if (!is_readable(BACKEND."/modules/$this->module/build.php"))
throw_exception("No build script for module $this->module");
- $dir=require(BACKEND."/modules/$this->module/build.php");
+ $imagedir=require(BACKEND."/modules/$this->module/build.php");
switch ($this->status) {
case 'queued':
- $this->build_step=0;
- case 'got_signal':
- case 'failed':
$this->status='building';
- $this->details=count($S['build_steps']);
+ $this->build_step=0;
+ $this->num_steps=count($S['build_steps']);
$this->write();
case 'building':
$step=$this->build_step;
break;
- case 'uploading':
- case 'upload_failed':
- case 'cancel':
- case 'bundling':
default:
- $step=count($S['build_steps']);
+ return $imagedir;
}
+ if (!is_dir($workdir))
+ log_status('Create work directory '.$workdir, mkdir($workdir, 0700));
while ($step < count($S['build_steps'])) {
require(BACKEND."/modules/$this->module/{$S['build_steps'][$step]}.php");
$step++;
$this->build_step=$step;
$this->write();
+ if ($this->is_canceled()) return false;
}
- return $dir;
+ return $imagedir;
} catch(Exception $e) {
log_msg('Caught exception: '.$e->getMessage());
end_internal_task(1);
+ $this->failed();
return false;
}
}
+ public function bundle($imagedir, $workdir) {
+ global $S;
+ try {
+ $opts=$this->get_opts();
+ $bundler=$opts['bundler'];
+ if (!is_readable(BACKEND."/bundlers/$bundler/bundle.php"))
+ throw_exception("No bundle script for bundler $bundler");
+ $S['build_steps']=array();
+ $file=require(BACKEND."/bundlers/$bundler/bundle.php");
+ switch($this->status) {
+ case 'building':
+ $this->status='bundling';
+ $this->build_step=0;
+ $this->num_steps=count($S['build_steps']);
+ $this->write();
+ case 'bundling':
+ $step=$this->build_step;
+ break;
+ default:
+ return $file;
+ }
+ print_r($S['build_steps']);
+ while ($step < count($S['build_steps'])) {
+ require(BACKEND."/bundlers/$bundler/{$S['build_steps'][$step]}.php");
+ $step++;
+ $this->build_step=$step;
+ $this->write();
+ if ($this->is_canceled()) return false;
+ }
+ return $file;
+ } catch (Exception $e) {
+ log_msg('Caught exception: '.$e->getMessage());
+ end_internal_task(1);
+ $this->failed();
+ return false;
+ }
+ }
+ public function upload($file) {
+ $this->status='uploading';
+ $this->write();
+ $key=randstring(30);
+ $this->set_opt('uploadkey', $key);
+ $c=curl_init(url('backend/upload_image'));
+ curl_setopt($c, CURLOPT_POST, 1);
+ curl_setopt($c, CURLOPT_POSTFIELDS, array(
+ 'build' => $this->id,
+ 'key' => $key,
+ 'file' => "@$file"
+ ));
+ curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
+ $result=curl_exec($c);
+ $result($result !== false && strpos($result, 'Upload successful') !== false);
+ if ($result) {
+ $this->status='complete';
+ $this->finish=time();
+ $this->write();
+ } else
+ $this->failed();
+ return $result;
+ }
+ private function failed() {
+ $this->failed='true';
+ $this->finish=time();
+ $this->write();
+ }
+ public function is_canceled() {
+ $this->load();
+ return ($this->status == 'cancel');
+ }
}
?>