Skip to content

Commit

Permalink
fix: add variant to manifest entry (#368)
Browse files Browse the repository at this point in the history
  • Loading branch information
thesayyn authored Sep 26, 2023
1 parent 9708852 commit ca579be
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 65 deletions.
62 changes: 8 additions & 54 deletions oci/private/pull.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -329,23 +329,6 @@ load("@bazel_skylib//rules:write_file.bzl", "write_file")
package(default_visibility = ["//visibility:public"])
# Mimic the output of crane pull [image] layout --format=oci
write_file(
name = "write_layout",
out = "oci-layout",
content = [
"{{",
" \\"imageLayoutVersion\\": \\"1.0.0\\"",
"}}",
],
)
write_file(
name = "write_index",
out = "index.json",
content = [\"\"\"{index_content}\"\"\"],
)
copy_file(
name = "manifest",
src = "manifest.json",
Expand Down Expand Up @@ -373,7 +356,6 @@ copy_to_directory(
"index.json",
],
)
"""

def _find_platform_manifest(image_mf, platform_wanted):
Expand Down Expand Up @@ -427,45 +409,17 @@ def _oci_pull_impl(rctx):
if hash not in tars:
tars.append(hash)

# To make testing against `crane pull` simple, we take care to produce a byte-for-byte-identical
# index.json file, which means we can't use jq (it produces a trailing newline) or starlark
# json.encode_indent (it re-orders keys in the dictionary).
if rctx.attr.platform:
os, arch = rctx.attr.platform.split("/", 1)
index_mf = """\
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.index.v1+json",
"manifests": [
{
"mediaType": "%s",
"size": %s,
"digest": "%s",
"platform": {
"architecture": "%s",
"os": "%s"
}
}
]
}""" % (image_mf["mediaType"], image_mf_len, image_digest, arch, os)
else:
index_mf = """\
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.index.v1+json",
"manifests": [
{
"mediaType": "%s",
"size": %s,
"digest": "%s"
}
]
}""" % (image_mf["mediaType"], image_mf_len, image_digest)

rctx.file("index.json", util.build_manifest_json(
media_type = image_mf["mediaType"],
size = image_mf_len,
digest = image_digest,
platform = rctx.attr.platform
))
rctx.file("oci-layout", json.encode_indent({"imageLayoutVersion": "1.0.0"}, indent = " "))

rctx.file("BUILD.bazel", content = _build_file.format(
target_name = rctx.attr.target_name,
tars = tars,
index_content = index_mf,
image_digest = _trim_hash_algorithm(image_digest),
config_file = image_config_file,
))
Expand Down
41 changes: 40 additions & 1 deletion oci/private/util.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,49 @@ def _file_exists(rctx, path):
return result.return_code == 0


_INDEX_JSON_TMPL="""\
{{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.index.v1+json",
"manifests": [
{{
"mediaType": "{}",
"size": {},
"digest": "{}"{optional_platform}
}}
]
}}"""

def _build_manifest_json(media_type, size, digest, platform):

optional_platform = ""

if platform:
platform_parts = platform.split("/", 3)

optional_variant = ""
if len(platform_parts) == 3:
optional_variant = ''',
"variant": "{}"'''.format(platform_parts[2])

optional_platform = """,
"platform": {{
"architecture": "{}",
"os": "{}"{optional_variant}
}}""".format(platform_parts[1], platform_parts[0], optional_variant = optional_variant)

return _INDEX_JSON_TMPL.format(
media_type,
size,
digest,
optional_platform = optional_platform
)

util = struct(
parse_image = _parse_image,
sha256 = _sha256,
warning = _warning,
maybe_wrap_launcher_for_windows = _maybe_wrap_launcher_for_windows,
file_exists = _file_exists
file_exists = _file_exists,
build_manifest_json = _build_manifest_json
)
25 changes: 15 additions & 10 deletions oci/tests/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ load("@aspect_bazel_lib//lib:diff_test.bzl", "diff_test")
load("@bazel_skylib//rules:build_test.bzl", "build_test")
load(":pull_tests.bzl", "parse_image_test")

_PLATFORM = "linux/amd64"

IMAGES_TO_TEST = {
"distroless_java": "gcr.io/distroless/java17@sha256:161a1d97d592b3f1919801578c3a47c8e932071168a96267698f4b669c24c76d",
"distroless_static_linux_amd64": "gcr.io/distroless/static@sha256:c3c3d0230d487c0ad3a0d87ad03ee02ea2ff0b3dcce91ca06a1019e07de05f12",
"fluxcd_flux_single": "docker.io/fluxcd/flux:1.25.4",
"chainguard_static_linux_amd64": "cgr.dev/chainguard/static:latest",
"linux/amd64": {
"distroless_java": "gcr.io/distroless/java17@sha256:161a1d97d592b3f1919801578c3a47c8e932071168a96267698f4b669c24c76d",
"distroless_static_linux_amd64": "gcr.io/distroless/static@sha256:c3c3d0230d487c0ad3a0d87ad03ee02ea2ff0b3dcce91ca06a1019e07de05f12",
"fluxcd_flux_single": "docker.io/fluxcd/flux:1.25.4",
"chainguard_static_linux_amd64": "cgr.dev/chainguard/static:latest",
},
"linux/arm64/v8": {
"ubuntu_linux_arm64_v8": "ubuntu@sha256:67211c14fa74f070d27cc59d69a7fa9aeff8e28ea118ef3babc295a0428a6d21"
}
}

# Use crane to pull images as a comparison for our oci_pull repository rule
Expand All @@ -17,12 +20,12 @@ IMAGES_TO_TEST = {
name = "pull_{}".format(repo_name),
outs = [repo_name],
cmd = "$(CRANE_BIN) pull {reference} $@ --format=oci --platform={platform}".format(
platform = _PLATFORM,
platform = platform,
reference = reference,
),
local = True, # needs to run locally to able to use credential helpers
message = "Pulling {reference} for {platform}".format(
platform = _PLATFORM,
platform = platform,
reference = reference,
),
output_to_bindir = True,
Expand All @@ -32,7 +35,8 @@ IMAGES_TO_TEST = {
],
visibility = ["//visibility:public"],
)
for repo_name, reference in IMAGES_TO_TEST.items()
for platform in IMAGES_TO_TEST.keys()
for repo_name, reference in IMAGES_TO_TEST[platform].items()
]

[
Expand All @@ -43,7 +47,8 @@ IMAGES_TO_TEST = {
repo_name,
),
)
for repo_name, reference in IMAGES_TO_TEST.items()
for platform in IMAGES_TO_TEST.keys()
for repo_name, reference in IMAGES_TO_TEST[platform].items()
]

# assert than we don't break fetching these
Expand Down

0 comments on commit ca579be

Please sign in to comment.