diff options
Diffstat (limited to 'shared/classes/build.php')
-rw-r--r-- | shared/classes/build.php | 168 |
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'); + } } ?> |