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

Ensure basic auth when getting manifest #86

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

a186710
Copy link

@a186710 a186710 commented Mar 27, 2023

Include basic auth header when getting manifest, avoiding login failure with Nexus OSS repo.

Nexus OSS responds Sonatype Nexus Repository Manager as realm in the WWW-Authenticate header and does not play well with current implementation. However, getting a token should not be necessary with basic auth enabled. Go oras client works well already.

Current behavior

Targeting same nexus repository, that does not allow anonymous manifest/pull and requires basic auth.

oras CLI

oras pull my-nexus.example.com/my/image.db:latest
Downloading 394458a69d7a image.db
Downloaded  394458a69d7a image.db
Pulled my-nexus.example.com/my/image.db:latest
Digest: sha256:56d0ba1e3806f3af6b75d88eab8fe82f83d66b899e06efcda8d4eefa07b66e38

Test client

import logging
import oras.client

HOST='my-nexus.example.com'
IMG='my/image.db:latest'

logging.basicConfig(level=logging.DEBUG)

client = oras.client.OrasClient(hostname=HOST, insecure=False)
client.pull(target=IMG)

oras-py (with test client)

DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): my-nexus.example.com:443
DEBUG:urllib3.connectionpool:https://my-nexus.example.com:443 "GET /v2/my/image.db/manifests/latest HTTP/1.1" 401 113
DEBUG:oras.logger:No Authorization, requesting anonymous token
DEBUG:oras.logger:Final params are {}
INFO:oras.logger:Retrying in 3 seconds - error: Invalid URL 'Sonatype Nexus Repository Manager': No schema supplied. Perhaps you meant http://Sonatype Nexus Repository Manager?
DEBUG:urllib3.connectionpool:https://my-nexus.example.com:443 "GET /v2/my/image.db/manifests/latest HTTP/1.1" 401 113
DEBUG:oras.logger:No Authorization, requesting anonymous token
DEBUG:oras.logger:Final params are {}
INFO:oras.logger:Retrying in 5 seconds - error: Invalid URL 'Sonatype Nexus Repository Manager': No schema supplied. Perhaps you meant http://Sonatype Nexus Repository Manager?
DEBUG:urllib3.connectionpool:https://my-nexus.example.com:443 "GET /v2/my/image.db/manifests/latest HTTP/1.1" 401 113
DEBUG:oras.logger:No Authorization, requesting anonymous token
DEBUG:oras.logger:Final params are {}
INFO:oras.logger:Retrying in 11 seconds - error: Invalid URL 'Sonatype Nexus Repository Manager': No schema supplied. Perhaps you meant http://Sonatype Nexus Repository Manager?
DEBUG:urllib3.connectionpool:https://my-nexus.example.com:443 "GET /v2/my/image.db/manifests/latest HTTP/1.1" 401 113
DEBUG:oras.logger:No Authorization, requesting anonymous token
DEBUG:oras.logger:Final params are {}
INFO:oras.logger:Retrying in 29 seconds - error: Invalid URL 'Sonatype Nexus Repository Manager': No schema supplied. Perhaps you meant http://Sonatype Nexus Repository Manager?
DEBUG:urllib3.connectionpool:https://my-nexus.example.com:443 "GET /v2/my/image.db/manifests/latest HTTP/1.1" 401 113
DEBUG:oras.logger:No Authorization, requesting anonymous token
DEBUG:oras.logger:Final params are {}
INFO:oras.logger:Retrying in 83 seconds - error: Invalid URL 'Sonatype Nexus Repository Manager': No schema supplied. Perhaps you meant http://Sonatype Nexus Repository Manager?
DEBUG:urllib3.connectionpool:Resetting dropped connection: my-nexus.example.com
DEBUG:urllib3.connectionpool:https://my-nexus.example.com:443 "GET /v2/my/image.db/manifests/latest HTTP/1.1" 401 113
DEBUG:oras.logger:No Authorization, requesting anonymous token
DEBUG:oras.logger:Final params are {}
Traceback (most recent call last):
  File "/usr/lib/python3.10/runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib/python3.10/runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "/home/tst/.vscode-server/extensions/ms-python.python-2023.4.1/pythonFiles/lib/python/debugpy/adapter/../../debugpy/launcher/../../debugpy/__main__.py", line 39, in <module>
    cli.main()
  File "/home/tst/.vscode-server/extensions/ms-python.python-2023.4.1/pythonFiles/lib/python/debugpy/adapter/../../debugpy/launcher/../../debugpy/../debugpy/server/cli.py", line 430, in main
    run()
  File "/home/tst/.vscode-server/extensions/ms-python.python-2023.4.1/pythonFiles/lib/python/debugpy/adapter/../../debugpy/launcher/../../debugpy/../debugpy/server/cli.py", line 284, in run_file
    runpy.run_path(target, run_name="__main__")
  File "/home/tst/.vscode-server/extensions/ms-python.python-2023.4.1/pythonFiles/lib/python/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_runpy.py", line 321, in run_path
    return _run_module_code(code, init_globals, run_name,
  File "/home/tst/.vscode-server/extensions/ms-python.python-2023.4.1/pythonFiles/lib/python/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_runpy.py", line 135, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "/home/tst/.vscode-server/extensions/ms-python.python-2023.4.1/pythonFiles/lib/python/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_runpy.py", line 124, in _run_code
    exec(code, run_globals)
  File "/home/tst/oras-fork/test.py", line 10, in <module>
    client.pull(target=IMG)
  File "/home/tst/oras-fork/oras/client.py", line 137, in pull
    return self.remote.pull(*args, **kwargs)
  File "/home/tst/oras-fork/oras/provider.py", line 741, in pull
    manifest = self.get_manifest(container, allowed_media_type)
  File "/home/tst/oras-fork/oras/decorator.py", line 35, in __call__
    return self.func(cls, *args, **kwargs)
  File "/home/tst/oras-fork/oras/provider.py", line 796, in get_manifest
    response = self.do_request(get_manifest, "GET", headers=headers)
  File "/home/tst/oras-fork/oras/decorator.py", line 60, in __call__
    return self.func(cls, *args, **kwargs)
  File "/home/tst/oras-fork/oras/provider.py", line 845, in do_request
    if self.authenticate_request(response):
  File "/home/tst/oras-fork/oras/provider.py", line 901, in authenticate_request
    if self.request_anonymous_token(h):
  File "/home/tst/oras-fork/oras/provider.py", line 965, in request_anonymous_token
    response = self.session.request("GET", h.realm, params=params)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 528, in request
    prep = self.prepare_request(req)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 456, in prepare_request
    p.prepare(
  File "/usr/lib/python3/dist-packages/requests/models.py", line 316, in prepare
    self.prepare_url(url, params)
  File "/usr/lib/python3/dist-packages/requests/models.py", line 390, in prepare_url
    raise MissingSchema(error)
requests.exceptions.MissingSchema: Invalid URL 'Sonatype Nexus Repository Manager': No schema supplied. Perhaps you meant http://Sonatype Nexus Repository Manager?

oras-py (with test client) in this patch

DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): my-nexus.example.com:443
DEBUG:urllib3.connectionpool:https://my-nexus.example.com:443 "GET /v2/my/image.db/manifests/latest HTTP/1.1" 200 513
DEBUG:urllib3.connectionpool:https://my-nexus.example.com:443 "GET /v2/my/image.db/blobs/sha256:394458a69d7a4beb146fbeed181b6646b2dfb583df1b8fc5f71ada8034eb7726 HTTP/1.1" 200 809119
INFO:oras.logger:Successfully pulled /tmp/oras-tmp.4tafaoj1/image.db.

Include basic auth header when getting manifest, avoiding login failure with Nexus OSS repo

Signed-off-by: amontfaucon <[email protected]>
@vsoch
Copy link
Contributor

vsoch commented Mar 27, 2023

This looks good - could you please bump the version in oras/version.py and add a corresponding line to CHANGELOG.md?

@a186710
Copy link
Author

a186710 commented Mar 27, 2023

Thanks, added both.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants