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

Make cargohold use amazonka instead of aws #1157

Merged
merged 17 commits into from
Jul 13, 2020

Conversation

mheinzel
Copy link
Contributor

@mheinzel mheinzel commented Jul 2, 2020

Fixes #876.
Also see https://github.com/zinfra/backend-issues/issues/1481.

This revives #483 with a more recent version of amazonka. Everything seems to work without performance regressions except for problems against Minio with the pre-signed download URLs we generate (more docs). This still needs to be investigated.

edit: I found the issue in amazonka and made a fix

Before merging:

@mheinzel mheinzel force-pushed the mheinzel/cargohold-use-amazonka branch 2 times, most recently from 19a002c to c25d4ba Compare July 6, 2020 10:54
@mheinzel mheinzel changed the title [WIP] Make cargohold use amazonka instead of aws Make cargohold use amazonka instead of aws Jul 6, 2020
@mheinzel mheinzel force-pushed the mheinzel/cargohold-use-amazonka branch from 338b372 to f9abcc5 Compare July 7, 2020 09:47
@mheinzel mheinzel marked this pull request as ready for review July 7, 2020 12:33
Copy link
Contributor

@tiago-loureiro tiago-loureiro left a comment

Choose a reason for hiding this comment

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

Did some early review with @fisx - we did not manage to review the resumable uploads but already have some feedback and wanted to leave them here already... in general looks great!

main = withOpenSSL $ do
options <- getOptions desc Nothing defaultPath
run options
main = do
Copy link
Contributor

Choose a reason for hiding this comment

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

I remember we had a chat about it and mentioned we should probably keep using openSSL but then it was removed in the PR anyway; was it easier to remove it or what was the reason for the change?

Copy link
Contributor

Choose a reason for hiding this comment

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

@franziskuskiefer do you have an opinion on openssl vs. http://hackage.haskell.org/package/tls?

We had this a while back, and after struggling for a while between "In Haskell with a few good habits, many mistakes cannot be expressed in the language" and "openssl has had so many bugs closed, how many more can there be?", we stuck with openssl.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, I undid the changes removing OpenSSL, but must have missed this one. Interestingly, the code using OpenSSL still worked without the initialization here. Good catch!

For this PR I think it makes sense to stick with OpenSSL for consistency with the rest of the codebase, but yeah, we should think about which library we want to use in general.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

instance AWS.MonadAWS Amazon where
liftAWS a = view amazonkaEnv >>= flip AWS.runAWS a

mkEnv ::
Copy link
Contributor

Choose a reason for hiding this comment

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

For future reference, pretty much all our services have a nearly identical copy of this AWS monad (except for the mkEnv), would be nice to at some point generalize it.

services/cargohold/src/CargoHold/S3.hs Show resolved Hide resolved
signed <-
AWS.execute (AWS.useDownloadEndpoint e) $
presignURL now (Seconds (fromIntegral ttl)) req
return =<< toUri signed
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
return =<< toUri signed
toUri signed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

as part of 877c9a9

return $ statusIsServerError s
]
parseMIMEType :: Text -> Maybe MIME.Type
parseMIMEType = MIME.parseMIMEType
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it worth having this as it's just an alias?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, will inline it. Same for encodeMIMEType.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

services/cargohold/src/CargoHold/S3.hs Outdated Show resolved Hide resolved
Comment on lines 162 to 177
execCatch ::
(AWSRequest a, AWS.HasEnv r, MonadUnliftIO m, MonadCatch m, MonadThrow m) =>
r ->
a ->
m (Either AWS.Error (Rs a))
execCatch e cmd =
runResourceT . AWST.runAWST e
$ AWST.trying AWS._Error
$ AWST.send cmd

exec ::
(AWSRequest a, AWS.HasEnv r, MonadUnliftIO m, MonadCatch m, MonadThrow m) =>
r ->
a ->
m (Rs a)
exec e cmd = execCatch e cmd >>= either (throwM . GeneralError) return
Copy link
Contributor

Choose a reason for hiding this comment

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

These are not used and have functions with the same name on the S3 module; perhaps move those functions here since they are generic and can be used in other modules (although they are not)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It was not quite as easy as copying them, because of the module dependencies (Cargohold.AWS doesn't know about App and Env), but here it is: 959adbc

- byteable >=0.1
- base16-bytestring >=0.1
- blaze-builder >=0.3
- binary >=0.8
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit-pick: I think the only thing used from binary is toLazyByteString, which I think is just a re-export from bytestring.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good spot. We also do this in a few other places, so I cleaned them up, too.
0bfad02

Copy link
Contributor

@fisx fisx left a comment

Choose a reason for hiding this comment

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

Given that the resume functionality (which is not used by any client btw) is somewhat covered in the test suite, I'll take your word for that the changes are valid.

But does the V3 in the tests stand for the signature version, and do we need to cover V4 as well? I am missing a lot of context here. :)

main = withOpenSSL $ do
options <- getOptions desc Nothing defaultPath
run options
main = do
Copy link
Contributor

Choose a reason for hiding this comment

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

@franziskuskiefer do you have an opinion on openssl vs. http://hackage.haskell.org/package/tls?

We had this a while back, and after struggling for a while between "In Haskell with a few good habits, many mistakes cannot be expressed in the language" and "openssl has had so many bugs closed, how many more can there be?", we stuck with openssl.

@tiago-loureiro
Copy link
Contributor

But does the V3 in the tests stand for the signature version, and do we need to cover V4 as well? I am missing a lot of context here. :)

V3 is the Cargohold API version, nothing to do with signatures

@franziskuskiefer
Copy link
Contributor

@franziskuskiefer do you have an opinion on openssl vs. http://hackage.haskell.org/package/tls?
We had this a while back, and after struggling for a while between "In Haskell with a few good habits, many mistakes cannot be expressed in the language" and "openssl has had so many bugs closed, how many more can there be?", we stuck with openssl.

I generally prefer not using openssl for multiple reasons. But that haskell package doesn't appear to be used a lot, which is crucial for a TLS lib (most errors are found while using it).
I'm happy to look into what we could generally use on the BE for TLS instead of openssl. But we should probably handle that separately.

@mheinzel mheinzel force-pushed the mheinzel/cargohold-use-amazonka branch from 959adbc to 0ecdbfe Compare July 10, 2020 14:42
@mheinzel
Copy link
Contributor Author

I addressed all comments and now rebased to resolve conflicts. Looking forward to more feedback!

@tiago-loureiro tiago-loureiro force-pushed the mheinzel/cargohold-use-amazonka branch from 4a5a869 to bde835d Compare July 10, 2020 20:49
Copy link
Contributor

@tiago-loureiro tiago-loureiro left a comment

Choose a reason for hiding this comment

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

:shipit:

Small note: I added an extra commit with a little comment a few extra config options explaining how you could test with cloudfront too and updated the file on S3

@mheinzel mheinzel merged commit e570f2e into develop Jul 13, 2020
@mheinzel mheinzel deleted the mheinzel/cargohold-use-amazonka branch July 13, 2020 08:43
@fisx fisx mentioned this pull request Jul 13, 2020
fisx added a commit that referenced this pull request Jul 13, 2020
fisx added a commit that referenced this pull request Jul 14, 2020
mheinzel added a commit to wireapp/wire-server-deploy that referenced this pull request Jul 14, 2020
* provide AWS_REGION variable to cargohold

Now with cargohold using V4 signatures
(wireapp/wire-server#1157),
the region is part of the Authorization header and needs to configured correctly.
We already do that for the other services, so I just copied the code from there.

* provide AWS env vars to cargohold integration

We do this for all the other servers, too, but I'm actually not sure
why. The integration tests themselves don't call AWS.

We should probably just remove it (+ from the other services).
fisx pushed a commit that referenced this pull request Jul 14, 2020
* squash #483

* remove all usages of aws

* support s3DownloadEndpoint config

* stack.yaml: pin updated fork of amazonka

The update to stack.yaml just takes all amazonka packages from the pinned fork.
They depend on core, so need to be rebuilt anyways.
We also drop elb, redshift, route53

* depend on OpenSSL again

This is mostly done for consistency with the other services. If we want to change it,
we should change it everywhere.

* remove unnecessary dependencies on binary and blaze-builder

* Add comment on how to use cloudfront

Co-authored-by: Tiago Loureiro <tiago.loureiro@gmail.com>
@fisx fisx mentioned this pull request Jul 29, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

is the code using S3 support V4 signature
4 participants