Allow ext storage Local to go unavailable

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>
This commit is contained in:
Vincent Petry 2023-08-03 23:09:17 +02:00 committed by Simon L
parent 6f520f2304
commit 8d1a3daa3f
3 changed files with 24 additions and 0 deletions

View 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);
}
}

View 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() {

View 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);
}
}