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

Support for config.json credHelpers #142

Open
hanikesn opened this issue Jun 10, 2024 · 5 comments
Open

Support for config.json credHelpers #142

hanikesn opened this issue Jun 10, 2024 · 5 comments

Comments

@hanikesn
Copy link

A lot of legacy clients and for example the oras cli support credHelpers from ~/.docker/config.json. Support for those would be very helpful.

@vsoch
Copy link
Contributor

vsoch commented Jun 10, 2024

This should already be supported here:

oras-py/oras/provider.py

Lines 188 to 207 in fd8a83c

# Login
# https://docker-py.readthedocs.io/en/stable/client.html?highlight=login#docker.client.DockerClient.login
try:
client = oras.utils.get_docker_client(tls_verify=tls_verify)
return client.login(
username=username,
password=password,
registry=hostname,
dockercfg_path=config_path,
)
# Fallback to manual login
except Exception:
return login.DockerClient().login(
username=username, # type: ignore
password=password, # type: ignore
registry=hostname, # type: ignore
dockercfg_path=config_path,
)
in that the DockerClient looks for that path.
return docker.DockerClient(tls=tls_verify, **kwargs)

@hanikesn
Copy link
Author

I don't have a username or password, so client.login() will interactively ask for those. I'm using docker-credential-gcloud helper though, which doesn't need either.

I solved this by doing the following override in my registry:

    def load_configs(self, container: container_type, configs: Optional[list] = None):
        if self._basic_auth:
            return
        config = docker.auth.load_config()
        hostname = docker.auth.convert_to_hostname(self.hostname)
        auth = config.resolve_authconfig(hostname)
        self.set_basic_auth(username=auth['Username'], password=auth['Password'])

@vsoch
Copy link
Contributor

vsoch commented Jun 10, 2024

We have a new set of auth backends for this purpose:

https://github.com/oras-project/oras-py/blob/main/oras/auth/base.py

What you'd do is subclass that base, and update the load_configs to be that (and edit the other functions if needed for google cloud). Would you be open to doing a PR with these changes? Then you could specify your auth backend and it should just work.

@wosc
Copy link

wosc commented Jun 20, 2024

I have the same usecase (access google cloud registry while the local docker client already has all the authentication set up). My guess is, using the new "base" auth code structure, the basic idea would look something like this (have not thought about error handling yet though):

import docker.auth
import oras.auth

class DockerClientAuth(oras.auth.BasicAuth):
    def _load_auth(self, hostname: str) -> bool:
        if super()._load_auth(hostname):
            return True
        config = docker.auth.load_config()
        hostname = docker.auth.convert_to_hostname(hostname)
        a = config.resolve_authconfig(hostname)
        self.set_basic_auth(username=a['Username'], password=a['Password'])
        return True

oras.auth.auth_backends['docker'] = DockerClientAuth

registry = Registry(auth_backend='docker')
filenames = registry.pull('europe-west3-docker.pkg.dev/myproject/myrepo:tag')

This of course depends on the https://pypi.org/project/docker/ package being installed.

@vsoch
Copy link
Contributor

vsoch commented Jun 20, 2024

In case you missed the message above, we already have the docker client included and "login" is called from it:

return docker.DockerClient(tls=tls_verify, **kwargs)

I would be open to review a PR to address this need, from either of you.

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

No branches or pull requests

3 participants