Skip to content

Commit ddbc6a8

Browse files
committed
feat: add command to check files_external dependencies
Signed-off-by: Robin Appelman <robin@icewind.nl>
1 parent 0dc9711 commit ddbc6a8

File tree

7 files changed

+98
-5
lines changed

7 files changed

+98
-5
lines changed

apps/files_external/appinfo/info.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ External storage can be configured using the GUI or at the command line. This se
5353
<command>OCA\Files_External\Command\Verify</command>
5454
<command>OCA\Files_External\Command\Notify</command>
5555
<command>OCA\Files_External\Command\Scan</command>
56+
<command>OCA\Files_External\Command\Dependencies</command>
5657
</commands>
5758

5859
<settings>

apps/files_external/composer/composer/autoload_classmap.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
'OCA\\Files_External\\Command\\Config' => $baseDir . '/../lib/Command/Config.php',
1515
'OCA\\Files_External\\Command\\Create' => $baseDir . '/../lib/Command/Create.php',
1616
'OCA\\Files_External\\Command\\Delete' => $baseDir . '/../lib/Command/Delete.php',
17+
'OCA\\Files_External\\Command\\Dependencies' => $baseDir . '/../lib/Command/Dependencies.php',
1718
'OCA\\Files_External\\Command\\Export' => $baseDir . '/../lib/Command/Export.php',
1819
'OCA\\Files_External\\Command\\Import' => $baseDir . '/../lib/Command/Import.php',
1920
'OCA\\Files_External\\Command\\ListCommand' => $baseDir . '/../lib/Command/ListCommand.php',

apps/files_external/composer/composer/autoload_static.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class ComposerStaticInitFiles_External
2929
'OCA\\Files_External\\Command\\Config' => __DIR__ . '/..' . '/../lib/Command/Config.php',
3030
'OCA\\Files_External\\Command\\Create' => __DIR__ . '/..' . '/../lib/Command/Create.php',
3131
'OCA\\Files_External\\Command\\Delete' => __DIR__ . '/..' . '/../lib/Command/Delete.php',
32+
'OCA\\Files_External\\Command\\Dependencies' => __DIR__ . '/..' . '/../lib/Command/Dependencies.php',
3233
'OCA\\Files_External\\Command\\Export' => __DIR__ . '/..' . '/../lib/Command/Export.php',
3334
'OCA\\Files_External\\Command\\Import' => __DIR__ . '/..' . '/../lib/Command/Import.php',
3435
'OCA\\Files_External\\Command\\ListCommand' => __DIR__ . '/..' . '/../lib/Command/ListCommand.php',
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
/**
3+
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
4+
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
5+
* SPDX-License-Identifier: AGPL-3.0-only
6+
*/
7+
namespace OCA\Files_External\Command;
8+
9+
use OC\Core\Command\Base;
10+
use OCA\Files_External\Lib\Auth\AuthMechanism;
11+
use OCA\Files_External\Lib\Backend\Backend;
12+
use OCA\Files_External\Lib\DefinitionParameter;
13+
use OCA\Files_External\Service\BackendService;
14+
use Symfony\Component\Console\Input\InputArgument;
15+
use Symfony\Component\Console\Input\InputInterface;
16+
use Symfony\Component\Console\Output\OutputInterface;
17+
18+
class Dependencies extends Base {
19+
public function __construct(
20+
private readonly BackendService $backendService,
21+
) {
22+
parent::__construct();
23+
}
24+
25+
protected function configure(): void {
26+
$this
27+
->setName('files_external:dependencies')
28+
->setDescription('Show information about the backend dependencies');
29+
parent::configure();
30+
}
31+
32+
protected function execute(InputInterface $input, OutputInterface $output): int {
33+
$storageBackends = $this->backendService->getBackends();
34+
35+
$anyMissing = false;
36+
37+
foreach ($storageBackends as $backend) {
38+
if ($backend->getDeprecateTo() !== null) {
39+
continue;
40+
}
41+
$missingDependencies = $backend->checkDependencies();
42+
if ($missingDependencies) {
43+
$anyMissing = true;
44+
$output->writeln($backend->getText() . ':');
45+
foreach ($missingDependencies as $missingDependency) {
46+
if ($missingDependency->getMessage()) {
47+
$output->writeln(" - <comment>{$missingDependency->getDependency()}</comment>: {$missingDependency->getMessage()}");
48+
} else {
49+
$output->writeln(" - <comment>{$missingDependency->getDependency()}</comment>");
50+
}
51+
}
52+
}
53+
}
54+
55+
if (!$anyMissing) {
56+
$output->writeln("<info>All dependencies are met</info>");
57+
}
58+
59+
return self::SUCCESS;
60+
}
61+
}

apps/files_external/lib/Lib/Backend/SMB.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,21 @@
1010
use Icewind\SMB\BasicAuth;
1111
use Icewind\SMB\KerberosApacheAuth;
1212
use Icewind\SMB\KerberosAuth;
13+
use Icewind\SMB\Native\NativeServer;
14+
use Icewind\SMB\Wrapped\Server;
1315
use OCA\Files_External\Lib\Auth\AuthMechanism;
1416
use OCA\Files_External\Lib\Auth\Password\Password;
1517
use OCA\Files_External\Lib\Auth\SMB\KerberosApacheAuth as KerberosApacheAuthMechanism;
1618
use OCA\Files_External\Lib\DefinitionParameter;
1719
use OCA\Files_External\Lib\InsufficientDataForMeaningfulAnswerException;
1820
use OCA\Files_External\Lib\LegacyDependencyCheckPolyfill;
21+
use OCA\Files_External\Lib\MissingDependency;
22+
use OCA\Files_External\Lib\Storage\SystemBridge;
1923
use OCA\Files_External\Lib\StorageConfig;
2024
use OCP\IL10N;
2125
use OCP\IUser;
2226

2327
class SMB extends Backend {
24-
use LegacyDependencyCheckPolyfill;
25-
2628
public function __construct(IL10N $l, Password $legacyAuth) {
2729
$this
2830
->setIdentifier('smb')
@@ -122,4 +124,20 @@ public function manipulateStorageConfig(StorageConfig &$storage, ?IUser $user =
122124

123125
$storage->setBackendOption('auth', $smbAuth);
124126
}
127+
128+
public function checkDependencies() {
129+
$system = \OCP\Server::get(SystemBridge::class);
130+
if (NativeServer::available($system)) {
131+
return [];
132+
} else if (Server::available($system)) {
133+
$missing = new MissingDependency('php-smbclient');
134+
$missing->setOptional(true);
135+
$missing->setMessage("The php-smbclient library provides improved compatibility and performance for SMB storages.");
136+
return [$missing];
137+
} else {
138+
$missing = new MissingDependency('php-smbclient');
139+
$missing->setMessage("Either the php-smbclient library (preferred) or the smbclient binary is required for SMB storages.");
140+
return [$missing, new MissingDependency('smbclient')];
141+
}
142+
}
125143
}

apps/files_external/lib/Lib/MissingDependency.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@
1212
class MissingDependency {
1313

1414
/** @var string|null Custom message */
15-
private $message = null;
15+
private ?string $message = null;
16+
private bool $optional = false;
1617

1718
/**
1819
* @param string $dependency
1920
*/
2021
public function __construct(
21-
private $dependency,
22+
private readonly string $dependency,
2223
) {
2324
}
2425

@@ -38,4 +39,12 @@ public function setMessage($message) {
3839
$this->message = $message;
3940
return $this;
4041
}
42+
43+
public function isOptional(): bool {
44+
return $this->optional;
45+
}
46+
47+
public function setOptional(bool $optional): void {
48+
$this->optional = $optional;
49+
}
4150
}

apps/files_external/lib/Service/BackendService.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use OCA\Files_External\Lib\Backend\Backend;
1313
use OCA\Files_External\Lib\Config\IAuthMechanismProvider;
1414
use OCA\Files_External\Lib\Config\IBackendProvider;
15+
use OCA\Files_External\Lib\MissingDependency;
1516
use OCP\EventDispatcher\GenericEvent;
1617
use OCP\EventDispatcher\IEventDispatcher;
1718
use OCP\IAppConfig;
@@ -187,7 +188,8 @@ public function getBackends() {
187188
*/
188189
public function getAvailableBackends() {
189190
return array_filter($this->getBackends(), function ($backend) {
190-
return !$backend->checkDependencies();
191+
$missing = array_filter($backend->checkDependencies(), fn (MissingDependency $dependency) => !$dependency->isOptional());
192+
return count($missing) === 0;
191193
});
192194
}
193195

0 commit comments

Comments
 (0)