Merge remote-tracking branch 'origin/support/3.2' into develop

This commit is contained in:
Molkobain
2024-04-12 11:08:59 +02:00
5 changed files with 71 additions and 27 deletions

View File

@@ -2281,4 +2281,19 @@ interface iKPILoggerExtension
* @return mixed
*/
public function LogOperation($oKpiLogData);
}
}
/**
* Implement this interface to add files to the backup
*
* @api
* @since 3.2.0
*/
interface iBackupExtraFilesExtension
{
/**
* @api
* @return string[] Array of relative paths (from app root) for files and directories to be included in the backup
*/
public function GetExtraFilesRelPaths(): array;
}

View File

@@ -265,35 +265,45 @@ class DBBackup
SetupUtils::copydir($sExtraDir, $sFile);
$aRet[] = $sFile;
}
$aExtraFiles = [];
if (MetaModel::GetConfig() !== null) // During unattended install config file may be absent
{
$aExtraFiles = MetaModel::GetModuleSetting('itop-backup', 'extra_files', []);
foreach($aExtraFiles as $sExtraFileOrDir)
}
foreach (utils::GetClassesForInterface('iBackupExtraFilesExtension', '', ['[\\\\/]lib[\\\\/]', '[\\\\/]node_modules[\\\\/]', '[\\\\/]test[\\\\/]', '[\\\\/]tests[\\\\/]']) as $sExtensionClass)
{
/** @var iBackupExtraFilesExtension $oExtensionInstance */
$oExtensionInstance = new $sExtensionClass();
$aExtraFiles = array_merge($aExtraFiles, $oExtensionInstance->GetExtraFilesRelPaths());
}
foreach($aExtraFiles as $sExtraFileOrDir)
{
if(!file_exists(APPROOT.'/'.$sExtraFileOrDir)) {
continue; // Ignore non-existing files
}
$sExtraFullPath = utils::RealPath(APPROOT.'/'.$sExtraFileOrDir, APPROOT);
if ($sExtraFullPath === false)
{
if(!file_exists(APPROOT.'/'.$sExtraFileOrDir)) {
continue; // Ignore non-existing files
}
$sExtraFullPath = utils::RealPath(APPROOT.'/'.$sExtraFileOrDir, APPROOT);
if ($sExtraFullPath === false)
{
throw new Exception("Backup: Aborting, resource '$sExtraFileOrDir'. Considered as UNSAFE because not inside the iTop directory.");
}
if (is_dir($sExtraFullPath))
{
$sFile = $sTmpFolder.'/'.$sExtraFileOrDir;
$this->LogInfo("backup: adding directory '$sExtraFileOrDir'");
SetupUtils::copydir($sExtraFullPath, $sFile);
$aRet[] = $sFile;
}
elseif (file_exists($sExtraFullPath))
{
$sFile = $sTmpFolder.'/'.$sExtraFileOrDir;
$this->LogInfo("backup: adding file '$sExtraFileOrDir'");
@mkdir(dirname($sFile), 0755, true);
copy($sExtraFullPath, $sFile);
$aRet[] = $sFile;
}
throw new Exception("Backup: Aborting, resource '$sExtraFileOrDir'. Considered as UNSAFE because not inside the iTop directory.");
}
if (is_dir($sExtraFullPath))
{
$sFile = $sTmpFolder.'/'.$sExtraFileOrDir;
$this->LogInfo("backup: adding directory '$sExtraFileOrDir'");
SetupUtils::copydir($sExtraFullPath, $sFile);
$aRet[] = $sFile;
}
elseif (file_exists($sExtraFullPath))
{
$sFile = $sTmpFolder.'/'.$sExtraFileOrDir;
$this->LogInfo("backup: adding file '$sExtraFileOrDir'");
@mkdir(dirname($sFile), 0755, true);
copy($sExtraFullPath, $sFile);
$aRet[] = $sFile;
}
}
if (!$bSkipSQLDumpForTesting)

View File

@@ -190,7 +190,7 @@ abstract class ItopCustomDatamodelTestCase extends ItopDataTestCase
CMDBSource::CreateDB($oTestConfig->Get('db_name'));
MetaModel::Startup($sConfFile, false /* $bModelOnly */, true /* $bAllowCache */, false /* $bTraceSourceFiles */, $sTestEnv);
// N°7446 For some reason we need to create the DB schema before starting the MM, then only we can create the tables.
MetaModel::DBCreate();
MetaModel::DBCreate();
$this->MarkEnvironmentReady();
$this->debug('Preparation of custom environment "'.$sTestEnv.'" done.');

View File

@@ -161,6 +161,10 @@ class ApplicationExtensionTest extends ItopCustomDatamodelTestCase
\iNewsroomProvider::class,
static::ENUM_API_CALL_METHOD_GETCLASSESFORINTERFACE,
],
\iBackupExtraFilesExtension::class => [
\iBackupExtraFilesExtension::class,
static::ENUM_API_CALL_METHOD_GETCLASSESFORINTERFACE,
],
];
}
}

View File

@@ -350,6 +350,21 @@ class ExampleFor_iKPILoggerExtension implements \iKPILoggerExtension
{
// Do nothing, we just need the class to exists for the unit test
}
}
]]></content>
</snippet>
<snippet id="ExampleFor_iBackupExtraFilesExtension" _delta="define">
<placement>core</placement>
<rank>0</rank>
<content><![CDATA[
class ExampleFor_iBackupExtraFilesExtension implements \iBackupExtraFilesExtension
{
public function GetExtraFilesRelPaths(): array
{
return [
'foo'
];
}
}
]]></content>
</snippet>