-
Notifications
You must be signed in to change notification settings - Fork 554
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
Is there a way to reuse token/transport to prevent repeated auth requests? #740
Comments
Thank you for the kind words.
I know there's no way to avoid doing this because there's not a standard API for notifications, but this can be pretty painful for registries :P Joseph Schorr wrote a proposal for a new registry API to support this, which obviously you wouldn't be able to use anytime soon, but I wish there was a better way to do this. It would be wonderful if some software project existed to multiplex over the various pubsub implementations of major registries and expose a common API, but that might be an eternal pipedream 😄
This is definitely an annoying problem, and I don't know if there's an easy way to fix it. There's not currently a great way to work around this, but I did have one idea: Everything in It seems reasonable to me that we could do a type check in This wouldn't have any change in existing behavior for current clients, but would allow you to create an I like this approach because it's a really simple implementation, opt-in behavior, and doesn't change the API at all. If you'd be willing to implement and test this out (to verify that it works as expected), it should only be a three line change in Also if you have any better ideas for how you'd tackle this, I'm all ears. |
Thanks for the quick reply!
I'll check out the proposal! Concourse's resource model is polling-based as it's generally more resilient to things like missed events - granted, often at the expense of the external systems. I'll soon be working on a proposal to allow it to also leverage webhooks to reduce the amount of polling to only when a hook or event is received, so proposals like this one may become relevant there. Thanks! The current approach has enough mitigating factors that I think it might not be too bad in practice:
re: the transport |
This is interesting to me, please cc me!
This is definitely better than most clients I've seen 😄 |
Sure! I'll aim to write something up next week; it's been getting near the top of my TODO list. @jonjohnsonjr So, funny thing: this actually kind of already works without making any changes! If I add this to my code: rt, err := transport.New(repo.Registry, auth, http.DefaultTransport, []string{repo.Scope(transport.PullScope)})
if err != nil {
return resource.CheckResponse{}, fmt.Errorf("resolve repository: %w", err)
}
opts = append(opts, remote.WithTransport(rt)) It still does the ping on every request, but the ping returns 200 because the request is already authenticated via the transport. The code then interprets this 200 as anonymous, which is maybe a bit hokey1, but this ultimately results in just returning I looked into making the change you suggested, but didn't see a super clean way to detect whether to skip the ping. One problem is that the transport given to All in all, I think I'm OK with how this currently works; the ping actually verifies that the token is still valid, and if we get an unauthorized response a new token will be acquired, so this pretty elegantly handles the case of an expired token in a long-lived transport object. I'm guessing ping requests don't count towards rate limits, but this is a total blind guess as there doesn't seem to be a documented standard there. In any case I think this issue can be closed, unless you'd like to leave it open to make this flow more obvious (e.g. documentation or refactoring the code to not assume a 200 response is 'anonymous'). 1 it's not really "anonymous", it's more like "you pinged with sufficient auth" - which may mean anonymous if no auth was given |
Fantastic.
Yeah this is unfortunate :/ we're dealing with 4 or 5 different wrappings, which was nice at the time for testing, but makes things a bit complicated.
so we end up with a By the time I almost feel like I need the go 1.13 error API stuff to deal with this 😄
The only issue I really have here is with double-wrapped transports. I think we would end up logging things twice and retrying things twice, which isn't ideal. Let's leave this open for now while I try to think of a better way to deal with ^^^^ that.
Yeah it's kinda funky with all the wrapping. It's anonymous in the outer layer because the inner layer handles all the auth. |
Hmm... I'm definitely wrong. The We can avoid that if we do what containerd does where they just start making requests and only authenticate when they hit a 401. Related: #666 (comment) |
This issue is stale because it has been open for 90 days with no |
Hi there, thanks for developing this package - it's pretty great!
I'm using this package in the Concourse
registry-image
resource for listing tags and detecting changes to digests that tags point to - specifically, this PR: concourse/registry-image-resource#214I noticed that when I point it to a repository that has many tags it can take a very long time to find everything. Judging from the debug logs, it looks like one thing contributing to this is that every
remote.Image
call is going through its own auth flow, probably from this call:go-containerregistry/pkg/v1/remote/descriptor.go
Lines 199 to 203 in 72597da
Is there any way to re-use the token and/or transport for multiple requests in order to speed this up, by skipping the ping + token request? I'm worried that sending so many requests could lead to being rate limited more quickly, though I'm not sure if rate limits apply to the auth flow or the ping call (maybe not).
Thanks!
The text was updated successfully, but these errors were encountered: