diff --git a/application/startup.inc.php b/application/startup.inc.php
index c3c1abdc3..4082d44b7 100644
--- a/application/startup.inc.php
+++ b/application/startup.inc.php
@@ -53,40 +53,6 @@ register_shutdown_function(function()
}
});
-// Use 'maintenance' parameter to bypass maintenance mode
-$bBypassMaintenance = !is_null(Utils::ReadParam('maintenance', null));
-
-// Maintenance mode
-if (file_exists(APPROOT.'.maintenance') && !$bBypassMaintenance)
-{
- $sMessage = 'Application is currently in maintenance';
- $sTitle = 'Maintenance';
-
- http_response_code(503);
- // Display message depending on the request
- switch (true)
- {
- case isset($_SERVER['REQUEST_URI']) && EndsWith($_SERVER['REQUEST_URI'], '/pages/ajax.searchform.php'):
- _MaintenanceHtmlMessage($sMessage);
- break;
-
- case array_key_exists('HTTP_X_COMBODO_AJAX', $_SERVER):
- case isset($_SERVER['REQUEST_URI']) && EndsWith($_SERVER['REQUEST_URI'], '/webservices/soapserver.php'):
- case isset($_SERVER['REQUEST_URI']) && EndsWith($_SERVER['REQUEST_URI'], '/webservices/rest.php'):
- _MaintenanceTextMessage($sMessage);
- break;
-
- case isset($_SERVER['CONTENT_TYPE']) && ($_SERVER['CONTENT_TYPE'] == 'application/json'):
- _MaintenanceJsonMessage($sTitle, $sMessage);
- break;
-
- default:
- _MaintenanceSetupPageMessage($sTitle, $sMessage);
- break;
- }
- exit();
-}
-
session_name('itop-'.md5(APPROOT));
session_start();
$sSwitchEnv = utils::ReadParam('switch_env', null);
@@ -120,80 +86,3 @@ else
}
$sConfigFile = APPCONF.$sEnv.'/'.ITOP_CONFIG_FILE;
MetaModel::Startup($sConfigFile, false /* $bModelOnly */, $bAllowCache, false /* $bTraceSourceFiles */, $sEnv);
-
-//
-// Maintenance message display functions
-//
-
-/**
- * Use a setup page to display the maintenance message
- * @param $sTitle
- * @param $sMessage
- */
-function _MaintenanceSetupPageMessage($sTitle, $sMessage)
-{
- // Web Page
- @include_once(APPROOT."/setup/setuppage.class.inc.php");
- if (class_exists('SetupPage'))
- {
- $oP = new SetupPage($sTitle);
- $oP->p("
$sMessage
");
- $oP->output();
- }
- else
- {
- _MaintenanceTextMessage($sMessage);
- }
-}
-
-/**
- * Use simple text to display the maintenance message
- * @param $sMessage
- */
-function _MaintenanceTextMessage($sMessage)
-{
- echo $sMessage;
-}
-
-/**
- * Use a simple HTML to display the maintenance message
- * @param $sMessage
- */
-function _MaintenanceHtmlMessage($sMessage)
-{
- echo ''.$sMessage.'
';
-}
-
-/**
- * Use a simple JSON to display the maintenance message
- *
- * @param $sTitle
- * @param $sMessage
- */
-function _MaintenanceJsonMessage($sTitle, $sMessage)
-{
- @include_once(APPROOT."/application/ajaxwebpage.class.inc.php");
- if (class_exists('ajax_page'))
- {
- $oP = new ajax_page($sTitle);
- $oP->add_header('Access-Control-Allow-Origin: *');
- $oP->SetContentType('application/json');
- $oP->add('{"code":100, "message":"'.$sMessage.'"}');
- $oP->Output();
- }
- else
- {
- _MaintenanceTextMessage($sMessage);
- }
-}
-
-/**
- * helper to test if a string ends with another
- * @param $haystack
- * @param $needle
- *
- * @return bool
- */
-function EndsWith($haystack, $needle) {
- return substr_compare($haystack, $needle, -strlen($needle)) === 0;
-}
\ No newline at end of file
diff --git a/approot.inc.php b/approot.inc.php
index e5cd6d0f2..585ca3ba8 100644
--- a/approot.inc.php
+++ b/approot.inc.php
@@ -12,4 +12,56 @@ else
{
$fItopStarted = 1000 * time();
}
-?>
+
+//
+// Maintenance mode
+//
+
+// Use 'maintenance' parameter to bypass maintenance mode
+if (!isset($bBypassMaintenance))
+{
+ $bBypassMaintenance = isset($_REQUEST['maintenance']) ? boolval($_REQUEST['maintenance']) : false;
+}
+
+if (file_exists(APPROOT.'.maintenance') && !$bBypassMaintenance)
+{
+ $sMessage = 'Application is currently in maintenance';
+ $sTitle = 'Maintenance';
+
+ http_response_code(503);
+ // Display message depending on the request
+ include(APPROOT.'maintenancemsg.php');
+
+ switch (true)
+ {
+ case isset($_SERVER['REQUEST_URI']) && EndsWith($_SERVER['REQUEST_URI'], '/pages/ajax.searchform.php'):
+ _MaintenanceHtmlMessage($sMessage);
+ break;
+
+ case array_key_exists('HTTP_X_COMBODO_AJAX', $_SERVER):
+ case isset($_SERVER['REQUEST_URI']) && EndsWith($_SERVER['REQUEST_URI'], '/webservices/soapserver.php'):
+ case isset($_SERVER['REQUEST_URI']) && EndsWith($_SERVER['REQUEST_URI'], '/webservices/rest.php'):
+ _MaintenanceTextMessage($sMessage);
+ break;
+
+ case isset($_SERVER['CONTENT_TYPE']) && ($_SERVER['CONTENT_TYPE'] == 'application/json'):
+ _MaintenanceJsonMessage($sTitle, $sMessage);
+ break;
+
+ default:
+ _MaintenanceSetupPageMessage($sTitle, $sMessage);
+ break;
+ }
+ exit();
+}
+
+/**
+ * helper to test if a string ends with another
+ * @param $haystack
+ * @param $needle
+ *
+ * @return bool
+ */
+function EndsWith($haystack, $needle) {
+ return substr_compare($haystack, $needle, -strlen($needle)) === 0;
+}
diff --git a/maintenancemsg.php b/maintenancemsg.php
new file mode 100644
index 000000000..82d24cb25
--- /dev/null
+++ b/maintenancemsg.php
@@ -0,0 +1,74 @@
+p("$sMessage
");
+ $oP->output();
+ }
+ else
+ {
+ _MaintenanceTextMessage($sMessage);
+ }
+}
+
+/**
+ * Use simple text to display the maintenance message
+ * @param $sMessage
+ */
+function _MaintenanceTextMessage($sMessage)
+{
+ echo $sMessage;
+}
+
+/**
+ * Use a simple HTML to display the maintenance message
+ * @param $sMessage
+ */
+function _MaintenanceHtmlMessage($sMessage)
+{
+ echo ''.$sMessage.'
';
+}
+
+/**
+ * Use a simple JSON to display the maintenance message
+ *
+ * @param $sTitle
+ * @param $sMessage
+ */
+function _MaintenanceJsonMessage($sTitle, $sMessage)
+{
+ @include_once(APPROOT.'bootstrap.inc.php');
+ @include_once(APPROOT."/application/ajaxwebpage.class.inc.php");
+ if (class_exists('ajax_page'))
+ {
+ $oP = new ajax_page($sTitle);
+ $oP->add_header('Access-Control-Allow-Origin: *');
+ $oP->SetContentType('application/json');
+ $oP->add('{"code":100, "message":"'.$sMessage.'"}');
+ $oP->Output();
+ }
+ else
+ {
+ _MaintenanceTextMessage($sMessage);
+ }
+}
diff --git a/pages/exec.php b/pages/exec.php
index 62e527dda..e44cbd708 100644
--- a/pages/exec.php
+++ b/pages/exec.php
@@ -26,16 +26,6 @@ require_once(APPROOT.'core/metamodel.class.php');
utils::InitTimeZone();
-// Maintenance mode
-if (file_exists(APPROOT.'.maintenance'))
-{
- http_response_code(503);
- require_once(APPROOT.'core/dict.class.inc.php');
- $sMessage = Dict::S('UI:Error:MaintenanceMode', 'Application is currently in maintenance');
- echo "$sMessage";
- exit;
-}
-
$sModule = utils::ReadParam('exec_module', '');
if ($sModule == '')
{
diff --git a/setup/applicationinstaller.class.inc.php b/setup/applicationinstaller.class.inc.php
index 1e1ef59ef..0a830e6af 100644
--- a/setup/applicationinstaller.class.inc.php
+++ b/setup/applicationinstaller.class.inc.php
@@ -137,7 +137,21 @@ class ApplicationInstaller
return ($iOverallStatus == self::OK);
}
-
+
+ private function GetConfig()
+ {
+ $sTargetEnvironment = $this->GetTargetEnv();
+ $sConfigFile = APPCONF.$sTargetEnvironment.'/'.ITOP_CONFIG_FILE;
+ try
+ {
+ return new Config($sConfigFile);
+ }
+ catch (Exception $e)
+ {
+ return null;
+ }
+ }
+
/**
* Executes the next step of the installation and reports about the progress
* and the next step to perform
@@ -151,7 +165,7 @@ class ApplicationInstaller
try
{
$fStart = microtime(true);
- SetupUtils::EnterMaintenanceMode();
+ SetupUtils::EnterMaintenanceMode($this->GetConfig());
switch ($sStep)
{
case '':
@@ -356,15 +370,11 @@ class ApplicationInstaller
'next-step-label' => "Unknown setup step '$sStep'.",
'percentage-completed' => 100,
);
+ break;
}
- SetupUtils::ExitMaintenanceMode();
- $fDuration = round(microtime(true) - $fStart, 2);
- SetupPage::log_info("##### STEP {$sStep} duration: {$fDuration}s");
}
catch (Exception $e)
{
- SetupUtils::ExitMaintenanceMode();
-
$aResult = array(
'status' => self::ERROR,
'message' => $e->getMessage(),
@@ -389,6 +399,12 @@ class ApplicationInstaller
$idx++;
}
}
+ finally
+ {
+ SetupUtils::ExitMaintenanceMode();
+ $fDuration = round(microtime(true) - $fStart, 2);
+ SetupPage::log_info("##### STEP {$sStep} duration: {$fDuration}s");
+ }
return $aResult;
}
@@ -946,6 +962,11 @@ class ApplicationInstaller
// Ready to go !!
require_once(APPROOT.'core/dict.class.inc.php');
MetaModel::ResetCache();
+
+ // Perform final setup tasks here
+ //
+ $aAvailableModules = $oProductionEnv->AnalyzeInstallation(MetaModel::GetConfig(), APPROOT.$sModulesDir);
+ $oProductionEnv->CallInstallerHandlers($aAvailableModules, $aSelectedModuleCodes, 'AfterCreateConfig');
}
}
diff --git a/setup/index.php b/setup/index.php
index 186dac86a..afe8e9413 100644
--- a/setup/index.php
+++ b/setup/index.php
@@ -17,6 +17,7 @@
* You should have received a copy of the GNU Affero General Public License
*/
+$bBypassMaintenance = true; // Reset maintenance mode in case of problem
require_once('../approot.inc.php');
require_once(APPROOT.'/bootstrap.inc.php');
require_once(APPROOT.'/application/utils.inc.php');
@@ -26,6 +27,7 @@ require_once(APPROOT.'/setup/wizardcontroller.class.inc.php');
require_once(APPROOT.'/setup/wizardsteps.class.inc.php');
clearstatcache(); // Make sure we know what we are doing !
+SetupUtils::ExitMaintenanceMode(false); // Reset maintenance mode in case of problem
// Set a long (at least 4 minutes) execution time for the setup to avoid timeouts during this phase
ini_set('max_execution_time', max(240, ini_get('max_execution_time')));
// While running the setup it is desirable to see any error that may happen
diff --git a/setup/setuputils.class.inc.php b/setup/setuputils.class.inc.php
index 23de149b8..10a31acfd 100644
--- a/setup/setuputils.class.inc.php
+++ b/setup/setuputils.class.inc.php
@@ -1836,20 +1836,47 @@ EOF
return APPROOT.'log/setup-queries-'.strftime('%Y-%m-%d_%H_%M').'.sql';
}
- public final static function EnterMaintenanceMode($bCheckBackgroundTask = false)
+ public final static function EnterMaintenanceMode($oConfig)
{
@touch(APPROOT.'.maintenance');
- if ($bCheckBackgroundTask)
+ SetupPage::log("----> Entering maintenance mode");
+ try
{
-
- // Assume database is OK but datamodel is not usable
- $iCount = CMDBSource::QueryToScalar('SELECT COUNT(*) FROM priv_backgroundtask WHERE running=1');
+ // Wait for cron to stop
+ if (is_null($oConfig))
+ {
+ return;
+ }
+ // Use mutex to check if cron is running
+ $oMutex = new iTopMutex(
+ 'cron'.$oConfig->Get('db_name').$oConfig->Get('db_subname'),
+ $oConfig->Get('db_host'),
+ $oConfig->Get('db_user'),
+ $oConfig->Get('db_pwd'),
+ $oConfig->Get('db_tls.enabled'),
+ $oConfig->Get('db_tls.ca')
+ );
+ $iCount = 1;
+ while ($oMutex->IsLocked())
+ {
+ SetupPage::log("Waiting for cron to stop ($iCount)");
+ $iCount++;
+ sleep(10);
+ }
+ }
+ catch(Exception $e)
+ {
+ // Ignore errors
}
}
- public final static function ExitMaintenanceMode()
+ public final static function ExitMaintenanceMode($bLog = true)
{
@unlink(APPROOT.'.maintenance');
+ if ($bLog)
+ {
+ SetupPage::log("<---- Exiting maintenance mode");
+ }
}
}
diff --git a/webservices/cron.php b/webservices/cron.php
index 4c872a92d..3a4288202 100644
--- a/webservices/cron.php
+++ b/webservices/cron.php
@@ -566,7 +566,7 @@ try
{
// Note: testing this now in case some of the background processes forces the read-only mode for a while
// in that case it is better to exit with the check on reentrance (mutex)
- if (!MetaModel::DBHasAccess(ACCESS_ADMIN_WRITE) || file_exists(APPROOT.'.maintenance'))
+ if (!MetaModel::DBHasAccess(ACCESS_ADMIN_WRITE))
{
$oP->p("A maintenance is ongoing");
$oP->Output();