From a974d00571d1edcd3ad2f727427eb03237de7ba8 Mon Sep 17 00:00:00 2001 From: Ferdinand Thiessen Date: Mon, 27 Apr 2026 19:28:36 +0200 Subject: [PATCH] feat: add new `IRepairStepExpensive` interface Expensive repair steps are non-critical repair steps that might take a long time to execute. Non-critical means that they are not required to directly be executed during migration to have a working instance, but they might be required to have a fully working instance later on. Expensive repair steps are only executed when explicitly requested by the administrator. Signed-off-by: Ferdinand Thiessen --- core/Command/Maintenance/Repair.php | 11 ++-- lib/private/Repair.php | 53 +++++++++---------- lib/public/Migration/IRepairStepExpensive.php | 20 +++++++ 3 files changed, 49 insertions(+), 35 deletions(-) create mode 100644 lib/public/Migration/IRepairStepExpensive.php diff --git a/core/Command/Maintenance/Repair.php b/core/Command/Maintenance/Repair.php index 84bfe0b4cb3..7b5959871c9 100644 --- a/core/Command/Maintenance/Repair.php +++ b/core/Command/Maintenance/Repair.php @@ -51,14 +51,11 @@ class Repair extends Command { } protected function execute(InputInterface $input, OutputInterface $output): int { - $repairSteps = $this->repair::getRepairSteps(); - - if ($input->getOption('include-expensive')) { - $repairSteps = array_merge($repairSteps, $this->repair::getExpensiveRepairSteps()); - } + $includeExpensive = (bool)$input->getOption('include-expensive'); + $repairSteps = $this->repair::getRepairSteps($includeExpensive); foreach ($repairSteps as $step) { - $this->repair->addStep($step); + $this->repair->addStep($step, $includeExpensive); } $apps = $this->appManager->getEnabledApps(); @@ -74,7 +71,7 @@ class Repair extends Command { $steps = $info['repair-steps']['post-migration']; foreach ($steps as $step) { try { - $this->repair->addStep($step); + $this->repair->addStep($step, $includeExpensive); } catch (Exception $ex) { $output->writeln("Failed to load repair step for $app: {$ex->getMessage()}"); } diff --git a/lib/private/Repair.php b/lib/private/Repair.php index e35feda3357..b053f5d1e05 100644 --- a/lib/private/Repair.php +++ b/lib/private/Repair.php @@ -64,6 +64,7 @@ use OCP\IConfig; use OCP\IDBConnection; use OCP\Migration\IOutput; use OCP\Migration\IRepairStep; +use OCP\Migration\IRepairStepExpensive; use OCP\Server; use Psr\Container\ContainerExceptionInterface; use Psr\Log\LoggerInterface; @@ -113,10 +114,11 @@ class Repair implements IOutput { /** * Add repair step * - * @param IRepairStep|class-string $repairStep repair step + * @param IRepairStep|class-string $repairStep Repair step + * @param bool $includeExpensive Whether to include expensive repair steps, defaults to false * @throws \Exception */ - public function addStep(IRepairStep|string $repairStep): void { + public function addStep(IRepairStep|string $repairStep, bool $includeExpensive = false): void { if (is_string($repairStep)) { try { $s = Server::get($repairStep); @@ -134,24 +136,30 @@ class Repair implements IOutput { } } - if ($s instanceof IRepairStep) { - $this->repairSteps[] = $s; - } else { + if (!($s instanceof IRepairStep)) { throw new \Exception("Repair step '$repairStep' is not of type \\OCP\\Migration\\IRepairStep"); } + + $repairStep = $s; + } + + if (($repairStep instanceof IRepairStepExpensive) && !$includeExpensive) { + $this->debug("Skipping expensive repair step '" . $repairStep::class . "'"); } else { $this->repairSteps[] = $repairStep; } } /** - * Returns the default repair steps to be run on the - * command line or after an upgrade. + * Returns the core repair steps to be run on the command line or after an upgrade. * + * @param bool $includeExpensive Whether to include expensive repair steps, defaults to false * @return list + * + * @since 34.0.0, the $includeExpensive parameter was added */ - public static function getRepairSteps(): array { - return [ + public static function getRepairSteps(bool $includeExpensive = false): array { + $repairSteps = [ new Collation(Server::get(IConfig::class), Server::get(LoggerInterface::class), Server::get(IDBConnection::class), false), Server::get(CleanTags::class), Server::get(RepairInvalidShares::class), @@ -190,28 +198,17 @@ class Repair implements IOutput { Server::get(AddMovePreviewJob::class), Server::get(ConfigKeyMigration::class), ]; - } - /** - * Returns expensive repair steps to be run on the - * command line with a special option. - * - * @return list - */ - public static function getExpensiveRepairSteps(): array { - $expensiveSteps = [ - Server::get(OldGroupMembershipShares::class), - Server::get(RemoveBrokenProperties::class), - Server::get(RepairMimeTypes::class), - Server::get(DeleteSchedulingObjects::class), - Server::get(RemoveObjectProperties::class), - ]; - - if (class_exists(CleanupShareTarget::class)) { - $expensiveSteps[] = Server::get(CleanupShareTarget::class); + if ($includeExpensive) { + $expensiveSteps = [ + Server::get(OldGroupMembershipShares::class), + Server::get(RemoveBrokenProperties::class), + Server::get(RepairMimeTypes::class), + ]; + $repairSteps = array_merge($repairSteps, $expensiveSteps); } - return $expensiveSteps; + return $repairSteps; } /** diff --git a/lib/public/Migration/IRepairStepExpensive.php b/lib/public/Migration/IRepairStepExpensive.php new file mode 100644 index 00000000000..0f954c3eade --- /dev/null +++ b/lib/public/Migration/IRepairStepExpensive.php @@ -0,0 +1,20 @@ +