Merge pull request #52681 from nextcloud/occ-external-dependencies

feat: add command to check files_external dependencies
pull/52688/head
Robin Appelman 5 months ago committed by GitHub
commit 56897b6f3c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      apps/files_external/appinfo/info.xml
  2. 1
      apps/files_external/composer/composer/autoload_classmap.php
  3. 1
      apps/files_external/composer/composer/autoload_static.php
  4. 56
      apps/files_external/lib/Command/Dependencies.php
  5. 23
      apps/files_external/lib/Lib/Backend/SMB.php
  6. 13
      apps/files_external/lib/Lib/MissingDependency.php
  7. 4
      apps/files_external/lib/Service/BackendService.php

@ -53,6 +53,7 @@ External storage can be configured using the GUI or at the command line. This se
<command>OCA\Files_External\Command\Verify</command> <command>OCA\Files_External\Command\Verify</command>
<command>OCA\Files_External\Command\Notify</command> <command>OCA\Files_External\Command\Notify</command>
<command>OCA\Files_External\Command\Scan</command> <command>OCA\Files_External\Command\Scan</command>
<command>OCA\Files_External\Command\Dependencies</command>
</commands> </commands>
<settings> <settings>

@ -14,6 +14,7 @@ return array(
'OCA\\Files_External\\Command\\Config' => $baseDir . '/../lib/Command/Config.php', 'OCA\\Files_External\\Command\\Config' => $baseDir . '/../lib/Command/Config.php',
'OCA\\Files_External\\Command\\Create' => $baseDir . '/../lib/Command/Create.php', 'OCA\\Files_External\\Command\\Create' => $baseDir . '/../lib/Command/Create.php',
'OCA\\Files_External\\Command\\Delete' => $baseDir . '/../lib/Command/Delete.php', 'OCA\\Files_External\\Command\\Delete' => $baseDir . '/../lib/Command/Delete.php',
'OCA\\Files_External\\Command\\Dependencies' => $baseDir . '/../lib/Command/Dependencies.php',
'OCA\\Files_External\\Command\\Export' => $baseDir . '/../lib/Command/Export.php', 'OCA\\Files_External\\Command\\Export' => $baseDir . '/../lib/Command/Export.php',
'OCA\\Files_External\\Command\\Import' => $baseDir . '/../lib/Command/Import.php', 'OCA\\Files_External\\Command\\Import' => $baseDir . '/../lib/Command/Import.php',
'OCA\\Files_External\\Command\\ListCommand' => $baseDir . '/../lib/Command/ListCommand.php', 'OCA\\Files_External\\Command\\ListCommand' => $baseDir . '/../lib/Command/ListCommand.php',

@ -29,6 +29,7 @@ class ComposerStaticInitFiles_External
'OCA\\Files_External\\Command\\Config' => __DIR__ . '/..' . '/../lib/Command/Config.php', 'OCA\\Files_External\\Command\\Config' => __DIR__ . '/..' . '/../lib/Command/Config.php',
'OCA\\Files_External\\Command\\Create' => __DIR__ . '/..' . '/../lib/Command/Create.php', 'OCA\\Files_External\\Command\\Create' => __DIR__ . '/..' . '/../lib/Command/Create.php',
'OCA\\Files_External\\Command\\Delete' => __DIR__ . '/..' . '/../lib/Command/Delete.php', 'OCA\\Files_External\\Command\\Delete' => __DIR__ . '/..' . '/../lib/Command/Delete.php',
'OCA\\Files_External\\Command\\Dependencies' => __DIR__ . '/..' . '/../lib/Command/Dependencies.php',
'OCA\\Files_External\\Command\\Export' => __DIR__ . '/..' . '/../lib/Command/Export.php', 'OCA\\Files_External\\Command\\Export' => __DIR__ . '/..' . '/../lib/Command/Export.php',
'OCA\\Files_External\\Command\\Import' => __DIR__ . '/..' . '/../lib/Command/Import.php', 'OCA\\Files_External\\Command\\Import' => __DIR__ . '/..' . '/../lib/Command/Import.php',
'OCA\\Files_External\\Command\\ListCommand' => __DIR__ . '/..' . '/../lib/Command/ListCommand.php', 'OCA\\Files_External\\Command\\ListCommand' => __DIR__ . '/..' . '/../lib/Command/ListCommand.php',

@ -0,0 +1,56 @@
<?php
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Files_External\Command;
use OC\Core\Command\Base;
use OCA\Files_External\Service\BackendService;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class Dependencies extends Base {
public function __construct(
private readonly BackendService $backendService,
) {
parent::__construct();
}
protected function configure(): void {
$this
->setName('files_external:dependencies')
->setDescription('Show information about the backend dependencies');
parent::configure();
}
protected function execute(InputInterface $input, OutputInterface $output): int {
$storageBackends = $this->backendService->getBackends();
$anyMissing = false;
foreach ($storageBackends as $backend) {
if ($backend->getDeprecateTo() !== null) {
continue;
}
$missingDependencies = $backend->checkDependencies();
if ($missingDependencies) {
$anyMissing = true;
$output->writeln($backend->getText() . ':');
foreach ($missingDependencies as $missingDependency) {
if ($missingDependency->getMessage()) {
$output->writeln(" - <comment>{$missingDependency->getDependency()}</comment>: {$missingDependency->getMessage()}");
} else {
$output->writeln(" - <comment>{$missingDependency->getDependency()}</comment>");
}
}
}
}
if (!$anyMissing) {
$output->writeln('<info>All dependencies are met</info>');
}
return self::SUCCESS;
}
}

@ -10,19 +10,20 @@ namespace OCA\Files_External\Lib\Backend;
use Icewind\SMB\BasicAuth; use Icewind\SMB\BasicAuth;
use Icewind\SMB\KerberosApacheAuth; use Icewind\SMB\KerberosApacheAuth;
use Icewind\SMB\KerberosAuth; use Icewind\SMB\KerberosAuth;
use Icewind\SMB\Native\NativeServer;
use Icewind\SMB\Wrapped\Server;
use OCA\Files_External\Lib\Auth\AuthMechanism; use OCA\Files_External\Lib\Auth\AuthMechanism;
use OCA\Files_External\Lib\Auth\Password\Password; use OCA\Files_External\Lib\Auth\Password\Password;
use OCA\Files_External\Lib\Auth\SMB\KerberosApacheAuth as KerberosApacheAuthMechanism; use OCA\Files_External\Lib\Auth\SMB\KerberosApacheAuth as KerberosApacheAuthMechanism;
use OCA\Files_External\Lib\DefinitionParameter; use OCA\Files_External\Lib\DefinitionParameter;
use OCA\Files_External\Lib\InsufficientDataForMeaningfulAnswerException; use OCA\Files_External\Lib\InsufficientDataForMeaningfulAnswerException;
use OCA\Files_External\Lib\LegacyDependencyCheckPolyfill; use OCA\Files_External\Lib\MissingDependency;
use OCA\Files_External\Lib\Storage\SystemBridge;
use OCA\Files_External\Lib\StorageConfig; use OCA\Files_External\Lib\StorageConfig;
use OCP\IL10N; use OCP\IL10N;
use OCP\IUser; use OCP\IUser;
class SMB extends Backend { class SMB extends Backend {
use LegacyDependencyCheckPolyfill;
public function __construct(IL10N $l, Password $legacyAuth) { public function __construct(IL10N $l, Password $legacyAuth) {
$this $this
->setIdentifier('smb') ->setIdentifier('smb')
@ -122,4 +123,20 @@ class SMB extends Backend {
$storage->setBackendOption('auth', $smbAuth); $storage->setBackendOption('auth', $smbAuth);
} }
public function checkDependencies() {
$system = \OCP\Server::get(SystemBridge::class);
if (NativeServer::available($system)) {
return [];
} elseif (Server::available($system)) {
$missing = new MissingDependency('php-smbclient');
$missing->setOptional(true);
$missing->setMessage('The php-smbclient library provides improved compatibility and performance for SMB storages.');
return [$missing];
} else {
$missing = new MissingDependency('php-smbclient');
$missing->setMessage('Either the php-smbclient library (preferred) or the smbclient binary is required for SMB storages.');
return [$missing, new MissingDependency('smbclient')];
}
}
} }

@ -12,13 +12,14 @@ namespace OCA\Files_External\Lib;
class MissingDependency { class MissingDependency {
/** @var string|null Custom message */ /** @var string|null Custom message */
private $message = null; private ?string $message = null;
private bool $optional = false;
/** /**
* @param string $dependency * @param string $dependency
*/ */
public function __construct( public function __construct(
private $dependency, private readonly string $dependency,
) { ) {
} }
@ -38,4 +39,12 @@ class MissingDependency {
$this->message = $message; $this->message = $message;
return $this; return $this;
} }
public function isOptional(): bool {
return $this->optional;
}
public function setOptional(bool $optional): void {
$this->optional = $optional;
}
} }

@ -12,6 +12,7 @@ use OCA\Files_External\Lib\Auth\AuthMechanism;
use OCA\Files_External\Lib\Backend\Backend; use OCA\Files_External\Lib\Backend\Backend;
use OCA\Files_External\Lib\Config\IAuthMechanismProvider; use OCA\Files_External\Lib\Config\IAuthMechanismProvider;
use OCA\Files_External\Lib\Config\IBackendProvider; use OCA\Files_External\Lib\Config\IBackendProvider;
use OCA\Files_External\Lib\MissingDependency;
use OCP\EventDispatcher\GenericEvent; use OCP\EventDispatcher\GenericEvent;
use OCP\EventDispatcher\IEventDispatcher; use OCP\EventDispatcher\IEventDispatcher;
use OCP\IAppConfig; use OCP\IAppConfig;
@ -187,7 +188,8 @@ class BackendService {
*/ */
public function getAvailableBackends() { public function getAvailableBackends() {
return array_filter($this->getBackends(), function ($backend) { return array_filter($this->getBackends(), function ($backend) {
return !$backend->checkDependencies(); $missing = array_filter($backend->checkDependencies(), fn (MissingDependency $dependency) => !$dependency->isOptional());
return count($missing) === 0;
}); });
} }

Loading…
Cancel
Save