diff --git a/.drone.yml b/.drone.yml index 385138d6c8..614c0dc40c 100644 --- a/.drone.yml +++ b/.drone.yml @@ -596,6 +596,7 @@ pipeline: image: nextcloudci/php7.0:php7.0-19 commands: - phpenmod xdebug + - ./tests/drone-wait-objectstore.sh - TEST_SELECTION=PRIMARY-${OBJECT_STORE} ./autotest.sh sqlite - wget https://codecov.io/bash -O codecov.sh - sh -c "if [ '$DRONE_BUILD_EVENT' = 'pull_request' ]; then bash codecov.sh -B $DRONE_BRANCH -C $DRONE_COMMIT -P $DRONE_PULL_REQUEST -t 117641e2-a9e8-4b7b-984b-ae872d9b05f5 -f tests/autotest-clover-sqlite.xml; fi" @@ -743,6 +744,8 @@ matrix: - TESTS: carddavtester-old-endpoint - TESTS: object-store OBJECT_STORE: s3 + - TESTS: object-store + OBJECT_STORE: swift - TESTS: sqlite-php7.0-samba-native - TESTS: sqlite-php7.0-samba-non-native - TEST: memcache-memcached @@ -838,6 +841,14 @@ services: when: matrix: OBJECT_STORE: s3 + dockswift: + image: icewind1991/dockswift + environment: + - INITIALIZE=yes + - IPADDRESS=dockswift + when: + matrix: + OBJECT_STORE: swift selenium: image: selenium/standalone-firefox:2.53.1-beryllium environment: diff --git a/autotest.sh b/autotest.sh index 7a91b07719..ff59386e1b 100755 --- a/autotest.sh +++ b/autotest.sh @@ -369,6 +369,9 @@ function execute_tests { if [ "$TEST_SELECTION" == "PRIMARY-s3" ]; then GROUP='--group PRIMARY-s3' fi + if [ "$TEST_SELECTION" == "PRIMARY-swift" ]; then + GROUP='--group PRIMARY-swift' + fi COVER='' if [ -z "$NOCOVERAGE" ]; then diff --git a/lib/private/Files/Mount/ObjectHomeMountProvider.php b/lib/private/Files/Mount/ObjectHomeMountProvider.php index 440a8bc460..9c09c0737c 100644 --- a/lib/private/Files/Mount/ObjectHomeMountProvider.php +++ b/lib/private/Files/Mount/ObjectHomeMountProvider.php @@ -84,10 +84,11 @@ class ObjectHomeMountProvider implements IHomeMountProvider { if (!isset($config['arguments'])) { $config['arguments'] = []; } - $config['arguments']['user'] = $user; // instantiate object store implementation $config['arguments']['objectstore'] = new $config['class']($config['arguments']); + $config['arguments']['user'] = $user; + return $config; } diff --git a/lib/private/Files/ObjectStore/ObjectStoreStorage.php b/lib/private/Files/ObjectStore/ObjectStoreStorage.php index 094a291573..45c22a81a7 100644 --- a/lib/private/Files/ObjectStore/ObjectStoreStorage.php +++ b/lib/private/Files/ObjectStore/ObjectStoreStorage.php @@ -369,7 +369,7 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common { 'app' => 'objectstore', 'message' => 'Could not create object for ' . $path, ]); - return false; + throw $ex; } } return true; diff --git a/lib/private/Files/ObjectStore/Swift.php b/lib/private/Files/ObjectStore/Swift.php index 70bc4ed843..a3cba488f5 100644 --- a/lib/private/Files/ObjectStore/Swift.php +++ b/lib/private/Files/ObjectStore/Swift.php @@ -26,6 +26,7 @@ namespace OC\Files\ObjectStore; use Guzzle\Http\Exception\ClientErrorResponseException; +use Guzzle\Http\Exception\CurlException; use Icewind\Streams\RetryWrapper; use OCP\Files\ObjectStore\IObjectStore; use OCP\Files\StorageAuthException; @@ -87,6 +88,9 @@ class Swift implements IObjectStore { $this->params = $params; } + /** + * @suppress PhanNonClassMethodCall + */ protected function init() { if ($this->container) { return; @@ -117,6 +121,10 @@ class Swift implements IObjectStore { /** @var Catalog $catalog */ $catalog = $this->client->getCatalog(); + if (count($catalog->getItems()) === 0) { + throw new StorageAuthException('Keystone did not provide a valid catalog, verify the credentials'); + } + if (isset($this->params['serviceName'])) { $serviceName = $this->params['serviceName']; } else { @@ -153,6 +161,13 @@ class Swift implements IObjectStore { } else { throw $ex; } + } catch (CurlException $e) { + if ($e->getErrorNo() === 7) { + $host = $e->getCurlHandle()->getUrl()->getHost() . ':' . $e->getCurlHandle()->getUrl()->getPort(); + \OC::$server->getLogger()->error("Can't connect to object storage server at $host"); + throw new StorageNotAvailableException("Can't connect to object storage server at $host", StorageNotAvailableException::STATUS_ERROR, $e); + } + throw $e; } } @@ -176,7 +191,7 @@ class Swift implements IObjectStore { $itemClass = new \stdClass(); $itemClass->name = $item['name']; $itemClass->endpoints = array_map(function (array $endpoint) { - return (object) $endpoint; + return (object)$endpoint; }, $item['endpoints']); $itemClass->type = $item['type']; diff --git a/tests/drone-wait-objectstore.sh b/tests/drone-wait-objectstore.sh new file mode 100755 index 0000000000..14d0b6f1f6 --- /dev/null +++ b/tests/drone-wait-objectstore.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +if [ "$OBJECT_STORE" == "swift" ]; then + echo "waiting for swift" + until curl -I http://dockswift:5000/v3 + do + sleep 2 + done + sleep 60 +fi diff --git a/tests/lib/Files/ObjectStore/SwiftTest.php b/tests/lib/Files/ObjectStore/SwiftTest.php index f2aeace769..1ea55a8462 100644 --- a/tests/lib/Files/ObjectStore/SwiftTest.php +++ b/tests/lib/Files/ObjectStore/SwiftTest.php @@ -23,6 +23,9 @@ namespace Test\Files\ObjectStore; use OC\Files\ObjectStore\Swift; +/** + * @group PRIMARY-swift + */ class SwiftTest extends ObjectStoreTest { /** * @return \OCP\Files\ObjectStore\IObjectStore diff --git a/tests/preseed-config.php b/tests/preseed-config.php index 7c08003873..5fbdc56541 100644 --- a/tests/preseed-config.php +++ b/tests/preseed-config.php @@ -34,3 +34,19 @@ if (getenv('OBJECT_STORE') === 's3') { ) ]; } +if (getenv('OBJECT_STORE') === 'swift') { + $swiftHost = getenv('DRONE') === 'true' ? 'dockswift' : 'localhost'; + $CONFIG['objectstore'] = [ + 'class' => 'OC\\Files\\ObjectStore\\Swift', + 'arguments' => array( + 'autocreate' => true, + 'username' => 'swift', + 'tenantName' => 'service', + 'password' => 'swift', + 'serviceName' => 'swift', + 'region' => 'regionOne', + 'url' => "http://$swiftHost:5000/v2.0", + 'bucket' => 'nextcloud' + ) + ]; +}