From 6e12d830d581d62ef5abe66c3b53e8870eed132a Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 1 Aug 2014 14:20:00 +0200 Subject: [PATCH] Fix AmazonS3 rmdir on the root --- apps/files_external/lib/amazons3.php | 57 +++++++++++++++++++------- apps/files_external/tests/amazons3.php | 24 +---------- 2 files changed, 43 insertions(+), 38 deletions(-) diff --git a/apps/files_external/lib/amazons3.php b/apps/files_external/lib/amazons3.php index c82b739102..38e6371f5b 100644 --- a/apps/files_external/lib/amazons3.php +++ b/apps/files_external/lib/amazons3.php @@ -73,6 +73,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { sleep($this->timeout); } } + private function cleanKey($path) { if ($path === '.') { return '/'; @@ -90,13 +91,13 @@ class AmazonS3 extends \OC\Files\Storage\Common { $this->bucket = $params['bucket']; $scheme = ($params['use_ssl'] === 'false') ? 'http' : 'https'; $this->test = isset($params['test']); - $this->timeout = ( ! isset($params['timeout'])) ? 15 : $params['timeout']; - $params['region'] = ( ! isset($params['region']) || $params['region'] === '' ) ? 'eu-west-1' : $params['region']; - $params['hostname'] = ( !isset($params['hostname']) || $params['hostname'] === '' ) ? 's3.amazonaws.com' : $params['hostname']; + $this->timeout = (!isset($params['timeout'])) ? 15 : $params['timeout']; + $params['region'] = (!isset($params['region']) || $params['region'] === '') ? 'eu-west-1' : $params['region']; + $params['hostname'] = (!isset($params['hostname']) || $params['hostname'] === '') ? 's3.amazonaws.com' : $params['hostname']; if (!isset($params['port']) || $params['port'] === '') { $params['port'] = ($params['use_ssl'] === 'false') ? 80 : 443; } - $base_url = $scheme.'://'.$params['hostname'].':'.$params['port'].'/'; + $base_url = $scheme . '://' . $params['hostname'] . ':' . $params['port'] . '/'; $this->connection = S3Client::factory(array( 'key' => $params['key'], @@ -119,7 +120,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { 'waiter.interval' => 1, 'waiter.max_attempts' => 15 )); - $this->testTimeout(); + $this->testTimeout(); } catch (S3Exception $e) { \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); throw new \Exception("Creation of bucket failed."); @@ -128,8 +129,8 @@ class AmazonS3 extends \OC\Files\Storage\Common { if (!$this->file_exists('.')) { $result = $this->connection->putObject(array( 'Bucket' => $this->bucket, - 'Key' => $this->cleanKey('.'), - 'Body' => '', + 'Key' => $this->cleanKey('.'), + 'Body' => '', 'ContentType' => 'httpd/unix-directory', 'ContentLength' => 0 )); @@ -145,10 +146,10 @@ class AmazonS3 extends \OC\Files\Storage\Common { } try { - $result = $this->connection->putObject(array( + $this->connection->putObject(array( 'Bucket' => $this->bucket, - 'Key' => $path . '/', - 'Body' => '', + 'Key' => $path . '/', + 'Body' => '', 'ContentType' => 'httpd/unix-directory', 'ContentLength' => 0 )); @@ -187,6 +188,10 @@ class AmazonS3 extends \OC\Files\Storage\Common { public function rmdir($path) { $path = $this->normalizePath($path); + if ($path === '.') { + return $this->clearBucket(); + } + if (!$this->file_exists($path)) { return false; } @@ -199,7 +204,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { )); try { - $result = $this->connection->deleteObjects(array( + $this->connection->deleteObjects(array( 'Bucket' => $this->bucket, 'Objects' => $objects['Contents'] )); @@ -212,6 +217,28 @@ class AmazonS3 extends \OC\Files\Storage\Common { return true; } + protected function clearBucket() { + try { + $this->connection->clearBucket($this->bucket); + // clearBucket() is not working with Ceph, so if it fails we try the slower approach + } catch (\Exception $e) { + try { + $iterator = $this->connection->getIterator('ListObjects', array( + 'Bucket' => $this->bucket + )); + + foreach ($iterator as $object) { + $this->connection->deleteObject(array( + 'Bucket' => $this->bucket, + 'Key' => $object['Key'] + )); + } + } catch (S3Exception $e) { + return false; + } + } + } + public function opendir($path) { $path = $this->normalizePath($path); @@ -271,7 +298,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { $stat['atime'] = time(); return $stat; - } catch(S3Exception $e) { + } catch (S3Exception $e) { \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); return false; } @@ -302,7 +329,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { public function unlink($path) { $path = $this->normalizePath($path); - if ( $this->is_dir($path) ) { + if ($this->is_dir($path)) { return $this->rmdir($path); } @@ -463,7 +490,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { } $dh = $this->opendir($path1); - if(is_resource($dh)) { + if (is_resource($dh)) { while (($file = readdir($dh)) !== false) { if ($file === '.' || $file === '..') { continue; @@ -534,7 +561,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { } try { - $result= $this->connection->putObject(array( + $result = $this->connection->putObject(array( 'Bucket' => $this->bucket, 'Key' => $this->cleanKey(self::$tmpFiles[$tmpFile]), 'SourceFile' => $tmpFile, diff --git a/apps/files_external/tests/amazons3.php b/apps/files_external/tests/amazons3.php index a73b6307b0..fb98a1f509 100644 --- a/apps/files_external/tests/amazons3.php +++ b/apps/files_external/tests/amazons3.php @@ -38,29 +38,7 @@ class AmazonS3 extends Storage { public function tearDown() { if ($this->instance) { - $connection = $this->instance->getConnection(); - - try { - // NOTE(berendt): clearBucket() is not working with Ceph - $iterator = $connection->getIterator('ListObjects', array( - 'Bucket' => $this->config['amazons3']['bucket'] - )); - - foreach ($iterator as $object) { - $connection->deleteObject(array( - 'Bucket' => $this->config['amazons3']['bucket'], - 'Key' => $object['Key'] - )); - } - } catch (S3Exception $e) { - } - - $connection->deleteBucket(array( - 'Bucket' => $this->config['amazons3']['bucket'] - )); - - //wait some seconds for completing the replication - sleep(30); + $this->instance->rmdir(''); } } }