$sModules = implode(', ', get_loaded_extensions()); // Get the datamodel directory $oFilter = DBObjectSearch::FromOQL('SELECT ModuleInstallation WHERE name="datamodel"'); $oSet = new DBObjectSet($oFilter, array('installed' => false)); // Most recent first $oLastInstall = $oSet->Fetch(); $sLastInstallDate = $oLastInstall->Get('installed'); $sDataModelVersion = $oLastInstall->Get('version'); $aDataModelInfo = json_decode($oLastInstall->Get('comment'), true); $sDataModelSourceDir = $aDataModelInfo['source_dir']; require_once APPROOT . 'setup/runtimeenv.class.inc.php'; $sCurrEnv = utils::GetCurrentEnvironment(); $oRuntimeEnv = new RunTimeEnvironment($sCurrEnv); $aAvailableModules = $oRuntimeEnv->AnalyzeInstallation(MetaModel::GetConfig(), array(APPROOT . $sDataModelSourceDir, APPROOT . 'extensions')); require_once APPROOT . 'setup/setuputils.class.inc.php'; $aLicenses = SetupUtils::GetLicenses(); $aItopSettings = array('cron_max_execution_time', 'timezone'); $aPHPSettings = array('memory_limit', 'max_execution_time', 'upload_max_filesize', 'post_max_size'); $aMySQLSettings = array('max_allowed_packet', 'key_buffer_size', 'query_cache_size'); $aMySQLStatuses = array('Key_read_requests', 'Key_reads'); if (extension_loaded('suhosin')) { $aPHPSettings[] = 'suhosin.post.max_vars'; $aPHPSettings[] = 'suhosin.get.max_value_length'; } $aMySQLVars = array(); foreach (CMDBSource::QueryToArray('SHOW VARIABLES') as $aRow) { $aMySQLVars[$aRow['Variable_name']] = $aRow['Value']; } $aMySQLStats = array(); foreach (CMDBSource::QueryToArray('SHOW GLOBAL STATUS') as $aRow) { $aMySQLStats[$aRow['Variable_name']] = $aRow['Value'];
/** * Helper to create a ZIP out of a data file and the configuration file */ protected function DoZip($aFiles, $sZipArchiveFile) { foreach ($aFiles as $aFile) { $sFile = $aFile['source']; if (!is_file($sFile) && !is_dir($sFile)) { throw new BackupException("File '{$sFile}' does not exist or could not be read"); } } // Make sure the target path exists $sZipDir = dirname($sZipArchiveFile); SetupUtils::builddir($sZipDir); $oZip = new ZipArchiveEx(); $res = $oZip->open($sZipArchiveFile, ZipArchive::CREATE | ZipArchive::OVERWRITE); if ($res === TRUE) { foreach ($aFiles as $aFile) { if (is_dir($aFile['source'])) { $oZip->addDir($aFile['source'], $aFile['dest']); } else { $oZip->addFile($aFile['source'], $aFile['dest']); } } if ($oZip->close()) { $this->LogInfo("Archive: {$sZipArchiveFile} created"); } else { $this->LogError("Failed to save zip archive: {$sZipArchiveFile}"); throw new BackupException("Failed to save zip archive: {$sZipArchiveFile}"); } } else { $this->LogError("Failed to create zip archive: {$sZipArchiveFile}."); throw new BackupException("Failed to create zip archive: {$sZipArchiveFile}."); } }
protected function CompileModuleDesigns($sTempTargetDir, $sFinalTargetDir) { SetupUtils::builddir($sTempTargetDir . '/core/module_designs'); $oDesigns = $this->oFactory->GetNodes('/itop_design/module_designs/module_design'); foreach ($oDesigns as $oDesign) { $oDoc = new ModuleDesign(); $oClone = $oDoc->importNode($oDesign->cloneNode(true), true); $oDoc->appendChild($oClone); $oDoc->save($sTempTargetDir . '/core/module_designs/' . $oDesign->getAttribute('id') . '.xml'); } }
public static function GetLanguageSelect($sSourceDir, $sInputName, $sDefaultLanguageCode) { $sHtml = '<select id="' . $sInputName . '" name="' . $sInputName . '">'; $sSourceDir = APPROOT . 'dictionaries/'; $aLanguages = SetupUtils::GetAvailableLanguages($sSourceDir); foreach ($aLanguages as $sCode => $aInfo) { $sSelected = $sCode == $sDefaultLanguageCode ? ' selected ' : ''; $sHtml .= '<option value="' . $sCode . '"' . $sSelected . '>' . htmlentities($aInfo['description'], ENT_QUOTES, 'UTF-8') . ' (' . htmlentities($aInfo['localized_description'], ENT_QUOTES, 'UTF-8') . ')</option>'; } $sHtml .= '</select></td></tr>'; return $sHtml; }
public function RestoreFromZip($sZipFile, $sEnvironment = 'production') { $this->LogInfo("Starting restore of " . basename($sZipFile)); $oZip = new ZipArchiveEx(); $res = $oZip->open($sZipFile); // Load the database // $sDataDir = tempnam(SetupUtils::GetTmpDir(), 'itop-'); unlink($sDataDir); // I need a directory, not a file... SetupUtils::builddir($sDataDir); // Here is the directory $oZip->extractTo($sDataDir, 'itop-dump.sql'); $sDataFile = $sDataDir . '/itop-dump.sql'; $this->LoadDatabase($sDataFile); unlink($sDataFile); // Update the code // $sDeltaFile = APPROOT . 'data/' . $sEnvironment . '.delta.xml'; if ($oZip->locateName('delta.xml') !== false) { // Extract and rename delta.xml => <env>.delta.xml; file_put_contents($sDeltaFile, $oZip->getFromName('delta.xml')); } else { @unlink($sDeltaFile); } if (is_dir(APPROOT . 'data/production-modules/')) { SetupUtils::rrmdir(APPROOT . 'data/production-modules/'); } if ($oZip->locateName('production-modules/') !== false) { $oZip->extractDirTo(APPROOT . 'data/', 'production-modules/'); } $sConfigFile = APPROOT . 'conf/' . $sEnvironment . '/config-itop.php'; @chmod($sConfigFile, 0770); // Allow overwriting the file $oZip->extractTo(APPROOT . 'conf/' . $sEnvironment, 'config-itop.php'); @chmod($sConfigFile, 0444); // Read-only $oEnvironment = new RunTimeEnvironment($sEnvironment); $oEnvironment->CompileFrom($sEnvironment); }
public function Process($iUnixTimeLimit) { $oMutex = new iTopMutex('backup.' . utils::GetCurrentEnvironment()); $oMutex->Lock(); try { // Make sure the target directory exists SetupUtils::builddir($this->sBackupDir); $oBackup = new DBBackupScheduled(); // Eliminate files exceeding the retention setting // if ($this->iRetentionCount > 0) { $aFiles = $oBackup->ListFiles($this->sBackupDir); while (count($aFiles) >= $this->iRetentionCount) { $sFileToDelete = array_shift($aFiles); unlink($sFileToDelete); if (file_exists($sFileToDelete)) { // Ok, do not loop indefinitely on this break; } } } // Do execute the backup // $oBackup->SetMySQLBinDir(MetaModel::GetConfig()->GetModuleSetting('itop-backup', 'mysql_bindir', '')); $sBackupFile = MetaModel::GetConfig()->GetModuleSetting('itop-backup', 'file_name_format', '__DB__-%Y-%m-%d_%H_%M'); $sName = $oBackup->MakeName($sBackupFile); if ($sName == '') { $sName = $oBackup->MakeName(BACKUP_DEFAULT_FORMAT); } $sZipFile = $this->sBackupDir . $sName . '.zip'; $sSourceConfigFile = APPCONF . utils::GetCurrentEnvironment() . '/' . ITOP_CONFIG_FILE; $oBackup->CreateZip($sZipFile, $sSourceConfigFile); } catch (Exception $e) { $oMutex->Unlock(); throw $e; } $oMutex->Unlock(); return "Created the backup: {$sZipFile}"; }
protected function CompileBranding($oBrandingNode, $sTempTargetDir, $sFinalTargetDir) { if ($oBrandingNode) { // Transform file refs into files in the images folder SetupUtils::builddir($sTempTargetDir . '/branding'); $this->CompileFiles($oBrandingNode, $sTempTargetDir . '/branding', $sFinalTargetDir . '/branding', 'branding'); $this->CompileLogo($oBrandingNode, $sTempTargetDir, $sFinalTargetDir, 'main_logo', 'main-logo'); $this->CompileLogo($oBrandingNode, $sTempTargetDir, $sFinalTargetDir, 'login_logo', 'login-logo'); $this->CompileLogo($oBrandingNode, $sTempTargetDir, $sFinalTargetDir, 'portal_logo', 'portal-logo'); // Cleanup the images directory (eventually made by CompileFiles) if (file_exists($sTempTargetDir . '/branding/images')) { SetupUtils::rrmdir($sTempTargetDir . '/branding/images'); } } }
public function Display(WebPage $oPage) { // Check if there are some manual steps required: $aManualSteps = array(); $aAvailableModules = SetupUtils::AnalyzeInstallation($this->oWizard); $sRootUrl = utils::GetAbsoluteUrlAppRoot(); $aSelectedModules = json_decode($this->oWizard->GetParameter('selected_modules'), true); foreach ($aSelectedModules as $sModuleId) { if (!empty($aAvailableModules[$sModuleId]['doc.manual_setup'])) { $aManualSteps[$aAvailableModules[$sModuleId]['label']] = $sRootUrl . $aAvailableModules[$sModuleId]['doc.manual_setup']; } } if (count($aManualSteps) > 0) { $oPage->add("<h2>Manual operations required</h2>"); $oPage->p("In order to complete the installation, the following manual operations are required:"); foreach ($aManualSteps as $sModuleLabel => $sUrl) { $oPage->p("<a href=\"{$sUrl}\" target=\"_blank\">Manual instructions for {$sModuleLabel}</a>"); } $oPage->add("<h2>Congratulations for installing " . ITOP_APPLICATION . "</h2>"); } else { $oPage->add("<h2>Congratulations for installing " . ITOP_APPLICATION . "</h2>"); $oPage->ok("The installation completed successfully."); } if ($this->oWizard->GetParameter('mode', '') == 'upgrade' && $this->oWizard->GetParameter('db_backup', false)) { $sBackupDestination = $this->oWizard->GetParameter('db_backup_path', ''); if (file_exists($sBackupDestination)) { // To mitigate security risks: pass only the filename without the extension, the download will add the extension itself $sTruncatedFilePath = preg_replace('/\\.zip$/', '', $sBackupDestination); $oPage->p('Your backup is ready'); $oPage->p('<a style="background:transparent;" href="' . utils::GetAbsoluteUrlAppRoot() . 'setup/ajax.dataloader.php?operation=async_action&step_class=WizStepDone¶ms[backup]=' . urlencode($sTruncatedFilePath) . '" target="_blank"><img src="../images/tar.png" style="border:0;vertical-align:middle;"> Download ' . basename($sBackupDestination) . '</a>'); } else { $oPage->p('<img src="../images/error.png"/> Warning: Backup creation failed !'); } } // Form goes here.. No back button since the job is done ! $oPage->add('<table style="width:600px;border:0;padding:0;"><tr>'); $oPage->add("<td><a style=\"background:transparent;padding:0;\" title=\"Free: Register your iTop version.\" href=\"http://www.combodo.com/register?product=iTop&version=" . urlencode(ITOP_VERSION . " revision " . ITOP_REVISION) . "\" target=\"_blank\"><img style=\"border:0\" src=\"../images/setup-register.gif\"/></td></a>"); $oPage->add("<td><a style=\"background:transparent;padding:0;\" title=\"Get Professional Support from Combodo\" href=\"http://www.combodo.com/itopsupport\" target=\"_blank\"><img style=\"border:0\" src=\"../images/setup-support.gif\"/></td></a>"); $oPage->add("<td><a style=\"background:transparent;padding:0;\" title=\"Get Professional Training from Combodo\" href=\"http://www.combodo.com/itoptraining\" target=\"_blank\"><img style=\"border:0\" src=\"../images/setup-training.gif\"/></td></a>"); $oPage->add('</tr></table>'); $sForm = '<form method="post" action="' . $this->oWizard->GetParameter('application_url') . 'pages/UI.php">'; $sForm .= '<input type="hidden" name="auth_user" value="' . htmlentities($this->oWizard->GetParameter('admin_user'), ENT_QUOTES, 'UTF-8') . '">'; $sForm .= '<input type="hidden" name="auth_pwd" value="' . htmlentities($this->oWizard->GetParameter('admin_pwd'), ENT_QUOTES, 'UTF-8') . '">'; $sForm .= "<p style=\"text-align:center;width:100%\"><button id=\"enter_itop\" type=\"submit\">Enter " . ITOP_APPLICATION . "</button></p>"; $sForm .= '</form>'; $sPHPVersion = phpversion(); $sMySQLVersion = SetupUtils::GetMySQLVersion($this->oWizard->GetParameter('db_server'), $this->oWizard->GetParameter('db_user'), $this->oWizard->GetParameter('db_pwd')); $oPage->add('<img style="border:0" src="http://www.combodo.com/stats/?p=' . urlencode(ITOP_APPLICATION) . '&v=' . urlencode(ITOP_VERSION) . '&php=' . urlencode($sPHPVersion) . '&mysql=' . urlencode($sMySQLVersion) . '&os=' . urlencode(PHP_OS) . '"/>'); $sForm = addslashes($sForm); $oPage->add_ready_script("\$('#wiz_form').after('{$sForm}');"); }
$oP->p(Dict::S('bkp-status-backups-none')); } $oP->add("</fieldset>"); // 2nd table: list the backups made manually // $aDetails = array(); foreach ($oBackup->ListFiles($sBackupDirManual) as $sBackupFile) { $sFileName = basename($sBackupFile); $sFilePath = 'manual/' . $sFileName; if (MetaModel::GetConfig()->Get('demo_mode')) { $sName = $sFileName; } else { $sAjax = utils::GetAbsoluteUrlModulePage('itop-backup', 'ajax.backup.php', array('operation' => 'download', 'file' => $sFilePath)); $sName = "<a href=\"{$sAjax}\">" . $sFileName . '</a>'; } $sSize = SetupUtils::HumanReadableSize(filesize($sBackupFile)); $sConfirmRestore = addslashes(Dict::Format('bkp-confirm-restore', $sFileName)); $sFileEscaped = addslashes($sFilePath); $sRestoreBtn = '<button class="restore" onclick="LaunchRestoreNow(\'' . $sFileEscaped . '\', \'' . $sConfirmRestore . '\');" ' . $sDisableRestore . '>' . Dict::S('bkp-button-restore-now') . '</button>'; $aDetails[] = array('file' => $sName, 'size' => $sSize, 'actions' => $sRestoreBtn); } $aConfig = array('file' => array('label' => Dict::S('bkp-table-file'), 'description' => Dict::S('bkp-table-file+')), 'size' => array('label' => Dict::S('bkp-table-size'), 'description' => Dict::S('bkp-table-size+')), 'actions' => array('label' => Dict::S('bkp-table-actions'), 'description' => Dict::S('bkp-table-actions+'))); $oP->add("<fieldset>"); $oP->add("<legend>" . Dict::S('bkp-status-backups-manual') . "</legend>"); if (count($aDetails) > 0) { $oP->add('<div style="max-height:400px; overflow: auto;">'); $oP->table($aConfig, array_reverse($aDetails)); $oP->add('</div>'); } else { $oP->p(Dict::S('bkp-status-backups-none')); }
} } else { require_once APPROOT . 'application/loginwebpage.class.inc.php'; LoginWebPage::DoLogin(); // Check user rights and prompt if needed $bDownloadBackup = utils::ReadParam('download', false); } if (!UserRights::IsAdministrator()) { ExitError($oP, "Access restricted to administors"); } if (CheckParam('?') || CheckParam('h') || CheckParam('help')) { Usage($oP); $oP->output(); exit; } $sDefaultBackupFileName = SetupUtils::GetTmpDir() . '/' . "__DB__-%Y-%m-%d"; $sBackupFile = utils::ReadParam('backup_file', $sDefaultBackupFileName, true, 'raw_data'); // Interpret strftime specifications (like %Y) and database placeholders $oBackup = new MyDBBackup($oP); $oBackup->SetMySQLBinDir(MetaModel::GetConfig()->GetModuleSetting('itop-backup', 'mysql_bindir', '')); $sBackupFile = $oBackup->MakeName($sBackupFile); $sZipArchiveFile = $sBackupFile . '.zip'; $bSimulate = utils::ReadParam('simulate', false, true); $res = false; if ($bSimulate) { $oP->p("Simulate: would create file '{$sZipArchiveFile}'"); } elseif (MetaModel::GetConfig()->Get('demo_mode')) { $oP->p("Sorry, iTop is in demonstration mode: the feature is disabled"); } else { $oBackup->CreateZip($sZipArchiveFile); }
protected static function DoCompile($aSelectedModules, $sSourceDir, $sExtensionDir, $sTargetDir, $sEnvironment, $bUseSymbolicLinks = false) { SetupPage::log_info("Compiling data model."); require_once APPROOT . 'setup/modulediscovery.class.inc.php'; require_once APPROOT . 'setup/modelfactory.class.inc.php'; require_once APPROOT . 'setup/compiler.class.inc.php'; if (empty($sSourceDir) || empty($sTargetDir)) { throw new Exception("missing parameter source_dir and/or target_dir"); } $sSourcePath = APPROOT . $sSourceDir; $aDirsToScan = array($sSourcePath); $sExtensionsPath = APPROOT . $sExtensionDir; if (is_dir($sExtensionsPath)) { // if the extensions dir exists, scan it for additional modules as well $aDirsToScan[] = $sExtensionsPath; } $sExtraPath = APPROOT . '/data/' . $sEnvironment . '-modules/'; if (is_dir($sExtraPath)) { // if the extra dir exists, scan it for additional modules as well $aDirsToScan[] = $sExtraPath; } $sTargetPath = APPROOT . $sTargetDir; if (!is_dir($sSourcePath)) { throw new Exception("Failed to find the source directory '{$sSourcePath}', please check the rights of the web server"); } if (!is_dir($sTargetPath)) { if (!mkdir($sTargetPath)) { throw new Exception("Failed to create directory '{$sTargetPath}', please check the rights of the web server"); } else { // adjust the rights if and only if the directory was just created // owner:rwx user/group:rx chmod($sTargetPath, 0755); } } else { if (substr($sTargetPath, 0, strlen(APPROOT)) == APPROOT) { // If the directory is under the root folder - as expected - let's clean-it before compiling SetupUtils::tidydir($sTargetPath); } } $oFactory = new ModelFactory($aDirsToScan); $sDeltaFile = APPROOT . 'core/datamodel.core.xml'; if (file_exists($sDeltaFile)) { $oCoreModule = new MFCoreModule('core', 'Core Module', $sDeltaFile); $oFactory->LoadModule($oCoreModule); } $sDeltaFile = APPROOT . 'application/datamodel.application.xml'; if (file_exists($sDeltaFile)) { $oApplicationModule = new MFCoreModule('application', 'Application Module', $sDeltaFile); $oFactory->LoadModule($oApplicationModule); } $aModules = $oFactory->FindModules(); foreach ($aModules as $foo => $oModule) { $sModule = $oModule->GetName(); if (in_array($sModule, $aSelectedModules)) { $oFactory->LoadModule($oModule); } } $sDeltaFile = APPROOT . 'data/' . $sEnvironment . '.delta.xml'; if (file_exists($sDeltaFile)) { $oDelta = new MFDeltaModule($sDeltaFile); $oFactory->LoadModule($oDelta); } //$oFactory->Dump(); if ($oFactory->HasLoadErrors()) { foreach ($oFactory->GetLoadErrors() as $sModuleId => $aErrors) { SetupPage::log_error("Data model source file (xml) could not be loaded - found errors in module: {$sModuleId}"); foreach ($aErrors as $oXmlError) { SetupPage::log_error("Load error: File: " . $oXmlError->file . " Line:" . $oXmlError->line . " Message:" . $oXmlError->message); } } throw new Exception("The data model could not be compiled. Please check the setup error log"); } else { $oMFCompiler = new MFCompiler($oFactory); $oMFCompiler->Compile($sTargetPath, null, $bUseSymbolicLinks); //$aCompilerLog = $oMFCompiler->GetLog(); //SetupPage::log_info(implode("\n", $aCompilerLog)); SetupPage::log_info("Data model successfully compiled to '{$sTargetPath}'."); } // Special case to patch a ugly patch in itop-config-mgmt $sFileToPatch = $sTargetPath . '/itop-config-mgmt-1.0.0/model.itop-config-mgmt.php'; if (file_exists($sFileToPatch)) { $sContent = file_get_contents($sFileToPatch); $sContent = str_replace("require_once(APPROOT.'modules/itop-welcome-itil/model.itop-welcome-itil.php');", "//\n// The line below is no longer needed in iTop 2.0 -- patched by the setup program\n// require_once(APPROOT.'modules/itop-welcome-itil/model.itop-welcome-itil.php');", $sContent); file_put_contents($sFileToPatch, $sContent); } }