-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Handle error message from token server with containerd backend #50176
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
Handle error message from token server with containerd backend #50176
Conversation
4587d18
to
ae68a4e
Compare
Failure looks unrelated, but hadn't seen this one before, so posting;
edit: known flaky test; tracked in #50168 |
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.
left some minor comment about formatting (preventing linters to complain).
Interesting though that the docker hub response uses details
(plural); took me a bit to spot that difference, and now I'm wondering if that was a mistake; might be worth adding a comment on the tokenServerError
type to outline this (I added a link to the old implementation that we can align with)
daemon/containerd/registry_errors.go
Outdated
type tokenServerError struct { | ||
Details string `json:"details"` | ||
} |
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 curious if there wasn't a definition for this, but looking at the old code from docker/distribution, it looks like this type was added for incorrectly formatted responses that are missing some of the other fields (?); perhaps adding a similar comment here could be useful.
moby/vendor/github.com/docker/distribution/registry/client/errors.go
Lines 64 to 72 in e1d0aac
// For backward compatibility, handle irregularly formatted | |
// messages that contain a "details" field. | |
var detailsErr struct { | |
Details string `json:"details"` | |
} | |
err = json.Unmarshal(body, &detailsErr) | |
if err == nil && detailsErr.Details != "" { | |
return makeError(statusCode, detailsErr.Details) | |
} |
Looks like the old code also looks for mediatype, and if it doesn't match, it returns the whole body, but not sure if that's a good idea (at least not without a limit-reader;
moby/vendor/github.com/docker/distribution/registry/client/errors.go
Lines 60 to 62 in e1d0aac
if contentType != "application/json" && contentType != "application/vnd.api+json" { | |
return makeError(statusCode, string(body)) | |
} |
I'm slightly curious though if the current type would work for this; I see code further down handling the docker.Errors
type (which awkwardly uses a interface{}
for details, not a string);
moby/daemon/containerd/registry_errors.go
Lines 36 to 37 in 3b1d2f7
var derr docker.Error | |
if errors.As(err, &derr) { |
moby/vendor/github.com/containerd/containerd/v2/core/remotes/docker/errcode.go
Lines 114 to 118 in 0aa8fe0
// Error provides a wrapper around ErrorCode with extra Details provided. | |
type Error struct { | |
Code ErrorCode `json:"code"` | |
Message string `json:"message"` | |
Detail interface{} `json:"detail,omitempty"` |
☝️ that error looks to be what's now in the distribution-spec (perhaps containerd should use that as well, but not really important); https://github.com/opencontainers/distribution-spec/blob/583e014d15418d839d67f68152bc2c83821770e0/specs-go/v1/error.go#L35-L40
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'm slightly curious though if the current type would work for this
🙈 🤔 never mind; looks like that's using detail
(singular) not details
(plural); and now I wonder where the plural came from! Was that a mistake on the Docker Hub side, and is that's what's causing the error-details to not be picked up?
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 just an old format from before the distribution-spec. The token server still uses it in some situations, if the token server no longer used then we wouldn't need to consider. The distribution code path today already has a compatibility path for this though.
Signed-off-by: Derek McGowan <[email protected]>
ae68a4e
to
941d09e
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
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
return cerrdefs.ErrPermissionDenied.WithMessage(fmt.Sprintf("%s - %s", docker.ErrorCodeDenied.Message(), tokenErr.Details)) | ||
} | ||
} | ||
} | ||
} else { |
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 need to cleanup some of this function; following the logic then, this "else" branch is used to return if err == nil
- which we probably should handle at the start.
Token server may return an error in the format
{"details": "some errors message"}
, for example requesting a token with a PAT which does not have enough scope returns{"details":"access token has insufficient scopes"}
. Without this change, those details are not returned to the user.