-
Notifications
You must be signed in to change notification settings - Fork 54
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
Export pull_layer & auth API #9
Conversation
I seem to remember there being a reason why these methods were not public. @bacongobbler or @radu-matei was there a reason either of you remember why these were private? |
Yes - some of that conversation can be found here: krustlet/krustlet#564 |
Basically the user should not be given any control over As for exposing |
Is there a compromise we can make here? I think that should be something |
If it helps contextualize the OP's desire, one of my hopeful use-cases when consuming this crate is a flavor/variant of https://oras.land/ - specifically with the goal of usage for smarter CI caching. This means that I may be running my caching utility in memory-constrained contexts while also dealing with up-to-multi-gigabyte payloads when considering the "image" as a whole. One of the possible optimizations under those constraints would be for me to be able to stream individual layers to decompress and write to disk during the logical pull operation, so that I never need to buffer an entire layer payload in-memory. I have an analogous desire during pushing as well due to the same memory constraints, where I wouldn't wish to hold those entire layers in-memory all at once. I'd have to know the checksum ahead of time for the push per the registry API, but that doesn't directly require me to hold the payload in memory. Most of these ideas appear incompatible with this crate's implementation details today, which I understand has been mostly informed by krustlet's usecase and contending with much smaller WASM artifacts. (I recognize that my goals are not inherently this project's goals and may need to find my own way as a result if the examples I've offered are not compelling-enough.) |
We've discussed the idea with a few of the ORAS maintainers. They were interested in oci-distribution being the basis of a Rust client for ORAS. oras-rs imported krustlet (including oci-distribution) as a subtree project, but hasn't seen any activity since that point. I assume the goal was to copy oci-distribution as a starting point for a Rust client. If you're looking for an As oras-rs matures, I could see much of oci-distribution being ported over to oras-rs. Implementing the entire OCI distribution spec is one of our stated goals, and that goal aligns with some parts of ORAS as well.
I don't see how exposing methods like We could also abstract some of the |
Yes, current Another reason we want export |
I think we're in agreement here. I want to re-think the design approach though.
Would you mind weighing in on this? Do you have an example how you plan to use |
For parallel image layer data processing, we may don't need use
For on demand pull, we may need auth when token is expired:
We can also hiden the auth for
|
3ec6f78
to
204ce49
Compare
src/client.rs
Outdated
@@ -233,10 +230,7 @@ impl Client { | |||
image_manifest: Option<OciManifest>, | |||
) -> anyhow::Result<String> { | |||
debug!("Pushing image: {:?}", image_ref); | |||
let op = RegistryOperation::Push; | |||
if !self.tokens.contains_key(image_ref, op) { |
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.
Why are we forcing an auth even if we have a token? Isn't this a bit excessive?
src/client.rs
Outdated
&mut self, | ||
image: &Reference, | ||
authentication: &RegistryAuth, | ||
operation: RegistryOperation, | ||
) -> anyhow::Result<()> { | ||
debug!("Authorizing for image: {:?}", image); | ||
if self.tokens.contains_key(image, operation) { |
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.
Hmm... I see the reasoning behind this change. I think we designed it the other way so the caller can force a token refresh. It makes the code a little less DRY, but it does give the caller a bit more flexibility.
The other thing we need to address at some point is whether the token has expired (which I noticed in your review). Not required for this PR, but it's worth keeping in mind.
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.
Should we remove this commit? or replace with public TokenCache
for user to do the token expire check?
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.
oci-distribution should be the one responsible for checking and refreshing auth tokens. I don't think that should be the caller's responsibility.
That being said, this change actively prevents the user from refreshing the auth token, so I think this is a breaking change that should be reverted. Users should be able to manually refresh tokens by calling client.auth
at-will.
Can't we just address that in the calling code by checking the token's expiration date? That would mean you can just call |
I still don't understand why this can't be handled in oci-distribution. Why does this have to be orchestrated from another library? Why can't a We could just implement some form of middleware pattern so that https://doc.rust-lang.org/book/ch19-05-advanced-functions-and-closures.html |
Yes, we can do that way, but current
|
Thanks for your suggestions. Yes, we can pass functions to current |
@bacongobbler Another concern is container image layers are shared, after we pull the image manifests, we also need check whether the host already have shared layers pulled by other containers, and we only need pulling the missed parts of the layers. Image service/runtime are operate at image layer level and image distribution may also need export the layer related API. |
204ce49
to
9f8c838
Compare
Hi @bacongobbler @thomastaylor312 @flavio I rebased the PR and updated the commit message, please review. |
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 still disagree with this change in relation to oci-distribution's current API, but I don't really have the time right now to make contributions for further improvements. I'm fine with this going through for now. We can make changes to this API in future iterations since we haven't hit 1.0 yet, so there's plenty of time to refactor if necessary.
I see one code regression that I'd like to see changed. Otherwise this looks good to go.
@thomastaylor312 and @flavio do you have any ideas/concerns about this change?
src/client.rs
Outdated
&mut self, | ||
image: &Reference, | ||
authentication: &RegistryAuth, | ||
operation: RegistryOperation, | ||
) -> anyhow::Result<()> { | ||
debug!("Authorizing for image: {:?}", image); | ||
if self.tokens.contains_key(image, operation) { |
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.
oci-distribution should be the one responsible for checking and refreshing auth tokens. I don't think that should be the caller's responsibility.
That being said, this change actively prevents the user from refreshing the auth token, so I think this is a breaking change that should be reverted. Users should be able to manually refresh tokens by calling client.auth
at-will.
Yeah I think this is fine for now. We should just be careful as we approach 1.0 as we decide whether or not the |
1. Container images will share layers, the API should support the scenario which don't need pull all the layers 2. Container image size may vary from megabyte to gigabyte, export pull_blob API can allow the user to the following layer decompress/unpack/store operations in parallel. Signed-off-by: Arron Wang <[email protected]>
For some container image service which support ondemand layer pull like: * stargz https://github.com/containerd/stargz-snapshotter * Nydus Image Service https://github.com/dragonflyoss/image-service export auth API is a requirement when token is expired. Signed-off-by: Arron Wang <[email protected]>
9f8c838
to
3dfe4be
Compare
Thanks Matt, fully agree to keep
|
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 think we could find a better solution for this problem, as @bacongobbler suggested. Maybe approving this change will allow us to understand better how things could be changed.
I'm fine with this PR, but this is something we will need to discuss as we approach the 1.0 release
@bacongobbler This good to go from your end? |
@bacongobbler @thomastaylor312 @flavio Thanks, much appreciated! |
Export pull_layer & auth API
Export pull_blob API
1. Container images will share layers, the API should support the scenario which don't need pull all the layers.
2. Container image size may vary from megabyte to gigabyte, export pull_layer API can allow the user to the following layer decompress/unpack/store operations in parallel.
Export auth API
For some container image service which support ondemand layer pull like:
* stargz https://github.com/containerd/stargz-snapshotter
* Nydus Image Service https://github.com/dragonflyoss/image-service
export auth API is a requirement when token is expired.