-
Notifications
You must be signed in to change notification settings - Fork 295
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
Fixes #37302 - push containers through Katello #10952
Fixes #37302 - push containers through Katello #10952
Conversation
eb8c7f3
to
a94868d
Compare
Hi Ian, thanks for the earlier fix. It looks like small/medium images are pushed properly but larger images run into issues. I have been seeing
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few comments...
@@ -9,7 +9,9 @@ class Api::Registry::RegistryProxiesController < Api::V2::ApiController | |||
before_action :optional_authorize, only: [:token, :catalog] | |||
before_action :registry_authorize, except: [:token, :v1_search, :catalog] | |||
before_action :authorize_repository_read, only: [:pull_manifest, :tags_list] | |||
before_action :authorize_repository_write, only: [:push_manifest] | |||
# authorize_repository_write commented out until Katello indexes Pulp container push repositories. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know some of our automation looks for "TODO" and "FIXME" flags in comments. Perhaps this would be a good spot to indicate something.
config/routes/api/registry.rb
Outdated
@@ -11,15 +11,15 @@ class ActionDispatch::Routing::Mapper | |||
match '/v2/token' => 'registry_proxies#token', :via => :post | |||
match '/v2/*repository/manifests/:tag' => 'registry_proxies#pull_manifest', :via => :get | |||
# Push-related routes are disabled until there is support for pushing to Pulp 3. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this comment should be removed.
@@ -182,15 +184,8 @@ def pull_manifest | |||
end | |||
|
|||
def check_blob |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a feeling the image size issue is something with this method. We were setting a content length value in the response header that doesn't seem to exist anymore? Qualifier on this advice: I may not know what I'm talking about.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Our code actually errors out before we even reach this method, the issue is between podman and puma rather than our code. The MAX_CHUNK_HEADER_SIZE is so small that puma rejects the request that podman sends to us. I'm going to report an issue to puma to see what they say.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good to know, thanks! Interesting issue. Are you wanting to keep this on the back burner until they get back to you or push this through under the pretense larger image sizes should be fine in the future?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like Puma already has a fix for this: puma/puma#3338
I think as such we can add that to the list of things that need fixing for container push to be fully functional and press forward.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feel free to patch in that fix, it's a very small change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, thanks!
a94868d
to
b01de38
Compare
Reminder for myself to see about adding / modifying tests. |
b01de38
to
b726cd4
Compare
[test katello] |
b726cd4
to
2649255
Compare
key.match("^HTTP_.*") | ||
end | ||
env.each do |header| | ||
current_headers[header[0].split('_')[1..-1].join('-')] = header[1] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ianballou : Could you explain why this is needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is one bit of the code that was created a while back. I believe it's here because request.env contains environment variables, and some of which translate to headers. The headers as env vars have underscores and are prefixed with "HTTP_". To turn them into true headers, they need the underscores turned into hyphens also the HTTP prefix needs removing.
I need to read up more on it to verify, but one example I saw was that our apache must set the Remote-User header, which eventually reaches Pulp/Django as "HTTP_REMOTE_USER".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was trying to remember why start_upload_blob
doesn't use translated_headers_for_proxy
, and remembered that uploading a blob doesn't require special headers, unlike actually uploading the blob. For example: https://specs.opencontainers.org/distribution-spec/?v=v1.0.0#DISTRIBUTION-SPEC-93
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some more helpful material about the web server environment variables https://medium.com/@cipeinado/unlock-http-info-in-rails-with-rack-request-env-and-uri-c7835397dc14
It clarifies my thinking a bit about how the HTTP_ variables relate to headers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another thing that's interesting -- so request.headers
doesn't list anything by default. You need to look up a specific header to get info. If you type request.headers.to_a
, for example, you end up just getting the normal request.env
information more or less. It would need to be verified, but I think request.headers['key']
looks for headers by various naming conventions. For example:
[13] pry(#<Katello::Api::Registry::RegistryProxiesController>)> request.headers
=> #<ActionDispatch::Http::Headers:0x000055afdecc0450
@req=
#<ActionDispatch::Request POST "https://centos8-katello-devel.manicotto.example.com/v2/organization/product/hello-world/blobs/uploads/" for 192.168.122.147>>
[14] pry(#<Katello::Api::Registry::RegistryProxiesController>)> request.headers['Authorization']
=> "Bearer $2a$09$1b6453892473a467d0737uL4crR75S3rqz44qQcdMGK68gYLHX/Ba"
[15] pry(#<Katello::Api::Registry::RegistryProxiesController>)> request.headers['AUTHORIZATION']
=> "Bearer $2a$09$1b6453892473a467d0737uL4crR75S3rqz44qQcdMGK68gYLHX/Ba"
[16] pry(#<Katello::Api::Registry::RegistryProxiesController>)> request.headers['HTTP_AUTHORIZATION']
=> "Bearer $2a$09$1b6453892473a467d0737uL4crR75S3rqz44qQcdMGK68gYLHX/Ba"
[17] pry(#<Katello::Api::Registry::RegistryProxiesController>)> request.headers['HTT_AUTHORIZATION']
=> nil
[18] pry(#<Katello::Api::Registry::RegistryProxiesController>)> request.headers['HTTP_AUTHORIZATION']
=> "Bearer $2a$09$1b6453892473a467d0737uL4crR75S3rqz44qQcdMGK68gYLHX/Ba"
[19] pry(#<Katello::Api::Registry::RegistryProxiesController>)> request.headers['x-authorization']
=> nil
[20] pry(#<Katello::Api::Registry::RegistryProxiesController>)> request.headers['X-Authorization']
=> nil
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did realize that some headers, like the Content-Length, don't make it in with the HTTP_ env vars. So I'll add explicit checks for those.
2649255
to
d4c16dc
Compare
@qcjames53 my PR is ready for another round of reviews. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Ian. I was able to test this PR again with a large image (I used keycloak again, 461MB). Using the puma patch you mentioned, I'm unfortunately still seeing 502 bad gateway errors. Still the same puma error as well: #<Puma::HttpParserError: maximum size of chunk header exceeded>
. I'm hoping I'm doing something incorrect with this testing; please let me know if this should be working on my end.
Thanks for adding test cases for the new functionality; good addition. I was unable to get them to run locally but it looks like the GH automation was happy. As of now I don't think we need a test for large images since you are mocking the pulp responses anyways.
Thanks for the other small formatting/comment changes. Outside of the one comment below, everything else looks pretty good to me.
File.open(tmp_file("#{params[:uuid]}.tar"), 'ab', 0600) do |file| | ||
file.write request.body.read | ||
headers = translated_headers_for_proxy | ||
headers['Content-Type'] = request.headers['Content-Type'] if request.headers['Content-Type'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It really feels like there should be a more concise way to do all these calls but neither ||= or &&= works. Perhaps you could split all three of these test blocks into a method? I don't think fancier syntax is necessarily required; this is very easy to understand as-is. It just bugs me at the kernel level.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lemme take a look about if there's a less verbose way to do this that doesn't lose readability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on our video call I'm happy to call this ok. It's very readable and quick as you wrote it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't find a less verbose way to write this, that check for nil seems like a requirement. C'mon Ruby!
Can confirm that the new puma patch works to allow pushes for larger images. Thank you for the help with that config, Ian. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK
What are the changes introduced in this pull request?
Adds support for pushing content through Katello to Pulp. Does not index any information from Pulp. As such, only pushing is possible through Katello.
Considerations taken when implementing this change?
The REMOTE_USER header must be set to perform remote auth with the Pulpcore registry. Apache will set this rather than Katello, so it's left out here.
What are the testing steps for this pull request?
/usr/lib/python3.11/site-packages/pulp_container/app/token_verification.py
, addreturn RemoteUserRegistryAuthentication().authenticate(request)
to the top ofRegistryAuthentication.authenticate.
/etc/httpd/conf.d/05-foreman-ssl.conf
so that the/pulpcore_registry/v2/
location losesRequestHeader set REMOTE_USER "%{SSL_CLIENT_S_DN_CN}s" env=SSL_CLIENT_S_DN_CN
and gainsRequestHeader set REMOTE_USER "admin"
.foreman/config/settings.plugins.d/katello.yaml
:podman pull
so there is something to push.