diff options
author | Eudyptula <eitan@mosenkis.net> | 2009-06-19 01:00:34 -0400 |
---|---|---|
committer | Eudyptula <eitan@mosenkis.net> | 2009-06-19 01:00:34 -0400 |
commit | 28b33c0c19620780290c978cf7df14ef36109916 (patch) | |
tree | 5a5bad2f466024b58584abf656b76e20d5795b59 | |
parent | Removed extraneous line from routing.csv (diff) | |
download | ingenue-28b33c0c19620780290c978cf7df14ef36109916.tar.gz ingenue-28b33c0c19620780290c978cf7df14ef36109916.tar.bz2 ingenue-28b33c0c19620780290c978cf7df14ef36109916.zip |
Added sessions, login, build request on frontend; changed backend to use build queue from db (generated by frontend)
-rwxr-xr-x | backend/backend.php | 40 | ||||
-rw-r--r-- | backend/functions/build.php | 15 | ||||
-rw-r--r-- | backend/functions/error_handling.php | 2 | ||||
-rw-r--r-- | backend/functions/execution.php | 4 | ||||
-rw-r--r-- | frontend/include/header.php | 37 | ||||
-rw-r--r-- | frontend/include/setup.php | 27 | ||||
-rw-r--r-- | frontend/index.php | 3 | ||||
-rw-r--r-- | frontend/pages/login.php | 55 | ||||
-rw-r--r-- | frontend/pages/logview.php | 10 | ||||
-rw-r--r-- | frontend/pages/wizard.php | 44 | ||||
-rw-r--r-- | frontend/routing.csv | 4 | ||||
-rwxr-xr-x | newclass.php | 15 | ||||
-rw-r--r-- | shared/classes/session.php | 30 | ||||
-rw-r--r-- | todo | 2 |
14 files changed, 232 insertions, 56 deletions
diff --git a/backend/backend.php b/backend/backend.php index 5e7d657..1cb1cdb 100755 --- a/backend/backend.php +++ b/backend/backend.php @@ -3,6 +3,7 @@ require_once(dirname(__FILE__).'/../shared/include/includes.php'); // USE __DIR__ once 5.3.0 is out require_once(SHARED.'/config.php'); require_once(SHARED.'/include/dbinit.php'); +$pdo=&$S['pdo']; $opts=getopt('f'); if (isset($opts['f'])) { $f=pcntl_fork(); @@ -16,34 +17,21 @@ if (isset($opts['f'])) { echo "I am the child!\n"; } } -// TODO this should be in the frontend -$fails=0; while (true) { - $id=randstring(6); - log_msg("Trying id=$id...", false); - // Maybe we should query the DB, not see if insert fails? - $build=new sql_build($id, 0, 'Test build', 'pre-build', null, null); - try { - if ($build->write()) { - if (is_dir(WORK.'/build-'.$id)) { - log_msg('failed... directory already exists (this is bad - it should be in the database)'); - $build->delete(); - } else { - break; - } + // TODO check first for builds that need to be resumed + $r=$pdo->query('SELECT * FROM `builds` WHERE `status`="build/ready" LIMIT 1'); // TODO ORDER BY `ctime` ASC + if ($r->rowCount()) { + $build=new sql_build($r->fetch(PDO::FETCH_ASSOC)); + echo 'Starting build id='.$build->id."\n"; + try { + build($build); + } catch (Exception $e) { + echo 'Caught exception: '.$e->getMessage()."\n"; } - } catch (Exception $e) { - if (get_class($e) != 'PDOException' || !isset($e->errorInfo) || !isset($e->errorInfo[0]) || $e->errorInfo[0] != 23000) { - log_msg(''); // For \n - throw ($e); - } else { - log_msg('already taken in the database'); - } - } - if (++$fails >= 10) { - log_msg('Something is wrong - failed 10 times to choose a unique build id'); - die; + echo 'Finished with build id='.$build->id."\n"; } + echo 'Sleeping...'; + sleep(5); + echo "done\n"; } -build($id); ?> diff --git a/backend/functions/build.php b/backend/functions/build.php index 13bacbb..9859020 100644 --- a/backend/functions/build.php +++ b/backend/functions/build.php @@ -6,14 +6,15 @@ $conf['pkgdir']='/home/eitan/soc/tinderbox/default-linux-amd64'; $conf['chost']='x86_64-pc-linux-gnu'; $conf['port_logdir']='$W/log'; $conf['emerge_log_dir']=$conf['port_logdir']; -$conf['emerge_default_opts']='-t -K --color=n'; +$conf['emerge_default_opts']='-t -K --color=n --root-deps=rdeps'; $conf['portage_tmpdir']='$W/tmp'; $profile='/etc/make.profile'; // This is the main function that carries out a build from start to finish -function build($id) { +function build(&$build) { global $conf, $profile; - $build=new sql_build($id); - define('W', WORK.'/build-'.$id); + $build->status='build/started'; + $build->write(); + define('W', WORK.'/build-'.$build->id); fatal(log_status('Creating work directory '.W, mkdir(W, 0700))); fatal(log_status('Creating '.W.'/image', mkdir(W.'/image', 0700))); define('I', W.'/image'); @@ -34,8 +35,8 @@ function build($id) { 'PORTAGE_CONFIGROOT' => C, 'ROOT' => I ); - fatal(!log_command($id, 'emerge --info', null, $env)!=0); - fatal(!log_command($id, 'emerge -pv system', null, $env)!=0); - fatal(!log_command($id, 'emerge -v system', null, $env)!=0); + fatal(!log_command($build, 'emerge --info', null, $env)!=0); + fatal(!log_command($build, 'emerge -pv system', null, $env)!=0); + fatal(!log_command($build, 'emerge -v system', null, $env)!=0); } ?> diff --git a/backend/functions/error_handling.php b/backend/functions/error_handling.php index 4439509..945f556 100644 --- a/backend/functions/error_handling.php +++ b/backend/functions/error_handling.php @@ -1,7 +1,7 @@ <?php function fatal($status) { if ($status === false) { - exit(1); + throw new Exception('Failed'); } else { return $status; } diff --git a/backend/functions/execution.php b/backend/functions/execution.php index a06e962..c201adf 100644 --- a/backend/functions/execution.php +++ b/backend/functions/execution.php @@ -1,11 +1,11 @@ <?php -function log_command($id, $command, $path=null, $env=null) { +function log_command(&$build, $command, $path=null, $env=null) { $descriptorspec=array( 0 => array('pipe', 'r'), // STDIN 1 => array('pipe', 'w'), // STDOUT 2 => array('pipe', 'w') // STDERR ); - $task=new sql_task(null, $id, $command, null); + $task=new sql_task(null, $build->id, $command, null); $task->write(); $p=proc_open($command, $descriptorspec, $pipes, $path, $env); foreach ($pipes as $pipe) { diff --git a/frontend/include/header.php b/frontend/include/header.php index ae6f118..578605a 100644 --- a/frontend/include/header.php +++ b/frontend/include/header.php @@ -1,6 +1,6 @@ <?php - ob_start(); - echo xmlheader(); +ob_start(); +echo xmlheader(); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> @@ -9,27 +9,36 @@ <link rel="shortcut icon" href="<?php echo url('images/favicon.ico'); ?>" /> <link rel="icon" href="<?php echo url('images/icon.gif'); ?>" type="image/gif" /> <title><?php - echo ($S['title'] != null?$S['title'].' | ':'').$conf['title']; +echo ($S['title'] != null?$S['title'].' | ':'').$conf['title']; ?></title> <?php - $scripts=array('GetXmlHttpObject', 'url', 'ajax'); - if ($conf['debug']) { - array_unshift($scripts, 'debug'); - } - foreach (array_merge($S['scripts'], $scripts) as $script) { - echo '<script type="text/javascript" src="'.url('js/'.$script.'.js').'"></script>'."\n"; - } - if (isset($S['head'])) { - echo $S['head']; - } +$scripts=array('GetXmlHttpObject', 'url', 'ajax'); +if ($conf['debug']) { + array_unshift($scripts, 'debug'); +} +foreach (array_merge($S['scripts'], $scripts) as $script) { + echo '<script type="text/javascript" src="'.url('js/'.$script.'.js').'"></script>'."\n"; +} +if (isset($S['head'])) { + echo $S['head']; +} ?> </head> <body> <div id="left" class="box"> <h1>Ingenue</h1> +<ul> +<?php +echo '<li><a href="'.url().'">Home</a></li>'; +echo '<li><a href="'.url('create').'">Create an image</a></li>'; +echo '<li><a href="'.url('logs').'">Log viewer</a></li>'; +?> +</ul> </div> <div id="top" class="box"> -Top stuff +<?php + echo (isset($S['user'])?'<a href="'.url('logout').'">Logout</a>':'<a href="'.url('login').'">Login</a>'); +?> </div> <div id="main" class="box"> <?php diff --git a/frontend/include/setup.php b/frontend/include/setup.php index df288c4..dbdc3fa 100644 --- a/frontend/include/setup.php +++ b/frontend/include/setup.php @@ -25,5 +25,30 @@ if (isset($conf['rootDir'])) { // What on Earth is going on here? $S['root']=rtrim('http://'.$_SERVER['HTTP_HOST'].($_SERVER['SERVER_PORT']==(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']?443:80)?'':':'.$_SERVER['SERVER_PORT']).$cDir, '/'); } require_once(SHARED.'/include/dbinit.php'); -// TODO DB init and sql_row_obj::set_pdo_obj +if (isset($_COOKIE[$conf['cookiename']])) { + $cookie=$_COOKIE[$conf['cookiename']]; + debug('session', 'cookie received '.$conf['cookiename'].'='.htmlentities($cookie)); + if (preg_match('/[a-z0-9]{30}/', $cookie)) { + $r=$S['pdo']->query('SELECT * FROM `sessions` WHERE `id`="'.$cookie.'"'); + if ($r->rowCount()) { + $S['session']=new sql_session($r->fetch(PDO::FETCH_ASSOC)); + if ($S['session']->atime+$S['session']->expire < time()) { + setcookie($conf['cookiename'], '', 1, $S['cookie_dir'], '', false, true); + $S['sesion']->delete(); + unset($S['session']); + } else { + $S['session']->atime=time(); + $S['session']->write(); + $S['user']=new sql_user($S['session']->user); + debug('session', 'sessionid='.$S['session']->id.', email='.$S['user']->email); + setcookie($conf['cookiename'], $S['session']->id, time()+$conf['sessionlength'], $S['cookie_dir'], '', false, true); + } + } else { + debug('session', 'session not found'); + setcookie($conf['cookiename'], '', 1, $S['cookie_dir'], '', false, true); + } + } else { + debug('session', 'session id invalid'); + } +} ?> diff --git a/frontend/index.php b/frontend/index.php index 149bee8..846a3f9 100644 --- a/frontend/index.php +++ b/frontend/index.php @@ -42,6 +42,9 @@ for ($line=fgets($routing, 32768); !feof($routing); $line=fgets($routing, 32768) } while ($dest != null) { debug('routing','Routing to '.$dest); + if (!is_file('pages/'.$dest.'.php')) { + throw new Exception('Routing to '.$dest.' but pages/'.$dest.'.php doesn\'t exist.'); + } require_once('pages/'.$dest.'.php'); $dest=str_replace(array('/', '-'), '_', $dest); $initfunc='init_'.$dest; diff --git a/frontend/pages/login.php b/frontend/pages/login.php new file mode 100644 index 0000000..881a821 --- /dev/null +++ b/frontend/pages/login.php @@ -0,0 +1,55 @@ +<?php +function init_login() { + global $S, $request, $conf; + if (isset($S['user'])) { + return 'welcome'; + } else { + if (isset($request['email']) && isset($request['password'])) { + $r=$S['pdo']->query('SELECT * FROM `users` WHERE `email`='.$S['pdo']->quote($request['email']).' AND `passhash`="'.sha1($request['password']).'"'); + if ($r->rowCount()) { + $S['user']=new sql_user($r->fetch(PDO::FETCH_ASSOC)); + $id=null; + while (!$id) { + $id=randstring(30); + $r=$S['pdo']->query('SELECT * FROM `sessions` WHERE `id`="'.$id.'"'); + if ($r->rowCount()) { + $id=null; + } + } + $session=new sql_session($id, $S['user']->id, time(), $conf['sessionlength']); + debug('setcookie', $conf['cookiename'].'='.$id); + if (setcookie($conf['cookiename'], $session->id, time()+$conf['sessionlength'], $S['cookie_dir'], '', false, true)) { + $session->write(); + $S['login_result']=true; + } + } else { + $S['login_result']=false; + } + } + return array('title' => 'Login'); + } +} +function body_login() { + global $request, $S; + if (substr($S['request'], 0, 5) != 'login') { + $request['go']=$S['request']; + echo print_warning('Please sign in to access this page.'); + } + if (isset($S['login_result'])) { + if ($S['login_result'] === 'error') { + echo print_error('An error occurred while signing you in.'); + } elseif ($S['login_result']) { + echo print_success('Welcome, '.$S['user']->name); + echo '<a href="'.url(isset($request['go'])?$request['go']:'').'">Continue</a>'; +die; + } else { + echo print_error('Your email and password combination was not recognized.'); + } + } + echo '<h3>Login</h3><form action="'.url('login').'" method="post">'; + if (isset($request['go'])) { + echo '<input type="hidden" name="go" value="'.htmlentities($request['go']).'" />'; + } + echo 'Email: <input name="email" /><br/>Password: <input type="password" name="password" /><br/><input type="submit" value="Submit" /></form>'; +} +?> diff --git a/frontend/pages/logview.php b/frontend/pages/logview.php index 9ef4ecd..bb4900b 100644 --- a/frontend/pages/logview.php +++ b/frontend/pages/logview.php @@ -27,20 +27,24 @@ function body_logview() { if (isset($request['task']) && is_numeric($request['task'])) { $s=$S['pdo']->query('SELECT * FROM `buildlogs` WHERE `task`='.$task->id.' ORDER BY `order` ASC'); if ($s->rowCount()) { - echo '<code>'; + echo '<div style="font-family: monospace">'; while ($entry=$s->fetch(PDO::FETCH_ASSOC)) { $entry=new sql_buildlog_entry($entry); - $text=str_replace("\n", "<br/>\n", htmlentities($entry->text)); + $text=str_replace(array("\n", "\t"), array("<hr/>\n", str_repeat(' ', 4)), htmlentities($entry->text)); echo '<a name="entry_'.$task->id.'_'.$entry->order.'"'.($entry->stream=='stderr'?' style="color: red" ':'').' title="'.strtoupper($entry->stream).', entry #'.$entry->order.' @ '.date('D j M Y @ H:i:s', $entry->timestamp).' UTC">'.$text.'</a>'; } echo '<a name="end"> </a>'; - echo '</code>'; + echo '</div>'; } else { echo '<b>No output</b>'; } } } elseif (isset($request['build']) && preg_match('/[a-z0-9]{6}/', $request['build'])) { + echo '<h3>Build '.$request['build'].'</h3>'; $r=$S['pdo']->query('SELECT * FROM `tasks` WHERE `build`="'.$request['build'].'" ORDER BY `id` ASC'); + if ($r->rowCount() == 0) { + echo '<b>No tasks found.</b>'; + } $i=0; while ($task=$r->fetch(PDO::FETCH_ASSOC)) { $task=new sql_task($task); diff --git a/frontend/pages/wizard.php b/frontend/pages/wizard.php new file mode 100644 index 0000000..2e0066c --- /dev/null +++ b/frontend/pages/wizard.php @@ -0,0 +1,44 @@ +<?php +function init_wizard() { + if (isset($GLOBALS['S']['user'])) { + return array('title' => 'Image Creator'); + } else { + return 'login'; + } +} +function body_wizard() { + global $request, $S; + if (isset($request['submit'])) { + $fails=0; + while (true) { + $id=randstring(6); + debug("Trying id=$id..."); + // Maybe we should query the DB, not see if insert fails? + $build=new sql_build($id, $S['user']->id, $request['name'], 'build/ready', null, null); + try { + if ($build->write()) { + if (is_dir(WORK.'/build-'.$id)) { + debug('failed... directory already exists (this is bad - it should be in the database)'); + $build->delete(); + } else { + break; + } + } + } catch (Exception $e) { + if (get_class($e) != 'PDOException' || !isset($e->errorInfo) || !isset($e->errorInfo[0]) || $e->errorInfo[0] != 23000) { + throw ($e); + } else { + debug('already taken in the database'); + } + } + if (++$fails >= 10) { + die(print_error('Something is wrong - failed 10 times to choose a unique build id')); +die; + } + } + echo '<h3>Build submitted</h3><p><b>ID: '.$id.'</b></p><p>Check your build\'s status <a href="'.url('logs/build'.$id).'">here</a>.</p>'; + } else { + echo '<form action="'.url('create').'" method="post"><h3>Request an image built</h3>Name of your build (optional): <input name="name" /><br/><input type="submit" name="submit" value="Submit" /></form>'; + } +} +?> diff --git a/frontend/routing.csv b/frontend/routing.csv index 232daef..ba0f7c1 100644 --- a/frontend/routing.csv +++ b/frontend/routing.csv @@ -11,9 +11,13 @@ # Home ^$ welcome +# Logs ^logs$ logview ^logs/build([a-z0-9]{6})$ logview build ^logs/task([0-9]+)$ logview task +# Build creation +^create$ wizard +^create/[0-9]+$ wizard stage # Session ^login$ login ^logout$ logout diff --git a/newclass.php b/newclass.php index f942416..75d20df 100755 --- a/newclass.php +++ b/newclass.php @@ -57,9 +57,20 @@ if (!$tables) { } echo 'Generating classes for table(s): '.implode(', ', $tables)."\n"; foreach ($tables as $table) { - $default=rtrim($table, 's'); + $default='sql_'; + if (substr($table, -1) == 's') { + $default.=substr($table, 0, strlen($table)-1); + } else { + $default.=$table; + } $class=prompt_string('Class name for table '.$table.':', $default); - $file=SHARED.'/classes/'.prompt_string('Filename for class '.$class.': '.SHARED.'/classes/', $class.'.php'); + if (substr($class, 0, 4) == 'sql_') { + $default=substr($class, 4); + } else { + $default=$class; + } + $default.='.php'; + $file=SHARED.'/classes/'.prompt_string('Filename for class '.$class.': '.SHARED.'/classes/', $default); if (is_file($file)) { if (!prompt_bool($file.' exists. Overwrite?', false)) { echo 'Skipping table '.$table."\n"; diff --git a/shared/classes/session.php b/shared/classes/session.php new file mode 100644 index 0000000..9b8a0a2 --- /dev/null +++ b/shared/classes/session.php @@ -0,0 +1,30 @@ +<?php +class sql_session extends sql_row_obj { + protected $table='sessions', $primary_key='id', $columns=array( + 'id' => array ( + 'type' => 'VARCHAR', + 'length' => 30, + 'not_null' => true + ), + 'user' => array ( + 'type' => 'INT', + 'length' => 10, + 'unsigned' => true, + 'not_null' => true + ), + 'atime' => array ( + 'type' => 'INT', + 'length' => 10, + 'unsigned' => true, + 'not_null' => true + ), + 'expire' => array ( + 'type' => 'INT', + 'length' => 10, + 'unsigned' => true, + 'not_null' => true + ) + + ); +} +?> @@ -4,3 +4,5 @@ Investigate using testing branch of portage (2.2) Add a builds table and class, integrate it in backend Add signal handling to the backend so when you hit Ctrl-C, it doesn't leave the logs saying "running" for the current task Find kernels +Add a 'requested' column to builds so we know which ones to start first +Add status column of builds to log viewer |