-
Notifications
You must be signed in to change notification settings - Fork 388
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
fixes to make local registry (unauthenticated) usable #1164
base: main
Are you sure you want to change the base?
Conversation
Thanks for submitting your first pull request! You are awesome! 🤗 |
hmm i am just realizing that this might break docker images that are like |
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.
Thanks for investigating this! I've no objection to the changes here, but I can't quite see how this is affecting the results. When I test it with sample images, the registry host is stripped off by truncating images. What are the values of the image string where this doesn't do the right thing? I tried with localhost:32000/repo/image:tag
and it all seems right already.
binderhub/builder.py
Outdated
@@ -291,7 +291,7 @@ async def get(self, provider_prefix, _unescaped_spec): | |||
if self.settings['use_registry']: | |||
for _ in range(3): | |||
try: | |||
image_manifest = await self.registry.get_image_manifest(*'/'.join(image_name.split('/')[-2:]).split(':', 1)) | |||
image_manifest = await self.registry.get_image_manifest(*'/'.join(image_name.split('/')[-2:]).rsplit(':', 1)) |
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 believe this change doesn't affect the result since image_name.split("/")[-2:]
will drop the hostname, so this is called without the host:
(py3) In [14]: for image_name in ["gcr.io/repo/name", "repo/name", "repo/name:tag", "localhost:123/repo/name", "localhost:123/repo/name:tag"]:
...: image_tag = '/'.join(image_name.split('/')[-2:]).split(':', 1)
...: print(f"{image_name} -> {image_tag}")
...: assert '/'.join(image_name.split('/')[-2:]).split(':', 1) == '/'.join(image_name.split('/')[-2:]).rsplit(':', 1)
...:
gcr.io/repo/name -> ['repo/name']
repo/name -> ['repo/name']
repo/name:tag -> ['repo/name', 'tag']
localhost:123/repo/name -> ['repo/name']
localhost:123/repo/name:tag -> ['repo/name', 'tag']
binderhub/registry.py
Outdated
@@ -188,6 +188,10 @@ def _default_password(self): | |||
@gen.coroutine | |||
def get_image_manifest(self, image, tag): | |||
client = httpclient.AsyncHTTPClient() | |||
if '/' in image: |
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.
From what I can tell, this /
is never in image, since it is split off of the image. Can you tell where it's being called with the host?
Ah, on re-reading more carefully, I realize that a local registry can have top-level images (i.e. I think it would probably be good to actually parse this info rather than our increasingly nested sequence of image splits. What I don't understand, though, is how docker determines if a tag of the form
I've tested with a local registry running on port 80 so I could exclude port info:
and I was able to push images with 0-many
Docker's implementation defines a domain prefix as containing # added 127.0.0.1 testhost to /etc/hosts
$ docker tag registry:2 testhost/registry:2
$ docker push testhost/registry:2
The push refers to repository [docker.io/testhost/registry]
... So we can implement proper image string parsing to always return registry, repository, and tag: def parse_image(image_name):
"""Parse a docker image string into (registry, repository, tag)"""
# image_name could be "localhost:5000/foo:tag" or "gcr.io/project/subrepo/sub/sub/sub:tag" or "org/repo:tag" for implicit docker.io
registry, _, repo_tag = image_name.partition("/")
if registry == "localhost" or any(c in registry for c in (".", ":")):
# registry host is specified
pass
else:
# registry not given, use implicit default docker.io registry
registry = "docker.io"
repo_tag = image_name
repository, _, tag = repo_tag.partition(":")
return (registry, repository, tag) That eliminates our assumptions about how many |
I was running in the exact same situation.
Yes! Using something like The I would be happy to help :) |
2ed984f
to
25e8317
Compare
test image_prefix trait validation add image name parser simplify get_image_manifest method extend get_image_manifest tests update zero-to-binderhub doc, private registry section
25e8317
to
0e02519
Compare
These are a couple of small fixes to make images of type
localhost:32000/my-image
work throughout binder.With these fixes I was able to set up a microk8s single-machine cluster that serves binder.