diff --git a/config/config.sample.php b/config/config.sample.php index e95f2535af..862c5ec1a1 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -1354,6 +1354,23 @@ $CONFIG = [ ], ], +/** + * If this is set to true and a multibucket object store is configured then + * newly created previews are put into 256 dedicated buckets. + * + * Those buckets are named like the mulibucket version but with the postfix + * ``-preview-NUMBER`` where NUMBER is between 0 and 255. + * + * Keep in mind that only previews of files are put in there that don't have + * some already. Otherwise the old bucket will be used. + * + * To migrate existing previews to this new multibucket distribution of previews + * use the occ command ``preview:repair``. For now this will only migrate + * previews that were generated before Nextcloud 19 in the flat + * ``appdata_INSTANCEID/previews/FILEID`` folder structure. + */ +'objectstore.multibucket.preview-distribution' => false, + /** * Sharing diff --git a/lib/private/Files/Mount/ObjectStorePreviewCacheMountProvider.php b/lib/private/Files/Mount/ObjectStorePreviewCacheMountProvider.php index dba1dfc28e..9bbb744bbc 100644 --- a/lib/private/Files/Mount/ObjectStorePreviewCacheMountProvider.php +++ b/lib/private/Files/Mount/ObjectStorePreviewCacheMountProvider.php @@ -55,6 +55,9 @@ class ObjectStorePreviewCacheMountProvider implements IRootMountProvider { if (!is_array($this->config->getSystemValue('objectstore_multibucket'))) { return []; } + if ($this->config->getSystemValue('objectstore.multibucket.preview-distribution', false) !== true) { + return []; + } $instanceId = $this->config->getSystemValueString('instanceid', ''); $mountPoints = []; diff --git a/lib/private/Preview/Storage/Root.php b/lib/private/Preview/Storage/Root.php index 37ae175812..a284b037b3 100644 --- a/lib/private/Preview/Storage/Root.php +++ b/lib/private/Preview/Storage/Root.php @@ -32,23 +32,23 @@ use OCP\Files\NotFoundException; use OCP\Files\SimpleFS\ISimpleFolder; class Root extends AppData { + private $isMultibucketPreviewDistributionEnabled = false; public function __construct(IRootFolder $rootFolder, SystemConfig $systemConfig) { parent::__construct($rootFolder, $systemConfig, 'preview'); + + $this->isMultibucketPreviewDistributionEnabled = $systemConfig->getValue('objectstore.multibucket.preview-distribution', false) === true; } public function getFolder(string $name): ISimpleFolder { $internalFolder = $this->getInternalFolder($name); - try { - return parent::getFolder('old-multibucket/' . $internalFolder); - } catch (NotFoundException $e) { - // not in multibucket fallback #1 - } - try { - return parent::getFolder('old-multibucket/' . $name); - } catch (NotFoundException $e) { - // not in multibucket fallback #2 + if ($this->isMultibucketPreviewDistributionEnabled) { + try { + return parent::getFolder('old-multibucket/' . $internalFolder); + } catch (NotFoundException $e) { + // not in multibucket fallback + } } try { diff --git a/tests/lib/Files/Mount/ObjectStorePreviewCacheMountProviderTest.php b/tests/lib/Files/Mount/ObjectStorePreviewCacheMountProviderTest.php index 2da07393f4..400808d7cd 100644 --- a/tests/lib/Files/Mount/ObjectStorePreviewCacheMountProviderTest.php +++ b/tests/lib/Files/Mount/ObjectStorePreviewCacheMountProviderTest.php @@ -71,22 +71,29 @@ class ObjectStorePreviewCacheMountProviderTest extends \Test\TestCase { } public function testMultibucketObjectStorage() { + $objectstoreConfig = [ + 'class' => S3::class, + 'arguments' => [ + 'bucket' => 'abc', + 'num_buckets' => 64, + 'key' => 'KEY', + 'secret' => 'SECRET', + 'hostname' => 'IP', + 'port' => 'PORT', + 'use_ssl' => false, + 'use_path_style' => true, + ], + ]; $this->config->expects($this->any()) ->method('getSystemValue') - ->with('objectstore_multibucket') - ->willReturn([ - 'class' => S3::class, - 'arguments' => [ - 'bucket' => 'abc', - 'num_buckets' => 64, - 'key' => 'KEY', - 'secret' => 'SECRET', - 'hostname' => 'IP', - 'port' => 'PORT', - 'use_ssl' => false, - 'use_path_style' => true, - ], - ]); + ->willReturnCallback(function ($config) use ($objectstoreConfig) { + if ($config === 'objectstore_multibucket') { + return $objectstoreConfig; + } elseif ($config === 'objectstore.multibucket.preview-distribution') { + return true; + } + return null; + }); $this->config->expects($this->once()) ->method('getSystemValueString') ->with('instanceid')