-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
fix: pull error response docker rest api compatibility #20239
fix: pull error response docker rest api compatibility #20239
Conversation
Adding the "do-not-merge/release-note-label-needed" label because no release-note block was detected, please follow our release note process to remove it. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
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.
Thanks for contributing!
I don't think that's correct. Docker calls FormatStatus which in turn does exactly what Podman seems to be doing already, see
https://github.com/moby/moby/blob/master/pkg/streamformatter/streamformatter.go#L32-L41.
So my current conclusion is that the Docker API docs are incomplete?
Yes, that can be true. I haven't thought about that before. |
You mentioned that in the issue. Do you have a reproducer for that? |
Sorry, I didn't clarify, but I am not the creator of the issue. I never used that library the owner of that issue is @Alex-Izquierdo, I just saw what he mentioned and reproduced the messages using the Docker and Podman API. curl --no-buffer -XPOST --unix-socket ./docker.sock "http:/v1.43/images/create?fromImage=quay.io/idonotexist/idonotexist:dummy" I received this response: {"message":"unauthorized: access to the requested resource is not authorized"} But, If I run Podman: ./bin/podman system service -t 0 --log-level=debug When I send a request to Podman in the same way: curl --no-buffer -XPOST --unix-socket /run/user/1000/podman/podman.sock "http:/v1.43/images/create?fromImage=quay.io/idonotexist/idonotexist:dummy" | json_pp I received this response: {
"error" : "initializing source docker://quay.io/idonotexist/idonotexist:dummy: reading manifest dummy in quay.io/idonotexist/idonotexist: unauthorized: access to the requested resource is not authorized",
"errorDetail" : {
"message" : "initializing source docker://quay.io/idonotexist/idonotexist:dummy: reading manifest dummy in quay.io/idonotexist/idonotexist: unauthorized: access to the requested resource is not authorized"
},
"progressDetail" : {}
} Alex says that the different responses give him trouble when he tries to use those libraries. |
Thanks, @jackgris ! I will take a closer look. |
OK, I believe to see the code in question (see https://github.com/moby/moby/blob/master/api/server/router/image/image_routes.go#L148-L151). Docker will send the error-detail as is if (and only if) no progress data has been sent yet. So Podman's compat API should do the same. @jackgris do you feel comfortable tackling that or shall we take over? |
OK, I'll try to send a new pull request these days. I'll remove the field that I added to |
Thank you, @jackgris ! I can help writing tests once the PR has been updated. |
I tried to take a look, but I realized it wasn't going to be as quick as I had hoped and I haven't had the time to revisit it in detail. Thanks a lot @jackgris to address the issue. |
Ephemeral COPR build failed. @containers/packit-build please check. |
Sorry, I made a mistake and completely forgot to squash my commit, before pushing the 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.
The direction looks good to me. Thanks!
pkg/api/handlers/compat/images.go
Outdated
message := jsonmessage.JSONError{ | ||
Message: msg, | ||
} | ||
if err := enc.Encode(message); err != 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.
We can do enc.Encode(report.Error)
directly I think.
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.
If I encode the message with enc.Encode(report.Error)
Podman will return this message:
{
"message" : "initializing source docker://quay.io/idonotexist/idonotexist:dummy: reading manifest dummy in quay.io/idonotexist/idonotexist: unauthorized: access to the requested resource is not authorized"
}
Have more details that the return message unwrapped, that is like this:
{
"message" : "unauthorized: access to the requested resource is not authorized"
}
Docker returns the same message as the second option. What is your opinion on this? What do you prefer?
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.
Nice catch! I do not feel strongly about it. However, some libraries try to string-match errors, so returning the same error as Docker is probably the right thing do to.
pkg/api/handlers/compat/images.go
Outdated
if err := enc.Encode(report); err != nil { | ||
logrus.Warnf("Failed to json encode error %q", err.Error()) | ||
|
||
if err != nil && !progressSent { |
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.
Please add a comment here elaborating on this specific case and why it needs to be done (docker compat).
OK, I think tomorrow I will send a new pull request with the changes you suggest. |
c888050
to
b70dfb2
Compare
Heads up: in case #20328 is merged before, you need to rebase. It moves the code to another file. |
OK, I see that. Now that code is in |
3062836
to
e434e6a
Compare
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.
Thanks!
Last step is to add tests which live here: https://github.com/containers/podman/blob/main/test/apiv2/10-images.at
I think we should match against the JSON payload and look for the message
field. The syntax of the tests is explained here: https://github.com/containers/podman/tree/main/test/apiv2#writing-tests
Okay, I will follow those steps to write tests. I've never used that tool before; it seems similar to shell scripting. |
What do you think about that test? Do you believe it's correct, or does it need to be made more generic? One thing I find a bit challenging to understand is how to incorporate regular expressions into it. How can I rewrite the test with a regular expression to accept any message value and only check if the 'message' key is present? |
This is related to the issue containers#20013 Signed-off-by: Gabriel Pozo <[email protected]>
694c7c5
to
b9f2c4d
Compare
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.
LGTM
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: jackgris, vrothberg The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Can you give an example? Something like @edsantiago PTAL |
POSIX regexes should work, per the bash |
First of all, thank you, both. Well, I think I've found what I was looking for—something like this: t POST "/images/create?fromImage=quay.io/idonotexist/idonotexist:dummy" 401 \
.message~'unauthorized: [a-z]' That test passed. What do you think is better for this case? Do you prefer the way a pull is requested or this new one? |
I like the current implementation of the test as it checks for an explicit error message. LGTM |
OK, nice. Is there something more to do to finish the process? |
/lgtm |
Just a LGTM from another maintainer. Thanks a lot for contributing! This fix will make it into the next Podman 4.8 release which is scheduled for November. |
This is related to the issue #20013
I have not added another e2e test, because in the
pull_test.go
file the test called "podman pull bogus image" is checking that the response contains "unauthorized: access to the requested resource is not authorized"One thing that I was not sure you agreed with is the modified
jsonmessage.JSONMessage{}
type. That is used there but belongs to the Docker jsonmessage package inside the vendor folder. Maybe it is better to copy that type into the same package and modify it there.Does this PR introduce a user-facing change?
This changes the error response message to the comment in the issue.