Skip to content

Commit

Permalink
Split upgrade and backup process
Browse files Browse the repository at this point in the history
  • Loading branch information
Morgan Pichat committed Oct 9, 2024
1 parent ca793d3 commit 23de625
Show file tree
Hide file tree
Showing 38 changed files with 543 additions and 279 deletions.
4 changes: 2 additions & 2 deletions classes/Commands/RestoreCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

use Exception;
use PrestaShop\Module\AutoUpgrade\Task\ExitCode;
use PrestaShop\Module\AutoUpgrade\Task\Runner\AllRollbackTasks;
use PrestaShop\Module\AutoUpgrade\Task\Runner\AllRestoreTasks;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
Expand Down Expand Up @@ -70,7 +70,7 @@ protected function execute(InputInterface $input, OutputInterface $output): ?int
return ExitCode::FAIL;
}

$controller = new AllRollbackTasks($this->upgradeContainer);
$controller = new AllRestoreTasks($this->upgradeContainer);
$controller->setOptions([
'backup' => $backup,
]);
Expand Down
4 changes: 2 additions & 2 deletions classes/Commands/UpdateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
use Exception;
use PrestaShop\Module\AutoUpgrade\DeveloperDocumentation;
use PrestaShop\Module\AutoUpgrade\Task\ExitCode;
use PrestaShop\Module\AutoUpgrade\Task\Runner\AllUpgradeTasks;
use PrestaShop\Module\AutoUpgrade\Task\Runner\AllUpdateTasks;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
Expand Down Expand Up @@ -89,7 +89,7 @@ protected function execute(InputInterface $input, OutputInterface $output): ?int

$this->logger->debug('Configuration loaded successfully.');
$this->logger->debug('Starting the update process.');
$controller = new AllUpgradeTasks($this->upgradeContainer);
$controller = new AllUpdateTasks($this->upgradeContainer);
$controller->setOptions([
'data' => $input->getOption('data'),
'action' => $input->getOption('action'),
Expand Down
79 changes: 37 additions & 42 deletions classes/Progress/CompletionCalculator.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,57 +28,58 @@
namespace PrestaShop\Module\AutoUpgrade\Progress;

use InvalidArgumentException;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeConfiguration;
use PrestaShop\Module\AutoUpgrade\Task\Rollback\RestoreDb;
use PrestaShop\Module\AutoUpgrade\Task\Backup\BackupComplete;
use PrestaShop\Module\AutoUpgrade\Task\Backup\BackupDatabase;
use PrestaShop\Module\AutoUpgrade\Task\Backup\BackupFiles;
use PrestaShop\Module\AutoUpgrade\Task\Backup\BackupInitialization;
use PrestaShop\Module\AutoUpgrade\Task\Rollback\Restore;
use PrestaShop\Module\AutoUpgrade\Task\Rollback\RestoreComplete;
use PrestaShop\Module\AutoUpgrade\Task\Rollback\RestoreDatabase;
use PrestaShop\Module\AutoUpgrade\Task\Rollback\RestoreFiles;
use PrestaShop\Module\AutoUpgrade\Task\Rollback\Rollback;
use PrestaShop\Module\AutoUpgrade\Task\Rollback\RollbackComplete;
use PrestaShop\Module\AutoUpgrade\Task\Upgrade\BackupDb;
use PrestaShop\Module\AutoUpgrade\Task\Upgrade\BackupFiles;
use PrestaShop\Module\AutoUpgrade\Task\Upgrade\CleanDatabase;
use PrestaShop\Module\AutoUpgrade\Task\Upgrade\Download;
use PrestaShop\Module\AutoUpgrade\Task\Upgrade\Unzip;
use PrestaShop\Module\AutoUpgrade\Task\Upgrade\UpgradeComplete;
use PrestaShop\Module\AutoUpgrade\Task\Upgrade\UpgradeDb;
use PrestaShop\Module\AutoUpgrade\Task\Upgrade\UpgradeFiles;
use PrestaShop\Module\AutoUpgrade\Task\Upgrade\UpgradeModules;
use PrestaShop\Module\AutoUpgrade\Task\Upgrade\UpgradeNow;
use PrestaShop\Module\AutoUpgrade\Task\Update\CleanDatabase;
use PrestaShop\Module\AutoUpgrade\Task\Update\Download;
use PrestaShop\Module\AutoUpgrade\Task\Update\Unzip;
use PrestaShop\Module\AutoUpgrade\Task\Update\UpdateComplete;
use PrestaShop\Module\AutoUpgrade\Task\Update\UpdateDatabase;
use PrestaShop\Module\AutoUpgrade\Task\Update\UpdateFiles;
use PrestaShop\Module\AutoUpgrade\Task\Update\UpdateInitialization;
use PrestaShop\Module\AutoUpgrade\Task\Update\UpdateModules;

class CompletionCalculator
{
/** @var UpgradeConfiguration */
private $upgradeConfiguration;

public function __construct(UpgradeConfiguration $upgradeConfiguration)
public function __construct()
{
$this->upgradeConfiguration = $upgradeConfiguration;
}

/**
* The key baseWithoutBackup exists while the backup and upgrade are on the same workflow
*
* @return array<string, array{base:int, baseWithoutBackup:int|null}>
* @return array<string, int>
*/
private static function getPercentages(): array
{
return [
// Upgrade (+ backup)
UpgradeNow::class => ['base' => 0],
Download::class => ['base' => 5, 'baseWithoutBackup' => 10],
Unzip::class => ['base' => 10, 'baseWithoutBackup' => 20],
BackupFiles::class => ['base' => 20],
BackupDb::class => ['base' => 40],
UpgradeFiles::class => ['base' => 50, 'baseWithoutBackup' => 40],
UpgradeDb::class => ['base' => 70, 'baseWithoutBackup' => 60],
UpgradeModules::class => ['base' => 90, 'baseWithoutBackup' => 80],
CleanDatabase::class => ['base' => 100],
UpgradeComplete::class => ['base' => 100],
// Backup
BackupInitialization::class => 0,
BackupFiles::class => 33,
BackupDatabase::class => 66,
BackupComplete::class => 100,

// Update
UpdateInitialization::class => 0,
Download::class => 10,
Unzip::class => 20,
UpdateFiles::class => 40,
UpdateDatabase::class => 60,
UpdateModules::class => 80,
CleanDatabase::class => 100,
UpdateComplete::class => 100,

// Restore
Rollback::class => ['base' => 0],
RestoreFiles::class => ['base' => 33],
RestoreDb::class => ['base' => 66],
RollbackComplete::class => ['base' => 100],
Restore::class => 0,
RestoreFiles::class => 33,
RestoreDatabase::class => 66,
RestoreComplete::class => 100,
];
}

Expand All @@ -94,13 +95,7 @@ public function getBasePercentageOfTask(string $taskName): int
throw new InvalidArgumentException($taskName . ' has no percentage. Make sure to send an upgrade, backup or restore task.');
}

$withoutBackup = !$this->upgradeConfiguration->shouldBackupFilesAndDatabase();

if ($withoutBackup && isset($percentages[$taskName]['baseWithoutBackup'])) {
return $percentages[$taskName]['baseWithoutBackup'];
}

return $percentages[$taskName]['base'];
return $percentages[$taskName];
}

/**
Expand Down
2 changes: 1 addition & 1 deletion classes/Task/AbstractTask.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ abstract class AbstractTask
*/
protected $nextParams = [];
/**
* @var string
* @var TaskName::TASK_*|null
*/
protected $next;

Expand Down
58 changes: 58 additions & 0 deletions classes/Task/Backup/BackupComplete.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to [email protected] so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <[email protected]>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/

namespace PrestaShop\Module\AutoUpgrade\Task\Backup;

use Exception;
use PrestaShop\Module\AutoUpgrade\Analytics;
use PrestaShop\Module\AutoUpgrade\Task\AbstractTask;
use PrestaShop\Module\AutoUpgrade\Task\ExitCode;
use PrestaShop\Module\AutoUpgrade\Task\TaskName;
use PrestaShop\Module\AutoUpgrade\Task\TaskType;

class BackupComplete extends AbstractTask
{
const TASK_TYPE = TaskType::TASK_TYPE_BACKUP;

/**
* @throws Exception
*/
public function run(): int
{
$this->container->getState()->setProgressPercentage(
$this->container->getCompletionCalculator()->getBasePercentageOfTask(self::class)
);

$this->stepDone = true;
$this->next = TaskName::TASK_COMPLETE;

$this->container->getAnalytics()->track('Backup Succeeded', Analytics::WITH_BACKUP_PROPERTIES);
$this->logger->info($this->translator->trans('Backup completed successfully.'));

return ExitCode::SUCCESS;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,19 @@
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/

namespace PrestaShop\Module\AutoUpgrade\Task\Upgrade;
namespace PrestaShop\Module\AutoUpgrade\Task\Backup;

use Exception;
use PrestaShop\Module\AutoUpgrade\Analytics;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeFileNames;
use PrestaShop\Module\AutoUpgrade\Progress\Backlog;
use PrestaShop\Module\AutoUpgrade\Task\AbstractTask;
use PrestaShop\Module\AutoUpgrade\Task\ExitCode;
use PrestaShop\Module\AutoUpgrade\Task\TaskName;
use PrestaShop\Module\AutoUpgrade\Task\TaskType;
use PrestaShop\Module\AutoUpgrade\Tools14;
use PrestaShop\Module\AutoUpgrade\UpgradeContainer;

class BackupDb extends AbstractTask
class BackupDatabase extends AbstractTask
{
const TASK_TYPE = TaskType::TASK_TYPE_BACKUP;

Expand All @@ -46,28 +46,19 @@ class BackupDb extends AbstractTask
*/
public function run(): int
{
if (!$this->container->getUpgradeConfiguration()->shouldBackupFilesAndDatabase()) {
$this->stepDone = true;
$this->container->getState()->setDbStep(0);
$this->logger->info($this->translator->trans('Database backup skipped. Now upgrading files...'));
$this->next = 'upgradeFiles';

return ExitCode::SUCCESS;
}

$timeAllowed = $this->container->getUpgradeConfiguration()->getNumberOfFilesPerCall();
$relative_backup_path = str_replace(_PS_ROOT_DIR_, '', $this->container->getProperty(UpgradeContainer::BACKUP_PATH));
$report = '';
if (!\ConfigurationTest::test_dir($relative_backup_path, false, $report)) {
$this->logger->error($this->translator->trans('Backup directory is not writable (%path%).', ['%path%' => $this->container->getProperty(UpgradeContainer::BACKUP_PATH)]));
$this->next = 'error';
$this->next = TaskName::TASK_ERROR;
$this->setErrorFlag();

return ExitCode::FAIL;
}

$this->stepDone = false;
$this->next = 'backupDb';
$this->next = TaskName::TASK_BACKUP_DATABASE;
$start_time = time();
$time_elapsed = 0;

Expand Down Expand Up @@ -137,7 +128,7 @@ public function run(): int
// start init file
// Figure out what compression is available and open the file
if (file_exists($backupfile)) {
$this->next = 'error';
$this->next = TaskName::TASK_ERROR;
$this->setErrorFlag();
$this->logger->error($this->translator->trans('Backup file %s already exists. Operation aborted.', [$backupfile]));
}
Expand All @@ -154,7 +145,7 @@ public function run(): int

if ($fp === false) {
$this->logger->error($this->translator->trans('Unable to create backup database file %s.', [addslashes($backupfile)]));
$this->next = 'error';
$this->next = TaskName::TASK_ERROR;
$this->setErrorFlag();
$this->logger->info($this->translator->trans('Error during database backup.'));

Expand Down Expand Up @@ -182,7 +173,7 @@ public function run(): int
}
$this->logger->error($this->translator->trans('An error occurred while backing up. Unable to obtain the schema of %s', [$table]));
$this->logger->info($this->translator->trans('Error during database backup.'));
$this->next = 'error';
$this->next = TaskName::TASK_ERROR;
$this->setErrorFlag();

return ExitCode::FAIL;
Expand Down Expand Up @@ -269,13 +260,13 @@ public function run(): int
}

$this->container->getState()->setProgressPercentage(
$this->container->getCompletionCalculator()->computePercentage($tablesToBackup, self::class, UpgradeFiles::class)
$this->container->getCompletionCalculator()->computePercentage($tablesToBackup, self::class, BackupComplete::class)
);
$this->container->getFileConfigurationStorage()->save($tablesToBackup->dump(), UpgradeFileNames::DB_TABLES_TO_BACKUP_LIST);

if ($tablesToBackup->getRemainingTotal()) {
$this->logger->debug($this->translator->trans('%s tables have been saved.', [$found]));
$this->next = 'backupDb';
$this->next = TaskName::TASK_BACKUP_DATABASE;
$this->stepDone = false;
$this->logger->info($this->translator->trans('Database backup: %s table(s) left...', [$tablesToBackup->getRemainingTotal()]));

Expand All @@ -302,10 +293,8 @@ public function run(): int
// reset dbStep at the end of this step
$this->container->getState()->setDbStep(0);

$this->logger->info($this->translator->trans('Database backup done in filename %s. Now upgrading files...', [$this->container->getState()->getBackupName()]));
$this->next = 'upgradeFiles';

$this->container->getAnalytics()->track('Backup Succeeded', Analytics::WITH_BACKUP_PROPERTIES);
$this->logger->info($this->translator->trans('Database backup done in filename %s.', [$this->container->getState()->getBackupName()]));
$this->next = TaskName::TASK_COMPLETE;

return ExitCode::SUCCESS;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/

namespace PrestaShop\Module\AutoUpgrade\Task\Upgrade;
namespace PrestaShop\Module\AutoUpgrade\Task\Backup;

use Exception;
use PrestaShop\Module\AutoUpgrade\Parameters\UpgradeFileNames;
use PrestaShop\Module\AutoUpgrade\Progress\Backlog;
use PrestaShop\Module\AutoUpgrade\Task\AbstractTask;
use PrestaShop\Module\AutoUpgrade\Task\ExitCode;
use PrestaShop\Module\AutoUpgrade\Task\TaskName;
use PrestaShop\Module\AutoUpgrade\Task\TaskType;
use PrestaShop\Module\AutoUpgrade\UpgradeContainer;

Expand All @@ -44,18 +45,10 @@ class BackupFiles extends AbstractTask
*/
public function run(): int
{
if (!$this->container->getUpgradeConfiguration()->shouldBackupFilesAndDatabase()) {
$this->stepDone = true;
$this->next = 'backupDb';
$this->logger->info('File backup skipped.');

return ExitCode::SUCCESS;
}

$this->stepDone = false;
$backupFilesFilename = $this->container->getState()->getBackupFilesFilename();
if (empty($backupFilesFilename)) {
$this->next = 'error';
$this->next = TaskName::TASK_ERROR;
$this->setErrorFlag();
$this->logger->info($this->translator->trans('Error during backupFiles'));
$this->logger->error($this->translator->trans('[ERROR] backupFiles filename has not been set'));
Expand Down Expand Up @@ -87,27 +80,27 @@ public function run(): int
$backlog = Backlog::fromContents($this->container->getFileConfigurationStorage()->load(UpgradeFileNames::FILES_TO_BACKUP_LIST));
}

$this->next = 'backupFiles';
$this->next = TaskName::TASK_BACKUP_FILES;
$remainingFiles = $backlog->getRemainingTotal();
if ($remainingFiles) {
$this->logger->info($this->translator->trans('Backup files in progress. %d files left', [$remainingFiles]));

$this->stepDone = false;
$res = $this->container->getZipAction()->compress($backlog, $this->container->getProperty(UpgradeContainer::BACKUP_PATH) . DIRECTORY_SEPARATOR . $backupFilesFilename);
if (!$res) {
$this->next = 'error';
$this->next = TaskName::TASK_ERROR;
$this->logger->info($this->translator->trans('Unable to open archive'));

return ExitCode::FAIL;
}
$this->container->getFileConfigurationStorage()->save($backlog->dump(), UpgradeFileNames::FILES_TO_BACKUP_LIST);
$this->container->getState()->setProgressPercentage(
$this->container->getCompletionCalculator()->computePercentage($backlog, self::class, BackupDb::class)
$this->container->getCompletionCalculator()->computePercentage($backlog, self::class, BackupDatabase::class)
);
} else {
$this->stepDone = true;
$this->status = 'ok';
$this->next = 'backupDb';
$this->next = TaskName::TASK_BACKUP_DATABASE;
$this->logger->debug($this->translator->trans('All files have been added to archive.'));
$this->logger->info($this->translator->trans('All files saved. Now backing up database'));
}
Expand Down
Loading

0 comments on commit 23de625

Please sign in to comment.