Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>tags/v25.0.0beta4
use Exception; | use Exception; | ||||
use OCP\App\IAppManager; | use OCP\App\IAppManager; | ||||
use OCP\EventDispatcher\Event; | |||||
use OCP\EventDispatcher\IEventDispatcher; | |||||
use OCP\IConfig; | use OCP\IConfig; | ||||
use OC\Repair\Events\RepairAdvanceEvent; | |||||
use OC\Repair\Events\RepairErrorEvent; | |||||
use OC\Repair\Events\RepairFinishEvent; | |||||
use OC\Repair\Events\RepairInfoEvent; | |||||
use OC\Repair\Events\RepairStartEvent; | |||||
use OC\Repair\Events\RepairStepEvent; | |||||
use OC\Repair\Events\RepairWarningEvent; | |||||
use Symfony\Component\Console\Command\Command; | use Symfony\Component\Console\Command\Command; | ||||
use Symfony\Component\Console\Helper\ProgressBar; | use Symfony\Component\Console\Helper\ProgressBar; | ||||
use Symfony\Component\Console\Input\InputInterface; | use Symfony\Component\Console\Input\InputInterface; | ||||
use Symfony\Component\Console\Input\InputOption; | use Symfony\Component\Console\Input\InputOption; | ||||
use Symfony\Component\Console\Output\OutputInterface; | use Symfony\Component\Console\Output\OutputInterface; | ||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface; | |||||
use Symfony\Component\EventDispatcher\GenericEvent; | |||||
class Repair extends Command { | class Repair extends Command { | ||||
protected \OC\Repair $repair; | protected \OC\Repair $repair; | ||||
protected IConfig $config; | protected IConfig $config; | ||||
private EventDispatcherInterface $dispatcher; | |||||
private IEventDispatcher $dispatcher; | |||||
private ProgressBar $progress; | private ProgressBar $progress; | ||||
private OutputInterface $output; | private OutputInterface $output; | ||||
private IAppManager $appManager; | private IAppManager $appManager; | ||||
public function __construct(\OC\Repair $repair, IConfig $config, EventDispatcherInterface $dispatcher, IAppManager $appManager) { | |||||
public function __construct(\OC\Repair $repair, IConfig $config, IEventDispatcher $dispatcher, IAppManager $appManager) { | |||||
$this->repair = $repair; | $this->repair = $repair; | ||||
$this->config = $config; | $this->config = $config; | ||||
$this->dispatcher = $dispatcher; | $this->dispatcher = $dispatcher; | ||||
$this->progress = new ProgressBar($output); | $this->progress = new ProgressBar($output); | ||||
$this->output = $output; | $this->output = $output; | ||||
$this->dispatcher->addListener('\OC\Repair::startProgress', [$this, 'handleRepairFeedBack']); | |||||
$this->dispatcher->addListener('\OC\Repair::advance', [$this, 'handleRepairFeedBack']); | |||||
$this->dispatcher->addListener('\OC\Repair::finishProgress', [$this, 'handleRepairFeedBack']); | |||||
$this->dispatcher->addListener('\OC\Repair::step', [$this, 'handleRepairFeedBack']); | |||||
$this->dispatcher->addListener('\OC\Repair::info', [$this, 'handleRepairFeedBack']); | |||||
$this->dispatcher->addListener('\OC\Repair::warning', [$this, 'handleRepairFeedBack']); | |||||
$this->dispatcher->addListener('\OC\Repair::error', [$this, 'handleRepairFeedBack']); | |||||
$this->dispatcher->addListener(RepairStartEvent::class, [$this, 'handleRepairFeedBack']); | |||||
$this->dispatcher->addListener(RepairAdvanceEvent::class, [$this, 'handleRepairFeedBack']); | |||||
$this->dispatcher->addListener(RepairFinishEvent::class, [$this, 'handleRepairFeedBack']); | |||||
$this->dispatcher->addListener(RepairStepEvent::class, [$this, 'handleRepairFeedBack']); | |||||
$this->dispatcher->addListener(RepairInfoEvent::class, [$this, 'handleRepairFeedBack']); | |||||
$this->dispatcher->addListener(RepairWarningEvent::class, [$this, 'handleRepairFeedBack']); | |||||
$this->dispatcher->addListener(RepairErrorEvent::class, [$this, 'handleRepairFeedBack']); | |||||
$this->repair->run(); | $this->repair->run(); | ||||
return 0; | return 0; | ||||
} | } | ||||
public function handleRepairFeedBack($event) { | |||||
if (!$event instanceof GenericEvent) { | |||||
return; | |||||
} | |||||
switch ($event->getSubject()) { | |||||
case '\OC\Repair::startProgress': | |||||
$this->progress->start($event->getArgument('max')); | |||||
break; | |||||
case '\OC\Repair::advance': | |||||
$this->progress->advance($event->getArgument('step')); | |||||
break; | |||||
case '\OC\Repair::finishProgress': | |||||
$this->progress->finish(); | |||||
$this->output->writeln(''); | |||||
break; | |||||
case '\OC\Repair::step': | |||||
$this->output->writeln(' - ' . $event->getArgument('step')); | |||||
break; | |||||
case '\OC\Repair::info': | |||||
$this->output->writeln(' - ' . $event->getArgument('message')); | |||||
break; | |||||
case '\OC\Repair::warning': | |||||
$this->output->writeln(' - WARNING: ' . $event->getArgument('message')); | |||||
break; | |||||
case '\OC\Repair::error': | |||||
$this->output->writeln('<error> - ERROR: ' . $event->getArgument('message') . '</error>'); | |||||
break; | |||||
public function handleRepairFeedBack(Event $event): void { | |||||
if ($event instanceof RepairStartEvent) { | |||||
$this->progress->start($event->getMaxStep()); | |||||
} elseif ($event instanceof RepairAdvanceEvent) { | |||||
$this->progress->advance($event->getCurrentStep()); | |||||
} elseif ($event instanceof RepairFinishEvent) { | |||||
$this->progress->finish(); | |||||
$this->output->writeln(''); | |||||
} elseif ($event instanceof RepairStepEvent) { | |||||
$this->output->writeln(' - ' . $event->getStepName()); | |||||
} elseif ($event instanceof RepairInfoEvent) { | |||||
$this->output->writeln(' - ' . $event->getMessage()); | |||||
} elseif ($event instanceof RepairWarningEvent) { | |||||
$this->output->writeln(' - WARNING: ' . $event->getMessage()); | |||||
} elseif ($event instanceof RepairErrorEvent) { | |||||
$this->output->writeln('<error> - ERROR: ' . $event->getMessage() . '</error>'); | |||||
} | } | ||||
} | } | ||||
} | } |
*/ | */ | ||||
namespace OC\Core\Command; | namespace OC\Core\Command; | ||||
use OCP\EventDispatcher\Event; | |||||
use OCP\EventDispatcher\IEventDispatcher; | use OCP\EventDispatcher\IEventDispatcher; | ||||
use OCP\IConfig; | use OCP\IConfig; | ||||
use OCP\Util; | use OCP\Util; | ||||
use OC\Console\TimestampFormatter; | use OC\Console\TimestampFormatter; | ||||
use OC\DB\MigratorExecuteSqlEvent; | use OC\DB\MigratorExecuteSqlEvent; | ||||
use OC\Installer; | use OC\Installer; | ||||
use OC\Repair\Events\RepairAdvanceEvent; | |||||
use OC\Repair\Events\RepairErrorEvent; | |||||
use OC\Repair\Events\RepairFinishEvent; | |||||
use OC\Repair\Events\RepairInfoEvent; | |||||
use OC\Repair\Events\RepairStartEvent; | |||||
use OC\Repair\Events\RepairStepEvent; | |||||
use OC\Repair\Events\RepairWarningEvent; | |||||
use OC\Updater; | use OC\Updater; | ||||
use Psr\Log\LoggerInterface; | use Psr\Log\LoggerInterface; | ||||
use Symfony\Component\Console\Command\Command; | use Symfony\Component\Console\Command\Command; | ||||
use Symfony\Component\Console\Helper\ProgressBar; | use Symfony\Component\Console\Helper\ProgressBar; | ||||
use Symfony\Component\Console\Input\InputInterface; | use Symfony\Component\Console\Input\InputInterface; | ||||
use Symfony\Component\Console\Output\OutputInterface; | use Symfony\Component\Console\Output\OutputInterface; | ||||
use Symfony\Component\EventDispatcher\GenericEvent; | |||||
class Upgrade extends Command { | class Upgrade extends Command { | ||||
public const ERROR_SUCCESS = 0; | public const ERROR_SUCCESS = 0; | ||||
$this->installer | $this->installer | ||||
); | ); | ||||
$dispatcher = \OC::$server->getEventDispatcher(); | |||||
/** @var IEventDispatcher $newDispatcher */ | |||||
$newDispatcher = \OC::$server->get(IEventDispatcher::class); | |||||
/** @var IEventDispatcher $dispatcher */ | |||||
$dispatcher = \OC::$server->get(IEventDispatcher::class); | |||||
$progress = new ProgressBar($output); | $progress = new ProgressBar($output); | ||||
$progress->setFormat(" %message%\n %current%/%max% [%bar%] %percent:3s%%"); | $progress->setFormat(" %message%\n %current%/%max% [%bar%] %percent:3s%%"); | ||||
$listener = function (MigratorExecuteSqlEvent $event) use ($progress, $output) { | $listener = function (MigratorExecuteSqlEvent $event) use ($progress, $output) { | ||||
} | } | ||||
} | } | ||||
}; | }; | ||||
$repairListener = function ($event) use ($progress, $output) { | |||||
if (!$event instanceof GenericEvent) { | |||||
return; | |||||
} | |||||
switch ($event->getSubject()) { | |||||
case '\OC\Repair::startProgress': | |||||
$progress->setMessage('Starting ...'); | |||||
$output->writeln($event->getArgument('step')); | |||||
$output->writeln(''); | |||||
$progress->start($event->getArgument('max')); | |||||
break; | |||||
case '\OC\Repair::advance': | |||||
$desc = $event->getArgument('desc'); | |||||
if (!empty($desc)) { | |||||
$progress->setMessage($desc); | |||||
} | |||||
$progress->advance($event->getArgument('step')); | |||||
break; | |||||
case '\OC\Repair::finishProgress': | |||||
$progress->setMessage('Done'); | |||||
$progress->finish(); | |||||
$output->writeln(''); | |||||
break; | |||||
case '\OC\Repair::step': | |||||
if (OutputInterface::VERBOSITY_NORMAL < $output->getVerbosity()) { | |||||
$output->writeln('<info>Repair step: ' . $event->getArgument('step') . '</info>'); | |||||
} | |||||
break; | |||||
case '\OC\Repair::info': | |||||
if (OutputInterface::VERBOSITY_NORMAL < $output->getVerbosity()) { | |||||
$output->writeln('<info>Repair info: ' . $event->getArgument('message') . '</info>'); | |||||
} | |||||
break; | |||||
case '\OC\Repair::warning': | |||||
$output->writeln('<error>Repair warning: ' . $event->getArgument('message') . '</error>'); | |||||
break; | |||||
case '\OC\Repair::error': | |||||
$output->writeln('<error>Repair error: ' . $event->getArgument('message') . '</error>'); | |||||
break; | |||||
$repairListener = function (Event $event) use ($progress, $output) { | |||||
if ($event instanceof RepairStartEvent) { | |||||
$progress->setMessage('Starting ...'); | |||||
$output->writeln($event->getCurrentStepName()); | |||||
$output->writeln(''); | |||||
$progress->start($event->getMaxStep()); | |||||
} elseif ($event instanceof RepairAdvanceEvent) { | |||||
$desc = $event->getDescription(); | |||||
if (!empty($desc)) { | |||||
$progress->setMessage($desc); | |||||
} | |||||
$progress->advance($event->getCurrentStep()); | |||||
} elseif ($event instanceof RepairFinishEvent) { | |||||
$progress->setMessage('Done'); | |||||
$progress->finish(); | |||||
$output->writeln(''); | |||||
} elseif ($event instanceof RepairStepEvent) { | |||||
if (OutputInterface::VERBOSITY_NORMAL < $output->getVerbosity()) { | |||||
$output->writeln('<info>Repair step: ' . $event->getStepName() . '</info>'); | |||||
} | |||||
} elseif ($event instanceof RepairInfoEvent) { | |||||
if (OutputInterface::VERBOSITY_NORMAL < $output->getVerbosity()) { | |||||
$output->writeln('<info>Repair info: ' . $event->getMessage() . '</info>'); | |||||
} | |||||
} elseif ($event instanceof RepairWarningEvent) { | |||||
$output->writeln('<error>Repair warning: ' . $event->getMessage() . '</error>'); | |||||
} elseif ($event instanceof RepairErrorEvent) { | |||||
$output->writeln('<error>Repair error: ' . $event->getMessage() . '</error>'); | |||||
} | } | ||||
}; | }; | ||||
$newDispatcher->addListener(MigratorExecuteSqlEvent::class, $listener); | |||||
$dispatcher->addListener('\OC\Repair::startProgress', $repairListener); | |||||
$dispatcher->addListener('\OC\Repair::advance', $repairListener); | |||||
$dispatcher->addListener('\OC\Repair::finishProgress', $repairListener); | |||||
$dispatcher->addListener('\OC\Repair::step', $repairListener); | |||||
$dispatcher->addListener('\OC\Repair::info', $repairListener); | |||||
$dispatcher->addListener('\OC\Repair::warning', $repairListener); | |||||
$dispatcher->addListener('\OC\Repair::error', $repairListener); | |||||
$dispatcher->addListener(MigratorExecuteSqlEvent::class, $listener); | |||||
$dispatcher->addListener(RepairStartEvent::class, $repairListener); | |||||
$dispatcher->addListener(RepairAdvanceEvent::class, $repairListener); | |||||
$dispatcher->addListener(RepairFinishEvent::class, $repairListener); | |||||
$dispatcher->addListener(RepairStepEvent::class, $repairListener); | |||||
$dispatcher->addListener(RepairInfoEvent::class, $repairListener); | |||||
$dispatcher->addListener(RepairWarningEvent::class, $repairListener); | |||||
$dispatcher->addListener(RepairErrorEvent::class, $repairListener); | |||||
$updater->listen('\OC\Updater', 'maintenanceEnabled', function () use ($output) { | $updater->listen('\OC\Updater', 'maintenanceEnabled', function () use ($output) { |
* along with this program. If not, see <http://www.gnu.org/licenses/> | * along with this program. If not, see <http://www.gnu.org/licenses/> | ||||
* | * | ||||
*/ | */ | ||||
use OCP\EventDispatcher\Event; | |||||
use OCP\EventDispatcher\IEventDispatcher; | use OCP\EventDispatcher\IEventDispatcher; | ||||
use OCP\IEventSource; | use OCP\IEventSource; | ||||
use OCP\IL10N; | use OCP\IL10N; | ||||
use OCP\ILogger; | use OCP\ILogger; | ||||
use OC\DB\MigratorExecuteSqlEvent; | use OC\DB\MigratorExecuteSqlEvent; | ||||
use Symfony\Component\EventDispatcher\GenericEvent; | |||||
use OC\Repair\Events\RepairAdvanceEvent; | |||||
use OC\Repair\Events\RepairErrorEvent; | |||||
use OC\Repair\Events\RepairFinishEvent; | |||||
use OC\Repair\Events\RepairInfoEvent; | |||||
use OC\Repair\Events\RepairStartEvent; | |||||
use OC\Repair\Events\RepairStepEvent; | |||||
use OC\Repair\Events\RepairWarningEvent; | |||||
if (strpos(@ini_get('disable_functions'), 'set_time_limit') === false) { | if (strpos(@ini_get('disable_functions'), 'set_time_limit') === false) { | ||||
@set_time_limit(0); | @set_time_limit(0); | ||||
$this->l10n = $l10n; | $this->l10n = $l10n; | ||||
} | } | ||||
public function handleRepairFeedback($event): void { | |||||
if (!$event instanceof GenericEvent) { | |||||
return; | |||||
} | |||||
switch ($event->getSubject()) { | |||||
case '\OC\Repair::startProgress': | |||||
$this->progressStateMax = $event->getArgument('max'); | |||||
$this->progressStateStep = 0; | |||||
$this->currentStep = (string)$event->getArgument('step'); | |||||
break; | |||||
case '\OC\Repair::advance': | |||||
$this->progressStateStep += $event->getArgument('step'); | |||||
$desc = $event->getArgument('desc'); | |||||
if (empty($desc)) { | |||||
$desc = $this->currentStep; | |||||
} | |||||
$this->eventSource->send('success', $this->l10n->t('[%d / %d]: %s', [$this->progressStateStep, $this->progressStateMax, $desc])); | |||||
break; | |||||
case '\OC\Repair::finishProgress': | |||||
$this->progressStateMax = $this->progressStateStep; | |||||
$this->eventSource->send('success', $this->l10n->t('[%d / %d]: %s', [$this->progressStateStep, $this->progressStateMax, $this->currentStep])); | |||||
break; | |||||
case '\OC\Repair::step': | |||||
$this->eventSource->send('success', $this->l10n->t('Repair step:') . ' ' . $event->getArgument('step')); | |||||
break; | |||||
case '\OC\Repair::info': | |||||
$this->eventSource->send('success', $this->l10n->t('Repair info:') . ' ' . $event->getArgument('message')); | |||||
break; | |||||
case '\OC\Repair::warning': | |||||
$this->eventSource->send('notice', $this->l10n->t('Repair warning:') . ' ' . $event->getArgument('message')); | |||||
break; | |||||
case '\OC\Repair::error': | |||||
$this->eventSource->send('notice', $this->l10n->t('Repair error:') . ' ' . $event->getArgument('message')); | |||||
break; | |||||
public function handleRepairFeedback(Event $event): void { | |||||
if ($event instanceof RepairStartEvent) { | |||||
$this->progressStateMax = $event->getMaxStep(); | |||||
$this->progressStateStep = 0; | |||||
$this->currentStep = $event->getCurrentStepName(); | |||||
} elseif ($event instanceof RepairAdvanceEvent) { | |||||
$this->progressStateStep += $event->getCurrentStep(); | |||||
$desc = $event->getDescription(); | |||||
if (empty($desc)) { | |||||
$desc = $this->currentStep; | |||||
} | |||||
$this->eventSource->send('success', $this->l10n->t('[%d / %d]: %s', [$this->progressStateStep, $this->progressStateMax, $desc])); | |||||
} elseif ($event instanceof RepairFinishEvent) { | |||||
$this->progressStateMax = $this->progressStateStep; | |||||
$this->eventSource->send('success', $this->l10n->t('[%d / %d]: %s', [$this->progressStateStep, $this->progressStateMax, $this->currentStep])); | |||||
} elseif ($event instanceof RepairStepEvent) { | |||||
$this->eventSource->send('success', $this->l10n->t('Repair step:') . ' ' . $event->getStepName()); | |||||
} elseif ($event instanceof RepairInfoEvent) { | |||||
$this->eventSource->send('success', $this->l10n->t('Repair info:') . ' ' . $event->getMessage()); | |||||
} elseif ($event instanceof RepairWarningEvent) { | |||||
$this->eventSource->send('notice', $this->l10n->t('Repair warning:') . ' ' . $event->getMessage()); | |||||
} elseif ($event instanceof RepairErrorEvent) { | |||||
$this->eventSource->send('notice', $this->l10n->t('Repair error:') . ' ' . $event->getMessage()); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
); | ); | ||||
$incompatibleApps = []; | $incompatibleApps = []; | ||||
$dispatcher = \OC::$server->getEventDispatcher(); | |||||
/** @var IEventDispatcher $newDispatcher */ | |||||
$newDispatcher = \OC::$server->get(IEventDispatcher::class); | |||||
$newDispatcher->addListener(MigratorExecuteSqlEvent::class, function (MigratorExecuteSqlEvent $event) use ($eventSource, $l) { | |||||
/** @var IEventDispatcher $dispatcher */ | |||||
$dispatcher = \OC::$server->get(IEventDispatcher::class); | |||||
$dispatcher->addListener(MigratorExecuteSqlEvent::class, function (MigratorExecuteSqlEvent $event) use ($eventSource, $l) { | |||||
$eventSource->send('success', $l->t('[%d / %d]: %s', [$event->getCurrentStep(), $event->getMaxStep(), $event->getSql()])); | $eventSource->send('success', $l->t('[%d / %d]: %s', [$event->getCurrentStep(), $event->getMaxStep(), $event->getSql()])); | ||||
}); | }); | ||||
$feedBack = new FeedBackHandler($eventSource, $l); | $feedBack = new FeedBackHandler($eventSource, $l); | ||||
$dispatcher->addListener('\OC\Repair::startProgress', [$feedBack, 'handleRepairFeedback']); | |||||
$dispatcher->addListener('\OC\Repair::advance', [$feedBack, 'handleRepairFeedback']); | |||||
$dispatcher->addListener('\OC\Repair::finishProgress', [$feedBack, 'handleRepairFeedback']); | |||||
$dispatcher->addListener('\OC\Repair::step', [$feedBack, 'handleRepairFeedback']); | |||||
$dispatcher->addListener('\OC\Repair::info', [$feedBack, 'handleRepairFeedback']); | |||||
$dispatcher->addListener('\OC\Repair::warning', [$feedBack, 'handleRepairFeedback']); | |||||
$dispatcher->addListener('\OC\Repair::error', [$feedBack, 'handleRepairFeedback']); | |||||
$dispatcher->addListener(RepairStartEvent::class, [$feedBack, 'handleRepairFeedback']); | |||||
$dispatcher->addListener(RepairAdvanceEvent::class, [$feedBack, 'handleRepairFeedback']); | |||||
$dispatcher->addListener(RepairFinishEvent::class, [$feedBack, 'handleRepairFeedback']); | |||||
$dispatcher->addListener(RepairStepEvent::class, [$feedBack, 'handleRepairFeedback']); | |||||
$dispatcher->addListener(RepairInfoEvent::class, [$feedBack, 'handleRepairFeedback']); | |||||
$dispatcher->addListener(RepairWarningEvent::class, [$feedBack, 'handleRepairFeedback']); | |||||
$dispatcher->addListener(RepairErrorEvent::class, [$feedBack, 'handleRepairFeedback']); | |||||
$updater->listen('\OC\Updater', 'maintenanceEnabled', function () use ($eventSource, $l) { | $updater->listen('\OC\Updater', 'maintenanceEnabled', function () use ($eventSource, $l) { | ||||
$eventSource->send('success', $l->t('Turned on maintenance mode')); | $eventSource->send('success', $l->t('Turned on maintenance mode')); |
$application->add(new OC\Core\Command\Upgrade(\OC::$server->getConfig(), \OC::$server->get(LoggerInterface::class), \OC::$server->query(\OC\Installer::class))); | $application->add(new OC\Core\Command\Upgrade(\OC::$server->getConfig(), \OC::$server->get(LoggerInterface::class), \OC::$server->query(\OC\Installer::class))); | ||||
$application->add(new OC\Core\Command\Maintenance\Repair( | $application->add(new OC\Core\Command\Maintenance\Repair( | ||||
new \OC\Repair([], \OC::$server->getEventDispatcher(), \OC::$server->get(LoggerInterface::class)), | |||||
new \OC\Repair([], \OC::$server->get(\OCP\EventDispatcher\IEventDispatcher::class), \OC::$server->get(LoggerInterface::class)), | |||||
\OC::$server->getConfig(), | \OC::$server->getConfig(), | ||||
\OC::$server->getEventDispatcher(), | |||||
\OC::$server->get(\OCP\EventDispatcher\IEventDispatcher::class), | |||||
\OC::$server->getAppManager() | \OC::$server->getAppManager() | ||||
)); | )); | ||||
'OC\\Repair\\ClearFrontendCaches' => $baseDir . '/lib/private/Repair/ClearFrontendCaches.php', | 'OC\\Repair\\ClearFrontendCaches' => $baseDir . '/lib/private/Repair/ClearFrontendCaches.php', | ||||
'OC\\Repair\\ClearGeneratedAvatarCache' => $baseDir . '/lib/private/Repair/ClearGeneratedAvatarCache.php', | 'OC\\Repair\\ClearGeneratedAvatarCache' => $baseDir . '/lib/private/Repair/ClearGeneratedAvatarCache.php', | ||||
'OC\\Repair\\Collation' => $baseDir . '/lib/private/Repair/Collation.php', | 'OC\\Repair\\Collation' => $baseDir . '/lib/private/Repair/Collation.php', | ||||
'OC\\Repair\\Events\\RepairAdvanceEvent' => $baseDir . '/lib/private/Repair/Events/RepairAdvanceEvent.php', | |||||
'OC\\Repair\\Events\\RepairErrorEvent' => $baseDir . '/lib/private/Repair/Events/RepairErrorEvent.php', | |||||
'OC\\Repair\\Events\\RepairFinishEvent' => $baseDir . '/lib/private/Repair/Events/RepairFinishEvent.php', | |||||
'OC\\Repair\\Events\\RepairInfoEvent' => $baseDir . '/lib/private/Repair/Events/RepairInfoEvent.php', | |||||
'OC\\Repair\\Events\\RepairStartEvent' => $baseDir . '/lib/private/Repair/Events/RepairStartEvent.php', | |||||
'OC\\Repair\\Events\\RepairStepEvent' => $baseDir . '/lib/private/Repair/Events/RepairStepEvent.php', | |||||
'OC\\Repair\\Events\\RepairWarningEvent' => $baseDir . '/lib/private/Repair/Events/RepairWarningEvent.php', | |||||
'OC\\Repair\\MoveUpdaterStepFile' => $baseDir . '/lib/private/Repair/MoveUpdaterStepFile.php', | 'OC\\Repair\\MoveUpdaterStepFile' => $baseDir . '/lib/private/Repair/MoveUpdaterStepFile.php', | ||||
'OC\\Repair\\NC11\\FixMountStorages' => $baseDir . '/lib/private/Repair/NC11/FixMountStorages.php', | 'OC\\Repair\\NC11\\FixMountStorages' => $baseDir . '/lib/private/Repair/NC11/FixMountStorages.php', | ||||
'OC\\Repair\\NC13\\AddLogRotateJob' => $baseDir . '/lib/private/Repair/NC13/AddLogRotateJob.php', | 'OC\\Repair\\NC13\\AddLogRotateJob' => $baseDir . '/lib/private/Repair/NC13/AddLogRotateJob.php', |
'OC\\Repair\\ClearFrontendCaches' => __DIR__ . '/../../..' . '/lib/private/Repair/ClearFrontendCaches.php', | 'OC\\Repair\\ClearFrontendCaches' => __DIR__ . '/../../..' . '/lib/private/Repair/ClearFrontendCaches.php', | ||||
'OC\\Repair\\ClearGeneratedAvatarCache' => __DIR__ . '/../../..' . '/lib/private/Repair/ClearGeneratedAvatarCache.php', | 'OC\\Repair\\ClearGeneratedAvatarCache' => __DIR__ . '/../../..' . '/lib/private/Repair/ClearGeneratedAvatarCache.php', | ||||
'OC\\Repair\\Collation' => __DIR__ . '/../../..' . '/lib/private/Repair/Collation.php', | 'OC\\Repair\\Collation' => __DIR__ . '/../../..' . '/lib/private/Repair/Collation.php', | ||||
'OC\\Repair\\Events\\RepairAdvanceEvent' => __DIR__ . '/../../..' . '/lib/private/Repair/Events/RepairAdvanceEvent.php', | |||||
'OC\\Repair\\Events\\RepairErrorEvent' => __DIR__ . '/../../..' . '/lib/private/Repair/Events/RepairErrorEvent.php', | |||||
'OC\\Repair\\Events\\RepairFinishEvent' => __DIR__ . '/../../..' . '/lib/private/Repair/Events/RepairFinishEvent.php', | |||||
'OC\\Repair\\Events\\RepairInfoEvent' => __DIR__ . '/../../..' . '/lib/private/Repair/Events/RepairInfoEvent.php', | |||||
'OC\\Repair\\Events\\RepairStartEvent' => __DIR__ . '/../../..' . '/lib/private/Repair/Events/RepairStartEvent.php', | |||||
'OC\\Repair\\Events\\RepairStepEvent' => __DIR__ . '/../../..' . '/lib/private/Repair/Events/RepairStepEvent.php', | |||||
'OC\\Repair\\Events\\RepairWarningEvent' => __DIR__ . '/../../..' . '/lib/private/Repair/Events/RepairWarningEvent.php', | |||||
'OC\\Repair\\MoveUpdaterStepFile' => __DIR__ . '/../../..' . '/lib/private/Repair/MoveUpdaterStepFile.php', | 'OC\\Repair\\MoveUpdaterStepFile' => __DIR__ . '/../../..' . '/lib/private/Repair/MoveUpdaterStepFile.php', | ||||
'OC\\Repair\\NC11\\FixMountStorages' => __DIR__ . '/../../..' . '/lib/private/Repair/NC11/FixMountStorages.php', | 'OC\\Repair\\NC11\\FixMountStorages' => __DIR__ . '/../../..' . '/lib/private/Repair/NC11/FixMountStorages.php', | ||||
'OC\\Repair\\NC13\\AddLogRotateJob' => __DIR__ . '/../../..' . '/lib/private/Repair/NC13/AddLogRotateJob.php', | 'OC\\Repair\\NC13\\AddLogRotateJob' => __DIR__ . '/../../..' . '/lib/private/Repair/NC13/AddLogRotateJob.php', |
$random = \OC::$server->getSecureRandom(); | $random = \OC::$server->getSecureRandom(); | ||||
$platform = $this->getDatabasePlatform(); | $platform = $this->getDatabasePlatform(); | ||||
$config = \OC::$server->getConfig(); | $config = \OC::$server->getConfig(); | ||||
$dispatcher = \OC::$server->getEventDispatcher(); | |||||
$dispatcher = \OC::$server->get(\OCP\EventDispatcher\IEventDispatcher::class); | |||||
if ($platform instanceof SqlitePlatform) { | if ($platform instanceof SqlitePlatform) { | ||||
return new SQLiteMigrator($this, $config, $dispatcher); | return new SQLiteMigrator($this, $config, $dispatcher); | ||||
} elseif ($platform instanceof OraclePlatform) { | } elseif ($platform instanceof OraclePlatform) { |
public function __construct( | public function __construct( | ||||
string $sql, | string $sql, | ||||
int $current, | int $current, | ||||
int $max, | |||||
int $max | |||||
) { | ) { | ||||
$this->sql = $sql; | $this->sql = $sql; | ||||
$this->current = $current; | $this->current = $current; |
*/ | */ | ||||
namespace OC\Migration; | namespace OC\Migration; | ||||
use OC\NeedsUpdateException; | |||||
use OC\Repair; | |||||
use OC_App; | |||||
use OCP\AppFramework\Utility\ITimeFactory; | use OCP\AppFramework\Utility\ITimeFactory; | ||||
use OCP\BackgroundJob\IJobList; | use OCP\BackgroundJob\IJobList; | ||||
use OCP\BackgroundJob\TimedJob; | use OCP\BackgroundJob\TimedJob; | ||||
use OCP\EventDispatcher\IEventDispatcher; | |||||
use OC\NeedsUpdateException; | |||||
use OC\Repair; | |||||
use OC_App; | |||||
use Psr\Log\LoggerInterface; | use Psr\Log\LoggerInterface; | ||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface; | |||||
/** | /** | ||||
* Class BackgroundRepair | * Class BackgroundRepair | ||||
class BackgroundRepair extends TimedJob { | class BackgroundRepair extends TimedJob { | ||||
private IJobList $jobList; | private IJobList $jobList; | ||||
private LoggerInterface $logger; | private LoggerInterface $logger; | ||||
private EventDispatcherInterface $dispatcher; | |||||
private IEventDispatcher $dispatcher; | |||||
public function __construct(EventDispatcherInterface $dispatcher, ITimeFactory $time, LoggerInterface $logger, IJobList $jobList) { | |||||
public function __construct(IEventDispatcher $dispatcher, ITimeFactory $time, LoggerInterface $logger, IJobList $jobList) { | |||||
parent::__construct($time); | parent::__construct($time); | ||||
$this->dispatcher = $dispatcher; | $this->dispatcher = $dispatcher; | ||||
$this->logger = $logger; | $this->logger = $logger; |
*/ | */ | ||||
namespace OC; | namespace OC; | ||||
use OCP\AppFramework\QueryException; | |||||
use OCP\AppFramework\Utility\ITimeFactory; | |||||
use OCP\Collaboration\Resources\IManager; | |||||
use OCP\EventDispatcher\IEventDispatcher; | |||||
use OCP\Migration\IOutput; | |||||
use OCP\Migration\IRepairStep; | |||||
use OC\App\AppStore\Bundles\BundleFetcher; | use OC\App\AppStore\Bundles\BundleFetcher; | ||||
use OC\Avatar\AvatarManager; | use OC\Avatar\AvatarManager; | ||||
use OC\DB\Connection; | use OC\DB\Connection; | ||||
use OC\Repair\ClearFrontendCaches; | use OC\Repair\ClearFrontendCaches; | ||||
use OC\Repair\ClearGeneratedAvatarCache; | use OC\Repair\ClearGeneratedAvatarCache; | ||||
use OC\Repair\Collation; | use OC\Repair\Collation; | ||||
use OC\Repair\Events\RepairAdvanceEvent; | |||||
use OC\Repair\Events\RepairErrorEvent; | |||||
use OC\Repair\Events\RepairFinishEvent; | |||||
use OC\Repair\Events\RepairInfoEvent; | |||||
use OC\Repair\Events\RepairStartEvent; | |||||
use OC\Repair\Events\RepairStepEvent; | |||||
use OC\Repair\Events\RepairWarningEvent; | |||||
use OC\Repair\MoveUpdaterStepFile; | use OC\Repair\MoveUpdaterStepFile; | ||||
use OC\Repair\NC22\LookupServerSendCheck; | |||||
use OC\Repair\NC24\AddTokenCleanupJob; | |||||
use OC\Repair\Owncloud\CleanPreviews; | |||||
use OC\Repair\Owncloud\MigrateOauthTables; | |||||
use OC\Repair\NC11\FixMountStorages; | use OC\Repair\NC11\FixMountStorages; | ||||
use OC\Repair\Owncloud\MoveAvatars; | |||||
use OC\Repair\Owncloud\InstallCoreBundle; | |||||
use OC\Repair\Owncloud\UpdateLanguageCodes; | |||||
use OC\Repair\NC13\AddLogRotateJob; | use OC\Repair\NC13\AddLogRotateJob; | ||||
use OC\Repair\NC14\AddPreviewBackgroundCleanupJob; | use OC\Repair\NC14\AddPreviewBackgroundCleanupJob; | ||||
use OC\Repair\NC16\AddClenupLoginFlowV2BackgroundJob; | use OC\Repair\NC16\AddClenupLoginFlowV2BackgroundJob; | ||||
use OC\Repair\NC20\ShippedDashboardEnable; | use OC\Repair\NC20\ShippedDashboardEnable; | ||||
use OC\Repair\NC21\AddCheckForUserCertificatesJob; | use OC\Repair\NC21\AddCheckForUserCertificatesJob; | ||||
use OC\Repair\NC21\ValidatePhoneNumber; | use OC\Repair\NC21\ValidatePhoneNumber; | ||||
use OC\Repair\NC22\LookupServerSendCheck; | |||||
use OC\Repair\NC24\AddTokenCleanupJob; | |||||
use OC\Repair\OldGroupMembershipShares; | use OC\Repair\OldGroupMembershipShares; | ||||
use OC\Repair\Owncloud\CleanPreviews; | |||||
use OC\Repair\Owncloud\DropAccountTermsTable; | use OC\Repair\Owncloud\DropAccountTermsTable; | ||||
use OC\Repair\Owncloud\InstallCoreBundle; | |||||
use OC\Repair\Owncloud\MigrateOauthTables; | |||||
use OC\Repair\Owncloud\MoveAvatars; | |||||
use OC\Repair\Owncloud\SaveAccountsTableData; | use OC\Repair\Owncloud\SaveAccountsTableData; | ||||
use OC\Repair\Owncloud\UpdateLanguageCodes; | |||||
use OC\Repair\RemoveLinkShares; | use OC\Repair\RemoveLinkShares; | ||||
use OC\Repair\RepairDavShares; | use OC\Repair\RepairDavShares; | ||||
use OC\Repair\RepairInvalidShares; | use OC\Repair\RepairInvalidShares; | ||||
use OC\Repair\RepairMimeTypes; | use OC\Repair\RepairMimeTypes; | ||||
use OC\Repair\SqliteAutoincrement; | use OC\Repair\SqliteAutoincrement; | ||||
use OC\Template\JSCombiner; | use OC\Template\JSCombiner; | ||||
use OCP\AppFramework\QueryException; | |||||
use OCP\AppFramework\Utility\ITimeFactory; | |||||
use OCP\Collaboration\Resources\IManager; | |||||
use OCP\Migration\IOutput; | |||||
use OCP\Migration\IRepairStep; | |||||
use Psr\Log\LoggerInterface; | use Psr\Log\LoggerInterface; | ||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface; | |||||
use Symfony\Component\EventDispatcher\GenericEvent; | |||||
use Throwable; | use Throwable; | ||||
class Repair implements IOutput { | class Repair implements IOutput { | ||||
/** @var IRepairStep[] */ | /** @var IRepairStep[] */ | ||||
private $repairSteps; | private $repairSteps; | ||||
/** @var EventDispatcherInterface */ | |||||
private $dispatcher; | |||||
private IEventDispatcher $dispatcher; | |||||
/** @var string */ | /** @var string */ | ||||
private $currentStep; | private $currentStep; | ||||
* | * | ||||
* @param IRepairStep[] $repairSteps array of RepairStep instances | * @param IRepairStep[] $repairSteps array of RepairStep instances | ||||
*/ | */ | ||||
public function __construct(array $repairSteps, EventDispatcherInterface $dispatcher, LoggerInterface $logger) { | |||||
public function __construct(array $repairSteps, IEventDispatcher $dispatcher, LoggerInterface $logger) { | |||||
$this->repairSteps = $repairSteps; | $this->repairSteps = $repairSteps; | ||||
$this->dispatcher = $dispatcher; | $this->dispatcher = $dispatcher; | ||||
$this->logger = $logger; | $this->logger = $logger; | ||||
*/ | */ | ||||
public function run() { | public function run() { | ||||
if (count($this->repairSteps) === 0) { | if (count($this->repairSteps) === 0) { | ||||
$this->emit('\OC\Repair', 'info', ['message' => 'No repair steps available']); | |||||
$this->dispatcher->dispatchTyped(new RepairInfoEvent('No repair steps available')); | |||||
return; | return; | ||||
} | } | ||||
// run each repair step | // run each repair step | ||||
foreach ($this->repairSteps as $step) { | foreach ($this->repairSteps as $step) { | ||||
$this->currentStep = $step->getName(); | $this->currentStep = $step->getName(); | ||||
$this->emit('\OC\Repair', 'step', ['step' => $this->currentStep]); | |||||
$this->dispatcher->dispatchTyped(new RepairStepEvent($this->currentStep)); | |||||
try { | try { | ||||
$step->run($this); | $step->run($this); | ||||
} catch (\Exception $e) { | } catch (\Exception $e) { | ||||
$this->logger->error("Exception while executing repair step " . $step->getName(), ['exception' => $e]); | $this->logger->error("Exception while executing repair step " . $step->getName(), ['exception' => $e]); | ||||
$this->emit('\OC\Repair', 'error', ['message' => $e->getMessage()]); | |||||
$this->dispatcher->dispatchTyped(new RepairErrorEvent($e->getMessage())); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
public function addStep($repairStep) { | public function addStep($repairStep) { | ||||
if (is_string($repairStep)) { | if (is_string($repairStep)) { | ||||
try { | try { | ||||
$s = \OC::$server->query($repairStep); | |||||
$s = \OC::$server->get($repairStep); | |||||
} catch (QueryException $e) { | } catch (QueryException $e) { | ||||
if (class_exists($repairStep)) { | if (class_exists($repairStep)) { | ||||
try { | try { | ||||
} | } | ||||
/** | /** | ||||
* @param array<string, mixed> $arguments | |||||
* @param string $message | |||||
*/ | */ | ||||
public function emit(string $scope, string $method, array $arguments = []): void { | |||||
$this->dispatcher->dispatch("$scope::$method", | |||||
new GenericEvent("$scope::$method", $arguments)); | |||||
} | |||||
public function info($string) { | |||||
public function info($message) { | |||||
// for now just emit as we did in the past | // for now just emit as we did in the past | ||||
$this->emit('\OC\Repair', 'info', ['message' => $string]); | |||||
$this->dispatcher->dispatchTyped(new RepairInfoEvent($message)); | |||||
} | } | ||||
/** | /** | ||||
*/ | */ | ||||
public function warning($message) { | public function warning($message) { | ||||
// for now just emit as we did in the past | // for now just emit as we did in the past | ||||
$this->emit('\OC\Repair', 'warning', ['message' => $message]); | |||||
$this->dispatcher->dispatchTyped(new RepairWarningEvent($message)); | |||||
} | } | ||||
/** | /** | ||||
*/ | */ | ||||
public function startProgress($max = 0) { | public function startProgress($max = 0) { | ||||
// for now just emit as we did in the past | // for now just emit as we did in the past | ||||
$this->emit('\OC\Repair', 'startProgress', ['max' => $max, 'step' => $this->currentStep]); | |||||
$this->dispatcher->dispatchTyped(new RepairStartEvent($max, $this->currentStep)); | |||||
} | } | ||||
/** | /** | ||||
*/ | */ | ||||
public function advance($step = 1, $description = '') { | public function advance($step = 1, $description = '') { | ||||
// for now just emit as we did in the past | // for now just emit as we did in the past | ||||
$this->emit('\OC\Repair', 'advance', ['step' => $step, 'desc' => $description]); | |||||
$this->dispatcher->dispatchTyped(new RepairAdvanceEvent($step, $description)); | |||||
} | } | ||||
/** | /** | ||||
*/ | */ | ||||
public function finishProgress() { | public function finishProgress() { | ||||
// for now just emit as we did in the past | // for now just emit as we did in the past | ||||
$this->emit('\OC\Repair', 'finishProgress', []); | |||||
$this->dispatcher->dispatchTyped(new RepairFinishEvent()); | |||||
} | } | ||||
} | } |
<?php | |||||
/** | |||||
* @copyright Copyright (c) 2022 Côme Chilliet <come.chilliet@nextcloud.com> | |||||
* | |||||
* @author Côme Chilliet <come.chilliet@nextcloud.com> | |||||
* | |||||
* @license AGPL-3.0 | |||||
* | |||||
* This code is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Affero General Public License, version 3, | |||||
* as published by the Free Software Foundation. | |||||
* | |||||
* This program is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Affero General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Affero General Public License, version 3, | |||||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||||
* | |||||
*/ | |||||
namespace OC\Repair\Events; | |||||
use OCP\EventDispatcher\Event; | |||||
class RepairAdvanceEvent extends Event { | |||||
// TODO Is that current step or step increment? | |||||
private int $current; | |||||
private string $description; | |||||
public function __construct( | |||||
int $current, | |||||
string $description | |||||
) { | |||||
$this->current = $current; | |||||
$this->description = $description; | |||||
} | |||||
public function getCurrentStep(): int { | |||||
return $this->current; | |||||
} | |||||
public function getDescription(): string { | |||||
return $this->description; | |||||
} | |||||
} |
<?php | |||||
/** | |||||
* @copyright Copyright (c) 2022 Côme Chilliet <come.chilliet@nextcloud.com> | |||||
* | |||||
* @author Côme Chilliet <come.chilliet@nextcloud.com> | |||||
* | |||||
* @license AGPL-3.0 | |||||
* | |||||
* This code is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Affero General Public License, version 3, | |||||
* as published by the Free Software Foundation. | |||||
* | |||||
* This program is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Affero General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Affero General Public License, version 3, | |||||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||||
* | |||||
*/ | |||||
namespace OC\Repair\Events; | |||||
use OCP\EventDispatcher\Event; | |||||
class RepairErrorEvent extends Event { | |||||
private string $message; | |||||
public function __construct( | |||||
string $message | |||||
) { | |||||
$this->message = $message; | |||||
} | |||||
public function getMessage(): string { | |||||
return $this->message; | |||||
} | |||||
} |
<?php | |||||
/** | |||||
* @copyright Copyright (c) 2022 Côme Chilliet <come.chilliet@nextcloud.com> | |||||
* | |||||
* @author Côme Chilliet <come.chilliet@nextcloud.com> | |||||
* | |||||
* @license AGPL-3.0 | |||||
* | |||||
* This code is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Affero General Public License, version 3, | |||||
* as published by the Free Software Foundation. | |||||
* | |||||
* This program is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Affero General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Affero General Public License, version 3, | |||||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||||
* | |||||
*/ | |||||
namespace OC\Repair\Events; | |||||
use OCP\EventDispatcher\Event; | |||||
class RepairFinishEvent extends Event { | |||||
} |
<?php | |||||
/** | |||||
* @copyright Copyright (c) 2022 Côme Chilliet <come.chilliet@nextcloud.com> | |||||
* | |||||
* @author Côme Chilliet <come.chilliet@nextcloud.com> | |||||
* | |||||
* @license AGPL-3.0 | |||||
* | |||||
* This code is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Affero General Public License, version 3, | |||||
* as published by the Free Software Foundation. | |||||
* | |||||
* This program is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Affero General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Affero General Public License, version 3, | |||||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||||
* | |||||
*/ | |||||
namespace OC\Repair\Events; | |||||
use OCP\EventDispatcher\Event; | |||||
class RepairInfoEvent extends Event { | |||||
private string $message; | |||||
public function __construct( | |||||
string $message | |||||
) { | |||||
$this->message = $message; | |||||
} | |||||
public function getMessage(): string { | |||||
return $this->message; | |||||
} | |||||
} |
<?php | |||||
/** | |||||
* @copyright Copyright (c) 2022 Côme Chilliet <come.chilliet@nextcloud.com> | |||||
* | |||||
* @author Côme Chilliet <come.chilliet@nextcloud.com> | |||||
* | |||||
* @license AGPL-3.0 | |||||
* | |||||
* This code is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Affero General Public License, version 3, | |||||
* as published by the Free Software Foundation. | |||||
* | |||||
* This program is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Affero General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Affero General Public License, version 3, | |||||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||||
* | |||||
*/ | |||||
namespace OC\Repair\Events; | |||||
use OCP\EventDispatcher\Event; | |||||
class RepairStartEvent extends Event { | |||||
private int $max; | |||||
private string $current; | |||||
public function __construct( | |||||
int $max, | |||||
string $current | |||||
) { | |||||
$this->max = $max; | |||||
$this->current = $current; | |||||
} | |||||
public function getMaxStep(): int { | |||||
return $this->max; | |||||
} | |||||
public function getCurrentStepName(): string { | |||||
return $this->current; | |||||
} | |||||
} |
<?php | |||||
/** | |||||
* @copyright Copyright (c) 2022 Côme Chilliet <come.chilliet@nextcloud.com> | |||||
* | |||||
* @author Côme Chilliet <come.chilliet@nextcloud.com> | |||||
* | |||||
* @license AGPL-3.0 | |||||
* | |||||
* This code is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Affero General Public License, version 3, | |||||
* as published by the Free Software Foundation. | |||||
* | |||||
* This program is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Affero General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Affero General Public License, version 3, | |||||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||||
* | |||||
*/ | |||||
namespace OC\Repair\Events; | |||||
use OCP\EventDispatcher\Event; | |||||
class RepairStepEvent extends Event { | |||||
private string $stepName; | |||||
public function __construct( | |||||
string $stepName | |||||
) { | |||||
$this->stepName = $stepName; | |||||
} | |||||
public function getStepName(): string { | |||||
return $this->stepName; | |||||
} | |||||
} |
<?php | |||||
/** | |||||
* @copyright Copyright (c) 2022 Côme Chilliet <come.chilliet@nextcloud.com> | |||||
* | |||||
* @author Côme Chilliet <come.chilliet@nextcloud.com> | |||||
* | |||||
* @license AGPL-3.0 | |||||
* | |||||
* This code is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Affero General Public License, version 3, | |||||
* as published by the Free Software Foundation. | |||||
* | |||||
* This program is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Affero General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Affero General Public License, version 3, | |||||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||||
* | |||||
*/ | |||||
namespace OC\Repair\Events; | |||||
use OCP\EventDispatcher\Event; | |||||
class RepairWarningEvent extends Event { | |||||
private string $message; | |||||
public function __construct( | |||||
string $message | |||||
) { | |||||
$this->message = $message; | |||||
} | |||||
public function getMessage(): string { | |||||
return $this->message; | |||||
} | |||||
} |
*/ | */ | ||||
namespace OC; | namespace OC; | ||||
use OCP\App\IAppManager; | |||||
use OCP\EventDispatcher\Event; | |||||
use OCP\EventDispatcher\IEventDispatcher; | |||||
use OCP\HintException; | |||||
use OCP\IConfig; | |||||
use OCP\ILogger; | |||||
use OCP\Util; | |||||
use OC\App\AppManager; | use OC\App\AppManager; | ||||
use OC\DB\Connection; | use OC\DB\Connection; | ||||
use OC\DB\MigrationService; | use OC\DB\MigrationService; | ||||
use OC\DB\MigratorExecuteSqlEvent; | |||||
use OC\Hooks\BasicEmitter; | use OC\Hooks\BasicEmitter; | ||||
use OC\IntegrityCheck\Checker; | use OC\IntegrityCheck\Checker; | ||||
use OC\Repair\Events\RepairAdvanceEvent; | |||||
use OC\Repair\Events\RepairErrorEvent; | |||||
use OC\Repair\Events\RepairFinishEvent; | |||||
use OC\Repair\Events\RepairInfoEvent; | |||||
use OC\Repair\Events\RepairStartEvent; | |||||
use OC\Repair\Events\RepairStepEvent; | |||||
use OC\Repair\Events\RepairWarningEvent; | |||||
use OC_App; | use OC_App; | ||||
use OCP\App\IAppManager; | |||||
use OCP\HintException; | |||||
use OCP\IConfig; | |||||
use OCP\ILogger; | |||||
use OCP\Util; | |||||
use Psr\Log\LoggerInterface; | use Psr\Log\LoggerInterface; | ||||
use Symfony\Component\EventDispatcher\GenericEvent; | |||||
/** | /** | ||||
* Class that handles autoupdating of ownCloud | * Class that handles autoupdating of ownCloud | ||||
* @return bool true if the operation succeeded, false otherwise | * @return bool true if the operation succeeded, false otherwise | ||||
*/ | */ | ||||
public function upgrade(): bool { | public function upgrade(): bool { | ||||
$this->emitRepairEvents(); | |||||
$this->logAllEvents(); | $this->logAllEvents(); | ||||
$logLevel = $this->config->getSystemValue('loglevel', ILogger::WARN); | $logLevel = $this->config->getSystemValue('loglevel', ILogger::WARN); | ||||
file_put_contents($this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/.ocdata', ''); | file_put_contents($this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/.ocdata', ''); | ||||
// pre-upgrade repairs | // pre-upgrade repairs | ||||
$repair = new Repair(Repair::getBeforeUpgradeRepairSteps(), \OC::$server->getEventDispatcher(), \OC::$server->get(LoggerInterface::class)); | |||||
$repair = new Repair(Repair::getBeforeUpgradeRepairSteps(), \OC::$server->get(\OCP\EventDispatcher\IEventDispatcher::class), \OC::$server->get(LoggerInterface::class)); | |||||
$repair->run(); | $repair->run(); | ||||
$this->doCoreUpgrade(); | $this->doCoreUpgrade(); | ||||
} | } | ||||
// post-upgrade repairs | // post-upgrade repairs | ||||
$repair = new Repair(Repair::getRepairSteps(), \OC::$server->getEventDispatcher(), \OC::$server->get(LoggerInterface::class)); | |||||
$repair = new Repair(Repair::getRepairSteps(), \OC::$server->get(\OCP\EventDispatcher\IEventDispatcher::class), \OC::$server->get(LoggerInterface::class)); | |||||
$repair->run(); | $repair->run(); | ||||
//Invalidate update feed | //Invalidate update feed | ||||
} | } | ||||
} | } | ||||
/** | |||||
* Forward messages emitted by the repair routine | |||||
*/ | |||||
private function emitRepairEvents(): void { | |||||
$dispatcher = \OC::$server->getEventDispatcher(); | |||||
$dispatcher->addListener('\OC\Repair::warning', function ($event) { | |||||
if ($event instanceof GenericEvent) { | |||||
$this->emit('\OC\Updater', 'repairWarning', $event->getArguments()); | |||||
} | |||||
}); | |||||
$dispatcher->addListener('\OC\Repair::error', function ($event) { | |||||
if ($event instanceof GenericEvent) { | |||||
$this->emit('\OC\Updater', 'repairError', $event->getArguments()); | |||||
} | |||||
}); | |||||
$dispatcher->addListener('\OC\Repair::info', function ($event) { | |||||
if ($event instanceof GenericEvent) { | |||||
$this->emit('\OC\Updater', 'repairInfo', $event->getArguments()); | |||||
} | |||||
}); | |||||
$dispatcher->addListener('\OC\Repair::step', function ($event) { | |||||
if ($event instanceof GenericEvent) { | |||||
$this->emit('\OC\Updater', 'repairStep', $event->getArguments()); | |||||
} | |||||
}); | |||||
} | |||||
private function logAllEvents(): void { | private function logAllEvents(): void { | ||||
$log = $this->log; | $log = $this->log; | ||||
$dispatcher = \OC::$server->getEventDispatcher(); | |||||
/** @var IEventDispatcher $newDispatcher */ | |||||
$newDispatcher = \OC::$server->get(IEventDispatcher::class); | |||||
$newDispatcher->addListener( | |||||
/** @var IEventDispatcher $dispatcher */ | |||||
$dispatcher = \OC::$server->get(IEventDispatcher::class); | |||||
$dispatcher->addListener( | |||||
MigratorExecuteSqlEvent::class, | MigratorExecuteSqlEvent::class, | ||||
function (MigratorExecuteSqlEvent $event) use ($log) { | function (MigratorExecuteSqlEvent $event) use ($log) { | ||||
$log->info(get_class($event).': ' . $event->getSql() . ' (' . $event->getCurrentStep() . ' of ' . $event->getMaxStep() . ')', ['app' => 'updater']); | $log->info(get_class($event).': ' . $event->getSql() . ' (' . $event->getCurrentStep() . ' of ' . $event->getMaxStep() . ')', ['app' => 'updater']); | ||||
} | } | ||||
); | ); | ||||
$repairListener = function ($event) use ($log) { | |||||
if (!$event instanceof GenericEvent) { | |||||
return; | |||||
} | |||||
switch ($event->getSubject()) { | |||||
case '\OC\Repair::startProgress': | |||||
$log->info('\OC\Repair::startProgress: Starting ... ' . $event->getArgument('max') . ' (' . $event->getArgument('step') . ')', ['app' => 'updater']); | |||||
break; | |||||
case '\OC\Repair::advance': | |||||
$desc = $event->getArgument('desc'); | |||||
if (empty($desc)) { | |||||
$desc = ''; | |||||
} | |||||
$log->info('\OC\Repair::advance: ' . $desc . ' (' . $event->getArgument('step') . ')', ['app' => 'updater']); | |||||
break; | |||||
case '\OC\Repair::finishProgress': | |||||
$log->info('\OC\Repair::finishProgress', ['app' => 'updater']); | |||||
break; | |||||
case '\OC\Repair::step': | |||||
$log->info('\OC\Repair::step: Repair step: ' . $event->getArgument('step'), ['app' => 'updater']); | |||||
break; | |||||
case '\OC\Repair::info': | |||||
$log->info('\OC\Repair::info: Repair info: ' . $event->getArgument('message'), ['app' => 'updater']); | |||||
break; | |||||
case '\OC\Repair::warning': | |||||
$log->warning('\OC\Repair::warning: Repair warning: ' . $event->getArgument('message'), ['app' => 'updater']); | |||||
break; | |||||
case '\OC\Repair::error': | |||||
$log->error('\OC\Repair::error: Repair error: ' . $event->getArgument('message'), ['app' => 'updater']); | |||||
break; | |||||
$repairListener = function (Event $event) use ($log) { | |||||
if ($event instanceof RepairStartEvent) { | |||||
$log->info(get_class($event).': Starting ... ' . $event->getMaxStep() . ' (' . $event->getCurrentStepName() . ')', ['app' => 'updater']); | |||||
} elseif ($event instanceof RepairAdvanceEvent) { | |||||
$desc = $event->getDescription(); | |||||
if (empty($desc)) { | |||||
$desc = ''; | |||||
} | |||||
$log->info(get_class($event).': ' . $desc . ' (' . $event->getCurrentStep() . ')', ['app' => 'updater']); | |||||
} elseif ($event instanceof RepairFinishEvent) { | |||||
$log->info(get_class($event), ['app' => 'updater']); | |||||
} elseif ($event instanceof RepairStepEvent) { | |||||
$log->info(get_class($event).': Repair step: ' . $event->getStepName(), ['app' => 'updater']); | |||||
} elseif ($event instanceof RepairInfoEvent) { | |||||
$log->info(get_class($event).': Repair info: ' . $event->getMessage(), ['app' => 'updater']); | |||||
} elseif ($event instanceof RepairWarningEvent) { | |||||
$log->warning(get_class($event).': Repair warning: ' . $event->getMessage(), ['app' => 'updater']); | |||||
} elseif ($event instanceof RepairErrorEvent) { | |||||
$log->error(get_class($event).': Repair error: ' . $event->getMessage(), ['app' => 'updater']); | |||||
} | } | ||||
}; | }; | ||||
$dispatcher->addListener('\OC\Repair::startProgress', $repairListener); | |||||
$dispatcher->addListener('\OC\Repair::advance', $repairListener); | |||||
$dispatcher->addListener('\OC\Repair::finishProgress', $repairListener); | |||||
$dispatcher->addListener('\OC\Repair::step', $repairListener); | |||||
$dispatcher->addListener('\OC\Repair::info', $repairListener); | |||||
$dispatcher->addListener('\OC\Repair::warning', $repairListener); | |||||
$dispatcher->addListener('\OC\Repair::error', $repairListener); | |||||
$dispatcher->addListener(RepairStartEvent::class, $repairListener); | |||||
$dispatcher->addListener(RepairAdvanceEvent::class, $repairListener); | |||||
$dispatcher->addListener(RepairFinishEvent::class, $repairListener); | |||||
$dispatcher->addListener(RepairStepEvent::class, $repairListener); | |||||
$dispatcher->addListener(RepairInfoEvent::class, $repairListener); | |||||
$dispatcher->addListener(RepairWarningEvent::class, $repairListener); | |||||
$dispatcher->addListener(RepairErrorEvent::class, $repairListener); | |||||
$this->listen('\OC\Updater', 'maintenanceEnabled', function () use ($log) { | $this->listen('\OC\Updater', 'maintenanceEnabled', function () use ($log) { |
* along with this program. If not, see <http://www.gnu.org/licenses/> | * along with this program. If not, see <http://www.gnu.org/licenses/> | ||||
* | * | ||||
*/ | */ | ||||
use OCP\AppFramework\QueryException; | |||||
use OCP\App\ManagerEvent; | |||||
use OCP\Authentication\IAlternativeLogin; | |||||
use OCP\ILogger; | |||||
use OCP\Settings\IManager as ISettingsManager; | |||||
use OC\AppFramework\Bootstrap\Coordinator; | |||||
use OC\App\DependencyAnalyzer; | use OC\App\DependencyAnalyzer; | ||||
use OC\App\Platform; | use OC\App\Platform; | ||||
use OC\AppFramework\Bootstrap\Coordinator; | |||||
use OC\DB\MigrationService; | use OC\DB\MigrationService; | ||||
use OC\Installer; | use OC\Installer; | ||||
use OC\Repair; | use OC\Repair; | ||||
use OC\Repair\Events\RepairErrorEvent; | |||||
use OC\ServerNotAvailableException; | use OC\ServerNotAvailableException; | ||||
use OCP\App\ManagerEvent; | |||||
use OCP\AppFramework\QueryException; | |||||
use OCP\Authentication\IAlternativeLogin; | |||||
use OCP\ILogger; | |||||
use OCP\Settings\IManager as ISettingsManager; | |||||
use Psr\Log\LoggerInterface; | use Psr\Log\LoggerInterface; | ||||
/** | /** | ||||
// load the app | // load the app | ||||
self::loadApp($appId); | self::loadApp($appId); | ||||
$dispatcher = OC::$server->getEventDispatcher(); | |||||
$dispatcher = \OC::$server->get(\OCP\EventDispatcher\IEventDispatcher::class); | |||||
// load the steps | // load the steps | ||||
$r = new Repair([], $dispatcher, \OC::$server->get(LoggerInterface::class)); | $r = new Repair([], $dispatcher, \OC::$server->get(LoggerInterface::class)); | ||||
try { | try { | ||||
$r->addStep($step); | $r->addStep($step); | ||||
} catch (Exception $ex) { | } catch (Exception $ex) { | ||||
$r->emit('\OC\Repair', 'error', ['message' => $ex->getMessage()]); | |||||
$dispatcher->dispatchTyped(new RepairErrorEvent($ex->getMessage())); | |||||
\OC::$server->getLogger()->logException($ex); | \OC::$server->getLogger()->logException($ex); | ||||
} | } | ||||
} | } |
/** | /** | ||||
* @param string $message | * @param string $message | ||||
* @return void | |||||
* @since 9.1.0 | * @since 9.1.0 | ||||
*/ | */ | ||||
public function info($message); | public function info($message); | ||||
/** | /** | ||||
* @param string $message | * @param string $message | ||||
* @return void | |||||
* @since 9.1.0 | * @since 9.1.0 | ||||
*/ | */ | ||||
public function warning($message); | public function warning($message); | ||||
/** | /** | ||||
* @param int $max | * @param int $max | ||||
* @return void | |||||
* @since 9.1.0 | * @since 9.1.0 | ||||
*/ | */ | ||||
public function startProgress($max = 0); | public function startProgress($max = 0); | ||||
/** | /** | ||||
* @param int $step | * @param int $step | ||||
* @param string $description | * @param string $description | ||||
* @return void | |||||
* @since 9.1.0 | * @since 9.1.0 | ||||
*/ | */ | ||||
public function advance($step = 1, $description = ''); | public function advance($step = 1, $description = ''); | ||||
/** | /** | ||||
* @param int $max | |||||
* @return void | |||||
* @since 9.1.0 | * @since 9.1.0 | ||||
*/ | */ | ||||
public function finishProgress(); | public function finishProgress(); |