Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for s3 storage classes #36075

Merged
merged 2 commits into from
Jan 16, 2023
Merged

Conversation

fmenabe
Copy link
Contributor

@fmenabe fmenabe commented Jan 10, 2023

Summary

This add support for s3 storage class in both primary objectstore and External Storage (files_external) application.

TODO

Checklist

@kesselb
Copy link
Contributor

kesselb commented Jan 10, 2023

Thanks for your pull request 👍

Traductions for files_external app manually done for english (not sure that should be done manually) but not for other languages

Please don't change the translation files.
A bot will update them automatically from Transifex once this pull request was merged.

@szaimen szaimen added this to the Nextcloud 26 milestone Jan 10, 2023
@szaimen szaimen added the 2. developing Work in progress label Jan 10, 2023
@fmenabe
Copy link
Contributor Author

fmenabe commented Jan 10, 2023

Please don't change the translation files. A bot will update them automatically from Transifex once this pull request was merged.

I removed the translations from the commit

Copy link
Contributor

@artonge artonge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Beside minor nitpick, looks good to me

@@ -81,6 +84,7 @@ protected function parseParams($params) {
$this->bucket = $params['bucket'];
$this->proxy = $params['proxy'] ?? false;
$this->timeout = $params['timeout'] ?? 15;
$this->storageClass = (isset($params['storageClass']) && !empty($params['storageClass'])) ? $params['storageClass'] : 'STANDARD';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use the same logic as for other params ?

Suggested change
$this->storageClass = (isset($params['storageClass']) && !empty($params['storageClass'])) ? $params['storageClass'] : 'STANDARD';
$this->storageClass = $params['storageClass'] ?? 'STANDARD';

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I've done at start ;-)

But in the external storage application (files_external), if the storage class is not specified, you get an empty class (an empty string), which is not a valid a storage class for the providers and generates an error. Not sure you can specified a default value for OCA\Files_External\Lib\DefinitionParameter?

It seemed to me more generic to ensure here that, if the storage class is not defined or is empty, we fallback to STANDARD.

Copy link
Contributor

@come-nc come-nc Jan 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
$this->storageClass = (isset($params['storageClass']) && !empty($params['storageClass'])) ? $params['storageClass'] : 'STANDARD';
$this->storageClass = !empty($params['storageClass']) ? $params['storageClass'] : 'STANDARD';

Then no need for isset, empty implies isset.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, the PR have been updated

Copy link
Contributor

@come-nc come-nc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some nitpick but otherwise looks fine.

@@ -123,7 +124,8 @@ protected function writeMultiPart(string $urn, StreamInterface $stream, string $
'key' => $urn,
'part_size' => $this->uploadPartSize,
'params' => [
'ContentType' => $mimetype
'ContentType' => $mimetype,
'StorageClass' => $this->storageClass
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
'StorageClass' => $this->storageClass
'StorageClass' => $this->storageClass,

@come-nc come-nc merged commit 5e090d0 into nextcloud:master Jan 16, 2023
@welcome
Copy link

welcome bot commented Jan 16, 2023

Thanks for your first pull request and welcome to the community! Feel free to keep them coming! If you are looking for issues to tackle then have a look at this selection: https://github.com/nextcloud/server/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22

@aentwist
Copy link

aentwist commented Mar 21, 2023

Since this comes with no tests or documentation, I'll ask here - has anyone actually tested this? It isn't working for me, and I am trying to make it available on the Docker image. I can open an issue?

  • new installation
  • empty bucket
  • config as correct as I can figure it should be after reading this code

-> everything gets STANDARD

Relevant config..

        "objectstore": {
            "class": "\\OC\\Files\\ObjectStore\\S3",
            "arguments": {
                "bucket": "redacted",
                "region": "us-east-1",
                "hostname": "",
                "port": "",
                "storageClass": "INTELLIGENT_TIERING",
                "objectPrefix": "urn:oid:",
                "autocreate": false,
                "use_ssl": true,
                "use_path_style": false,
                "legacy_auth": false
            }
        },

The log is empty

I am not trying to raise an issue here. I just need to verify that the usage above is as intended.

@fmenabe
Copy link
Contributor Author

fmenabe commented Mar 22, 2023

I've just retested on my dev environment (based on skjnldsv/docker-nextcloud-dev) and it "works for me". Switched the fork to v26.0.0 tag and it still works.

That's the config I used (seems pretty identical to what you paste and yes only storageClass parameter was added by this PR):

  'objectstore' => array(
    'class' => '\\OC\\Files\\ObjectStore\\S3',
    'arguments' => array(
      'bucket'     => '<BUCKET>',
      'key'        => '<KEY>',
      'secret'     => '<SECRET>',
      'hostname'   => 's3.fr-par.scw.cloud',
      'storageClass' => 'ONEZONE_IA',
      'port'       => '443',
      'use_ssl'    => true,
      'region'     => 'fr-par'
    )
  )

I also manually build a Docker image from nextcloud/docker applying something similar to nextcloud/docker#1933 but directly in 26/apache/config/s3.config.php directory and it also worked as expected.

$ git diff 26/apache/config/s3.config.php
diff --git a/26/apache/config/s3.config.php b/26/apache/config/s3.config.php
index aa3f4f5..4223d8a 100644
--- a/26/apache/config/s3.config.php
+++ b/26/apache/config/s3.config.php
@@ -15,6 +15,7 @@ if (getenv('OBJECTSTORE_S3_BUCKET')) {
         'hostname' => getenv('OBJECTSTORE_S3_HOST') ?: '',
         'port' => getenv('OBJECTSTORE_S3_PORT') ?: '',
         'objectPrefix' => getenv("OBJECTSTORE_S3_OBJECT_PREFIX") ? getenv("OBJECTSTORE_S3_OBJECT_PREFIX") : "urn:oid:",
+        'storageClass' => getenv("OBJECTSTORE_S3_STORAGE_CLASS") ? getenv("OBJECTSTORE_S3_STORAGE_CLASS") : "STANDARD",
         'autocreate' => (strtolower($autocreate) === 'false' || $autocreate == false) ? false : true,
         'use_ssl' => (strtolower($use_ssl) === 'false' || $use_ssl == false) ? false : true,
         // required for some non Amazon S3 implementations
@@ -24,4 +25,4 @@ if (getenv('OBJECTSTORE_S3_BUCKET')) {
       )
     )
   );
-} 
+}
$ cd 26/apache
$ docker build -t nextcloud-debug:26 .
$ docker-compose up

What I could suspect:

  • somehow you're not using Nextcloud 26 and the patch is not there, or the image is not built with or don't use OBJECTSTORE_S3_STORAGE_CLASS environment variable for whatever reason
  • the behaviour from your s3 provider is different and for some reason it falls back to STANDARD (would surprise me as from my tests, when the storage class was invalid, there was an invalid response from the provider and got 500/Internal Server Error)
  • another bug I don't see

Last note: if storageClass is not set in the configuration, it forces STANDARD (cf #36075 (comment))

@aentwist
Copy link

Good grief man I didn't check the release version this made it into. I figured with CI/CDs, since this is a feature and not a breaking change, that it had already made it out after a couple months into Nextcloud 25 and the corresponding Docker image. Can confirm it works flawlessly in Nextcloud 26 using my setup described above + S3. Thanks for this sanity check, and for your work on this.

@J0WI J0WI mentioned this pull request Mar 28, 2023
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2. developing Work in progress
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Setting of storage class for S3
8 participants