Skip to content

Commit c064ff1

Browse files
committed
Fix c/image fails to pull OCI image with non-http(s):// urls
Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
1 parent f5b23d3 commit c064ff1

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

docker/docker_image_src.go

+15-1
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,11 @@ func (s *dockerImageSource) GetBlobAt(ctx context.Context, info types.BlobInfo,
408408
// May update BlobInfoCache, preferably after it knows for certain that a blob truly exists at a specific location.
409409
func (s *dockerImageSource) GetBlob(ctx context.Context, info types.BlobInfo, cache types.BlobInfoCache) (io.ReadCloser, int64, error) {
410410
if len(info.URLs) != 0 {
411-
return s.getExternalBlob(ctx, info.URLs)
411+
if r, s, err := s.getExternalBlob(ctx, info.URLs); err == nil {
412+
return r, s, nil
413+
} else if containsValidHTTPURLs(info.URLs) { // if contains valid HTTP URLs, external blob should be fetched.
414+
return nil, 0, err
415+
} // no understandable urls are contained. Ignore urls and allow fallback.
412416
}
413417

414418
path := fmt.Sprintf(blobsPath, reference.Path(s.physicalRef.ref), info.Digest.String())
@@ -425,6 +429,16 @@ func (s *dockerImageSource) GetBlob(ctx context.Context, info types.BlobInfo, ca
425429
return res.Body, getBlobSize(res), nil
426430
}
427431

432+
func containsValidHTTPURLs(urls []string) bool {
433+
for _, s := range urls {
434+
u, err := url.Parse(s)
435+
if err == nil && (u.Scheme == "http" || u.Scheme == "https") {
436+
return true
437+
}
438+
}
439+
return false
440+
}
441+
428442
// GetSignatures returns the image's signatures. It may use a remote (= slow) service.
429443
// If instanceDigest is not nil, it contains a digest of the specific manifest instance to retrieve signatures for
430444
// (when the primary manifest is a manifest list); this never happens if the primary manifest is not a manifest list

oci/layout/oci_src.go

+16-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"io"
66
"io/ioutil"
77
"net/http"
8+
"net/url"
89
"os"
910
"strconv"
1011

@@ -113,7 +114,11 @@ func (s *ociImageSource) HasThreadSafeGetBlob() bool {
113114
// May update BlobInfoCache, preferably after it knows for certain that a blob truly exists at a specific location.
114115
func (s *ociImageSource) GetBlob(ctx context.Context, info types.BlobInfo, cache types.BlobInfoCache) (io.ReadCloser, int64, error) {
115116
if len(info.URLs) != 0 {
116-
return s.getExternalBlob(ctx, info.URLs)
117+
if r, s, err := s.getExternalBlob(ctx, info.URLs); err == nil {
118+
return r, s, nil
119+
} else if containsValidHTTPURLs(info.URLs) { // if contains valid HTTP URLs, external blob should be fetched.
120+
return nil, 0, err
121+
} // no understandable urls are contained. Ignore urls and allow fallback.
117122
}
118123

119124
path, err := s.ref.blobPath(info.Digest, s.sharedBlobDir)
@@ -132,6 +137,16 @@ func (s *ociImageSource) GetBlob(ctx context.Context, info types.BlobInfo, cache
132137
return r, fi.Size(), nil
133138
}
134139

140+
func containsValidHTTPURLs(urls []string) bool {
141+
for _, s := range urls {
142+
u, err := url.Parse(s)
143+
if err == nil && (u.Scheme == "http" || u.Scheme == "https") {
144+
return true
145+
}
146+
}
147+
return false
148+
}
149+
135150
// GetSignatures returns the image's signatures. It may use a remote (= slow) service.
136151
// If instanceDigest is not nil, it contains a digest of the specific manifest instance to retrieve signatures for
137152
// (when the primary manifest is a manifest list); this never happens if the primary manifest is not a manifest list

0 commit comments

Comments
 (0)