From e0761759022a30e5e0e882f8df60b57dba40447a Mon Sep 17 00:00:00 2001 From: "lenaick.moreira" Date: Thu, 30 Jul 2026 15:03:04 +0200 Subject: [PATCH] =?UTF-8?q?N=C2=B09118=20-=20No=20Safeguard=20when=20hub?= =?UTF-8?q?=20installation=20fail?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- datamodels/2.x/itop-hub-connector/land.php | 4 ++-- .../src/Controller/HubController.php | 13 ++++++++++--- setup/extensionsmap.class.inc.php | 14 ++++++++++---- setup/runtimeenv.class.inc.php | 5 +++-- .../src/Service/UnitTestRunTimeEnvironment.php | 2 +- 5 files changed, 26 insertions(+), 12 deletions(-) diff --git a/datamodels/2.x/itop-hub-connector/land.php b/datamodels/2.x/itop-hub-connector/land.php index f0921e33f..67e470745 100644 --- a/datamodels/2.x/itop-hub-connector/land.php +++ b/datamodels/2.x/itop-hub-connector/land.php @@ -20,7 +20,7 @@ function DisplayStatus(WebPage $oPage) if (is_dir($sPath)) { $aExtraDirs[] = $sPath; // Also read the extra downloaded-modules directory } - $oExtensionsMap = iTopExtensionsMap::GetExtensionsMap(ITOP_DEFAULT_ENV); + $oExtensionsMap = iTopExtensionsMap::GetExtensionsMap(ITOP_DEFAULT_ENV, $aExtraDirs); $oExtensionsMap->LoadChoicesFromDatabase(MetaModel::GetConfig()); foreach ($oExtensionsMap->GetAllExtensions() as $oExtension) { @@ -154,7 +154,7 @@ function DoInstall(WebPage $oPage) if (is_dir($sPath)) { $aExtraDirs[] = $sPath; // Also read the extra downloaded-modules directory } - $oExtensionsMap = iTopExtensionsMap::GetExtensionsMap(ITOP_DEFAULT_ENV); + $oExtensionsMap = iTopExtensionsMap::GetExtensionsMap(ITOP_DEFAULT_ENV, $aExtraDirs); $oExtensionsMap->LoadChoicesFromDatabase(MetaModel::GetConfig()); foreach ($oExtensionsMap->GetAllExtensions() as $oExtension) { diff --git a/datamodels/2.x/itop-hub-connector/src/Controller/HubController.php b/datamodels/2.x/itop-hub-connector/src/Controller/HubController.php index a205a98ff..43aae8c94 100644 --- a/datamodels/2.x/itop-hub-connector/src/Controller/HubController.php +++ b/datamodels/2.x/itop-hub-connector/src/Controller/HubController.php @@ -25,6 +25,7 @@ require_once(APPROOT.'core/mutex.class.inc.php'); require_once(APPROOT.'core/dict.class.inc.php'); require_once(APPROOT.'setup/xmldataloader.class.inc.php'); require_once(__DIR__.'/../setup/hubruntimeenvironment.class.inc.php'); +require_once(__DIR__.'/../Model/DBBackupWithErrorReporting.php'); class HubController { @@ -125,15 +126,21 @@ class HubController // First step: prepare the datamodel, if it fails, roll-back $aSelectedExtensionDirs = utils::ReadParam('extension_dirs', [], false, utils::ENUM_SANITIZATION_FILTER_MODULE_CODE); - $oRuntimeEnv = new HubRunTimeEnvironment('production', false); // use a temp environment: production-build + $oRuntimeEnv = new HubRunTimeEnvironment(ITOP_DEFAULT_ENV, false); // use a temp environment: production-build $oRuntimeEnv->MoveSelectedExtensions(APPROOT.'/data/downloaded-extensions/', $aSelectedExtensionDirs); - $oConfig = new Config(APPCONF.'production/'.ITOP_CONFIG_FILE); + $oExtensionMap = iTopExtensionsMap::GetExtensionsMap($oRuntimeEnv->GetBuildEnv()); + $aPreviousRemoteExtensions = $oExtensionMap->GetExtensionsFromDir(APPROOT.'data/'.$oRuntimeEnv->GetFinalEnv().'-modules/'); + $aCurrentRemoteExtensions = $oExtensionMap->GetExtensionsFromDir(APPROOT.'data/'.$oRuntimeEnv->GetBuildEnv().'-modules/'); + $aAddedExtensions = array_diff($aCurrentRemoteExtensions, $aPreviousRemoteExtensions); + + $sBuildConfigFile = APPCONF.ITOP_DEFAULT_ENV.'/'.ITOP_CONFIG_FILE; + $oConfig = new Config($sBuildConfigFile); if ($oConfig->Get('demo_mode')) { throw new Exception('Sorry the installation of extensions is not allowed in demo mode'); } - $oRuntimeEnv->CompileFrom('production'); // WARNING symlinks does not seem to be compatible with manual Commit + $oRuntimeEnv->CompileFrom(ITOP_DEFAULT_ENV, aAddedExtensions: array_keys($aAddedExtensions)); // WARNING symlinks does not seem to be compatible with manual Commit $oRuntimeEnv->UpdateIncludes($oConfig); $oRuntimeEnv->InitDataModel($oConfig, true /* model only */); diff --git a/setup/extensionsmap.class.inc.php b/setup/extensionsmap.class.inc.php index bee2fcce5..abaaac0da 100644 --- a/setup/extensionsmap.class.inc.php +++ b/setup/extensionsmap.class.inc.php @@ -40,14 +40,14 @@ class iTopExtensionsMap /** * @throws \Exception */ - public static function GetExtensionsMap(string $sFromEnvironment = ITOP_DEFAULT_ENV, ?string $sAppRootForTests = null): iTopExtensionsMap + public static function GetExtensionsMap(string $sFromEnvironment = ITOP_DEFAULT_ENV, array $aExtraDirs = [], ?string $sAppRootForTests = null): iTopExtensionsMap { if (!is_null($sAppRootForTests)) { - return new iTopExtensionsMap($sFromEnvironment, $sAppRootForTests); + return new iTopExtensionsMap($sFromEnvironment, $aExtraDirs, $sAppRootForTests); } if (!isset(self::$aInstancesByEnvironment[$sFromEnvironment])) { - self::$aInstancesByEnvironment[$sFromEnvironment] = new iTopExtensionsMap($sFromEnvironment); + self::$aInstancesByEnvironment[$sFromEnvironment] = new iTopExtensionsMap($sFromEnvironment, $aExtraDirs); } return self::$aInstancesByEnvironment[$sFromEnvironment]; @@ -57,11 +57,12 @@ class iTopExtensionsMap * The list of all discovered extensions * * @param string $sFromEnvironment The environment to scan + * @param array $aExtraDirs extensions dir to scan * @param string|null $sAppRootForTests * * @throws \Exception */ - private function __construct(string $sFromEnvironment = ITOP_DEFAULT_ENV, ?string $sAppRootForTests = null) + private function __construct(string $sFromEnvironment = ITOP_DEFAULT_ENV, array $aExtraDirs = [], ?string $sAppRootForTests = null) { $this->aExtensions = []; $this->aExtensionsByCode = []; @@ -69,6 +70,11 @@ class iTopExtensionsMap $sAppRoot = $sAppRootForTests ?? APPROOT; $this->ScanDisk($sFromEnvironment, $sAppRoot); + + foreach ($aExtraDirs as $sDir) { + $this->ReadDir($sDir, iTopExtension::SOURCE_REMOTE, bIsRootDir: true); + } + $this->CheckDependencies($sAppRoot); } diff --git a/setup/runtimeenv.class.inc.php b/setup/runtimeenv.class.inc.php index 1f2eddeb4..861158e13 100644 --- a/setup/runtimeenv.class.inc.php +++ b/setup/runtimeenv.class.inc.php @@ -1273,16 +1273,17 @@ class RunTimeEnvironment * * @param string $sSourceEnv The name of the source environment to 'imitate' * @param null $bUseSymLinks Whether to create symbolic links instead of copies + * @param array $aAddedExtensions List of additional extensions to add to the build environment * * @return string[] * @throws \ConfigException * @throws \CoreException */ - public function CompileFrom($sSourceEnv, $bUseSymLinks = null) + public function CompileFrom($sSourceEnv, $bUseSymLinks = null, $aAddedExtensions = []) { $oConfig = new Config(utils::GetConfigFilePath($sSourceEnv)); $this->InitExtensionMap($oConfig); - $aSelectedExtensions = $this->GetExtensionMap()->GetSelectedExtensions($oConfig, [], []); + $aSelectedExtensions = $this->GetExtensionMap()->GetSelectedExtensions($oConfig, $aAddedExtensions, []); $aSelectedModules = $this->GetModulesToLoadFromChoices($oConfig, $aSelectedExtensions); return $this->DoCompile($aSelectedExtensions, [], $aSelectedModules, $bUseSymLinks ?? false); } diff --git a/tests/php-unit-tests/src/Service/UnitTestRunTimeEnvironment.php b/tests/php-unit-tests/src/Service/UnitTestRunTimeEnvironment.php index 2f8c32830..4b288e644 100644 --- a/tests/php-unit-tests/src/Service/UnitTestRunTimeEnvironment.php +++ b/tests/php-unit-tests/src/Service/UnitTestRunTimeEnvironment.php @@ -49,7 +49,7 @@ class UnitTestRunTimeEnvironment extends RunTimeEnvironment */ protected $aAdditionExtensionFoldersByCode = null; - public function CompileFrom($sSourceEnv, $bUseSymLinks = null) + public function CompileFrom($sSourceEnv, $bUseSymLinks = null, $aAddedExtensions = []) { $sDestModulesDir = APPROOT.'data/'.$this->sBuildEnv.'-modules/'; if (is_dir($sDestModulesDir)) {