summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulius Härtl <jus@bitgrid.net>2023-03-07 07:20:38 +0100
committerGitHub <noreply@github.com>2023-03-07 07:20:38 +0100
commit9e73412e3f596d3bed478ecce4d014950d8993e9 (patch)
tree5b817de5fa024b16cc9fb96c53b5e42f70124d20
parentcddfb01d99193565a2d0329b0d23f6b681ffd930 (diff)
parentd515da502f34af151e156ba383c1d2e5c8289520 (diff)
downloadnextcloud-server-9e73412e3f596d3bed478ecce4d014950d8993e9.tar.gz
nextcloud-server-9e73412e3f596d3bed478ecce4d014950d8993e9.zip
Merge pull request #34835 from nextcloud/tests/integration-s3
-rw-r--r--.github/workflows/s3-primary-integration.yml84
-rw-r--r--apps/dav/lib/Connector/Sabre/Directory.php11
-rw-r--r--apps/dav/tests/unit/Connector/Sabre/DirectoryTest.php12
-rw-r--r--apps/provisioning_api/lib/Controller/UsersController.php5
-rw-r--r--lib/private/Files/View.php4
-rw-r--r--lib/private/User/User.php1
-rw-r--r--lib/private/legacy/OC_Helper.php11
7 files changed, 118 insertions, 10 deletions
diff --git a/.github/workflows/s3-primary-integration.yml b/.github/workflows/s3-primary-integration.yml
new file mode 100644
index 00000000000..5785cc858b4
--- /dev/null
+++ b/.github/workflows/s3-primary-integration.yml
@@ -0,0 +1,84 @@
+name: S3 primary storage integration tests
+on:
+ pull_request:
+ push:
+ branches:
+ - master
+ - stable*
+
+jobs:
+ s3-primary-integration-tests-minio:
+ runs-on: ubuntu-20.04
+
+ strategy:
+ # do not stop on another job's failure
+ fail-fast: false
+ matrix:
+ php-versions: ['8.0']
+ key: ['objectstore', 'objectstore_multibucket']
+
+ name: php${{ matrix.php-versions }}-${{ matrix.key }}-minio
+
+ services:
+ redis:
+ image: redis
+ ports:
+ - "6379:6379"
+ minio:
+ env:
+ MINIO_ACCESS_KEY: minio
+ MINIO_SECRET_KEY: minio123
+ image: bitnami/minio:2021.12.29
+ ports:
+ - "9000:9000"
+
+ steps:
+ - name: Checkout server
+ uses: actions/checkout@v3
+ with:
+ submodules: true
+
+ - name: Set up php ${{ matrix.php-versions }}
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php-versions }}
+ tools: phpunit:9
+ extensions: mbstring, fileinfo, intl, sqlite, pdo_sqlite, zip, gd, redis
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Wait for S3
+ run: |
+ sleep 10
+ curl -f -m 1 --retry-connrefused --retry 10 --retry-delay 10 http://localhost:9000/minio/health/ready
+
+ - name: Set up Nextcloud
+ run: |
+ mkdir data
+ echo '<?php $CONFIG=["${{ matrix.key }}" => ["class" => "OC\Files\ObjectStore\S3", "arguments" => ["bucket" => "nextcloud", "autocreate" => true, "key" => "minio", "secret" => "minio123", "hostname" => "localhost", "port" => 9000, "use_ssl" => false, "use_path_style" => true, "uploadPartSize" => 52428800]]];' > config/config.php
+ echo '<?php $CONFIG=["redis" => ["host" => "localhost", "port" => 6379], "memcache.local" => "\OC\Memcache\Redis", "memcache.distributed" => "\OC\Memcache\Redis"];' > config/redis.config.php
+ ./occ maintenance:install --verbose --database=sqlite --database-name=nextcloud --database-host=127.0.0.1 --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass admin
+ php -f index.php
+
+ - name: Integration
+ run: |
+ cd build/integration
+ bash run.sh --tags "~@failure-s3" features/webdav-related.feature
+
+ - name: S3 logs
+ if: always()
+ run: |
+ cat data/nextcloud.log
+ docker ps -a
+ docker ps -aq | while read container ; do IMAGE=$(docker inspect --format='{{.Config.Image}}' $container); echo $IMAGE; docker logs $container; echo "\n\n" ; done
+
+
+ s3-primary-integration-summary:
+ runs-on: ubuntu-latest
+ needs: [s3-primary-integration-tests-minio]
+
+ if: always()
+
+ steps:
+ - name: Summary status
+ run: if ${{ needs.s3-primary-integration-tests-minio.result != 'success' }}; then exit 1; fi
diff --git a/apps/dav/lib/Connector/Sabre/Directory.php b/apps/dav/lib/Connector/Sabre/Directory.php
index f4b1ee62190..531ccff9d92 100644
--- a/apps/dav/lib/Connector/Sabre/Directory.php
+++ b/apps/dav/lib/Connector/Sabre/Directory.php
@@ -35,7 +35,6 @@ namespace OCA\DAV\Connector\Sabre;
use OC\Files\Mount\MoveableMount;
use OC\Files\View;
use OC\Metadata\FileMetadata;
-use OC\Metadata\MetadataGroup;
use OCA\DAV\Connector\Sabre\Exception\FileLocked;
use OCA\DAV\Connector\Sabre\Exception\Forbidden;
use OCA\DAV\Connector\Sabre\Exception\InvalidPath;
@@ -57,7 +56,6 @@ use Sabre\DAV\INode;
use OCP\Share\IManager as IShareManager;
class Directory extends \OCA\DAV\Connector\Sabre\Node implements \Sabre\DAV\ICollection, \Sabre\DAV\IQuota, \Sabre\DAV\IMoveTarget, \Sabre\DAV\ICopyTarget {
-
/**
* Cached directory content
* @var \OCP\Files\FileInfo[]
@@ -116,7 +114,6 @@ class Directory extends \OCA\DAV\Connector\Sabre\Node implements \Sabre\DAV\ICol
// for chunked upload also updating a existing file is a "createFile"
// because we create all the chunks before re-assemble them to the existing file.
if (isset($_SERVER['HTTP_OC_CHUNKED'])) {
-
// exit if we can't create a new file and we don't updatable existing file
$chunkInfo = \OC_FileChunking::decodeName($name);
if (!$this->fileView->isCreatable($this->path) &&
@@ -328,8 +325,14 @@ class Directory extends \OCA\DAV\Connector\Sabre\Node implements \Sabre\DAV\ICol
if ($this->quotaInfo) {
return $this->quotaInfo;
}
+ $relativePath = $this->fileView->getRelativePath($this->info->getPath());
+ if ($relativePath === null) {
+ $logger->warning("error while getting quota as the relative path cannot be found");
+ return [0, 0];
+ }
+
try {
- $storageInfo = \OC_Helper::getStorageInfo($this->info->getPath(), $this->info, false);
+ $storageInfo = \OC_Helper::getStorageInfo($relativePath, $this->info, false);
if ($storageInfo['quota'] === \OCP\Files\FileInfo::SPACE_UNLIMITED) {
$free = \OCP\Files\FileInfo::SPACE_UNLIMITED;
} else {
diff --git a/apps/dav/tests/unit/Connector/Sabre/DirectoryTest.php b/apps/dav/tests/unit/Connector/Sabre/DirectoryTest.php
index edbe4278c3a..a74cb139966 100644
--- a/apps/dav/tests/unit/Connector/Sabre/DirectoryTest.php
+++ b/apps/dav/tests/unit/Connector/Sabre/DirectoryTest.php
@@ -304,6 +304,10 @@ class DirectoryTest extends \Test\TestCase {
->method('free_space')
->willReturn(800);
+ $this->info->expects($this->any())
+ ->method('getPath')
+ ->willReturn('/admin/files/foo');
+
$this->info->expects($this->once())
->method('getSize')
->willReturn(200);
@@ -312,6 +316,10 @@ class DirectoryTest extends \Test\TestCase {
->method('getMountPoint')
->willReturn($mountPoint);
+ $this->view->expects($this->any())
+ ->method('getRelativePath')
+ ->willReturn('/foo');
+
$mountPoint->method('getMountPoint')
->willReturn('/user/files/mymountpoint');
@@ -359,6 +367,10 @@ class DirectoryTest extends \Test\TestCase {
$mountPoint->method('getMountPoint')
->willReturn('/user/files/mymountpoint');
+ $this->view->expects($this->any())
+ ->method('getRelativePath')
+ ->willReturn('/foo');
+
$dir = new Directory($this->view, $this->info);
$this->assertEquals([200, 800], $dir->getQuotaInfo()); //200 used, 800 free
}
diff --git a/apps/provisioning_api/lib/Controller/UsersController.php b/apps/provisioning_api/lib/Controller/UsersController.php
index 97d66acd2e0..1613561fbe1 100644
--- a/apps/provisioning_api/lib/Controller/UsersController.php
+++ b/apps/provisioning_api/lib/Controller/UsersController.php
@@ -77,7 +77,6 @@ use OCP\User\Backend\ISetDisplayNameBackend;
use Psr\Log\LoggerInterface;
class UsersController extends AUserData {
-
/** @var IURLGenerator */
protected $urlGenerator;
/** @var LoggerInterface */
@@ -374,7 +373,7 @@ class UsersController extends AUserData {
$group = $this->groupManager->get($groupid);
// Check if group exists
if ($group === null) {
- throw new OCSException('Subadmin group does not exist', 102);
+ throw new OCSException('Subadmin group does not exist', 102);
}
// Check if trying to make subadmin of admin group
if ($group->getGID() === 'admin') {
@@ -1311,7 +1310,7 @@ class UsersController extends AUserData {
}
// Check if group exists
if ($group === null) {
- throw new OCSException('Group does not exist', 102);
+ throw new OCSException('Group does not exist', 102);
}
// Check if trying to make subadmin of admin group
if ($group->getGID() === 'admin') {
diff --git a/lib/private/Files/View.php b/lib/private/Files/View.php
index 456f804ee56..1bd131303e3 100644
--- a/lib/private/Files/View.php
+++ b/lib/private/Files/View.php
@@ -164,7 +164,7 @@ class View {
* get path relative to the root of the view
*
* @param string $path
- * @return string
+ * @return ?string
*/
public function getRelativePath($path) {
$this->assertPathLength($path);
@@ -1241,7 +1241,7 @@ class View {
* get the path relative to the default root for hook usage
*
* @param string $path
- * @return string
+ * @return ?string
*/
private function getHookPath($path) {
if (!Filesystem::getView()) {
diff --git a/lib/private/User/User.php b/lib/private/User/User.php
index 2b975c290ba..2d80dbc7adf 100644
--- a/lib/private/User/User.php
+++ b/lib/private/User/User.php
@@ -529,6 +529,7 @@ class User implements IUser {
$this->config->setUserValue($this->uid, 'files', 'quota', $quota);
$this->triggerChange('quota', $quota, $oldQuota);
}
+ \OC_Helper::clearStorageInfo('/' . $this->uid . '/files');
}
/**
diff --git a/lib/private/legacy/OC_Helper.php b/lib/private/legacy/OC_Helper.php
index c2036c7b863..8d708118b96 100644
--- a/lib/private/legacy/OC_Helper.php
+++ b/lib/private/legacy/OC_Helper.php
@@ -473,7 +473,7 @@ class OC_Helper {
if (!$view) {
throw new \OCP\Files\NotFoundException();
}
- $fullPath = $view->getAbsolutePath($path);
+ $fullPath = Filesystem::normalizePath($view->getAbsolutePath($path));
$cacheKey = $fullPath. '::' . ($includeMountPoints ? 'include' : 'exclude');
if ($useCache) {
@@ -620,6 +620,15 @@ class OC_Helper {
];
}
+ public static function clearStorageInfo(string $absolutePath): void {
+ /** @var ICacheFactory $cacheFactory */
+ $cacheFactory = \OC::$server->get(ICacheFactory::class);
+ $memcache = $cacheFactory->createLocal('storage_info');
+ $cacheKeyPrefix = Filesystem::normalizePath($absolutePath) . '::';
+ $memcache->remove($cacheKeyPrefix . 'include');
+ $memcache->remove($cacheKeyPrefix . 'exclude');
+ }
+
/**
* Returns whether the config file is set manually to read-only
* @return bool