Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/push.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions oci/private/push.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,13 @@ _attrs = {
""",
allow_single_file = True,
),
"tag_platform_images": attr.bool(
doc = """\
If true, tag platform specific images with each remote tag and an additional
'-${os}-${arch}' suffix. This is useful for platforms that cannot handle OCI
image indexes and instead require a reference to a platform specific image.
""",
),
"_crane": attr.label(
default = "@oci_crane_toolchains//:current_toolchain",
cfg = "exec",
Expand Down Expand Up @@ -205,6 +212,7 @@ def _impl(ctx):
"{{crane_path}}": to_rlocation_path(ctx, crane.crane_info.binary),
"{{jq_path}}": to_rlocation_path(ctx, jq.jqinfo.bin),
"{{image_dir}}": to_rlocation_path(ctx, ctx.file.image),
"{{tag_platform_images}}": "0",
"{{fixed_args}}": "",
}

Expand All @@ -218,6 +226,9 @@ def _impl(ctx):
files.append(ctx.file.remote_tags)
substitutions["{{tags}}"] = to_rlocation_path(ctx, ctx.file.remote_tags)

if ctx.attr.tag_platform_images:
substitutions["{{tag_platform_images}}"] = "1"

ctx.actions.expand_template(
template = ctx.file._push_sh_tpl,
output = executable,
Expand Down
35 changes: 32 additions & 3 deletions oci/private/push.sh.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ TAGS=()
# global crane flags to be passed with every crane invocation
GLOBAL_FLAGS=()

# tag platform specific images as ${tag}-${os}-${arch} (for use with
# AWS Lambda and other platforms that cannot handle multiarch OCI images).
TAG_PLATFORM_IMAGES="{{tag_platform_images}}"

# this will hold args specific to `crane push``
ARGS=()

Expand All @@ -36,6 +40,9 @@ while (( $# > 0 )); do
(--allow-nondistributable-artifacts|--insecure|-v|--verbose)
GLOBAL_FLAGS+=( "$1" )
shift;;
(-i|--tag-platform-images)
TAG_PLATFORM_IMAGES=1
shift;;
(--platform)
GLOBAL_FLAGS+=( "--platform" "$2" )
shift
Expand Down Expand Up @@ -65,16 +72,38 @@ if [[ -z "${REPOSITORY}" ]]; then
exit 1
fi

DIGEST=$("${JQ}" -r '.manifests[0].digest' "${IMAGE_DIR}/index.json")
MANIFEST_DIGEST=$("${JQ}" -r '.manifests[0].digest' "${IMAGE_DIR}/index.json")
MANIFEST_FILE="${IMAGE_DIR}/blobs/${MANIFEST_DIGEST%%:*}/${MANIFEST_DIGEST##*:}"
IMAGE_DIGESTS=$(${JQ} -r '.manifests[]? | [ .digest, .platform.os, .platform.architecture ] | @tsv ' "${MANIFEST_FILE}")
Comment on lines +75 to +77

Choose a reason for hiding this comment

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

P1 Badge Platform tagging reads image manifest instead of index

To build the per-platform tag list, MANIFEST_DIGEST is taken from index.json and used to open that manifest’s blob, then .manifests[] is queried from that file. For a standard OCI layout this blob is a single image manifest and contains no manifests array, so IMAGE_DIGESTS is empty and --tag-platform-images never tags any platform images. The per-platform digest list should be derived from index.json itself rather than a child manifest.

Useful? React with 👍 / 👎.


REFS=$(mktemp)
"${CRANE}" push "${GLOBAL_FLAGS[@]+"${GLOBAL_FLAGS[@]}"}" "${IMAGE_DIR}" "${REPOSITORY}@${DIGEST}" "${ARGS[@]+"${ARGS[@]}"}" --image-refs "${REFS}"
"${CRANE}" push "${GLOBAL_FLAGS[@]+"${GLOBAL_FLAGS[@]}"}" "${IMAGE_DIR}" "${REPOSITORY}@${MANIFEST_DIGEST}" "${ARGS[@]+"${ARGS[@]}"}" --image-refs "${REFS}"

for tag in "${TAGS[@]+"${TAGS[@]}"}"
do
"${CRANE}" tag "${GLOBAL_FLAGS[@]+"${GLOBAL_FLAGS[@]}"}" $(cat "${REFS}") "${tag}"
if [[ ${TAG_PLATFORM_IMAGES} -eq 1 ]]; then
echo "${IMAGE_DIGESTS}" | while read digest os arch ; do
if [[ -n "${os}" && -n "${arch}" ]]; then
"${CRANE}" tag "${REPOSITORY}@${digest}" "${tag}-${os}-${arch}"
fi
done
fi
done

if [[ -e "${TAGS_FILE:-}" ]]; then
cat "${TAGS_FILE}" | xargs -r -n1 "${CRANE}" tag "${GLOBAL_FLAGS[@]+"${GLOBAL_FLAGS[@]}"}" $(cat "${REFS}")
readarray -t tags < "${TAGS_FILE}"
for tag in "${tags[@]}"; do
if [[ -z "${tag}" ]]; then
continue
fi
"${CRANE}" tag "${GLOBAL_FLAGS[@]+"${GLOBAL_FLAGS[@]}"}" $(cat "${REFS}") "${tag}"
if [[ ${TAG_PLATFORM_IMAGES} -eq 1 ]]; then
echo "${IMAGE_DIGESTS}" | while read digest os arch ; do
if [[ -n "${os}" && -n "${arch}" ]]; then
"${CRANE}" tag "${REPOSITORY}@${digest}" "${tag}-${os}-${arch}"
fi
done
fi
done
fi