Skip to content

Commit 2f4e544

Browse files
committed
feat: add support for tagging architecture specific images
Add a `tag_platform_images` attribute to `oci_push`, which if enabled, results in each platform specific image being tagged with each remote tag and an additional '-${os}-${arch}' suffix. This makes it possible to reference platform specific images as `${tag}-${os}-${arch}` (e.g. "v1.2.3-linux-arm64"). This makes it easier to use rules_oci and multi-image indexes, with systems that do not handle OCI image indexes (such as AWS Lambda) and instead require a reference to a platform specific image.
1 parent ae4ca2c commit 2f4e544

File tree

3 files changed

+45
-5
lines changed

3 files changed

+45
-5
lines changed

docs/push.md

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

oci/private/push.bzl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,13 @@ _attrs = {
167167
""",
168168
allow_single_file = True,
169169
),
170+
"tag_platform_images": attr.bool(
171+
doc = """\
172+
If true, tag platform specific images with each remote tag and an additional
173+
'-${os}-${arch}' suffix. This is useful for platforms that cannot handle OCI
174+
image indexes and instead require a reference to a platform specific image.
175+
""",
176+
),
170177
"_crane": attr.label(
171178
default = "@oci_crane_toolchains//:current_toolchain",
172179
cfg = "exec",
@@ -205,6 +212,7 @@ def _impl(ctx):
205212
"{{crane_path}}": to_rlocation_path(ctx, crane.crane_info.binary),
206213
"{{jq_path}}": to_rlocation_path(ctx, jq.jqinfo.bin),
207214
"{{image_dir}}": to_rlocation_path(ctx, ctx.file.image),
215+
"{{tag_platform_images}}": "0",
208216
"{{fixed_args}}": "",
209217
}
210218

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

229+
if ctx.attr.tag_platform_images:
230+
substitutions["{{tag_platform_images}}"] = "1"
231+
221232
ctx.actions.expand_template(
222233
template = ctx.file._push_sh_tpl,
223234
output = executable,

oci/private/push.sh.tpl

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ TAGS=()
2828
# global crane flags to be passed with every crane invocation
2929
GLOBAL_FLAGS=()
3030

31+
# tag platform specific images as ${tag}-${os}-${arch} (for use with
32+
# AWS Lambda and other platforms that cannot handle multiarch OCI images).
33+
TAG_PLATFORM_IMAGES="{{tag_platform_images}}"
34+
3135
# this will hold args specific to `crane push``
3236
ARGS=()
3337

@@ -36,10 +40,12 @@ while (( $# > 0 )); do
3640
(--allow-nondistributable-artifacts|--insecure|-v|--verbose)
3741
GLOBAL_FLAGS+=( "$1" )
3842
shift;;
43+
(-i|--tag-platform-images)
44+
TAG_PLATFORM_IMAGES=1
45+
shift;;
3946
(--platform)
4047
GLOBAL_FLAGS+=( "--platform" "$2" )
4148
shift
42-
shift;;
4349
(-t|--tag)
4450
TAGS+=( "$2" )
4551
shift
@@ -65,16 +71,38 @@ if [[ -z "${REPOSITORY}" ]]; then
6571
exit 1
6672
fi
6773

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

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

7381
for tag in "${TAGS[@]+"${TAGS[@]}"}"
7482
do
7583
"${CRANE}" tag "${GLOBAL_FLAGS[@]+"${GLOBAL_FLAGS[@]}"}" $(cat "${REFS}") "${tag}"
84+
if [[ ${TAG_PLATFORM_IMAGES} -eq 1 ]]; then
85+
echo "${IMAGE_DIGESTS}" | while read digest os arch ; do
86+
if [[ -n "${os}" && -n "${arch}" ]]; then
87+
"${CRANE}" tag "${REPOSITORY}@${digest}" "${tag}-${os}-${arch}"
88+
fi
89+
done
90+
fi
7691
done
7792

7893
if [[ -e "${TAGS_FILE:-}" ]]; then
79-
cat "${TAGS_FILE}" | xargs -r -n1 "${CRANE}" tag "${GLOBAL_FLAGS[@]+"${GLOBAL_FLAGS[@]}"}" $(cat "${REFS}")
94+
readarray -t tags < "${TAGS_FILE}"
95+
for tag in "${tags[@]}"; do
96+
if [[ -z "${tag}" ]]; then
97+
continue
98+
fi
99+
"${CRANE}" tag "${GLOBAL_FLAGS[@]+"${GLOBAL_FLAGS[@]}"}" $(cat "${REFS}") "${tag}"
100+
if [[ ${TAG_PLATFORM_IMAGES} -eq 1 ]]; then
101+
echo "${IMAGE_DIGESTS}" | while read digest os arch ; do
102+
if [[ -n "${os}" && -n "${arch}" ]]; then
103+
"${CRANE}" tag "${REPOSITORY}@${digest}" "${tag}-${os}-${arch}"
104+
fi
105+
done
106+
fi
107+
done
80108
fi

0 commit comments

Comments
 (0)