Skip to content

Commit efaae5a

Browse files
committed
Use non-blocking download to get image blobs, on Bazel >=7.1.0
1 parent 7c26270 commit efaae5a

File tree

1 file changed

+17
-8
lines changed

1 file changed

+17
-8
lines changed

oci/private/pull.bzl

+17-8
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def _digest_into_blob_path(digest):
8686
digest_path = digest.replace(":", "/", 1)
8787
return "blobs/{}".format(digest_path)
8888

89-
def _download(rctx, authn, identifier, output, resource, headers = {}, allow_fail = False):
89+
def _download(rctx, authn, identifier, output, resource, headers = {}, allow_fail = False, block = True):
9090
"Use the Bazel Downloader to fetch from the remote registry"
9191

9292
if resource != "blobs" and resource != "manifests":
@@ -118,10 +118,13 @@ def _download(rctx, authn, identifier, output, resource, headers = {}, allow_fai
118118
auth = {registry_url: auth},
119119
allow_fail = allow_fail,
120120
)
121+
122+
# Use non-blocking download, and forward headers, on Bazel 7.1.0 and later.
121123
if versions.is_at_least("7.1.0", versions.get()):
122-
return rctx.download(headers = headers, **kwargs)
123-
else:
124-
return rctx.download(**kwargs)
124+
kwargs["block"] = block
125+
kwargs["headers"] = headers
126+
127+
return rctx.download(**kwargs)
125128

126129
def _download_manifest(rctx, authn, identifier, output):
127130
bytes = None
@@ -156,7 +159,7 @@ def _download_manifest(rctx, authn, identifier, output):
156159

157160
def _create_downloader(rctx, authn):
158161
return struct(
159-
download_blob = lambda identifier, output: _download(rctx, authn, identifier, output, "blobs"),
162+
download_blob = lambda identifier, output, block: _download(rctx, authn, identifier, output, "blobs", block = block),
160163
download_manifest = lambda identifier, output: _download_manifest(rctx, authn, identifier, output),
161164
)
162165

@@ -226,7 +229,7 @@ def _oci_pull_impl(rctx):
226229
rctx.template(_digest_into_blob_path(digest), "manifest.json")
227230

228231
config_output_path = _digest_into_blob_path(manifest["config"]["digest"])
229-
downloader.download_blob(manifest["config"]["digest"], config_output_path)
232+
downloader.download_blob(manifest["config"]["digest"], config_output_path, block = True)
230233

231234
# if the user provided a platform for the image, validate it matches the config as best effort.
232235
if rctx.attr.platform:
@@ -236,8 +239,14 @@ def _oci_pull_impl(rctx):
236239

237240
# download all layers
238241
# TODO: we should avoid eager-download of the layers ("shallow pull")
242+
results = []
239243
for layer in manifest["layers"]:
240-
downloader.download_blob(layer["digest"], _digest_into_blob_path(layer["digest"]))
244+
results.append(downloader.download_blob(layer["digest"], _digest_into_blob_path(layer["digest"]), block = False))
245+
246+
# wait for all downloads to complete, if download is asynchronous
247+
for r in results:
248+
if hasattr(r, "wait"):
249+
r.wait()
241250

242251
rctx.file("index.json", util.build_manifest_json(
243252
media_type = manifest["mediaType"],
@@ -311,7 +320,7 @@ def _oci_alias_impl(rctx):
311320
elif manifest["mediaType"] in _SUPPORTED_MEDIA_TYPES["manifest"]:
312321
# single arch image where the user specified the platform.
313322
config_output_path = _digest_into_blob_path(manifest["config"]["digest"])
314-
downloader.download_blob(manifest["config"]["digest"], config_output_path)
323+
downloader.download_blob(manifest["config"]["digest"], config_output_path, block = True)
315324
config_bytes = rctx.read(config_output_path)
316325
config = json.decode(config_bytes)
317326
if "os" in config and "architecture" in config:

0 commit comments

Comments
 (0)