Skip to content
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

When I execute an oras push, the scope that calls the get service token loses the push, only the pull #1599

Closed
1 task done
hopegi opened this issue Dec 26, 2024 · 9 comments · Fixed by #1608
Closed
1 task done
Labels
bug Something isn't working
Milestone

Comments

@hopegi
Copy link
Contributor

hopegi commented Dec 26, 2024

What happened in your environment?

  1. when i exec oras push xxx/xxx/test:v1 test.txt ,then i got a fail msg . but i add the --debug flag ,like oras push xxx/xxx/test:v1 test.txt --debug. it push successfully.
  2. this problem dose not apper in normal registry,like harbor,docker hub
  3. i catch access log find that when i exec cmd oras push xxx/xxx/test:v1 test.txt, the url of calling get service token like this https://127.0.0.1/service/token?service=hg-registry&scope=repository%3Ahg-ns1%2Ftest%3Apull and when i exec cmd oras push xxx/xxx/test:v1 test.txt --debug,the url is https://127.0.0.1/service/token?service=hg-registry&scope=repository%3Ahg-ns1%2Ftest%3Apush%2Cpull

there is something diff between within --debug and without --debug

What did you expect to happen?

No response

How can we reproduce it?

just exec the command and catch access log

What is the version of your ORAS CLI?

from 1.2.0 to latest 1.2.2 also has this problem

What is your OS environment?

every linux system

Are you willing to submit PRs to fix it?

  • Yes, I am willing to fix it.
@hopegi hopegi added bug Something isn't working triage New issues or PRs to be acknowledged by maintainers labels Dec 26, 2024
@TerryHowe
Copy link
Member

What is the failure message?

What is the registry?

Does it always succeed with --debug and always fail without?

@hopegi
Copy link
Contributor Author

hopegi commented Dec 27, 2024

Does it always succeed with --debug and always fail without?

yes, it always succeed with --debug,and always fail without。the registry is a custom registry base on harbor. we add some validate when client gets service token .

@hopegi
Copy link
Contributor Author

hopegi commented Dec 27, 2024

when i push something to a project which the registry is not contain in that project, it will be fail .because there are any valiations in get service token,other client like docker or ctr ,they will add pull and push in scope. but when oras do these,it only add pull

@TerryHowe
Copy link
Member

Based on your proposed fix, I would think it would work if you specified --to-tty which is at least a better work-around for you.

@shizhMSFT
Copy link
Contributor

Hi @hopegi, could you share a complete debug log of oras push for us to analyze? A run of oras version is also appreciated.

@shizhMSFT shizhMSFT added question Further information is requested and removed triage New issues or PRs to be acknowledged by maintainers labels Dec 30, 2024
@hopegi
Copy link
Contributor Author

hopegi commented Dec 30, 2024

Based on your proposed fix, I would think it would work if you specified --to-tty which is at least a better work-around for you.

did you mean --no-tty,i try add --no-tty,It is indeed effective in correcting the service token URL.Change the URL to the correct https://127.0.0..1/service/token?scope=repository%3Aoras-test%2Foras%3Apull&service=my-registry

@hopegi
Copy link
Contributor Author

hopegi commented Dec 30, 2024

Hi @hopegi, could you share a complete debug log of oras push for us to analyze? A run of oras version is also appreciated.

oras version is 1.2.0,1.2.2 also appera this problem.
the problem is that i exec oras push xxxxx --debug or oras push xxxxx --no-tty, then oras will use https://127.0.0..1/service/token?scope=repository%3Aoras-test%2Foras%3Apull%2Cpush&service=my-registry to get the serivce token . the url is correct in this time, but when i remove --debug or --no-tty , the url will be change to https://127.0.0..1/service/token?scope=repository%3Aoras-test%2Foras%3Apull&service=my-registry, which is lease push in scope`s action.

i show you the debug's log,but it is not easy to found the problem of the code i think. to releate the pr, ctx = registryutil.WithScopeHint(ctx, dst, auth.ActionPull, auth.ActionPush) can not set pull and push in to dst,because the dst is not instance of remote.Repository,

DEBU[0000] Request #0
> Request URL: "http://127.0.0.1/v2/oras-test/oras/manifests/sha256:0af3ccb91c9d298cf3f6bfb9aea101f26494b97f82c5298383ed127fbaa0ea28"
> Request method: "HEAD"
> Request headers:
   "Accept": "application/vnd.docker.distribution.manifest.v2+json, application/vnd.docker.distribution.manifest.list.v2+json, application/vnd.oci.image.manifest.v1+json, application/vnd.oci.image.index.v1+json, application/vnd.oci.artifact.manifest.v1+json"
   "User-Agent": "oras/1.2.0" 
DEBU[0000] Response #0
< Response Status: "401 Unauthorized"
< Response headers:
   "Server": "CTYun LB"
   "Date": "Mon, 30 Dec 2024 07:28:06 GMT"
   "Content-Type": "application/json; charset=utf-8"
   "Connection": "keep-alive"
   "Docker-Distribution-Api-Version": "registry/2.0"
   "Www-Authenticate": "Bearer realm=\"https://127.0.0.1/service/token\",service=\"ctyun-container-registry\"" 
DEBU[0000] Request #1
> Request URL: "https://127.0.0.1/service/token?scope=repository%3Aoras-test%2Foras%3Apull%2Cpush&service=ctyun-container-registry"
> Request method: "GET"
> Request headers:
   "Authorization": "*****"
   "User-Agent": "oras/1.2.0"

@Wwwsylvia
Copy link
Member

Wwwsylvia commented Jan 3, 2025

Thanks @hopegi for the information. This is indeed a bug. The root cause is that, when tty is used, originDst is wrapped by a status display handler on line 216, and the resulted dst is not a *remote.Repository. As a result, the scope hints cannot be correctly added on line 227. When tty is not used, originDst is not wrapped so the scope hints work as expected.

oras/cmd/oras/root/push.go

Lines 211 to 235 in 677529b

// prepare push
originalDst, err := opts.NewTarget(opts.Common, logger)
if err != nil {
return err
}
dst, stopTrack, err := displayStatus.TrackTarget(originalDst)
if err != nil {
return err
}
copyOptions := oras.DefaultCopyOptions
copyOptions.Concurrency = opts.concurrency
union := contentutil.MultiReadOnlyTarget(memoryStore, store)
displayStatus.UpdateCopyOptions(&copyOptions.CopyGraphOptions, union)
copy := func(root ocispec.Descriptor) error {
// add both pull and push scope hints for dst repository
// to save potential push-scope token requests during copy
ctx = registryutil.WithScopeHint(ctx, dst, auth.ActionPull, auth.ActionPush)
if tag := opts.Reference; tag == "" {
err = oras.CopyGraph(ctx, union, dst, root, copyOptions.CopyGraphOptions)
} else {
_, err = oras.Copy(ctx, union, root.Digest.String(), dst, tag, copyOptions)
}
return err
}

// WithScopeHint adds a hinted scope to the context.
func WithScopeHint(ctx context.Context, target any, actions ...string) context.Context {
if repo, ok := target.(*remote.Repository); ok {
return auth.AppendRepositoryScope(ctx, repo.Reference, actions...)
}
return ctx
}

The same issue exists in the main branch too.

@Wwwsylvia
Copy link
Member

Wwwsylvia commented Jan 3, 2025

One possible fix could be to pass the repo reference to auth.AppendRepositoryScope, avoiding casting the wrapped target to *remote.Repository?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants