public static function OnMetaModelStarted() { try { $oBackupMutex = new iTopMutex('backup.' . utils::GetCurrentEnvironment()); if ($oBackupMutex->TryLock()) { $oBackupMutex->Unlock(); } else { // Not needed: the DB dump is done in a single transaction //MetaModel::GetConfig()->Set('access_mode', ACCESS_READONLY, 'itop-backup'); //MetaModel::GetConfig()->Set('access_message', ' - '.dict::S('bkp-backup-running'), 'itop-backup'); } $oRestoreMutex = new iTopMutex('restore.' . utils::GetCurrentEnvironment()); if ($oRestoreMutex->TryLock()) { $oRestoreMutex->Unlock(); } else { MetaModel::GetConfig()->Set('access_mode', ACCESS_READONLY, 'itop-backup'); MetaModel::GetConfig()->Set('access_message', ' - ' . dict::S('bkp-restore-running'), 'itop-backup'); } } catch (Exception $e) { } }
public static function OnMetaModelStarted() { try { $oBackupMutex = new iTopMutex('backup.' . utils::GetCurrentEnvironment()); if ($oBackupMutex->TryLock()) { $oBackupMutex->Unlock(); } else { // Not needed: the DB dump is done in a single transaction //MetaModel::GetConfig()->Set('access_mode', ACCESS_READONLY, 'itop-backup'); //MetaModel::GetConfig()->Set('access_message', ' - '.dict::S('bkp-backup-running'), 'itop-backup'); } $oRestoreMutex = new iTopMutex('restore.' . utils::GetCurrentEnvironment()); if ($oRestoreMutex->TryLock()) { $oRestoreMutex->Unlock(); } else { IssueLog::Info(__CLASS__ . '::' . __FUNCTION__ . ' A user is trying to use iTop while a restore is running. The requested page is in read-only mode.'); MetaModel::GetConfig()->Set('access_mode', ACCESS_READONLY, 'itop-backup'); MetaModel::GetConfig()->Set('access_message', ' - ' . dict::S('bkp-restore-running'), 'itop-backup'); } } catch (Exception $e) { IssueLog::Error(__CLASS__ . '::' . __FUNCTION__ . ' Failed to check if a backup/restore is running: ' . $e->getMessage()); } }
$oPage->p('Error: ' . $e->getMessage()); } } $oPage->output(); break; case 'restore_get_token': require_once APPROOT . '/application/startup.inc.php'; require_once APPROOT . '/application/loginwebpage.class.inc.php'; LoginWebPage::DoLogin(true); // Check user rights and prompt if needed (must be admin) $oPage = new ajax_page(""); $oPage->no_cache(); $oPage->SetContentType('text/html'); $sEnvironment = utils::ReadParam('environment', 'production', false, 'raw_data'); $oRestoreMutex = new iTopMutex('restore.' . $sEnvironment); if ($oRestoreMutex->TryLock()) { $oRestoreMutex->Unlock(); $sFile = utils::ReadParam('file', '', false, 'raw_data'); $sToken = str_replace(' ', '', (string) microtime()); $sTokenFile = APPROOT . '/data/restore.' . $sToken . '.tok'; file_put_contents($sTokenFile, $sFile); $oPage->add_ready_script(<<<EOF \t\$("#restore_token").val('{$sToken}'); EOF ); } else { $oPage->p(Dict::S('bkp-restore-running')); } $oPage->output(); break; case 'restore_exec':
$aDisplayProcesses[] = get_class($oExecInstance); } $sDisplayProcesses = implode(', ', $aDisplayProcesses); $oP->p("Background processes: " . $sDisplayProcesses); } if (utils::ReadParam('status_only', false, true)) { // Display status and exit DisplayStatus($oP); exit(0); } require_once APPROOT . 'core/mutex.class.inc.php'; $oP->p("Starting: " . time() . ' (' . date('Y-m-d H:i:s') . ')'); try { $oConfig = utils::GetConfig(); $oMutex = new iTopMutex('cron.' . $oConfig->GetDBName() . '_' . $oConfig->GetDBSubname()); if ($oMutex->TryLock()) { // 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)) { $oP->p("A database maintenance is ongoing (read-only mode even for admins)."); $oP->Output(); exit - 1; } CronExec($oP, $aProcesses, $bVerbose); $oMutex->Unlock(); } else { // Exit silently $oP->p("Already running..."); } } catch (Exception $e) { $oP->p("ERROR: '" . $e->getMessage() . "'");
public function Display(WebPage $oPage) { $oPage->add_style(<<<EOF #changes_summary { \tmax-height: 200px; \toverflow: auto; } #changes_summary div { \twidth:100; \tmargin-top:0; \tpadding-top: 0.5em; \tpadding-left: 0; } #changes_summary div ul { \tmargin-left:0; \tpadding-left: 20px; } #changes_summary div.closed ul { \tdisplay:none; } #changes_summary div li { \tlist-style: none; \twidth: 100; \tmargin-left:0; \tpadding-left: 0em; } .title { \tpadding-left: 20px; \tfont-weight: bold; \tcursor: pointer; \tbackground: url(../images/minus.gif) 2px 2px no-repeat; } #changes_summary div.closed .title { \tbackground: url(../images/plus.gif) 2px 2px no-repeat; } EOF ); $this->bCanMoveForward = true; $bDisplayLicense = true; $sPreviousVersionDir = $this->oWizard->GetParameter('previous_version_dir', ''); $aInstalledInfo = SetupUtils::GetApplicationVersion($this->oWizard); if ($aInstalledInfo === false) { throw new Exception('No previous version of ' . ITOP_APPLICATION . ' found in the supplied database. The upgrade cannot continue.'); } else { if (strcasecmp($aInstalledInfo['product_name'], ITOP_APPLICATION) != 0) { $oPage->p("<b>Warning: The installed products seem different. Are you sure the you want to upgrade {$aInstalledInfo['product_name']} with " . ITOP_APPLICATION . "?</b>"); } } $sInstalledVersion = $aInstalledInfo['product_version']; $sInstalledDataModelVersion = $aInstalledInfo['datamodel_version']; $oPage->add("<h2>Information about the upgrade from version {$sInstalledVersion} to " . ITOP_VERSION . '.' . ITOP_REVISION . "</h2>"); if ($sInstalledVersion == ITOP_VERSION . '.' . ITOP_REVISION) { // Reinstalling the same version let's skip the license agreement... $bDisplayLicense = false; } $this->oWizard->SetParameter('license', $bDisplayLicense); // Remember for later if ($sInstalledDataModelVersion == '$ITOP_VERSION$.$WCREV$') { // Special case for upgrading some development versions (temporary) $sCompatibleDMDir = SetupUtils::GetLatestDataModelDir(); $sInstalledDataModelVersion = SetupUtils::GetDataModelVersion($sCompatibleDMDir); } else { $sCompatibleDMDir = SetupUtils::GetCompatibleDataModelDir($sInstalledDataModelVersion); } if ($sCompatibleDMDir === false) { // No compatible version exists... cannot upgrade. Either it is too old, or too new (downgrade !) $this->bCanMoveForward = false; $oPage->p("The current version of " . ITOP_APPLICATION . " (" . ITOP_VERSION . '.' . ITOP_REVISION . ") does not seem to be compatible with the installed version ({$sInstalledVersion})."); $oPage->p("The upgrade cannot continue, sorry."); } else { $sUpgradeDMVersion = SetupUtils::GetDataModelVersion($sCompatibleDMDir); $sPreviousSourceDir = isset($aInstalledInfo['source_dir']) ? $aInstalledInfo['source_dir'] : 'modules'; $aChanges = false; if (is_dir($sPreviousVersionDir)) { // Check if the previous version is a "genuine" one or not... $aChanges = SetupUtils::CheckVersion($sInstalledDataModelVersion, $sPreviousVersionDir . '/' . $sPreviousSourceDir); } if ($aChanges !== false && (count($aChanges['added']) > 0 || count($aChanges['removed']) > 0 || count($aChanges['modified']) > 0)) { // Some changes were detected, prompt the user to keep or discard them $oPage->p("<img src=\"../images/error.png\"/> Some modifications were detected between the " . ITOP_APPLICATION . " version in '{$sPreviousVersionDir}' and a genuine {$sInstalledVersion} version."); $oPage->p("What do you want to do?"); $aWritableDirs = array('modules', 'portal'); $aErrors = SetupUtils::CheckWritableDirs($aWritableDirs); $sChecked = $this->oWizard->GetParameter('upgrade_type') == 'keep-previous' ? ' checked ' : ''; $sDisabled = count($aErrors) > 0 ? ' disabled ' : ''; $oPage->p('<input id="radio_upgrade_keep" type="radio" name="upgrade_type" value="keep-previous"' . $sChecked . $sDisabled . '/><label for="radio_upgrade_keep"> Preserve the modifications of the installed version (the dasboards inside ' . ITOP_APPLICATION . ' may not be editable).</label>'); $oPage->add('<input type="hidden" name="datamodel_previous_version" value="' . htmlentities($sInstalledDataModelVersion, ENT_QUOTES, 'UTF-8') . '">'); $oPage->add('<input type="hidden" name="relative_source_dir" value="' . htmlentities($sPreviousSourceDir, ENT_QUOTES, 'UTF-8') . '">'); if (count($aErrors) > 0) { $oPage->p("Cannot copy the installed version due to the following access rights issue(s):"); foreach ($aErrors as $sDir => $oCheckResult) { $oPage->p('<img src="../images/error.png"/> ' . $oCheckResult->sLabel); } } $sChecked = $this->oWizard->GetParameter('upgrade_type') == 'use-compatible' ? ' checked ' : ''; $oPage->p('<input id="radio_upgrade_convert" type="radio" name="upgrade_type" value="use-compatible"' . $sChecked . '/><label for="radio_upgrade_convert"> Discard the modifications, use a standard ' . $sUpgradeDMVersion . ' data model.</label>'); $oPage->add('<input type="hidden" name="datamodel_path" value="' . htmlentities($sCompatibleDMDir, ENT_QUOTES, 'UTF-8') . '">'); $oPage->add('<input type="hidden" name="datamodel_version" value="' . htmlentities($sUpgradeDMVersion, ENT_QUOTES, 'UTF-8') . '">'); $oPage->add('<div id="changes_summary"><div class="closed"><span class="title">Details of the modifications</span><div>'); if (count($aChanges['added']) > 0) { $oPage->add('<ul>New files added:'); foreach ($aChanges['added'] as $sFilePath => $void) { $oPage->add('<li>' . $sFilePath . '</li>'); } $oPage->add('</ul>'); } if (count($aChanges['removed']) > 0) { $oPage->add('<ul>Deleted files:'); foreach ($aChanges['removed'] as $sFilePath => $void) { $oPage->add('<li>' . $sFilePath . '</li>'); } $oPage->add('</ul>'); } if (count($aChanges['modified']) > 0) { $oPage->add('<ul>Modified files:'); foreach ($aChanges['modified'] as $sFilePath => $void) { $oPage->add('<li>' . $sFilePath . '</li>'); } $oPage->add('</ul>'); } $oPage->add('</div></div></div>'); } else { // No changes detected... or no way to tell because of the lack of a manifest or previous source dir // Use the "compatible" datamodel as-is. $oPage->p("<img src=\"../images/validation_ok.png\"/> The datamodel will be upgraded from version {$sInstalledDataModelVersion} to version {$sUpgradeDMVersion}."); $oPage->add('<input type="hidden" name="upgrade_type" value="use-compatible">'); $oPage->add('<input type="hidden" name="datamodel_path" value="' . htmlentities($sCompatibleDMDir, ENT_QUOTES, 'UTF-8') . '">'); $oPage->add('<input type="hidden" name="datamodel_version" value="' . htmlentities($sUpgradeDMVersion, ENT_QUOTES, 'UTF-8') . '">'); } // Check if there are "extensions" to preserve and if it's possible if (is_dir($sPreviousVersionDir . '/extensions')) { $aExtensions = glob($sPreviousVersionDir . '/extensions/*', GLOB_ONLYDIR); if ($aExtensions !== false && count($aExtensions) > 0 && realpath($sPreviousVersionDir . '/extensions') != realpath(APPROOT . 'extensions')) { $aWritableDirs = array('extensions'); $aErrors = SetupUtils::CheckWritableDirs($aWritableDirs); if (count($aErrors) > 0) { $oPage->p("Cannot copy the extensions from '{$sPreviousVersionDir}/extensions' to '" . APPROOT . "extensions' due to the following access rights issue(s):"); foreach ($aErrors as $sDir => $oCheckResult) { $oPage->p('<img src="../images/error.png"/> ' . $oCheckResult->sLabel); } } else { $oPage->p("<b>Note:</b> The extensions present in '{$sPreviousVersionDir}/extensions' will be copied to '" . APPROOT . "extensions'."); $oPage->add('<input type="hidden" name="copy_extensions_from" value="' . htmlentities($sPreviousVersionDir . '/extensions', ENT_QUOTES, 'UTF-8') . '">'); } } } $oPage->add_ready_script(<<<EOF \t\$("#changes_summary .title").click(function() { \$(this).parent().toggleClass('closed'); } ); \t\$('input[name=upgrade_type]').bind('click change', function() { WizardUpdateButtons(); }); EOF ); $oMutex = new iTopMutex('cron.' . $this->oWizard->GetParameter('db_name', '') . '_' . $this->oWizard->GetParameter('db_prefix', ''), $this->oWizard->GetParameter('db_server', ''), $this->oWizard->GetParameter('db_user', ''), $this->oWizard->GetParameter('db_pwd', '')); if ($oMutex->TryLock()) { $oMutex->Unlock(); } else { $oPage->p("<img src=\"../images/error.png\"/> An iTop CRON process is being executed on the target database. It is highly recommended to stop any iTop CRON process prior to running the setup program."); } } }