Skip to content

Commit

Permalink
feat: only load available commands in maintenance mode
Browse files Browse the repository at this point in the history
Signed-off-by: Daniel Kesselberg <[email protected]>
  • Loading branch information
kesselb committed Apr 24, 2023
1 parent f4f6431 commit 19ddc24
Show file tree
Hide file tree
Showing 9 changed files with 229 additions and 143 deletions.
42 changes: 42 additions & 0 deletions core/Command/CommandUnavailableInMaintenanceMode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php
/**
* @copyright Daniel Kesselberg <[email protected]>
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

namespace OC\Core\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class CommandUnavailableInMaintenanceMode extends Command {
protected function configure(): void {
$this
->setName('command-unavailable-in-maintenance-mode')
->setAliases([
'user:add',
'user:delete',
])
->setHidden(true);
}

protected function execute(InputInterface $input, OutputInterface $output): int {
$output->writeln('<error>The command "' . $input->getArgument('command') . '" is unavailable in maintenance mode.</error>');
return 1;
}
}
3 changes: 2 additions & 1 deletion core/Command/User/Add.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
namespace OC\Core\Command\User;

use OC\Files\Filesystem;
use OCP\Command\IUnavailableInMaintenanceMode;
use OCP\IGroup;
use OCP\IGroupManager;
use OCP\IUser;
Expand All @@ -38,7 +39,7 @@
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;

class Add extends Command {
class Add extends Command implements IUnavailableInMaintenanceMode {
protected IUserManager $userManager;
protected IGroupManager $groupManager;

Expand Down
3 changes: 2 additions & 1 deletion core/Command/User/Delete.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,15 @@
namespace OC\Core\Command\User;

use OC\Core\Command\Base;
use OCP\Command\IUnavailableInMaintenanceMode;
use OCP\IUser;
use OCP\IUserManager;
use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class Delete extends Base {
class Delete extends Base implements IUnavailableInMaintenanceMode {
/** @var IUserManager */
protected $userManager;

Expand Down
222 changes: 116 additions & 106 deletions core/register_command.php

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions lib/composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@
'OCP\\Color' => $baseDir . '/lib/public/Color.php',
'OCP\\Command\\IBus' => $baseDir . '/lib/public/Command/IBus.php',
'OCP\\Command\\ICommand' => $baseDir . '/lib/public/Command/ICommand.php',
'OCP\\Command\\IUnavailableInMaintenanceMode' => $baseDir . '/lib/public/Command/IUnavailableInMaintenanceMode.php',
'OCP\\Comments\\CommentsEntityEvent' => $baseDir . '/lib/public/Comments/CommentsEntityEvent.php',
'OCP\\Comments\\CommentsEvent' => $baseDir . '/lib/public/Comments/CommentsEvent.php',
'OCP\\Comments\\IComment' => $baseDir . '/lib/public/Comments/IComment.php',
Expand Down Expand Up @@ -910,6 +911,7 @@
'OC\\Core\\Command\\Base' => $baseDir . '/core/Command/Base.php',
'OC\\Core\\Command\\Broadcast\\Test' => $baseDir . '/core/Command/Broadcast/Test.php',
'OC\\Core\\Command\\Check' => $baseDir . '/core/Command/Check.php',
'OC\\Core\\Command\\CommandUnavailableInMaintenanceMode' => $baseDir . '/core/Command/CommandUnavailableInMaintenanceMode.php',
'OC\\Core\\Command\\Config\\App\\Base' => $baseDir . '/core/Command/Config/App/Base.php',
'OC\\Core\\Command\\Config\\App\\DeleteConfig' => $baseDir . '/core/Command/Config/App/DeleteConfig.php',
'OC\\Core\\Command\\Config\\App\\GetConfig' => $baseDir . '/core/Command/Config/App/GetConfig.php',
Expand Down
2 changes: 2 additions & 0 deletions lib/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\Color' => __DIR__ . '/../../..' . '/lib/public/Color.php',
'OCP\\Command\\IBus' => __DIR__ . '/../../..' . '/lib/public/Command/IBus.php',
'OCP\\Command\\ICommand' => __DIR__ . '/../../..' . '/lib/public/Command/ICommand.php',
'OCP\\Command\\IUnavailableInMaintenanceMode' => __DIR__ . '/../../..' . '/lib/public/Command/IUnavailableInMaintenanceMode.php',
'OCP\\Comments\\CommentsEntityEvent' => __DIR__ . '/../../..' . '/lib/public/Comments/CommentsEntityEvent.php',
'OCP\\Comments\\CommentsEvent' => __DIR__ . '/../../..' . '/lib/public/Comments/CommentsEvent.php',
'OCP\\Comments\\IComment' => __DIR__ . '/../../..' . '/lib/public/Comments/IComment.php',
Expand Down Expand Up @@ -943,6 +944,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Core\\Command\\Base' => __DIR__ . '/../../..' . '/core/Command/Base.php',
'OC\\Core\\Command\\Broadcast\\Test' => __DIR__ . '/../../..' . '/core/Command/Broadcast/Test.php',
'OC\\Core\\Command\\Check' => __DIR__ . '/../../..' . '/core/Command/Check.php',
'OC\\Core\\Command\\CommandUnavailableInMaintenanceMode' => __DIR__ . '/../../..' . '/core/Command/CommandUnavailableInMaintenanceMode.php',
'OC\\Core\\Command\\Config\\App\\Base' => __DIR__ . '/../../..' . '/core/Command/Config/App/Base.php',
'OC\\Core\\Command\\Config\\App\\DeleteConfig' => __DIR__ . '/../../..' . '/core/Command/Config/App/DeleteConfig.php',
'OC\\Core\\Command\\Config\\App\\GetConfig' => __DIR__ . '/../../..' . '/core/Command/Config/App/GetConfig.php',
Expand Down
14 changes: 7 additions & 7 deletions lib/composer/composer/installed.php
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
<?php return array(
'root' => array(
'pretty_version' => '1.0.0+no-version-set',
'version' => '1.0.0.0',
'name' => '__root__',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => 'f5e7a1fbc40d93be93c9f4891a90fdcd3a1eedd4',
'type' => 'library',
'install_path' => __DIR__ . '/../../../',
'aliases' => array(),
'reference' => NULL,
'name' => '__root__',
'dev' => false,
),
'versions' => array(
'__root__' => array(
'pretty_version' => '1.0.0+no-version-set',
'version' => '1.0.0.0',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => 'f5e7a1fbc40d93be93c9f4891a90fdcd3a1eedd4',
'type' => 'library',
'install_path' => __DIR__ . '/../../../',
'aliases' => array(),
'reference' => NULL,
'dev_requirement' => false,
),
),
Expand Down
51 changes: 23 additions & 28 deletions lib/private/Console/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,15 @@
use OC\MemoryInfo;
use OC\NeedsUpdateException;
use OC_App;
use OCP\AppFramework\QueryException;
use OCP\App\IAppManager;
use OCP\AppFramework\QueryException;
use OCP\Command\IUnavailableInMaintenanceMode;
use OCP\Console\ConsoleEvent;
use OCP\IConfig;
use OCP\IRequest;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Application as SymfonyApplication;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
Expand All @@ -59,6 +61,8 @@ class Application {
/** @var MemoryInfo */
private $memoryInfo;

private bool $maintenanceMode;

public function __construct(IConfig $config,
EventDispatcherInterface $dispatcher,
IRequest $request,
Expand All @@ -71,6 +75,22 @@ public function __construct(IConfig $config,
$this->request = $request;
$this->logger = $logger;
$this->memoryInfo = $memoryInfo;
$this->maintenanceMode = $this->config->getSystemValueBool('maintenance');
}

/**
* Adds a command object.
*
* If a command with the same name already exists, it will be overridden.
* If the command is not enabled it will not be added.
*
* @return Command|null The registered command if enabled or null
*/
public function add(Command $command) {
if ($this->maintenanceMode && $command instanceof IUnavailableInMaintenanceMode) {
return null;
}
return $this->application->add($command);
}

/**
Expand Down Expand Up @@ -115,9 +135,7 @@ public function loadCommands(
if ($this->config->getSystemValueBool('installed', false)) {
if (\OCP\Util::needUpgrade()) {
throw new NeedsUpdateException();
} elseif ($this->config->getSystemValueBool('maintenance')) {
$this->writeMaintenanceModeInfo($input, $output);
} else {
} elseif (!$this->maintenanceMode) {
OC_App::loadApps();
$appManager = \OCP\Server::get(IAppManager::class);
foreach ($appManager->getInstalledApps() as $app) {
Expand Down Expand Up @@ -169,29 +187,6 @@ public function loadCommands(
}
}

/**
* Write a maintenance mode info.
* The commands "_completion" and "maintenance:mode" are excluded.
*
* @param InputInterface $input The input implementation for reading inputs.
* @param ConsoleOutputInterface $output The output implementation
* for writing outputs.
* @return void
*/
private function writeMaintenanceModeInfo(
InputInterface $input, ConsoleOutputInterface $output
) {
if ($input->getArgument('command') !== '_completion'
&& $input->getArgument('command') !== 'maintenance:mode'
&& $input->getArgument('command') !== 'status') {
$errOutput = $output->getErrorOutput();
$errOutput->writeln(
'<comment>Nextcloud is in maintenance mode, hence the database isn\'t accessible.' . PHP_EOL .
'Cannot perform any command except \'maintenance:mode --off\'</comment>' . PHP_EOL
);
}
}

/**
* Sets whether to automatically exit after a command execution or not.
*
Expand Down Expand Up @@ -231,7 +226,7 @@ private function loadCommandsFromInfoXml($commands) {
}
}

$this->application->add($c);
$this->add($c);
}
}
}
33 changes: 33 additions & 0 deletions lib/public/Command/IUnavailableInMaintenanceMode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types = 1);
/**
* @copyright Daniel Kesselberg <[email protected]>
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

namespace OCP\Command;

/**
* Implement if a command is unavailable in maintenance mode.
*
* Use this interface if your command is unavailable during maintenance mode enabled.
*
* @since 27.0.0
*/
interface IUnavailableInMaintenanceMode {
}

0 comments on commit 19ddc24

Please sign in to comment.