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

Fix c/image fails to pull OCI image with non-http(s):// urls #1403

Merged
merged 1 commit into from Nov 16, 2021

Conversation

ktock
Copy link
Contributor

@ktock ktock commented Nov 9, 2021

Fixes containers/podman#12231

Currently, c/image cannot pull OCI images that contain non-http(s):// urls.
This commit fixes this issue by allowing fallback when pull fails on non-http(s):// urls.

@flouthoc
Copy link
Contributor

flouthoc commented Nov 9, 2021

LGTM. I think a pull test libimage would be nice but afaik ghcr.io will rate limit CI pulls.

@vrothberg @giuseppe @rhatdan PTAL

oci/layout/oci_src.go Outdated Show resolved Hide resolved
Copy link
Member

@vrothberg vrothberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@mtrmac PTAL

Copy link
Collaborator

@mtrmac mtrmac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK overall.

(Reading the OCI spec, it might be possible to just always fall back to querying the registry. OTOH the docker/docker implementation fails the same way, and we can make the IPFS URLs possible without changing this, so let’s do the conservative thing now and not change that for HTTP.)

var (
resp *http.Response
err error
)
if len(urls) == 0 {
return nil, 0, errors.New("internal error: getExternalBlob called with no URLs")
return nil, 0, false, errors.New("internal error: getExternalBlob called with no URLs") // fatal error
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please drop the “fatal error” comment

  • It’s not “fatal” as otherwise understood (e.g. logrus.Fatal means “immediately terminate the whole process)
  • It’s completely unclear to me what the reader is supposed to do with the information in that comment. (We don’t generally have count++ // increase count comments — OTOH documenting the function API as this PR does is verry useful.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the review. Fixed.

// This returns a bool value (named "fallback") which indicates whether the caller can fallback to the pull of
// the non-external blob (i.e. pull from the registry).
// This parameter becomes true only if no url is supported by this function.
// Do not pass zero-length "urls". This is considered a fatal error and returns an error without allowing fallback.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Absolutely non-blocking: I wouldn’t overemphasize this. E.g. getExternalBlob returns the reader of the first available blob URL from urls, which must not be empty would be sufficient. See also the comment about error/fallback handling elsewhere, not having the (fallback == true, err != nil) special case would make documenting this simpler because “all errors are reported using err” is the default convention which doesn’t need documenting at all.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed the comment.

}
for _, url := range urls {
noSupportedURL := true
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking: hasSupportedURL would be more direct than the double negation in noSupportedURL = false.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Comment on lines 272 to 270
if noSupportedURL {
return nil, 0, true, errors.New("no supported url is specified") // fallback to non-external blob
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this now has:

  • err == nil: No error, blob stream available
  • err != nil, fallback == true: Fall back (and the err value is never used)
  • err != nil, fallback == false: General error

As a thought experiment, consider

  • err == nil, fallback == false: No error, blob stream available
  • err == nil, fallback == true: Fall back
  • err != nil: General error

where all errors are unusual, and we don’t have to worry about a “fallback” value on error paths (e.g. consider how the len(urls) case now needs extra documentation); and that can be turned into

  • err == nil, io.ReadCloser != nil: No error, blob stream available
  • err == nil, io.ReadCloser == nil: Fall back
  • err != nil: General error

which is simpler and more direct.

(I prefer the last option but I don’t feel too strongly about this; if @vrothberg is fine with the code as is, let’s keep it.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the suggestion. Fixed the logic.

for _, url := range urls {
noSupportedURL := true
for _, u := range urls {
if u, err := url.Parse(u); err != nil || (u.Scheme != "http" && u.Scheme != "https") {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolutely non-blocking: Do we want to silently ignore err here? The combination of “a failing HTTP fetch is a hard error” and “a completely invalid URL is silently accepted” is a bit weird.

OTOH ignoring them is consistent with the idea of allowing IPFS or whatever else, so this is fine as is — just raising this design point so that others speak up if they feel strongly about it.

@ktock
Copy link
Contributor Author

ktock commented Nov 11, 2021

@mtrmac Thank you for the review. Fixed.

Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
@ktock
Copy link
Contributor Author

ktock commented Nov 16, 2021

All green. Thank you for the review!

Could we move this forward?

Copy link
Member

@vrothberg vrothberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@rhatdan
Copy link
Member

rhatdan commented Nov 16, 2021

LGTM

@rhatdan rhatdan merged commit b55fb86 into containers:main Nov 16, 2021
@rhatdan
Copy link
Member

rhatdan commented Nov 16, 2021

Thanks @ktock

@ktock ktock deleted the urls-fallback branch March 28, 2024 06:36
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.

Podman fails to pull OCI image with non-http(s):// urls
5 participants