-
Notifications
You must be signed in to change notification settings - Fork 394
dockerClient: skip TLS verification if configured in registries #468
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
Conversation
01be7f1 to
516391d
Compare
|
@mtrmac The API change hasn't been discussed but I think it makes the API easier to use and ultimately avoids boilerplate code for its users. |
mtrmac
left a comment
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.
ACK on the API change, that is much better for callers.
| reg = FindRegistry("registry.com/image:tag", registries) | ||
| reg, err = FindRegistry(nil, "registry.com/image:tag") | ||
| assert.Nil(t, err) | ||
| assert.NotNil(t, reg) |
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.
(Some of these should be require. so that future asserts don’t fail with nil references. But that’s trivial to retrofit if the tests ever fail, so not blocking.
A fair amount of this would probably be smaller if the tests were table-driven, but again, this works just fine, absolutely non-blocking.)
f6b95bb to
c739214
Compare
Tests fail expectedly as skopeo needs to be updated. I suggest to merge this PR, then update Skopeo and after that I'll take care of the pull code. |
mtrmac
left a comment
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.
Not a full review yet, just a few notes.
mtrmac
left a comment
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.
(This should be a complete review.)
ba8aa86 to
4d2e090
Compare
mtrmac
left a comment
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.
One more code fix please, and then just a few stylistic nits.
FWIW I have checked with #256 that this does not modify other on-the-wire behavior.
We generally want to see the I have prepared containers/skopeo#521 for this. |
Thanks a lot! I've been testing it locally but wasn't sure about the process. |
312f082 to
b80a785
Compare
| // | ||
| // This way, it matches "/foobar", "/foobar:latest" and ":latest" | ||
| // but it doesn't match ":5000/foobar" or ":latest:foobar". | ||
| reg := regexp.MustCompile(`(?m)^(\/.*|:.[^:\/]*)$`) |
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.
Please move this to a global variable; we don’t need to compile the regex on every call to isPrefix (i.e. on every FindRegistry call, for each configured registry).
| // | ||
| // This way, it matches "/foobar", "/foobar:latest" and ":latest" | ||
| // but it doesn't match ":5000/foobar" or ":latest:foobar". | ||
| reg := regexp.MustCompile(`(?m)^(\/.*|:.[^:\/]*)$`) |
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.
(Probably skip these bullet points for now, and read the end first.)
- If I understand the spec correctly,
(?m)means that the^and$characters also match newlines; why is that desirable? - In
:.[^…], why is the first character after:treated specially? AFAICT it doesn’t matter because::or:/are invalid:tag suffixes either way, but it is an extra element to think about. Is there some extra nuance I am missing? (If I’m not, this could be made completely precise by matching":"+reference.TagRegexpfromc/image/docker/reference.) - If matching at the level of individual repos (i.e. with the
:tag suffix) is desirable, symmetrically@digest should be accepted as well. And, maybe surprisingly, it’s possible to say repo:tag@digest (seereference.ReferenceRegexp), where digest is algo:hex-digits, i.e. the suffix can legitimately contain two colons.
Ultimately, matching on the suffix only seems insufficient, because :5000 can either be a valid tag or a valid port number. So, example.com:5000 should not match example.com, but example.com/image:5000 should match example.com/image. This matters because of the CheckAuth/SearchRegistry uses in c/image/docker, which pass a repo hostname but not an image reference—strictly speaking that’s a violation of the FindRegistry API as documented, but it is a situation that we need to handle.
It should be possible to ultimately implement the desired semantics, with the current inputs, exactly correctly (e.g. by exporting DomainWithOptionalName in c/image/docker/registry, or something like that—and we’ve run into a few other cases where exporting that regexp would be useful), but maybe we can do something much simpler: redefine the input to FindRegistry to be a hostname or a repo name, not a full image reference, i.e. prohibit the tag/digest suffixes entirely and let the caller handle that. That’s especially attractive because this PR already calls FindRegistry that way: newDockerClientFromRef calls ref.ref.Name(); also, the implementation would be a trivial suffix == "" || suffix[0] == "/" if I’m not mistaken.
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.
Ultimately, matching on the suffix only seems insufficient, because :5000 can either be a valid tag or a valid port number. So, example.com:5000 should not match example.com, but example.com/image:5000 should match example.com/image.
This is already working and the regex detects that (minus the digest case).
- If matching at the level of individual repos (i.e. with the :tag suffix) is desirable, symmetrically @ digest should be accepted as well. And, maybe surprisingly, it’s possible to say repo:tag@digest (see reference.ReferenceRegexp), where digest is algo:hex-digits, i.e. the suffix can legitimately contain two colons.
[...] but maybe we can do something much simpler: redefine the input to FindRegistry to be a hostname or a repo name, not a full image reference, i.e. prohibit the tag/digest suffixes entirely and let the caller handle that [...]
I feely strongly against this as this would cause boilerplate code at (and move complexity to) the callees before the call (e.g., extracting the hostname from some input) and after the call (i.e., doing the suffix magic).
It should be possible to ultimately implement the desired semantics, with the current inputs, exactly correctly (e.g. by exporting
DomainWithOptionalNamein c/image/docker/registry, or something like that [...]
That's my favorit so far. It makes sense to put that into c/image/docker/* as we can reuse the regexes from there. I will have a look at that and ping you once the PR is updated.
Thanks for the great review, as always!
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.
It should be possible to ultimately implement the desired semantics, with the current inputs, exactly correctly (e.g. by exporting DomainWithOptionalName in c/image/docker/registry, or something like that [...].
I believe we can reduce complexity by just requiring the suffix/remainder to either be empty or to start either with / or with :. This would also match at port boundaries, but that might not be such a big deal. Some users might even find a usecase for it when wanting to mirror multiple registries running on one host.
We can still introduce a DomainWithOptionalName regex (or something similar) for input validation, but I don't think that's necessary now can be added at a later point.
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.
Ultimately, matching on the suffix only seems insufficient, because
:5000can either be a valid tag or a valid port number. So,example.com:5000should not matchexample.com, butexample.com/image:5000should matchexample.com/image.This is already working and the regex detects that (minus the digest case).
How? AFAICS it can’t work because the suffix is the same, and testing confirms it: https://play.golang.org/p/0QHfsmaoApO .
Am I overlooking something that can distinguish the two cases?
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 we can reduce complexity by just requiring the suffix/remainder to either be empty or to start either with
/or with:. This would also match at port boundaries, but that might not be such a big deal. Some users might even find a usecase for it when wanting to mirror multiple registries running on one host.
I’d rather do this precisely correctly; it seems to me it should not be that much code, maybe I could try to do that next week.
(Either way, the problematic matching code already exists, so it is not strictly blocking this PR. The skopeo test failures are — and I’m getting close to finishing the CLI rework in there, containers/skopeo#523 — and that rework seems mostly unnecessary for the purpose of this PR, after all; I will know for sure after I finish the tests in there.)
FWIW, the failed tests in there prompted me to write unit tests for There might be a simple way to make the specifically the |
Ouch. There are quite some unexpected pain points in the stack. CLI parsing sucks big time.
I may find time next week to help you untangle the code. |
It turns out that while So, only the namespace matching is outstanding. Arguably this PR should not block on it at all and that part could be split — OTOH enabling this implicit behavior with the |
|
@mtrmac Thanks for the info!
Yesterday, we hit a pretty interesting detail with the prefix/mirror downstream patch we maintain for Docker-ce. The issue is that registries can be nested under some path on the host (see An example is a registry running at |
The ”Docker reference” format just can’t express the difference between an image available through the API paths So, such registries can’t be used with Similarly, looking at So, this seems to be a server-side capability with no client-side implementation. Or are you saying that you want to add support for this in clients?
What does “auth issues” mean? (Overall, it seems reasonable to me that clients should use credentials they have stored for the mirror, and not for the underlying primary source, if they connect to a mirror. I can’t see how using non-empty path prefixes changes that, except maybe for the need to support them in (If the example below is supposed to be the “auth issue”, I can’t see any connection to authentication.)
Which of the strings in this paragraph are Docker references (hostname/ns…/repo) and which are API URLs? There isn’t a single Or are you saying that you want to deploy a registry at the URL
… I can’t see how; |
|
In contrast to my previous statement, I just added the The remaining bits regarding prefix matching etc. require some more thought. Maybe we can set up a meeting in the near future to share some ideas? What I mostly want to check with you is if we could rewire the sysregsv2 config. I find some beauty in the last design of the PR for Moby, which looks as follows: We can do the same with TOML. Prefixes must adhere to paths and paths only, so either host, namespace or registry. Another nice improvement is that the concept applies to pushing AND pulling, each configured separately. |
ACK, though this is primarily up to CRI-O maintainers. @runcom ? Or who can comment on this?
Yeah, a meeting could be quite useful.
The one thing that is blocking this PR is incorrectly matching prefixes and unwanted configurations; changing the config format is, I think, quite unrelated (both the current and any proposed different config format would need the prefix matching fixed). That said… The sysregistriesv2 code has already been vendored into buildah and presumably deployed in released binaries. I’ve heard people actively asking for mirror support. What is the status of the file format? Is it unstable until documented in https://github.com/containers/image/blob/master/docs/containers-registries.conf.5.md ? Sure, as long as it is compatible with the previous syntax, we can just keep pointing people at the old syntax and keep tweaking this one — as long as everyone understands that this is the status.
This is nice, an improvement over the earlier discussion around #468 (comment) .
|
For now, something like #534 ? |
I think I am the wrong audience for this statement given I am trying to push those things forward here and for Moby for quite some time :^)
The progress of this package certainly depends on the priority we give it to be finished. I think we're close for it to be useful in production. One thing I think we should have is an API to abstract from using those endpoints/mirrors for pushing and pulling. I wouldn't like libpod to keep all abstractions and others to start using those.
This week is packed for me and next week I'll be on vacation. Maybe we can set something up for early December? I always assumed you're located at the West Coast, are you? |
I'll comment over there :) |
Turns out, it was a mistake doing that. Podman isn't using sysregsv2 yet but vendors buildah, so The registries.conf looks as follows:
It's again the URL parsing and the fact that we're not using URI prefixes which confuses net/url. |
In one sense, this is primarily your work so it is perfectly up to you to declare it stable or not yet stable; in another, as soon as a few packages vendor in a particular implementation, no matter which one, and start relying on the new features, I’d expect significant pushback to future unstable changes. Basically I don’t know where we are in this process (as you say, Buildah has already vendored the subpackage) and whether this is widely understood; I’d like to prevent a misunderstanding. @rhatdan ? |
I default to thinking
I’ll be available for about one more week, and then I’ll be on vacation, in turn.
:) Central Europe. But given >24-hr advance notice, and no conflicts, I can be available any time at all. |
Perfect! How about Tuesday 4th of Dec at 2PM (CET)? Maybe you can join #podman to setup a conference tool of our choice? |
Buildah only uses the package but not the new format which gives us the chance to still change the format (i.e., extend it). I would really love to integrate the push/pull endpoints semantics similar to the ones of the Moby PR. This would also enable users to configure "push proxies". Starting from next week, I will have time to finish the remaining bits. @mtrmac, can we merge this PR? I think it does now what we wanted it to do. The remaining bits and potential extensions can be sorted out in a fresh PR. |
The one blocker for me is the prefix matching – sure, we can tell people not to use namespace/repo prefixes for now, but this matches prefixes of simple hostnames as well. I suppose we can do ~what you propose in #534 , and as a quick fix use strings.HasPrefix(ref, r.Prefix + "/") || ref == r.Prefix; the first part would work for named references vs. hostnames, and the second part for |
Sure. FWIW RH has a BlueJeans instance which should allow external connections. |
|
I scheduled a BlueJeans Meeting for Dec 4th 2pm (CET) 8am (EST) for containers/image discussions. |
@mtrmac, it's now addressed. Prefixes will now always end with a '/'. I also removed |
|
|
||
| // make sure a Prefix ends with "/" to ensure matching at | ||
| // path and hence at namespace boundaries | ||
| if !strings.HasSuffix(reg.Prefix, "/") { |
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.
Couldn't this be just moved to the check in FindRegistry instead of leaking into user-visible data?
Also, AFAICS this breaks the CheckAuth case (FindRegistry(…, hostnameWithoutAnySlashes)).
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.
… sure, independently it’s perfectly reasonable to define that canonical Registry.Prefix values always end with exactly one slash, and this is just normalizes the values to confirm to this definition, but if FindRegistry, the primary user, ends up having to undo that, then it’s a bit impractical.
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.
Also, AFAICS this breaks the CheckAuth case (FindRegistry(…, hostnameWithoutAnySlashes)).
I think that hostnameWithoutAnySlashes should be appended with a "/" in FindRegistry(...)? I didn't (yet) add code to throw an error if a Prefix doesn't end with slash but likely that's going to happen (to make it more transparent to the user). Once that happens, hostnameWithoutAnySlashes is problematic.
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 that
hostnameWithoutAnySlashesshould be appended with a "/" inFindRegistry(...)?
Would that involve adding an extra check whether the input is a hostname without any slashes, or would a slash be unconditionally added (even if the input is a named ref, possibly ending with a tag or digest)?
Even to implement precisely the proposed semantics (.Prefix matches hostnames and namespaces, not repos or tagged/digested images — at this point I’m fine with that, I’m not arguing about what the semantics should be, except that CheckAuth should work), adding the trailing slash to the .Prefix value just seems to make things more complex instead of simpler.
Or, of course, I’m being stupid — I haven’t actually tested anything about this in practice, so I may well be misunderstanding how the code actually works.
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.
No at all. You have a very valid point. Then let's go with your initial proposal (similar to strings.HasPrefix(ref, r.Prefix + "/") || ref == r.Prefix).
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.
Pushed the changes.
2f50c28 to
d0e7e3b
Compare
|
Looks good, but
|
Enfore matching at path boundaries for canonical image references or matching the entire prefix for hostname lookups (e.g., in `CheckAuth(...)`). Add some tests to catch potential future regressions. Signed-off-by: Valentin Rothberg <valentinrothberg@gmail.com>
Allow IP addresses to be specified in registries configuration. Prior to this change, an IP addresses caused a parsing error in net/url due to the absence of URI schemes. Signed-off-by: Valentin Rothberg <valentinrothberg@gmail.com>
d0e7e3b to
7854e94
Compare
|
👍 Tests in containers/skopeo#521 pass . 🎉 Thanks again! |
|
Awesome, thanks a lot!
…On Thu 29. Nov 2018 at 13:20, Miloslav Trmač ***@***.***> wrote:
👍
Tests in containers/skopeo#521
<containers/skopeo#521> pass . 🎉
Thanks again!
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#468 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ALI4g2jGafRC5QwNd4bZqSBkxkBfcV5yks5uz9D0gaJpZM4Uu5TC>
.
|
Based on a discussion from: #464 (comment)