mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-12 23:14:18 +01:00
N°8760: code legacy refactoring around module computation (AnalyzeInstallation)
AnalyzeInstallation refactoring fix ci call to ModuleInstallationService ci: fix code style get rid of itop_version refactoring: make code simpler get rid of unused name_db refactoring setup: rename version_db by installed_version refactoring setup: rename version_code by available_version code cleanup: avoid useless runtimeenv instanciation
This commit is contained in:
130
setup/AnalyzeInstallation.php
Normal file
130
setup/AnalyzeInstallation.php
Normal file
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__.'/ModuleInstallationService.php';
|
||||
|
||||
class AnalyzeInstallation
|
||||
{
|
||||
private static AnalyzeInstallation $oInstance;
|
||||
private ?array $aAvailableModules = null;
|
||||
private ?array $aSelectInstall = null;
|
||||
|
||||
protected function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
final public static function GetInstance(): AnalyzeInstallation
|
||||
{
|
||||
if (!isset(self::$oInstance)) {
|
||||
self::$oInstance = new AnalyzeInstallation();
|
||||
}
|
||||
|
||||
return self::$oInstance;
|
||||
}
|
||||
|
||||
final public static function SetInstance(?AnalyzeInstallation $oInstance): void
|
||||
{
|
||||
static::$oInstance = $oInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyzes the current installation and the possibilities
|
||||
*
|
||||
* @param null|Config $oConfig Defines the target environment (DB)
|
||||
* @param mixed $modulesPath Either a single string or an array of absolute paths
|
||||
* @param bool $bAbortOnMissingDependency ...
|
||||
* @param array $aModulesToLoad List of modules to search for, defaults to all if omitted
|
||||
*
|
||||
* @return array Array with the following format:
|
||||
* array =>
|
||||
* 'iTop' => array(
|
||||
* 'installed_version' => ... (could be empty in case of a fresh install)
|
||||
* 'available_version => ...
|
||||
* )
|
||||
* <module_name> => array(
|
||||
* 'installed_version' => ...
|
||||
* 'available_version' => ...
|
||||
* 'install' => array(
|
||||
* 'flag' => SETUP_NEVER | SETUP_OPTIONAL | SETUP_MANDATORY
|
||||
* 'message' => ...
|
||||
* )
|
||||
* 'uninstall' => array(
|
||||
* 'flag' => SETUP_NEVER | SETUP_OPTIONAL | SETUP_MANDATORY
|
||||
* 'message' => ...
|
||||
* )
|
||||
* 'label' => ...
|
||||
* 'dependencies' => array(<module1>, <module2>, ...)
|
||||
* 'visible' => true | false
|
||||
* )
|
||||
* )
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function AnalyzeInstallation(?Config $oConfig, mixed $modulesPath, bool $bAbortOnMissingDependency = false, ?array $aModulesToLoad = null)
|
||||
{
|
||||
$aRes = [
|
||||
ROOT_MODULE => [
|
||||
'installed_version' => '',
|
||||
'available_version' => ITOP_VERSION_FULL,
|
||||
'name_code' => ITOP_APPLICATION,
|
||||
],
|
||||
];
|
||||
|
||||
$aDirs = is_array($modulesPath) ? $modulesPath : [$modulesPath];
|
||||
if (! is_null($this->aAvailableModules)) {
|
||||
//test only
|
||||
$aAvailableModules = $this->aAvailableModules;
|
||||
} else {
|
||||
$aAvailableModules = ModuleDiscovery::GetAvailableModules($aDirs, $bAbortOnMissingDependency, $aModulesToLoad);
|
||||
}
|
||||
|
||||
foreach ($aAvailableModules as $sModuleId => $aModuleInfo) {
|
||||
list($sModuleName, $sModuleVersion) = ModuleDiscovery::GetModuleName($sModuleId);
|
||||
|
||||
$aModuleInfo['installed_version'] = '';
|
||||
$aModuleInfo['available_version'] = $sModuleVersion;
|
||||
|
||||
if ($aModuleInfo['mandatory']) {
|
||||
$aModuleInfo['install'] = [
|
||||
'flag' => MODULE_ACTION_MANDATORY,
|
||||
'message' => 'the module is part of the application',
|
||||
];
|
||||
} else {
|
||||
$aModuleInfo['install'] = [
|
||||
'flag' => MODULE_ACTION_OPTIONAL,
|
||||
'message' => '',
|
||||
];
|
||||
}
|
||||
$aRes[$sModuleName] = $aModuleInfo;
|
||||
}
|
||||
|
||||
$aCurrentlyInstalledModules = ModuleInstallationService::GetInstance()->ReadFromDB($oConfig);
|
||||
|
||||
// Adjust the list of proposed modules
|
||||
foreach ($aCurrentlyInstalledModules as $sModuleName => $aModuleDB) {
|
||||
if ($sModuleName == ROOT_MODULE) {
|
||||
$aRes[$sModuleName]['installed_version'] = $aModuleDB['version'];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!array_key_exists($sModuleName, $aRes)) {
|
||||
// A module was installed, it is not proposed in the new build... skip
|
||||
continue;
|
||||
}
|
||||
|
||||
$aRes[$sModuleName]['installed_version'] = $aModuleDB['version'];
|
||||
|
||||
if ($aRes[$sModuleName]['mandatory']) {
|
||||
$aRes[$sModuleName]['uninstall'] = [
|
||||
'flag' => MODULE_ACTION_IMPOSSIBLE,
|
||||
'message' => 'the module is part of the application',
|
||||
];
|
||||
} else {
|
||||
$aRes[$sModuleName]['uninstall'] = [
|
||||
'flag' => MODULE_ACTION_OPTIONAL,
|
||||
'message' => '',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $aRes;
|
||||
}
|
||||
}
|
||||
159
setup/ModuleInstallationService.php
Normal file
159
setup/ModuleInstallationService.php
Normal file
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
class ModuleInstallationService
|
||||
{
|
||||
private static ModuleInstallationService $oInstance;
|
||||
|
||||
protected function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
final public static function GetInstance(): ModuleInstallationService
|
||||
{
|
||||
if (!isset(self::$oInstance)) {
|
||||
self::$oInstance = new ModuleInstallationService();
|
||||
}
|
||||
|
||||
return self::$oInstance;
|
||||
}
|
||||
|
||||
final public static function SetInstance(?ModuleInstallationService $oInstance): void
|
||||
{
|
||||
static::$oInstance = $oInstance;
|
||||
}
|
||||
|
||||
private ?array $aSelectInstall = null;
|
||||
public function ReadFromDB(?Config $oConfig): array
|
||||
{
|
||||
try {
|
||||
$aSelectInstall = [];
|
||||
if (! is_null($oConfig)) {
|
||||
if (! is_null($this->aSelectInstall)) {
|
||||
//test only
|
||||
$aSelectInstall = $this->aSelectInstall;
|
||||
} else {
|
||||
CMDBSource::InitFromConfig($oConfig);
|
||||
|
||||
//read db module installations
|
||||
$aSelectInstallOld = CMDBSource::QueryToArray("SELECT * FROM ".$oConfig->Get('db_subname')."priv_module_install");
|
||||
//file_put_contents(APPROOT."/tests/php-unit-tests/unitary-tests/setup/ressources/priv_modules.json", json_encode($aSelectInstallOld, JSON_PRETTY_PRINT));
|
||||
|
||||
$iRootId = CMDBSource::QueryToScalar("SELECT max(parent_id) FROM ".$oConfig->Get('db_subname')."priv_module_install");
|
||||
$sDbSubName = $oConfig->Get('db_subname');
|
||||
// Get the latest installed modules, without the "root" ones (iTop version and datamodel version)
|
||||
$sSQL = <<<SQL
|
||||
SELECT * FROM $sDbSubName.priv_module_install
|
||||
WHERE
|
||||
parent_id='$iRootId'
|
||||
OR id='$iRootId'
|
||||
SQL;
|
||||
$aSelectInstall = CMDBSource::QueryToArray($sSQL);
|
||||
//file_put_contents(APPROOT."/tests/php-unit-tests/unitary-tests/setup/ressources/priv_modules2.json", json_encode($aSelectInstall, JSON_PRETTY_PRINT));
|
||||
}
|
||||
}
|
||||
} catch (MySQLException $e) {
|
||||
// No database or erroneous information
|
||||
}
|
||||
|
||||
return $this->ComputeInstalledModules($aSelectInstall);
|
||||
}
|
||||
|
||||
private function ComputeInstalledModulesLegacy(array $aSelectInstall): array
|
||||
{
|
||||
$aInstallByModule = []; // array of <module> => array ('installed' => timestamp, 'version' => <version>)
|
||||
$iRootId = 0;
|
||||
foreach ($aSelectInstall as $aInstall) {
|
||||
if (($aInstall['parent_id'] == 0) && ($aInstall['name'] != 'datamodel')) {
|
||||
// Root module, what is its ID ?
|
||||
$iId = (int) $aInstall['id'];
|
||||
if ($iId > $iRootId) {
|
||||
$iRootId = $iId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($aSelectInstall as $aInstall) {
|
||||
//$aInstall['comment']; // unsused
|
||||
$iInstalled = strtotime($aInstall['installed']);
|
||||
$sModuleName = $aInstall['name'];
|
||||
$sModuleVersion = $aInstall['version'];
|
||||
if ($sModuleVersion == '') {
|
||||
// Though the version cannot be empty in iTop 2.0, it used to be possible
|
||||
// therefore we have to put something here or the module will not be considered
|
||||
// as being installed
|
||||
$sModuleVersion = '0.0.0';
|
||||
}
|
||||
|
||||
if ($aInstall['parent_id'] == 0) {
|
||||
$sModuleName = ROOT_MODULE;
|
||||
} elseif ($aInstall['parent_id'] != $iRootId) {
|
||||
// Skip all modules belonging to previous installations
|
||||
continue;
|
||||
}
|
||||
|
||||
if (array_key_exists($sModuleName, $aInstallByModule)) {
|
||||
if ($iInstalled < $aInstallByModule[$sModuleName]['installed']) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ($aInstall['parent_id'] == 0) {
|
||||
$aInstallByModule[$sModuleName]['installed_version'] = $sModuleVersion;
|
||||
}
|
||||
|
||||
$aInstallByModule[$sModuleName]['installed'] = $iInstalled;
|
||||
$aInstallByModule[$sModuleName]['version'] = $sModuleVersion;
|
||||
}
|
||||
|
||||
return $aInstallByModule;
|
||||
}
|
||||
|
||||
private function ComputeInstalledModules(array $aSelectInstall): array
|
||||
{
|
||||
$aInstallByModule = []; // array of <module> => array ('installed' => timestamp, 'version' => <version>)
|
||||
|
||||
//module installation datetime is mostly the same for all modules
|
||||
//unless there was issue recording things in DB
|
||||
$sFirstDatetime = null;
|
||||
$iFirstTime = -1;
|
||||
foreach ($aSelectInstall as $aInstall) {
|
||||
//$aInstall['comment']; // unsused
|
||||
$sDatetime = $aInstall['installed'];
|
||||
|
||||
if (is_null($sFirstDatetime)) {
|
||||
$sFirstDatetime = $sDatetime;
|
||||
$iFirstTime = strtotime($sDatetime);
|
||||
$iInstalled = $iFirstTime;
|
||||
} elseif ($sDatetime === $sFirstDatetime) {
|
||||
$iInstalled = $iFirstTime;
|
||||
} else {
|
||||
$sDatetime = $aInstall['installed'];
|
||||
$iInstalled = strtotime($sDatetime);
|
||||
}
|
||||
|
||||
$sModuleName = $aInstall['name'];
|
||||
$sModuleVersion = $aInstall['version'];
|
||||
if ($sModuleVersion == '') {
|
||||
// Though the version cannot be empty in iTop 2.0, it used to be possible
|
||||
// therefore we have to put something here or the module will not be considered
|
||||
// as being installed
|
||||
$sModuleVersion = '0.0.0';
|
||||
}
|
||||
|
||||
if ($aInstall['parent_id'] == 0) {
|
||||
$aInstallByModule[ROOT_MODULE] = [
|
||||
'installed_version' => $sModuleVersion,
|
||||
'installed' => $iInstalled,
|
||||
'version' => $sModuleVersion,
|
||||
];
|
||||
} else {
|
||||
$aInstallByModule[$sModuleName] = [
|
||||
'installed' => $iInstalled,
|
||||
'version' => $sModuleVersion,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $aInstallByModule;
|
||||
}
|
||||
}
|
||||
@@ -120,10 +120,6 @@ class ModuleDiscovery
|
||||
if (is_null($aArgs) || ! is_array($aArgs)) {
|
||||
throw new ModuleFileReaderException("Error parsing module file args", 0, null, $sFilePath);
|
||||
}
|
||||
if (!array_key_exists('itop_version', $aArgs)) {
|
||||
// Assume 1.0.2
|
||||
$aArgs['itop_version'] = '1.0.2';
|
||||
}
|
||||
foreach (array_keys(self::$m_aModuleArgs) as $sArgName) {
|
||||
if (!array_key_exists($sArgName, $aArgs)) {
|
||||
throw new Exception("Module '$sId': missing argument '$sArgName'");
|
||||
|
||||
@@ -32,6 +32,7 @@ require_once APPROOT."setup/modulediscovery.class.inc.php";
|
||||
require_once APPROOT.'setup/modelfactory.class.inc.php';
|
||||
require_once APPROOT.'setup/compiler.class.inc.php';
|
||||
require_once APPROOT.'setup/extensionsmap.class.inc.php';
|
||||
require_once APPROOT.'setup/AnalyzeInstallation.php';
|
||||
|
||||
define('MODULE_ACTION_OPTIONAL', 1);
|
||||
define('MODULE_ACTION_MANDATORY', 2);
|
||||
@@ -145,12 +146,12 @@ class RunTimeEnvironment
|
||||
* @return array Array with the following format:
|
||||
* array =>
|
||||
* 'iTop' => array(
|
||||
* 'version_db' => ... (could be empty in case of a fresh install)
|
||||
* 'version_code => ...
|
||||
* 'installed_version' => ... (could be empty in case of a fresh install)
|
||||
* 'available_version => ...
|
||||
* )
|
||||
* <module_name> => array(
|
||||
* 'version_db' => ...
|
||||
* 'version_code' => ...
|
||||
* 'installed_version' => ...
|
||||
* 'available_version' => ...
|
||||
* 'install' => array(
|
||||
* 'flag' => SETUP_NEVER | SETUP_OPTIONAL | SETUP_MANDATORY
|
||||
* 'message' => ...
|
||||
@@ -168,137 +169,7 @@ class RunTimeEnvironment
|
||||
*/
|
||||
public function AnalyzeInstallation($oConfig, $modulesPath, $bAbortOnMissingDependency = false, $aModulesToLoad = null)
|
||||
{
|
||||
$aRes = [
|
||||
ROOT_MODULE => [
|
||||
'version_db' => '',
|
||||
'name_db' => '',
|
||||
'version_code' => ITOP_VERSION_FULL,
|
||||
'name_code' => ITOP_APPLICATION,
|
||||
],
|
||||
];
|
||||
|
||||
$aDirs = is_array($modulesPath) ? $modulesPath : [$modulesPath];
|
||||
$aModules = ModuleDiscovery::GetAvailableModules($aDirs, $bAbortOnMissingDependency, $aModulesToLoad);
|
||||
foreach ($aModules as $sModuleId => $aModuleInfo) {
|
||||
list($sModuleName, $sModuleVersion) = ModuleDiscovery::GetModuleName($sModuleId);
|
||||
if ($sModuleName == '') {
|
||||
throw new Exception("Missing name for the module: '$sModuleId'");
|
||||
}
|
||||
if ($sModuleVersion == '') {
|
||||
// The version must not be empty (it will be used as a criteria to determine wether a module has been installed or not)
|
||||
//throw new Exception("Missing version for the module: '$sModuleId'");
|
||||
$sModuleVersion = '1.0.0';
|
||||
}
|
||||
|
||||
$sModuleAppVersion = $aModuleInfo['itop_version'];
|
||||
$aModuleInfo['version_db'] = '';
|
||||
$aModuleInfo['version_code'] = $sModuleVersion;
|
||||
|
||||
if (!in_array($sModuleAppVersion, ['1.0.0', '1.0.1', '1.0.2'])) {
|
||||
// This module is NOT compatible with the current version
|
||||
$aModuleInfo['install'] = [
|
||||
'flag' => MODULE_ACTION_IMPOSSIBLE,
|
||||
'message' => 'the module is not compatible with the current version of the application',
|
||||
];
|
||||
} elseif ($aModuleInfo['mandatory']) {
|
||||
$aModuleInfo['install'] = [
|
||||
'flag' => MODULE_ACTION_MANDATORY,
|
||||
'message' => 'the module is part of the application',
|
||||
];
|
||||
} else {
|
||||
$aModuleInfo['install'] = [
|
||||
'flag' => MODULE_ACTION_OPTIONAL,
|
||||
'message' => '',
|
||||
];
|
||||
}
|
||||
$aRes[$sModuleName] = $aModuleInfo;
|
||||
}
|
||||
|
||||
try {
|
||||
$aSelectInstall = [];
|
||||
if (! is_null($oConfig)) {
|
||||
CMDBSource::InitFromConfig($oConfig);
|
||||
$aSelectInstall = CMDBSource::QueryToArray("SELECT * FROM ".$oConfig->Get('db_subname')."priv_module_install");
|
||||
}
|
||||
} catch (MySQLException $e) {
|
||||
// No database or erroneous information
|
||||
}
|
||||
|
||||
// Build the list of installed module (get the latest installation)
|
||||
//
|
||||
$aInstallByModule = []; // array of <module> => array ('installed' => timestamp, 'version' => <version>)
|
||||
$iRootId = 0;
|
||||
foreach ($aSelectInstall as $aInstall) {
|
||||
if (($aInstall['parent_id'] == 0) && ($aInstall['name'] != 'datamodel')) {
|
||||
// Root module, what is its ID ?
|
||||
$iId = (int) $aInstall['id'];
|
||||
if ($iId > $iRootId) {
|
||||
$iRootId = $iId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($aSelectInstall as $aInstall) {
|
||||
//$aInstall['comment']; // unsused
|
||||
$iInstalled = strtotime($aInstall['installed']);
|
||||
$sModuleName = $aInstall['name'];
|
||||
$sModuleVersion = $aInstall['version'];
|
||||
if ($sModuleVersion == '') {
|
||||
// Though the version cannot be empty in iTop 2.0, it used to be possible
|
||||
// therefore we have to put something here or the module will not be considered
|
||||
// as being installed
|
||||
$sModuleVersion = '0.0.0';
|
||||
}
|
||||
|
||||
if ($aInstall['parent_id'] == 0) {
|
||||
$sModuleName = ROOT_MODULE;
|
||||
} elseif ($aInstall['parent_id'] != $iRootId) {
|
||||
// Skip all modules belonging to previous installations
|
||||
continue;
|
||||
}
|
||||
|
||||
if (array_key_exists($sModuleName, $aInstallByModule)) {
|
||||
if ($iInstalled < $aInstallByModule[$sModuleName]['installed']) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ($aInstall['parent_id'] == 0) {
|
||||
$aRes[$sModuleName]['version_db'] = $sModuleVersion;
|
||||
$aRes[$sModuleName]['name_db'] = $aInstall['name'];
|
||||
}
|
||||
|
||||
$aInstallByModule[$sModuleName]['installed'] = $iInstalled;
|
||||
$aInstallByModule[$sModuleName]['version'] = $sModuleVersion;
|
||||
}
|
||||
|
||||
// Adjust the list of proposed modules
|
||||
//
|
||||
foreach ($aInstallByModule as $sModuleName => $aModuleDB) {
|
||||
if ($sModuleName == ROOT_MODULE) {
|
||||
continue;
|
||||
} // Skip the main module
|
||||
|
||||
if (!array_key_exists($sModuleName, $aRes)) {
|
||||
// A module was installed, it is not proposed in the new build... skip
|
||||
continue;
|
||||
}
|
||||
$aRes[$sModuleName]['version_db'] = $aModuleDB['version'];
|
||||
|
||||
if ($aRes[$sModuleName]['install']['flag'] == MODULE_ACTION_MANDATORY) {
|
||||
$aRes[$sModuleName]['uninstall'] = [
|
||||
'flag' => MODULE_ACTION_IMPOSSIBLE,
|
||||
'message' => 'the module is part of the application',
|
||||
];
|
||||
} else {
|
||||
$aRes[$sModuleName]['uninstall'] = [
|
||||
'flag' => MODULE_ACTION_OPTIONAL,
|
||||
'message' => '',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $aRes;
|
||||
return AnalyzeInstallation::GetInstance()->AnalyzeInstallation($oConfig, $modulesPath, $bAbortOnMissingDependency, $aModulesToLoad);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -365,8 +236,7 @@ class RunTimeEnvironment
|
||||
// Determine the installed modules and extensions
|
||||
//
|
||||
$oSourceConfig = new Config(APPCONF.$sSourceEnv.'/'.ITOP_CONFIG_FILE);
|
||||
$oSourceEnv = new RunTimeEnvironment($sSourceEnv);
|
||||
$aAvailableModules = $oSourceEnv->AnalyzeInstallation($oSourceConfig, $aDirsToCompile);
|
||||
$aAvailableModules = $this->AnalyzeInstallation($oSourceConfig, $aDirsToCompile);
|
||||
|
||||
// Actually read the modules available for the target environment,
|
||||
// but get the selection from the source environment and finally
|
||||
@@ -404,7 +274,7 @@ class RunTimeEnvironment
|
||||
$sModuleRootDir = $oModule->GetRootDir();
|
||||
$bIsExtra = $this->oExtensionsMap->ModuleIsChosenAsPartOfAnExtension($sModule, iTopExtension::SOURCE_REMOTE);
|
||||
if (array_key_exists($sModule, $aAvailableModules)) {
|
||||
if (($aAvailableModules[$sModule]['version_db'] != '') || $bIsExtra && !$oModule->IsAutoSelect()) { //Extra modules are always unless they are 'AutoSelect'
|
||||
if (($aAvailableModules[$sModule]['installed_version'] != '') || $bIsExtra && !$oModule->IsAutoSelect()) { //Extra modules are always unless they are 'AutoSelect'
|
||||
$aRet[$oModule->GetName()] = $oModule;
|
||||
}
|
||||
}
|
||||
@@ -648,7 +518,7 @@ class RunTimeEnvironment
|
||||
$oInstallRec->Set('comment', json_encode($aData));
|
||||
$oInstallRec->Set('parent_id', 0); // root module
|
||||
$oInstallRec->Set('installed', $iInstallationTime);
|
||||
$iMainItopRecord = $oInstallRec->DBInsertNoReload();
|
||||
$oInstallRec->DBInsertNoReload();
|
||||
|
||||
// Record main installation
|
||||
$oInstallRec = new ModuleInstallation();
|
||||
@@ -669,7 +539,7 @@ class RunTimeEnvironment
|
||||
}
|
||||
$aModuleData = $aAvailableModules[$sModuleId];
|
||||
$sName = $sModuleId;
|
||||
$sVersion = $aModuleData['version_code'];
|
||||
$sVersion = $aModuleData['available_version'];
|
||||
$sUninstallable = $aModuleData['uninstallable'] ?? 'yes';
|
||||
$aComments = [];
|
||||
$aComments[] = $sShortComment;
|
||||
@@ -975,7 +845,7 @@ class RunTimeEnvironment
|
||||
{
|
||||
foreach ($aAvailableModules as $sModuleId => $aModule) {
|
||||
if (($sModuleId != ROOT_MODULE) && in_array($sModuleId, $aSelectedModules)) {
|
||||
$aArgs = [MetaModel::GetConfig(), $aModule['version_db'], $aModule['version_code']];
|
||||
$aArgs = [MetaModel::GetConfig(), $aModule['installed_version'], $aModule['available_version']];
|
||||
RunTimeEnvironment::CallInstallerHandler($aAvailableModules[$sModuleId], $sHandlerName, $aArgs);
|
||||
}
|
||||
}
|
||||
@@ -1039,7 +909,7 @@ class RunTimeEnvironment
|
||||
$sRelativePath = 'env-'.$this->sTargetEnv.'/'.basename($aModule['root_dir']);
|
||||
// Load data only for selected AND newly installed modules
|
||||
if (in_array($sModuleId, $aSelectedModules)) {
|
||||
if ($aModule['version_db'] != '') {
|
||||
if ($aModule['installed_version'] != '') {
|
||||
// Simulate the load of the previously loaded XML files to get the mapping of the keys
|
||||
if ($bSampleData) {
|
||||
$aPreviouslyLoadedFiles = static::MergeWithRelativeDir($aPreviouslyLoadedFiles, $sRelativePath, $aAvailableModules[$sModuleId]['data.struct']);
|
||||
|
||||
@@ -1605,7 +1605,7 @@ EOF
|
||||
if ($this->bUpgrade) {
|
||||
// In upgrade mode, the defaults are the installed modules
|
||||
foreach ($aChoice['modules'] as $sModuleId) {
|
||||
if ($aModules[$sModuleId]['version_db'] != '') {
|
||||
if ($aModules[$sModuleId]['installed_version'] != '') {
|
||||
// A module corresponding to this choice is installed
|
||||
$aScores[$sChoiceId][$sModuleId] = true;
|
||||
}
|
||||
@@ -1663,7 +1663,7 @@ EOF
|
||||
}
|
||||
if (array_key_exists('modules', $aChoice)) {
|
||||
foreach ($aChoice['modules'] as $sModuleId) {
|
||||
if ($aModules[$sModuleId]['version_db'] != '') {
|
||||
if ($aModules[$sModuleId]['installed_version'] != '') {
|
||||
// A module corresponding to this choice is installed, increase the score of this choice
|
||||
if (!isset($aScores[$sChoiceId])) {
|
||||
$aScores[$sChoiceId] = [];
|
||||
|
||||
@@ -1019,10 +1019,10 @@ EOF
|
||||
if ($sModuleId == '_Root_') {
|
||||
continue;
|
||||
}
|
||||
if ($aModuleData['version_db'] == '') {
|
||||
if ($aModuleData['installed_version'] == '') {
|
||||
continue;
|
||||
}
|
||||
$oPage->add('InstalledModule/'.$sModuleId.': '.$aModuleData['version_db']."\n");
|
||||
$oPage->add('InstalledModule/'.$sModuleId.': '.$aModuleData['installed_version']."\n");
|
||||
}
|
||||
|
||||
$oPage->add('===== end =====');
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Setup;
|
||||
|
||||
use AnalyzeInstallation;
|
||||
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
use ModuleInstallationService;
|
||||
|
||||
class AnalyzeInstallationTest extends ItopTestCase
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->RequireOnceItopFile('setup/AnalyzeInstallation.php');
|
||||
$this->RequireOnceItopFile('setup/ModuleInstallationService.php');
|
||||
$this->RequireOnceItopFile('setup/modulediscovery.class.inc.php');
|
||||
$this->RequireOnceItopFile('setup/runtimeenv.class.inc.php');
|
||||
}
|
||||
|
||||
public static function AnalyzeInstallationProvider()
|
||||
{
|
||||
//$aModules = json_decode(file_get_contents(__DIR__.'/ressources/priv_modules.json'), true);
|
||||
$aAnalyzeInstallationOutput = json_decode(file_get_contents(__DIR__.'/ressources/analyze_installation_output.json'), true);
|
||||
$aAvailableModules = json_decode(file_get_contents(__DIR__.'/ressources/available_modules.json'), true);
|
||||
return [
|
||||
'new modules not in DB setup history' => [
|
||||
'aAvailableModules' => [
|
||||
'mandatory_module/1.0.0' => [
|
||||
"mandatory" => true,
|
||||
"ga" => "bu",
|
||||
],
|
||||
'optional_module/6.6.6' => [
|
||||
"mandatory" => false,
|
||||
"zo" => "meu",
|
||||
],
|
||||
],
|
||||
'aInstalledModules' => [],
|
||||
'expected' => [
|
||||
'_Root_' => [
|
||||
'installed_version' => '',
|
||||
'available_version' => '3.3.0-dev-svn',
|
||||
'name_code' => 'iTop',
|
||||
],
|
||||
'mandatory_module' => [
|
||||
"mandatory" => true,
|
||||
'installed_version' => '',
|
||||
'available_version' => '1.0.0',
|
||||
'install' => [
|
||||
'flag' => 2,
|
||||
'message' => 'the module is part of the application',
|
||||
],
|
||||
"ga" => "bu",
|
||||
],
|
||||
'optional_module' => [
|
||||
"mandatory" => false,
|
||||
'installed_version' => '',
|
||||
'available_version' => '6.6.6',
|
||||
"zo" => "meu",
|
||||
'install' => [
|
||||
'flag' => 1,
|
||||
'message' => '',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
'new modules ALREADY in DB setup history' => [
|
||||
'aAvailableModules' => [
|
||||
'mandatory_module/1.0.0' => [
|
||||
"mandatory" => true,
|
||||
"ga" => "bu",
|
||||
],
|
||||
'optional_module/6.6.6' => [
|
||||
"mandatory" => false,
|
||||
"zo" => "meu",
|
||||
],
|
||||
],
|
||||
'aInstalledModules' => json_decode(file_get_contents(__DIR__.'/ressources/priv_modules_simpleusecase.json'), true),
|
||||
'expected' => [
|
||||
'_Root_' => [
|
||||
'installed_version' => '3.3.0-dev-svn',
|
||||
'available_version' => '3.3.0-dev-svn',
|
||||
'name_code' => 'iTop',
|
||||
],
|
||||
'mandatory_module' => [
|
||||
"mandatory" => true,
|
||||
'installed_version' => '3.3.0',
|
||||
'available_version' => '1.0.0',
|
||||
"ga" => "bu",
|
||||
'install' => [
|
||||
'flag' => 2,
|
||||
'message' => 'the module is part of the application',
|
||||
],
|
||||
'uninstall' => [
|
||||
'flag' => 3,
|
||||
'message' => 'the module is part of the application',
|
||||
],
|
||||
],
|
||||
'optional_module' => [
|
||||
"mandatory" => false,
|
||||
'installed_version' => '3.3.0',
|
||||
'available_version' => '6.6.6',
|
||||
"zo" => "meu",
|
||||
'install' => [
|
||||
'flag' => 1,
|
||||
'message' => '',
|
||||
],
|
||||
'uninstall' => [
|
||||
'flag' => 1,
|
||||
'message' => '',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
'dummyfirst installation' => [
|
||||
'aAvailableModules' => [],
|
||||
'aInstalledModules' => [],
|
||||
'expected' => [
|
||||
'_Root_' => [
|
||||
'installed_version' => '',
|
||||
'available_version' => '3.3.0-dev-svn',
|
||||
'name_code' => 'iTop',
|
||||
],
|
||||
],
|
||||
],
|
||||
'dummy 2nd installation' => [
|
||||
'aAvailableModules' => [],
|
||||
'aInstalledModules' => json_decode(file_get_contents(__DIR__.'/ressources/priv_modules2.json'), true),
|
||||
'expected' => [
|
||||
'_Root_' => [
|
||||
'installed_version' => '3.3.0-dev-svn',
|
||||
'available_version' => '3.3.0-dev-svn',
|
||||
'name_code' => 'iTop',
|
||||
],
|
||||
],
|
||||
],
|
||||
'real_case' => [
|
||||
'aAvailableModules' => $aAvailableModules,
|
||||
'aInstalledModules' => json_decode(file_get_contents(__DIR__.'/ressources/priv_modules2.json'), true),
|
||||
'expected' => $aAnalyzeInstallationOutput,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider AnalyzeInstallationProvider
|
||||
*/
|
||||
public function testAnalyzeInstallation($aAvailableModules, $aInstalledModules, $expected)
|
||||
{
|
||||
$this->SetNonPublicProperty(AnalyzeInstallation::GetInstance(), "aAvailableModules", $aAvailableModules);
|
||||
//$aModules = json_decode(file_get_contents(__DIR__.'/ressources/priv_modules2.json'), true);
|
||||
$this->SetNonPublicProperty(ModuleInstallationService::GetInstance(), "aSelectInstall", $aInstalledModules);
|
||||
|
||||
$oConfig = $this->createMock(\Config::class);
|
||||
|
||||
$modulesPath = [
|
||||
APPROOT.'extensions',
|
||||
];
|
||||
$aModules = AnalyzeInstallation::GetInstance()->AnalyzeInstallation($oConfig, $modulesPath, false, null);
|
||||
$this->assertEquals($expected, $aModules);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,642 @@
|
||||
[
|
||||
{
|
||||
"0": "330",
|
||||
"id": "330",
|
||||
"1": "iTop",
|
||||
"name": "iTop",
|
||||
"2": "3.3.0-dev-svn",
|
||||
"version": "3.3.0-dev-svn",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nBuilt on $WCNOW$",
|
||||
"comment": "Done by the setup program\nBuilt on $WCNOW$",
|
||||
"5": "0",
|
||||
"parent_id": "0",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "331",
|
||||
"id": "331",
|
||||
"1": "authent-cas",
|
||||
"name": "authent-cas",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nMandatory\nVisible (during the setup)",
|
||||
"comment": "Done by the setup program\nMandatory\nVisible (during the setup)",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "332",
|
||||
"id": "332",
|
||||
"1": "authent-external",
|
||||
"name": "authent-external",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nOptional\nVisible (during the setup)",
|
||||
"comment": "Done by the setup program\nOptional\nVisible (during the setup)",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "333",
|
||||
"id": "333",
|
||||
"1": "authent-ldap",
|
||||
"name": "authent-ldap",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nOptional\nVisible (during the setup)",
|
||||
"comment": "Done by the setup program\nOptional\nVisible (during the setup)",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "334",
|
||||
"id": "334",
|
||||
"1": "authent-local",
|
||||
"name": "authent-local",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nMandatory\nVisible (during the setup)",
|
||||
"comment": "Done by the setup program\nMandatory\nVisible (during the setup)",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "335",
|
||||
"id": "335",
|
||||
"1": "combodo-backoffice-darkmoon-theme",
|
||||
"name": "combodo-backoffice-darkmoon-theme",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nMandatory\nHidden (selected automatically)",
|
||||
"comment": "Done by the setup program\nMandatory\nHidden (selected automatically)",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "336",
|
||||
"id": "336",
|
||||
"1": "combodo-backoffice-fullmoon-high-contrast-theme",
|
||||
"name": "combodo-backoffice-fullmoon-high-contrast-theme",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nMandatory\nHidden (selected automatically)",
|
||||
"comment": "Done by the setup program\nMandatory\nHidden (selected automatically)",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "337",
|
||||
"id": "337",
|
||||
"1": "combodo-backoffice-fullmoon-protanopia-deuteranopia-theme",
|
||||
"name": "combodo-backoffice-fullmoon-protanopia-deuteranopia-theme",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nMandatory\nHidden (selected automatically)",
|
||||
"comment": "Done by the setup program\nMandatory\nHidden (selected automatically)",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "338",
|
||||
"id": "338",
|
||||
"1": "combodo-backoffice-fullmoon-tritanopia-theme",
|
||||
"name": "combodo-backoffice-fullmoon-tritanopia-theme",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nMandatory\nHidden (selected automatically)",
|
||||
"comment": "Done by the setup program\nMandatory\nHidden (selected automatically)",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "339",
|
||||
"id": "339",
|
||||
"1": "itop-backup",
|
||||
"name": "itop-backup",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nMandatory\nHidden (selected automatically)",
|
||||
"comment": "Done by the setup program\nMandatory\nHidden (selected automatically)",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "340",
|
||||
"id": "340",
|
||||
"1": "itop-config",
|
||||
"name": "itop-config",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nMandatory\nHidden (selected automatically)",
|
||||
"comment": "Done by the setup program\nMandatory\nHidden (selected automatically)",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "341",
|
||||
"id": "341",
|
||||
"1": "itop-files-information",
|
||||
"name": "itop-files-information",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nOptional\nHidden (selected automatically)",
|
||||
"comment": "Done by the setup program\nOptional\nHidden (selected automatically)",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "342",
|
||||
"id": "342",
|
||||
"1": "itop-portal-base",
|
||||
"name": "itop-portal-base",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nMandatory\nHidden (selected automatically)",
|
||||
"comment": "Done by the setup program\nMandatory\nHidden (selected automatically)",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "343",
|
||||
"id": "343",
|
||||
"1": "itop-profiles-itil",
|
||||
"name": "itop-profiles-itil",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nMandatory\nHidden (selected automatically)",
|
||||
"comment": "Done by the setup program\nMandatory\nHidden (selected automatically)",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "344",
|
||||
"id": "344",
|
||||
"1": "itop-sla-computation",
|
||||
"name": "itop-sla-computation",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nMandatory\nHidden (selected automatically)",
|
||||
"comment": "Done by the setup program\nMandatory\nHidden (selected automatically)",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "345",
|
||||
"id": "345",
|
||||
"1": "itop-structure",
|
||||
"name": "itop-structure",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nMandatory\nHidden (selected automatically)",
|
||||
"comment": "Done by the setup program\nMandatory\nHidden (selected automatically)",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "346",
|
||||
"id": "346",
|
||||
"1": "itop-welcome-itil",
|
||||
"name": "itop-welcome-itil",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nMandatory\nHidden (selected automatically)",
|
||||
"comment": "Done by the setup program\nMandatory\nHidden (selected automatically)",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "347",
|
||||
"id": "347",
|
||||
"1": "itop-config-mgmt",
|
||||
"name": "itop-config-mgmt",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-structure\/2.7.1",
|
||||
"comment": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-structure\/2.7.1",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "348",
|
||||
"id": "348",
|
||||
"1": "itop-attachments",
|
||||
"name": "itop-attachments",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nOptional\nVisible (during the setup)",
|
||||
"comment": "Done by the setup program\nOptional\nVisible (during the setup)",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "349",
|
||||
"id": "349",
|
||||
"1": "itop-tickets",
|
||||
"name": "itop-tickets",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-structure\/2.7.1",
|
||||
"comment": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-structure\/2.7.1",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "350",
|
||||
"id": "350",
|
||||
"1": "combodo-db-tools",
|
||||
"name": "combodo-db-tools",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-structure\/3.0.0",
|
||||
"comment": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-structure\/3.0.0",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "351",
|
||||
"id": "351",
|
||||
"1": "itop-core-update",
|
||||
"name": "itop-core-update",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-files-information\/2.7.0\nDepends on module: combodo-db-tools\/2.7.0",
|
||||
"comment": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-files-information\/2.7.0\nDepends on module: combodo-db-tools\/2.7.0",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "352",
|
||||
"id": "352",
|
||||
"1": "itop-hub-connector",
|
||||
"name": "itop-hub-connector",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-config-mgmt\/2.4.0",
|
||||
"comment": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-config-mgmt\/2.4.0",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "353",
|
||||
"id": "353",
|
||||
"1": "itop-oauth-client",
|
||||
"name": "itop-oauth-client",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-welcome-itil\/3.1.0,",
|
||||
"comment": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-welcome-itil\/3.1.0,",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "354",
|
||||
"id": "354",
|
||||
"1": "itop-themes-compat",
|
||||
"name": "itop-themes-compat",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-structure\/3.1.0",
|
||||
"comment": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-structure\/3.1.0",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "355",
|
||||
"id": "355",
|
||||
"1": "itop-datacenter-mgmt",
|
||||
"name": "itop-datacenter-mgmt",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-config-mgmt\/2.2.0",
|
||||
"comment": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-config-mgmt\/2.2.0",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "356",
|
||||
"id": "356",
|
||||
"1": "itop-endusers-devices",
|
||||
"name": "itop-endusers-devices",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-config-mgmt\/2.2.0",
|
||||
"comment": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-config-mgmt\/2.2.0",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "357",
|
||||
"id": "357",
|
||||
"1": "itop-storage-mgmt",
|
||||
"name": "itop-storage-mgmt",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-config-mgmt\/2.4.0",
|
||||
"comment": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-config-mgmt\/2.4.0",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "358",
|
||||
"id": "358",
|
||||
"1": "itop-virtualization-mgmt",
|
||||
"name": "itop-virtualization-mgmt",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-config-mgmt\/2.4.0",
|
||||
"comment": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-config-mgmt\/2.4.0",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "359",
|
||||
"id": "359",
|
||||
"1": "itop-bridge-cmdb-ticket",
|
||||
"name": "itop-bridge-cmdb-ticket",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nOptional\nHidden (selected automatically)\nDepends on module: itop-config-mgmt\/2.7.1\nDepends on module: itop-tickets\/2.7.0",
|
||||
"comment": "Done by the setup program\nOptional\nHidden (selected automatically)\nDepends on module: itop-config-mgmt\/2.7.1\nDepends on module: itop-tickets\/2.7.0",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "360",
|
||||
"id": "360",
|
||||
"1": "itop-bridge-virtualization-storage",
|
||||
"name": "itop-bridge-virtualization-storage",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nOptional\nHidden (selected automatically)\nDepends on module: itop-storage-mgmt\/2.2.0\nDepends on module: itop-virtualization-mgmt\/2.2.0",
|
||||
"comment": "Done by the setup program\nOptional\nHidden (selected automatically)\nDepends on module: itop-storage-mgmt\/2.2.0\nDepends on module: itop-virtualization-mgmt\/2.2.0",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "361",
|
||||
"id": "361",
|
||||
"1": "itop-service-mgmt",
|
||||
"name": "itop-service-mgmt",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-tickets\/2.0.0",
|
||||
"comment": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-tickets\/2.0.0",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "362",
|
||||
"id": "362",
|
||||
"1": "itop-bridge-cmdb-services",
|
||||
"name": "itop-bridge-cmdb-services",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nOptional\nHidden (selected automatically)\nDepends on module: itop-config-mgmt\/2.7.1\nDepends on module: itop-service-mgmt\/2.7.1 || itop-service-mgmt-provider\/2.7.1",
|
||||
"comment": "Done by the setup program\nOptional\nHidden (selected automatically)\nDepends on module: itop-config-mgmt\/2.7.1\nDepends on module: itop-service-mgmt\/2.7.1 || itop-service-mgmt-provider\/2.7.1",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "363",
|
||||
"id": "363",
|
||||
"1": "itop-bridge-datacenter-mgmt-services",
|
||||
"name": "itop-bridge-datacenter-mgmt-services",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nOptional\nHidden (selected automatically)\nDepends on module: itop-config-mgmt\/2.7.1\nDepends on module: itop-service-mgmt\/2.7.1 || itop-service-mgmt-provider\/2.7.1\nDepends on module: itop-datacenter-mgmt\/3.1.0",
|
||||
"comment": "Done by the setup program\nOptional\nHidden (selected automatically)\nDepends on module: itop-config-mgmt\/2.7.1\nDepends on module: itop-service-mgmt\/2.7.1 || itop-service-mgmt-provider\/2.7.1\nDepends on module: itop-datacenter-mgmt\/3.1.0",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "364",
|
||||
"id": "364",
|
||||
"1": "itop-bridge-endusers-devices-services",
|
||||
"name": "itop-bridge-endusers-devices-services",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nOptional\nHidden (selected automatically)\nDepends on module: itop-config-mgmt\/2.7.1\nDepends on module: itop-service-mgmt\/2.7.1 || itop-service-mgmt-provider\/2.7.1\nDepends on module: itop-endusers-devices\/3.1.0",
|
||||
"comment": "Done by the setup program\nOptional\nHidden (selected automatically)\nDepends on module: itop-config-mgmt\/2.7.1\nDepends on module: itop-service-mgmt\/2.7.1 || itop-service-mgmt-provider\/2.7.1\nDepends on module: itop-endusers-devices\/3.1.0",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "365",
|
||||
"id": "365",
|
||||
"1": "itop-bridge-storage-mgmt-services",
|
||||
"name": "itop-bridge-storage-mgmt-services",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nOptional\nHidden (selected automatically)\nDepends on module: itop-config-mgmt\/2.7.1\nDepends on module: itop-service-mgmt\/2.7.1 || itop-service-mgmt-provider\/2.7.1\nDepends on module: itop-storage-mgmt\/3.1.0",
|
||||
"comment": "Done by the setup program\nOptional\nHidden (selected automatically)\nDepends on module: itop-config-mgmt\/2.7.1\nDepends on module: itop-service-mgmt\/2.7.1 || itop-service-mgmt-provider\/2.7.1\nDepends on module: itop-storage-mgmt\/3.1.0",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "366",
|
||||
"id": "366",
|
||||
"1": "itop-bridge-virtualization-mgmt-services",
|
||||
"name": "itop-bridge-virtualization-mgmt-services",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nOptional\nHidden (selected automatically)\nDepends on module: itop-config-mgmt\/2.7.1\nDepends on module: itop-service-mgmt\/2.7.1 || itop-service-mgmt-provider\/2.7.1\nDepends on module: itop-virtualization-mgmt\/3.1.0",
|
||||
"comment": "Done by the setup program\nOptional\nHidden (selected automatically)\nDepends on module: itop-config-mgmt\/2.7.1\nDepends on module: itop-service-mgmt\/2.7.1 || itop-service-mgmt-provider\/2.7.1\nDepends on module: itop-virtualization-mgmt\/3.1.0",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "367",
|
||||
"id": "367",
|
||||
"1": "itop-request-mgmt",
|
||||
"name": "itop-request-mgmt",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-tickets\/2.4.0",
|
||||
"comment": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-tickets\/2.4.0",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "368",
|
||||
"id": "368",
|
||||
"1": "itop-portal",
|
||||
"name": "itop-portal",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-portal-base\/2.7.0",
|
||||
"comment": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-portal-base\/2.7.0",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "369",
|
||||
"id": "369",
|
||||
"1": "itop-change-mgmt",
|
||||
"name": "itop-change-mgmt",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-config-mgmt\/2.2.0\nDepends on module: itop-tickets\/2.0.0",
|
||||
"comment": "Done by the setup program\nOptional\nVisible (during the setup)\nDepends on module: itop-config-mgmt\/2.2.0\nDepends on module: itop-tickets\/2.0.0",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,50 @@
|
||||
[
|
||||
{
|
||||
"0": "330",
|
||||
"id": "330",
|
||||
"1": "iTop",
|
||||
"name": "iTop",
|
||||
"2": "3.3.0-dev-svn",
|
||||
"version": "3.3.0-dev-svn",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nBuilt on $WCNOW$",
|
||||
"comment": "Done by the setup program\nBuilt on $WCNOW$",
|
||||
"5": "0",
|
||||
"parent_id": "0",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "331",
|
||||
"id": "331",
|
||||
"1": "mandatory_module",
|
||||
"name": "mandatory_module",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nMandatory\nVisible (during the setup)",
|
||||
"comment": "Done by the setup program\nMandatory\nVisible (during the setup)",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "yes"
|
||||
},
|
||||
{
|
||||
"0": "332",
|
||||
"id": "332",
|
||||
"1": "optional_module",
|
||||
"name": "optional_module",
|
||||
"2": "3.3.0",
|
||||
"version": "3.3.0",
|
||||
"3": "2025-11-10 11:50:12",
|
||||
"installed": "2025-11-10 11:50:12",
|
||||
"4": "Done by the setup program\nOptional\nVisible (during the setup)",
|
||||
"comment": "Done by the setup program\nOptional\nVisible (during the setup)",
|
||||
"5": "330",
|
||||
"parent_id": "330",
|
||||
"6": "yes",
|
||||
"uninstallable": "no"
|
||||
}
|
||||
]
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user