Skip to content
Snippets Groups Projects
Commit 731baca1 authored by Peter Rotich's avatar Peter Rotich
Browse files

Merge pull request #500 from protich/feature/upgrader_revisited

Upgrader revisited
parents 6934f912 293d845a
No related branches found
No related tags found
No related merge requests found
...@@ -30,5 +30,5 @@ $dispatcher = patterns('', ...@@ -30,5 +30,5 @@ $dispatcher = patterns('',
url_get('^client', 'client') url_get('^client', 'client')
)) ))
); );
print $dispatcher->resolve($_SERVER['PATH_INFO']); print $dispatcher->resolve($ost->get_path_info());
?> ?>
...@@ -26,5 +26,5 @@ $dispatcher = patterns('', ...@@ -26,5 +26,5 @@ $dispatcher = patterns('',
); );
# Call the respective function # Call the respective function
print $dispatcher->resolve($_SERVER['PATH_INFO']); print $dispatcher->resolve($ost->get_path_info());
?> ?>
...@@ -325,6 +325,43 @@ class osTicket { ...@@ -325,6 +325,43 @@ class osTicket {
return true; return true;
} }
/*
* Util functions
*
*/
function get_var($index, $vars, $default='', $type=null) {
if(is_array($vars)
&& array_key_exists($index, $vars)
&& (!$type || gettype($vars[$index])==$type))
return $vars[$index];
return $default;
}
function get_db_input($index, $vars, $quote=true) {
return db_input($this->get_var($index, $vars), $quote);
}
function get_path_info() {
if(isset($_SERVER['PATH_INFO']))
return $_SERVER['PATH_INFO'];
if(isset($_SERVER['ORIG_PATH_INFO']))
return $_SERVER['ORIG_PATH_INFO'];
//TODO: conruct possible path info.
return null;
}
/* returns true if script is being executed via commandline */
function is_cli() {
return (!strcasecmp(substr(php_sapi_name(), 0, 3), 'cli')
|| (!$_SERVER['REQUEST_METHOD'] && !$_SERVER['HTTP_HOST']) //Fallback when php-cgi binary is used via cli
);
}
/**** static functions ****/ /**** static functions ****/
function start($configId) { function start($configId) {
...@@ -338,13 +375,6 @@ class osTicket { ...@@ -338,13 +375,6 @@ class osTicket {
return $ost; return $ost;
} }
/* is_cli */
function is_cli() {
return (!strcasecmp(substr(php_sapi_name(), 0, 3), 'cli')
|| (!$_SERVER['REQUEST_METHOD'] && !$_SERVER['HTTP_HOST']) //Fallback when php-cgi binary is used via cli
);
}
} }
?> ?>
...@@ -23,13 +23,16 @@ class Upgrader extends SetupWizard { ...@@ -23,13 +23,16 @@ class Upgrader extends SetupWizard {
var $sqldir; var $sqldir;
var $signature; var $signature;
var $state;
var $mode;
function Upgrader($signature, $prefix, $sqldir) { function Upgrader($signature, $prefix, $sqldir) {
$this->signature = $signature; $this->signature = $signature;
$this->shash = substr($signature, 0, 8);
$this->prefix = $prefix; $this->prefix = $prefix;
$this->sqldir = $sqldir; $this->sqldir = $sqldir;
$this->errors = array(); $this->errors = array();
$this->mode = 'ajax'; //
//Disable time limit if - safe mode is set. //Disable time limit if - safe mode is set.
if(!ini_get('safe_mode')) if(!ini_get('safe_mode'))
...@@ -38,6 +41,8 @@ class Upgrader extends SetupWizard { ...@@ -38,6 +41,8 @@ class Upgrader extends SetupWizard {
//Init persistent state of upgrade. //Init persistent state of upgrade.
$this->state = &$_SESSION['ost_upgrader']['state']; $this->state = &$_SESSION['ost_upgrader']['state'];
$this->mode = &$_SESSION['ost_upgrader']['mode'];
//Init the task Manager. //Init the task Manager.
if(!isset($_SESSION['ost_upgrader'][$this->getShash()])) if(!isset($_SESSION['ost_upgrader'][$this->getShash()]))
$_SESSION['ost_upgrader'][$this->getShash()]['tasks']=array(); $_SESSION['ost_upgrader'][$this->getShash()]['tasks']=array();
...@@ -45,8 +50,8 @@ class Upgrader extends SetupWizard { ...@@ -45,8 +50,8 @@ class Upgrader extends SetupWizard {
//Tasks to perform - saved on the session. //Tasks to perform - saved on the session.
$this->tasks = &$_SESSION['ost_upgrader'][$this->getShash()]['tasks']; $this->tasks = &$_SESSION['ost_upgrader'][$this->getShash()]['tasks'];
//Database migrater //Database migrater
$this->migrater = new DatabaseMigrater($this->signature, SCHEMA_SIGNATURE, $this->sqldir); $this->migrater = null;
} }
function onError($error) { function onError($error) {
...@@ -87,7 +92,7 @@ class Upgrader extends SetupWizard { ...@@ -87,7 +92,7 @@ class Upgrader extends SetupWizard {
} }
function getShash() { function getShash() {
return $this->shash; return substr($this->getSchemaSignature(), 0, 8);
} }
function getTablePrefix() { function getTablePrefix() {
...@@ -106,13 +111,31 @@ class Upgrader extends SetupWizard { ...@@ -106,13 +111,31 @@ class Upgrader extends SetupWizard {
$this->state = $state; $this->state = $state;
} }
function getMode() {
return $this->mode;
}
function setMode($mode) {
$this->mode = $mode;
}
function getMigrater() {
if(!$this->migrater)
$this->migrater = new DatabaseMigrater($this->signature, SCHEMA_SIGNATURE, $this->sqldir);
return $this->migrater;
}
function getPatches() { function getPatches() {
return $this->migrater->getPatches(); $patches = array();
if($this->getMigrater())
$patches = $this->getMigrater()->getPatches();
return $patches;
} }
function getNextPatch() { function getNextPatch() {
$p = $this->getPatches(); return (($p=$this->getPatches()) && count($p)) ? $p[0] : false;
return (count($p)) ? $p[0] : false;
} }
function getNextVersion() { function getNextVersion() {
...@@ -140,7 +163,7 @@ class Upgrader extends SetupWizard { ...@@ -140,7 +163,7 @@ class Upgrader extends SetupWizard {
$action='Upgrade osTicket to '.$this->getVersion(); $action='Upgrade osTicket to '.$this->getVersion();
if($this->getNumPendingTasks() && ($task=$this->getNextTask())) { if($this->getNumPendingTasks() && ($task=$this->getNextTask())) {
$action = $task['desc']; $action = $task['desc'];
if($task['status']) //Progress report... if($task['status']) //Progress report...
$action.=' ('.$task['status'].')'; $action.=' ('.$task['status'].')';
} elseif($this->isUpgradable() && ($nextversion = $this->getNextVersion())) { } elseif($this->isUpgradable() && ($nextversion = $this->getNextVersion())) {
$action = "Upgrade to $nextversion"; $action = "Upgrade to $nextversion";
...@@ -161,9 +184,9 @@ class Upgrader extends SetupWizard { ...@@ -161,9 +184,9 @@ class Upgrader extends SetupWizard {
foreach($tasks as $k => $task) { foreach($tasks as $k => $task) {
if(!$task['done']) if(!$task['done'])
$pending[$k] = $task; $pending[$k] = $task;
} }
} }
return $pending; return $pending;
} }
...@@ -198,7 +221,11 @@ class Upgrader extends SetupWizard { ...@@ -198,7 +221,11 @@ class Upgrader extends SetupWizard {
if(!($tasks=$this->getPendingTasks())) if(!($tasks=$this->getPendingTasks()))
return true; //Nothing to do. return true; //Nothing to do.
$ost->logDebug('Upgrader', sprintf('There are %d pending upgrade tasks', count($tasks))); $c = count($tasks);
$ost->logDebug(
sprintf('Upgrader - %s (%d pending tasks).', $this->getShash(), $c),
sprintf('There are %d pending upgrade tasks for %s patch', $c, $this->getShash())
);
$start_time = Misc::micro_time(); $start_time = Misc::micro_time();
foreach($tasks as $k => $task) { foreach($tasks as $k => $task) {
//TODO: check time used vs. max execution - break if need be //TODO: check time used vs. max execution - break if need be
...@@ -211,7 +238,7 @@ class Upgrader extends SetupWizard { ...@@ -211,7 +238,7 @@ class Upgrader extends SetupWizard {
return $this->getPendingTasks(); return $this->getPendingTasks();
} }
function upgrade() { function upgrade() {
global $ost; global $ost;
...@@ -227,18 +254,20 @@ class Upgrader extends SetupWizard { ...@@ -227,18 +254,20 @@ class Upgrader extends SetupWizard {
if (!$this->load_sql_file($patch, $this->getTablePrefix())) if (!$this->load_sql_file($patch, $this->getTablePrefix()))
return false; return false;
//clear previous patch info - //clear previous patch info -
unset($_SESSION['ost_upgrader'][$this->getShash()]); unset($_SESSION['ost_upgrader'][$this->getShash()]);
$phash = substr(basename($patch), 0, 17); $phash = substr(basename($patch), 0, 17);
$shash = substr($phash, 9, 8);
//Log the patch info //Log the patch info
$logMsg = "Patch $phash applied "; $logMsg = "Patch $phash applied successfully ";
if(($info = $this->readPatchInfo($patch)) && $info['version']) if(($info = $this->readPatchInfo($patch)) && $info['version'])
$logMsg.= ' ('.$info['version'].') '; $logMsg.= ' ('.$info['version'].') ';
$ost->logDebug('Upgrader - Patch applied', $logMsg); $ost->logDebug("Upgrader - $shash applied", $logMsg);
$this->signature = $shash; //Update signature to the *new* HEAD
//Check if the said patch has scripted tasks //Check if the said patch has scripted tasks
if(!($tasks=$this->getTasksForPatch($phash))) { if(!($tasks=$this->getTasksForPatch($phash))) {
//Break IF elapsed time is greater than 80% max time allowed. //Break IF elapsed time is greater than 80% max time allowed.
...@@ -250,16 +279,14 @@ class Upgrader extends SetupWizard { ...@@ -250,16 +279,14 @@ class Upgrader extends SetupWizard {
} }
//We have work to do... set the tasks and break. //We have work to do... set the tasks and break.
$shash = substr($phash, 9, 8);
$_SESSION['ost_upgrader'][$shash]['tasks'] = $tasks; $_SESSION['ost_upgrader'][$shash]['tasks'] = $tasks;
$_SESSION['ost_upgrader'][$shash]['state'] = 'upgrade'; $_SESSION['ost_upgrader'][$shash]['state'] = 'upgrade';
$ost->logDebug('Upgrader', sprintf('Found %d tasks to be executed for %s',
count($tasks), $shash));
break; break;
} }
//Reset the migrater
$this->migrater = null;
return true; return true;
} }
...@@ -286,9 +313,9 @@ class Upgrader extends SetupWizard { ...@@ -286,9 +313,9 @@ class Upgrader extends SetupWizard {
break; break;
} }
//Check IF SQL cleanup exists. //Check IF SQL cleanup exists.
$file=$this->getSQLDir().$phash.'.cleanup.sql'; $file=$this->getSQLDir().$phash.'.cleanup.sql';
if(file_exists($file)) if(file_exists($file))
$tasks[] = array('func' => 'cleanup', $tasks[] = array('func' => 'cleanup',
'desc' => 'Post-upgrade cleanup!', 'desc' => 'Post-upgrade cleanup!',
'phash' => $phash); 'phash' => $phash);
...@@ -306,7 +333,7 @@ class Upgrader extends SetupWizard { ...@@ -306,7 +333,7 @@ class Upgrader extends SetupWizard {
if(!file_exists($file)) //No cleanup script. if(!file_exists($file)) //No cleanup script.
return 0; return 0;
//We have a cleanup script ::XXX: Don't abort on error? //We have a cleanup script ::XXX: Don't abort on error?
if($this->load_sql_file($file, $this->getTablePrefix(), false, true)) if($this->load_sql_file($file, $this->getTablePrefix(), false, true))
return 0; return 0;
...@@ -317,7 +344,7 @@ class Upgrader extends SetupWizard { ...@@ -317,7 +344,7 @@ class Upgrader extends SetupWizard {
function migrateAttachments2DB($taskId) { function migrateAttachments2DB($taskId) {
global $ost; global $ost;
if(!($max_time = ini_get('max_execution_time'))) if(!($max_time = ini_get('max_execution_time')))
$max_time = 30; //Default to 30 sec batches. $max_time = 30; //Default to 30 sec batches.
...@@ -330,7 +357,7 @@ class Upgrader extends SetupWizard { ...@@ -330,7 +357,7 @@ class Upgrader extends SetupWizard {
function migrateSessionFile2DB($taskId) { function migrateSessionFile2DB($taskId) {
# How about 'dis for a hack? # How about 'dis for a hack?
osTicketSession::write(session_id(), session_encode()); osTicketSession::write(session_id(), session_encode());
return 0; return 0;
} }
......
<?php <?php
if(!defined('OSTSCPINC') || !$thisstaff || !$thisstaff->isAdmin()) die('Access Denied'); if(!defined('OSTSCPINC') || !$thisstaff || !$thisstaff->isAdmin()) die('Access Denied');
//See if we need to switch the mode of upgrade...e.g from ajax (default) to manual
if(($mode = $ost->get_var('m', $_GET)) && $mode!=$upgrader->getMode()) {
//Set Persistent mode/
$upgrader->setMode($mode);
//Log warning about ajax calls - most likely culprit is AcceptPathInfo directive.
if($mode=='manual')
$ost->logWarning('Ajax calls are failing',
'Make sure your server has AcceptPathInfo directive set to "ON" or get technical help');
}
$action=$upgrader->getNextAction(); $action=$upgrader->getNextAction();
?> ?>
<h2>osTicket Upgrade</h2> <h2>osTicket Upgrade</h2>
...@@ -9,7 +20,7 @@ $action=$upgrader->getNextAction(); ...@@ -9,7 +20,7 @@ $action=$upgrader->getNextAction();
<p>Thank you for taking the time to upgrade your osTicket intallation!</p> <p>Thank you for taking the time to upgrade your osTicket intallation!</p>
<p>Please don't cancel or close the browser, any errors at this stage will be fatal.</p> <p>Please don't cancel or close the browser, any errors at this stage will be fatal.</p>
</div> </div>
<h2><?php echo $action ?></h2> <h2 id="task"><?php echo $action ?></h2>
<p>The upgrade wizard will now attempt to upgrade your database and core settings!</p> <p>The upgrade wizard will now attempt to upgrade your database and core settings!</p>
<ul> <ul>
<li>Database enhancements</li> <li>Database enhancements</li>
...@@ -20,8 +31,9 @@ $action=$upgrader->getNextAction(); ...@@ -20,8 +31,9 @@ $action=$upgrader->getNextAction();
<form method="post" action="upgrade.php" id="upgrade"> <form method="post" action="upgrade.php" id="upgrade">
<?php csrf_token(); ?> <?php csrf_token(); ?>
<input type="hidden" name="s" value="upgrade"> <input type="hidden" name="s" value="upgrade">
<input type="hidden" id="mode" name="m" value="<?php echo $upgrader->getMode(); ?>">
<input type="hidden" name="sh" value="<?php echo $upgrader->getSchemaSignature(); ?>"> <input type="hidden" name="sh" value="<?php echo $upgrader->getSchemaSignature(); ?>">
<input class="btn" type="submit" name="submit" value="Do It Now!"> <input class="btn" type="submit" name="submit" value="Upgrade Now!">
</form> </form>
</div> </div>
</div> </div>
...@@ -33,9 +45,11 @@ $action=$upgrader->getNextAction(); ...@@ -33,9 +45,11 @@ $action=$upgrader->getNextAction();
</div> </div>
<div class="clear"></div> <div class="clear"></div>
<div id="upgrading"> <div id="upgrading">
<h4><?php echo $action; ?></h4> <h4 id="action"><?php echo $action; ?></h4>
Please wait... while we upgrade your osTicket installation! Please wait... while we upgrade your osTicket installation!
<div id="msg" style="font-weight: bold;padding-top:10px;">Smile!</div> <div id="msg" style="font-weight: bold;padding-top:10px;">
<?php echo sprintf("%s - Relax!", $thisstaff->getFirstName()); ?>
</div>
</div> </div>
</div> </div>
<div class="clear"></div>` <div class="clear"></div>
...@@ -27,7 +27,7 @@ require('staff.inc.php'); ...@@ -27,7 +27,7 @@ require('staff.inc.php');
ini_set('display_errors','0'); //Disable error display ini_set('display_errors','0'); //Disable error display
ini_set('display_startup_errors','0'); ini_set('display_startup_errors','0');
//TODO: disable direct access via the browser? i,e All request must have REFER? //TODO: disable direct access via the browser? i,e All request must have REFER?
if(!defined('INCLUDE_DIR')) Http::response(500, 'Server configuration error'); if(!defined('INCLUDE_DIR')) Http::response(500, 'Server configuration error');
require_once INCLUDE_DIR.'/class.dispatcher.php'; require_once INCLUDE_DIR.'/class.dispatcher.php';
...@@ -65,5 +65,5 @@ $dispatcher = patterns('', ...@@ -65,5 +65,5 @@ $dispatcher = patterns('',
); );
# Call the respective function # Call the respective function
print $dispatcher->resolve($_SERVER['PATH_INFO']); print $dispatcher->resolve($ost->get_path_info());
?> ?>
jQuery(function($) { jQuery(function($) {
$("#overlay").css({ $("#overlay").css({
opacity : 0.3, opacity : 0.3,
top : 0, top : 0,
...@@ -12,18 +12,21 @@ jQuery(function($) { ...@@ -12,18 +12,21 @@ jQuery(function($) {
top : ($(window).height() / 3), top : ($(window).height() / 3),
left : ($(window).width() / 2 - 160) left : ($(window).width() / 2 - 160)
}); });
$('form#upgrade').submit(function(e) { $('form#upgrade').submit(function(e) {
e.preventDefault();
var form = $(this); var form = $(this);
$('input[type=submit]', this).attr('disabled', 'disabled'); $('input[type=submit]', this).attr('disabled', 'disabled');
$('#overlay, #upgrading').show(); $('#overlay, #upgrading').show();
doTasks('upgrade.php',form.serialize()); if($('input#mode', form).val() == 'manual') {
return true;
return false; } else {
}); e.preventDefault();
autoUpgrade('upgrade.php',form.serialize());
return false;
}
});
function doTasks(url, data) { function autoUpgrade(url, data) {
function _lp(count) { function _lp(count) {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
...@@ -33,26 +36,34 @@ jQuery(function($) { ...@@ -33,26 +36,34 @@ jQuery(function($) {
data: data, data: data,
dataType: 'text', dataType: 'text',
success: function(res) { success: function(res) {
if (res) { $('#main #task').html(res);
$('#loading #msg').html(res); $('#upgrading #action').html(res);
} $('#upgrading #msg').html('Still busy... smile #'+count);
}, },
statusCode: { statusCode: {
200: function() { 200: function() {
setTimeout(function() { _lp(count+1); }, 2); setTimeout(function() { _lp(count+1); }, 200);
}, },
201: function() { 201: function() {
$('#loading #msg').html("We're done... cleaning up!"); $('#upgrading #msg').html("Cleaning up!...");
setTimeout(function() { location.href =url+'?c='+count+'&r='+Math.floor((Math.random()*100)+1); }, 3000); setTimeout(function() { location.href =url+'?c='+count+'&r='+Math.floor((Math.random()*100)+1); }, 3000);
} }
}, },
error: function() { error: function(jqXHR, textStatus, errorThrown) {
$('#loading #msg').html("Something went wrong"); $('#upgrading #action').html('Error occurred. Aborting...');
setTimeout(function() { location.href =url+'?c='+count+'&r='+Math.floor((Math.random()*100)+1); }, 1000); switch(jqXHR.status) {
case 404:
$('#upgrading #msg').html("Manual upgrade required (ajax failed)");
setTimeout(function() { location.href =url+'?m=manual&c='+count+'&r='+Math.floor((Math.random()*100)+1); }, 2000);
break;
default:
$('#upgrading #msg').html("Something went wrong");
setTimeout(function() { location.href =url+'?c='+count+'&r='+Math.floor((Math.random()*100)+1); }, 2000);
}
} }
}); });
}; };
_lp(0); _lp(1);
} }
}); });
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment