From d035130d00eebc639b2805259495b6eaaf6e7d34 Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 7 Nov 2019 09:16:06 +0100 Subject: [PATCH] =?UTF-8?q?N=C2=B02240=20-=20Supportability=20-=20Maintena?= =?UTF-8?q?nce=20mode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- approot.inc.php | 1 + core/config.class.inc.php | 5 ++ core/metamodel.class.php | 2 +- core/tar-itop.class.inc.php | 2 +- datamodels/2.x/itop-hub-connector/ajax.php | 4 +- lib/pear/archive_tar/Archive/Tar.php | 6 ++ setup/applicationinstaller.class.inc.php | 41 +++++++++++--- setup/index.php | 1 + setup/setuputils.class.inc.php | 64 +++++++++++++++++----- 9 files changed, 99 insertions(+), 27 deletions(-) diff --git a/approot.inc.php b/approot.inc.php index d07b3e6cd..fbcb4879c 100644 --- a/approot.inc.php +++ b/approot.inc.php @@ -4,6 +4,7 @@ define('APPROOT', dirname(__FILE__).'/'); define('APPCONF', APPROOT.'conf/'); define('ITOP_DEFAULT_ENV', 'production'); define('MAINTENANCE_MODE_FILE', APPROOT.'data/.maintenance'); +define('READONLY_MODE_FILE', APPROOT.'data/.readonly'); if (function_exists('microtime')) { diff --git a/core/config.class.inc.php b/core/config.class.inc.php index 7d7b61a0e..1e6dcabb9 100644 --- a/core/config.class.inc.php +++ b/core/config.class.inc.php @@ -1546,6 +1546,11 @@ class Config } } + if (file_exists(READONLY_MODE_FILE)) + { + $this->Set('access_mode', ACCESS_READONLY, READONLY_MODE_FILE); + } + $this->m_bLogGlobal = isset($MySettings['log_global']) ? (bool)trim($MySettings['log_global']) : DEFAULT_LOG_GLOBAL; $this->m_bLogNotification = isset($MySettings['log_notification']) ? (bool)trim($MySettings['log_notification']) : DEFAULT_LOG_NOTIFICATION; $this->m_bLogIssue = isset($MySettings['log_issue']) ? (bool)trim($MySettings['log_issue']) : DEFAULT_LOG_ISSUE; diff --git a/core/metamodel.class.php b/core/metamodel.class.php index 05619a7eb..e93e9b121 100644 --- a/core/metamodel.class.php +++ b/core/metamodel.class.php @@ -5087,7 +5087,7 @@ abstract class MetaModel } /** - * Determines wether the target DB is frozen or not + * Determines whether the target DB is frozen or not * * @return bool */ diff --git a/core/tar-itop.class.inc.php b/core/tar-itop.class.inc.php index adf693402..18f0d0a78 100644 --- a/core/tar-itop.class.inc.php +++ b/core/tar-itop.class.inc.php @@ -45,4 +45,4 @@ class ITopArchiveTar extends Archive_Tar { IssueLog::Warning($p_message); } -} \ No newline at end of file +} diff --git a/datamodels/2.x/itop-hub-connector/ajax.php b/datamodels/2.x/itop-hub-connector/ajax.php index 335ae804f..af1ad8a8b 100644 --- a/datamodels/2.x/itop-hub-connector/ajax.php +++ b/datamodels/2.x/itop-hub-connector/ajax.php @@ -309,7 +309,7 @@ try unlink(APPROOT.'data/hub/compile_authent'); // Load the "production" config file to clone & update it $oConfig = new Config(APPCONF.'production/'.ITOP_CONFIG_FILE); - SetupUtils::EnterMaintenanceMode($oConfig); + SetupUtils::EnterReadOnlyMode($oConfig); $oRuntimeEnv->InitDataModel($oConfig, true /* model only */); @@ -381,7 +381,7 @@ try } finally { - SetupUtils::ExitMaintenanceMode(); + SetupUtils::ExitReadOnlyMode(); } break; diff --git a/lib/pear/archive_tar/Archive/Tar.php b/lib/pear/archive_tar/Archive/Tar.php index 53966c255..26f6b92a9 100644 --- a/lib/pear/archive_tar/Archive/Tar.php +++ b/lib/pear/archive_tar/Archive/Tar.php @@ -1189,6 +1189,11 @@ class Archive_Tar extends PEAR $p_add_dir, $p_remove_dir ); + + if (!$v_result) + { + return false; + } } } @@ -1211,6 +1216,7 @@ class Archive_Tar extends PEAR */ public function _addFile($p_filename, &$p_header, $p_add_dir, $p_remove_dir, $v_stored_filename = null) { + $this->_error('Adding file:'.$p_filename); if (!$this->_file) { $this->_error('Invalid file descriptor'); return false; diff --git a/setup/applicationinstaller.class.inc.php b/setup/applicationinstaller.class.inc.php index 5535e1395..84abc7e04 100644 --- a/setup/applicationinstaller.class.inc.php +++ b/setup/applicationinstaller.class.inc.php @@ -192,10 +192,7 @@ class ApplicationInstaller try { $fStart = microtime(true); - if ($bSwitchToMaintenance) - { - SetupUtils::EnterMaintenanceMode($this->GetConfig()); - } + $this->EnterReadOnlyMode(); switch ($sStep) { case '': @@ -389,6 +386,7 @@ class ApplicationInstaller 'next-step-label' => 'Completed', 'percentage-completed' => 100, ); + $this->ExitReadOnlyMode(); break; @@ -431,10 +429,6 @@ class ApplicationInstaller } finally { - if ($bSwitchToMaintenance) - { - SetupUtils::ExitMaintenanceMode(); - } $fDuration = round(microtime(true) - $fStart, 2); SetupPage::log_info("##### STEP {$sStep} duration: {$fDuration}s"); } @@ -442,6 +436,37 @@ class ApplicationInstaller return $aResult; } + private function EnterReadOnlyMode() + { + if ($this->GetTargetEnv() != 'production') + { + return; + } + + if (SetupUtils::IsInReadOnlyMode()) + { + return; + } + + SetupUtils::EnterReadOnlyMode($this->GetConfig()); + } + + private function ExitReadOnlyMode() + { + if ($this->GetTargetEnv() != 'production') + { + return; + } + + if (!SetupUtils::IsInReadOnlyMode()) + { + return; + } + + SetupUtils::ExitReadOnlyMode(); + } + + protected static function DoCopy($aCopies) { $aReports = array(); diff --git a/setup/index.php b/setup/index.php index afe8e9413..003f2d239 100644 --- a/setup/index.php +++ b/setup/index.php @@ -28,6 +28,7 @@ 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 +SetupUtils::ExitReadOnlyMode(false); // Reset readonly 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 a9596ce81..1cca800a2 100644 --- a/setup/setuputils.class.inc.php +++ b/setup/setuputils.class.inc.php @@ -1836,10 +1836,54 @@ EOF return APPROOT.'log/setup-queries-'.strftime('%Y-%m-%d_%H_%M').'.sql'; } - public final static function EnterMaintenanceMode($oConfig) + public static function EnterMaintenanceMode($oConfig) { @touch(MAINTENANCE_MODE_FILE); self::Log("----> Entering maintenance mode"); + self::WaitCronTermination($oConfig, "maintenance"); + } + + public static function ExitMaintenanceMode($bLog = true) + { + @unlink(MAINTENANCE_MODE_FILE); + if ($bLog) + { + self::Log("<---- Exiting maintenance mode"); + } + } + + public static function IsInMaintenanceMode() + { + return file_exists(MAINTENANCE_MODE_FILE); + } + + public static function EnterReadOnlyMode($oConfig) + { + @touch(READONLY_MODE_FILE); + self::Log("----> Entering read only mode"); + self::WaitCronTermination($oConfig, "read only"); + } + + public static function ExitReadOnlyMode($bLog = true) + { + @unlink(READONLY_MODE_FILE); + if ($bLog) + { + self::Log("<---- Exiting read only mode"); + } + } + + public static function IsInReadOnlyMode() + { + return file_exists(READONLY_MODE_FILE); + } + + /** + * @param Config $oConfig + * @param string $sMode + */ + private static function WaitCronTermination($oConfig, $sMode) + { try { // Wait for cron to stop @@ -1858,34 +1902,24 @@ EOF ); $iCount = 1; $iStarted = time(); - $iMaxDuration = $oConfig->Get('cron_max_execution_time'); + $iMaxDuration = $oConfig->Get('cron_max_execution_time') + 1; $iTimeLimit = $iStarted + $iMaxDuration; while ($oMutex->IsLocked()) { self::Log("Waiting for cron to stop ($iCount)"); $iCount++; - sleep(10); + sleep(1); if (time() > $iTimeLimit) { - throw new Exception("Cannot enter maintenance mode"); + throw new Exception("Cannot enter $sMode mode"); } } - } - catch(Exception $e) + } catch (Exception $e) { // Ignore errors } } - public final static function ExitMaintenanceMode($bLog = true) - { - @unlink(MAINTENANCE_MODE_FILE); - if ($bLog) - { - self::Log("<---- Exiting maintenance mode"); - } - } - /** * Create and store Setup authentication token *