:: Version 2.7.0 ::

Automated installation

The installation of iTop is generally performed interactively using the “setup” page. However once information about the desired configuration has been collected by the setup page, the actual installation process is fully unattended and therefore can be automated.

In order to automate the iTop installation you'll need:

  • An XML response file containing the desired configuration options
  • The unattened_install.php script (see below)

Response file

The response file is an XML file containing all the answers / choices to configure the application.

An example of the response file is the following:

default-params.xml
<?xml version="1.0" encoding="UTF-8"?>
<installation>
        <mode>install</mode>
        <preinstall>
                <copies type="array">
                        <copy>
                                <source>C:\inetpub\wwwroot\setup20\datamodel</source>
                                <destination>test_copy</destination>
                        </copy>
                </copies>
                <backup>
                        <configuration_file>../conf/production/config-itop.php</configuration_file>
                        <destination>../backups/__DB__-%Y-%m-%d.zip</destination>
                </backup>
        </preinstall>
        <source_dir>datamodel</source_dir>
        <source_env>production</source_env>
        <target_env>production</target_env>
        <workspace_dir/>
        <database>
                <server>localhost</server>
                <user>root</user>
                <pwd>root</pwd>
                <name>setup20</name>
                <prefix></prefix>
        </database>
        <url>http://localhost/setup20/</url>
        <admin_account>
                <user>admin</user>
                <pwd>admin</pwd>
                <language>FR FR</language>
        </admin_account>
        <language>IT IT</language>
        <selected_modules type="array">
                <module>authent-local</module>
                <module>itop-attachments</module>
                <module>itop-welcome-itil</module>
                <module>itop-profiles-itil</module>
                <module>itop-config-mgmt</module>
                <module>itop-service-mgmt</module>
                <module>itop-tickets</module>
        </selected_modules>
        <sample_data>1</sample_data>
        <options>
                <symlinks>1</symlinks>
                <mysql_bin_dir></mysql_bin_dir>
        </options>
</installation>

Generating the reponse file

The response file can be created manually using a text editor or generated by running the interactive setup with the additional parameter option[generate_config]=1.

This is achieved by adding ?option[generate_config]=1 at the end of the URL to specify this extra parameter. This gives the following sample URL:

http://localhost/itop/setup/?option[generate_config]=1

Then run the setup as usual, but instead of launching the installation, stop at the “summary” step, and click on “XML config file” to open this section of the summary. You can then copy/paste the response file:

Generating the response file

Another way to get a response file is to retrieve the installation.xml file from an existing iTop installation. Each time the iTop installation completes, it creates a file install-<date>-<revision>.xml in the log directory of an existing iTop installation. You can use this file for automatically installing another instance of iTop with the exact same parameters.

Unattended installation script

The following PHP script can be used to automated the installation of iTop:

unattended_install.php
<?php
<?php
require_once('../approot.inc.php');
require_once(APPROOT.'/application/utils.inc.php');
require_once(APPROOT.'/application/clipage.class.inc.php');
require_once(APPROOT.'/core/config.class.inc.php');
require_once(APPROOT.'/core/log.class.inc.php');
require_once(APPROOT.'/core/kpi.class.inc.php');
require_once(APPROOT.'/core/cmdbsource.class.inc.php');
require_once(APPROOT.'/setup/setuppage.class.inc.php');
require_once(APPROOT.'/setup/wizardcontroller.class.inc.php');
require_once(APPROOT.'/setup/wizardsteps.class.inc.php');
require_once(APPROOT.'/setup/applicationinstaller.class.inc.php');                       
 
 
 
/////////////////////////////////////////////////
$sParamFile = utils::ReadParam('response_file', 'default-params.xml', true /* CLI allowed */, 'raw_data');
$bCheckConsistency = (utils::ReadParam('check_consistency', '0', true /* CLI allowed */) == '1');
 
$oParams = new XMLParameters($sParamFile);
$sMode = $oParams->Get('mode');
 
if ($sMode == 'install')
{
        echo "Installation mode detected.\n";
        $bClean = utils::ReadParam('clean', false, true /* CLI allowed */);
        if ($bClean)
        {
                echo "Cleanup mode detected.\n";
                $sTargetEnvironment = $oParams->Get('target_env', '');
                if ($sTargetEnvironment == '')
                {
                        $sTargetEnvironment = 'production';
                }
                $sTargetDir = APPROOT.'env-'.$sTargetEnvironment;
 
                // Configuration file
                $sConfigFile = APPCONF.$sTargetEnvironment.'/'.ITOP_CONFIG_FILE;
                if (file_exists($sConfigFile))
                {
                        echo "Trying to delete the configuration file: '$sConfigFile'.\n";
                        @chmod($sConfigFile, 0770); // RWX for owner and group, nothing for others
                        unlink($sConfigFile);
                }
                else
                {
                        echo "No config file to delete ($sConfigFile does not exist).\n";
                }
 
                // env-xxx directory
                if (file_exists($sTargetDir))
                {
                        if (is_dir($sTargetDir))
                        {
                                echo "Emptying the target directory '$sTargetDir'.\n";
                                SetupUtils::tidydir($sTargetDir);
                        }
                        else
                        {
                                die("ERROR the target dir '$sTargetDir' exists, but is NOT a directory !!!\nExiting.\n");
                        }
                }
                else
                {
                        echo "No target directory to delete ($sTargetDir does not exist).\n";
                }
 
                // Database
                $aDBSettings = $oParams->Get('database', array());
                $sDBServer = $aDBSettings['server'];
                $sDBUser = $aDBSettings['user'];
                $sDBPwd = $aDBSettings['pwd'];
                $sDBName = $aDBSettings['name'];
                $sDBPrefix = $aDBSettings['prefix'];
 
                if ($sDBPrefix != '')
                {
                        die("Cleanup not implemented for a partial database (prefix= '$sDBPrefix')\nExiting.");
                }
 
                $oMysqli = new mysqli($sDBServer, $sDBUser, $sDBPwd);
                if ($oMysqli->connect_errno)
                {
                    die("Cannot connect to the MySQL server (".$mysqli->connect_errno . ") ".$mysqli->connect_error."\nExiting");
                }
                else
                {
                        if ($oMysqli->select_db($sDBName))
                        {
                                echo "Deleting database '$sDBName'\n";
                                $oMysqli->query("DROP DATABASE `$sDBName`");
                        }
                        else
                        {
                                echo "The database '$sDBName' does not seem to exist. Nothing to cleanup.\n";
                        }
                }
        }
}
else 
{
        $aDBSettings = $oParams->Get('database', array());
        $sDBServer = $aDBSettings['server'];
        $sDBUser = $aDBSettings['user'];
        $sDBPwd = $aDBSettings['pwd'];
        $sDBName = $aDBSettings['name'];
        $sDBPrefix = $aDBSettings['prefix'];
 
        $sTargetEnvironment = $oParams->Get('target_env', '');
        if ($sTargetEnvironment == '')
        {
                $sTargetEnvironment = 'production';
        }
        $sTargetDir = APPROOT.'env-'.$sTargetEnvironment;
}
 
$bHasErrors = false;
$aChecks = SetupUtils::CheckBackupPrerequisites(APPROOT.'data'); // mmm should be the backup destination dir
 
$aSelectedModules = $oParams->Get('selected_modules');
$sSourceDir = $oParams->Get('source_dir', 'datamodels/latest');
$sExtensionDir = $oParams->Get('extensions_dir', 'extensions');
$aChecks = array_merge($aChecks, SetupUtils::CheckSelectedModules($sSourceDir, $sExtensionDir, $aSelectedModules));
 
 
foreach($aChecks as $oCheckResult)
{
        switch($oCheckResult->iSeverity)
        {
        case CheckResult::ERROR:
                $bHasErrors = true;
                $sHeader = "Error";
                break;
 
        case CheckResult::WARNING:
                $sHeader = "Warning";
                break;
 
        case CheckResult::INFO:
        default:
                $sHeader = "Info";
                break;
        }
        echo $sHeader.": ".$oCheckResult->sLabel;
        if (strlen($oCheckResult->sDescription))
        {
                echo ' - '.$oCheckResult->sDescription;
        }
        echo "\n";
}
 
if ($bHasErrors)
{
        echo "Encountered stopper issues. Aborting...\n";
        die;
}
 
$bFoundIssues = false;
 
$bInstall = utils::ReadParam('install', true, true /* CLI allowed */);
if ($bInstall)
{
        echo "Starting the unattended installation...\n";
        $oWizard = new ApplicationInstaller($oParams);
        $bRes = $oWizard->ExecuteAllSteps();
        if (!$bRes)
        {
                echo "\nencountered installation issues!"; 
                $bFoundIssues = true;
        }
        else
        {
                $oMysqli = new mysqli($sDBServer, $sDBUser, $sDBPwd);
                if (!$oMysqli->connect_errno)
                {
                        if ($oMysqli->select_db($sDBName))
                        {
                                // Check the presence of a table to record information about the MTP (from the Designer)
                                $sDesignerUpdatesTable = $sDBPrefix.'priv_designer_update';
                                $sSQL = "SELECT id FROM `$sDesignerUpdatesTable`";
                                if ($oMysqli->query($sSQL) !== false)
                                {
                                        // Record the Designer Udpates in the priv_designer_update table
                                        $sDeltaFile = APPROOT.'data/'.$sTargetEnvironment.'.delta.xml';
                                        if (is_readable($sDeltaFile))
                                        {
                                                // Retrieve the revision
                                                $oDoc = new DOMDocument();
                                                $oDoc->load($sDeltaFile);
                                                $iRevision = 0;
                                                $iRevision = $oDoc->firstChild->getAttribute('revision_id');
                                                if ($iRevision > 0) // Safety net, just in case...
                                                {
                                                        $sDate = date('Y-m-d H:i:s');
                                                        $sSQL = "INSERT INTO `$sDesignerUpdatesTable` (revision_id, compilation_date, comment) VALUES ($iRevision, '$sDate', 'Deployed using unattended.php.')";
                                                        if ($oMysqli->query($sSQL) !== false)
                                                        {
                                                                echo "\nDesigner update (MTP at revision $iRevision) successfully recorded.\n";
                                                        }
                                                        else
                                                        {
                                                                echo "\nFailed to record designer updates(".$oMysqli->error.").\n";
                                                        }
                                                }
                                                else
                                                {
                                                        echo "\nFailed to read the revision from $sDeltaFile file. No designer update information will be recorded.\n";
 
                                                }
                                        }
                                        else
                                        {
                                                echo "\nNo $sDeltaFile file (or the file is not accessible). No designer update information to record.\n";
                                        }
                                }
                        }
                } 
        }
}
else
{
        echo "No installation requested.\n";
}
if (!$bFoundIssues && $bCheckConsistency)
{
        echo "Checking data model consistency.\n";
        ob_start();
        $sCheckRes = '';
        try
        {
                MetaModel::CheckDefinitions(false);
                $sCheckRes = ob_get_clean();
        }
        catch(Exception $e)
        {
                $sCheckRes = ob_get_clean()."\nException: ".$e->getMessage();
        }
        if (strlen($sCheckRes) > 0)
        {
                echo $sCheckRes;
                echo "\nfound consistency issues!"; 
                $bFoundIssues = true;
        }
}
 
if (!$bFoundIssues)
{
        // last line: used to check the install
        // the only way to track issues in case of Fatal error or even parsing error!
        echo "\ninstalled!"; 
        exit;
}

Execution of the unattended installation

Copy the unattended_install.php script in a toolkit directory at the root of iTop files. Then launch the script with the following command:

php unattended_install.php default-params.xml

Where:

  • default-params.xml is the reponse file containing your desired settings for the installation
Since the installation runs from the command line, make sure that the current user has enough rights to access the different locations and that the web server will be able to access the files and directories created during the scripted installation. In order to exactly emulate the behavior of the interactive installation it may be a good practice to run this installation from the user account used for running the web server process.
2_7_0/advancedtopics/automatic_install.txt · Last modified: 2020/04/15 15:23 (external edit)
Back to top
Contact us