]> source.dussan.org Git - nextcloud-server.git/commitdiff
Allow ext storage Local to go unavailable 39707/head
authorVincent Petry <pvince81@yahoo.fr>
Thu, 3 Aug 2023 21:09:17 +0000 (23:09 +0200)
committerSimon L <szaimen@e.mail.de>
Tue, 29 Aug 2023 09:04:31 +0000 (11:04 +0200)
Whenever an external storage of type Local points at a non-existing
directory, process this as a StorageNotAvailable instead of returning
404.

This makes desktop clients ignore the folder instead of deleting it when
it becomes unavailable.

The code change was limited to external storages to avoid issues during
setup and with the default home storage.
Signed-off-by: Vincent Petry <pvince81@yahoo.fr>
apps/files_external/lib/Lib/Backend/Local.php
lib/private/Files/Storage/Local.php
tests/lib/Files/Storage/LocalTest.php

index 88b251360d678585132abb365a87f6d2dfb421ff..bd15cb461271bcf77a200c43ef558d086f25691d 100644 (file)
@@ -26,8 +26,10 @@ namespace OCA\Files_External\Lib\Backend;
 use OCA\Files_External\Lib\Auth\AuthMechanism;
 use OCA\Files_External\Lib\Auth\NullMechanism;
 use OCA\Files_External\Lib\DefinitionParameter;
+use OCA\Files_External\Lib\StorageConfig;
 use OCA\Files_External\Service\BackendService;
 use OCP\IL10N;
+use OCP\IUser;
 
 class Local extends Backend {
        public function __construct(IL10N $l, NullMechanism $legacyAuth) {
@@ -45,4 +47,8 @@ class Local extends Backend {
                        ->setLegacyAuthMechanism($legacyAuth)
                ;
        }
+
+       public function manipulateStorageConfig(StorageConfig &$storage, IUser $user = null): void {
+               $storage->setBackendOption('isExternal', true);
+       }
 }
index 02708ed4f7d0038849fb61843f3363d34f24bb7a..fdc30b492595ecc9df0dfb95e9f9e2c4af426b5a 100644 (file)
@@ -51,6 +51,7 @@ use OCP\Files\ForbiddenException;
 use OCP\Files\GenericFileException;
 use OCP\Files\IMimeTypeDetector;
 use OCP\Files\Storage\IStorage;
+use OCP\Files\StorageNotAvailableException;
 use OCP\IConfig;
 use OCP\Util;
 use Psr\Log\LoggerInterface;
@@ -95,6 +96,12 @@ class Local extends \OC\Files\Storage\Common {
 
                // support Write-Once-Read-Many file systems
                $this->unlinkOnTruncate = $this->config->getSystemValueBool('localstorage.unlink_on_truncate', false);
+
+               if (isset($arguments['isExternal']) && $arguments['isExternal'] && !$this->stat('')) {
+                       // data dir not accessible or available, can happen when using an external storage of type Local
+                       // on an unmounted system mount point
+                       throw new StorageNotAvailableException('Local storage path does not exist "' . $this->getSourcePath('') . '"');
+               }
        }
 
        public function __destruct() {
index e324d2b28db066c4232cd0fba424cb1409710b91..1190a2b2da0435ae95dc348c716760a4734cb886 100644 (file)
@@ -139,4 +139,15 @@ class LocalTest extends Storage {
                umask($oldMask);
                $this->assertTrue($this->instance->isUpdatable('test.txt'));
        }
+
+       public function testUnavailableExternal() {
+               $this->expectException(\OCP\Files\StorageNotAvailableException::class);
+               $this->instance = new \OC\Files\Storage\Local(['datadir' => $this->tmpDir . '/unexist', 'isExternal' => true]);
+       }
+
+       public function testUnavailableNonExternal() {
+               $this->instance = new \OC\Files\Storage\Local(['datadir' => $this->tmpDir . '/unexist']);
+               // no exception thrown
+               $this->assertNotNull($this->instance);
+       }
 }