-
Notifications
You must be signed in to change notification settings - Fork 379
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
Allow config authors to always use Prefix #1368
base: main
Are you sure you want to change the base?
Conversation
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.
Needs tests and changes to docs. AFAIR the docs state the location must be set, and we need to explain how rewriting works when location is empty.
The tests should make sure that rewriting the reference will return the input.
4c1ec49
to
03c954d
Compare
Done. PTAL. |
03c954d
to
3c68593
Compare
LGTM |
3c68593
to
9e12044
Compare
@mtrmac removing the entire check for empty location from rewriteReference seemed to cause failures in |
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'd love a test with at least one registries.conf file with an empty location and set prefix.
docs/containers-registries.conf.5.md
Outdated
@@ -82,7 +82,7 @@ location = "internal-registry-for-example.net/bar" | |||
requests for the image `example.com/foo/myimage:latest` will actually work with the | |||
`internal-registry-for-example.net/bar/myimage:latest` image. | |||
|
|||
With a `prefix` containing a wildcard in the format: "*.example.com" for subdomain matching, | |||
With any valid `prefix` with or without a wildcard in the format: "*.example.com" for subdomain matching, | |||
the location can be empty. In such a case, |
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 sentence seems a bit too complicated. I suggest: "The location
can be empty if the prefix
is set."
} | ||
reg.Prefix = reg.Location | ||
} else { | ||
// Allow config authors to always use 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.
I don't find the comment helpful. I'd prefer a comment stating that either prefix OR location OR both must be set.
@lsm5 any update on this PR? |
@rhatdan working on it.. |
38823ca
to
48ddd0e
Compare
@mtrmac @vrothberg PTAL |
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.
LGTM
@mtrmac PTAL
@mtrmac ping PTAL |
On PTO until next week. |
48ddd0e
to
1fadd42
Compare
Previously an unset Location was only allowed for wildcarded Prefixes. This commit will allow configs with emtpy location or empty prefix, so long as the other is valid. Remove wildcard prefix check for empty location in rewriteReference. Fixes: 1. containers#1191 (comment) 2. containers#1191 (comment) Co-authored-by: Miloslav Trmač <[email protected]> Signed-off-by: Lokesh Mandvekar <[email protected]>
1fadd42
to
dcc2e8f
Compare
@mtrmac PTAL |
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 the PR, and I apologize for the late review.
ACK overall; a few more simplifications seem possible.
@@ -82,8 +82,7 @@ location = "internal-registry-for-example.net/bar" | |||
requests for the image `example.com/foo/myimage:latest` will actually work with the | |||
`internal-registry-for-example.net/bar/myimage:latest` image. | |||
|
|||
With a `prefix` containing a wildcard in the format: "*.example.com" for subdomain matching, | |||
the location can be empty. In such a case, | |||
With any valid `prefix`, the location can be emtpy. In such a case, |
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.
With any valid `prefix`, the location can be emtpy. In such a case, | |
With any valid `prefix`, the location can be empty. In such a case, |
but we don’t exactly mean “empty”, we mean “missing” / “not provided by the user”; that this shows up as ""
is just an implementation detail of our Go implementation (our lazy Go implementation, it would probably be possible to accurate… and reject ""
values).
With any valid `prefix`, the location can be emtpy. In such a case, | ||
prefix matching will occur, but no reference rewrite will occur. The |
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, the “Choosing a [[registry]]
TOML table” already describes the matching semantics, and that’s where it should be documented.
This is a paragraph about the location
field, in a “Remapping and mirroring registries” section; maybe all this needs to say is something like “if only one of prefix
and location
is provided, the original requested image reference will be used as-is without redirection”.
@@ -82,8 +82,7 @@ location = "internal-registry-for-example.net/bar" | |||
requests for the image `example.com/foo/myimage:latest` will actually work with the | |||
`internal-registry-for-example.net/bar/myimage:latest` image. | |||
|
|||
With a `prefix` containing a wildcard in the format: "*.example.com" for subdomain matching, | |||
the location can be empty. In such a case, | |||
With any valid `prefix`, the location can be emtpy. In such a case, | |||
prefix matching will occur, but no reference rewrite will occur. The | |||
original requested image string will be used as-is. But other settings like | |||
`insecure` / `blocked` / `mirrors` will be applied to matching images. |
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’m not sure we even need the example for doing nothing; we almost certainly don’t need two.
Also the “But other settings like” sentence is duplicated above and below the example, probably unnecessarily.
@@ -82,8 +82,7 @@ location = "internal-registry-for-example.net/bar" | |||
requests for the image `example.com/foo/myimage:latest` will actually work with the |
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.
Above, in
By default, this equal to
prefix
(in which caseprefix
can be omitted …
the parenthesized aside doesn’t make sense, if location
is unset, prefix
can’t be omitted.
Basically I think we should document it this way:
prefix
is how the right section is chosen. (It is ~assumed to be always set.)location
is how we redirect; if unset, no redirection happens.- As a special case, (
prefix
unset +location
set) is interpreted the same as (prefix
set +location
unset)
We already document the special case in the “Choosing a [[registry]]
TOML table” section, so maybe we can just not discuss it here at all.
} | ||
reg.Location = reg.Prefix | ||
} else { | ||
return &InvalidRegistries{s: "invalid condition: both location and prefix are unset"} |
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.
(Absolutely non-blocking, this is pre-existing and has more instances, i.e. basically a note to self to improve this later: invalid condition
is not very helpful in a user-facing message.)
} else { | ||
// Prefix and Location cannot both be empty. | ||
// Either one at least must be set. | ||
if 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.
This could be simpler as
if reg.Prefix == "" && reg.Location == "" { fail }
if reg.Location != "" { reg.Location, err = parseLocation(…); if err … }
if reg.Prefix == "" { reg.Prefix = reg.Location }
else { reg.Prefix, err = parseLocation(…); if err … }
or perhaps
// Validate individual fields
if reg.Location != "" { reg.Location, err = parseLocation(…); if err … }
if reg.Prefix != "" { reg.Prefix, err = parseLocation(…); if err … }
// Validate the combination, normalize to have reg.Prefix always set
if reg.Prefix == "" {
if reg.Location == "" { fail }
else { reg.Prefix = reg.Location }
}
Either way, please remove the parseLocation
call above this line, and make parseLocation
fail on ""
again.
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.
(Non-blocking: These should be require.
. OTOH this is consistent with the rest, and only matters on test failures.)
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.
so would you prefer require
be used for all other existing test cases too? Or only for the missing-location + set-prefix
case?
I could make a separate PR if we need to change it throughout the file.
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 honestly don’t think this is worth much worrying about; if you find updating pre-existing test cases fun, sure, go for it, but it’s not work that results in anything users could notice and consider valuable while using the software. As far as “clean code” goes, require
is a bit more correct but consistency is also nice, so to me that’s not a strong reason to prefer either.
(Just to be explicit: require
should be used for testing prerequisites that must be true for other checks to be even valid to do, e.g.
ptr, err := testSubject()
require.NoError(t, err)
assert.Equal(t, …, *ptr) // would crash if testSubject returned (nil, err) and the above were assert.NoError(…)
But there is a minimal practical difference; with assert.NoError(t, err)
the test crashes with a backtrace, with require.NoError(t, err)
the test fails with an error message containing err
. It doesn’t matter at all if the test completely succeeds. If the test fails because err
is set, in both cases the test fails, it’s easy enough to identify the location of the failure, and probably something about testSubject
needs to be updated. require
is only better in that it includes the actual error text in the test failure output, and that could help with a inconsistent rarely-occurring failure in CI.)
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, that's really helpful thanks, I'll consider introducing that in a future PR, will make a note in the test file for now.
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.
But there is a minimal practical difference; with
assert.NoError(t, err)
the test crashes with a backtrace, withrequire.NoError(t, err)
the test fails with an error message containingerr
.
I’m sorry, this is nonsense of course; assert.NoError(t, err)
does report the unexpected error value first, it’s just the later use of *ptr
that crashes. So really the difference between failures of the two implementations is basically cosmetic.
Previously an unset Location was only allowed for wildcarded Prefixes.
This commit will allow any valid Prefix.
Fixes: #1191 (comment)
Signed-off-by: Lokesh Mandvekar [email protected]
@vrothberg @mtrmac @ashcrow PTAL