Skip to content

Commit

Permalink
Support repotags
Browse files Browse the repository at this point in the history
  • Loading branch information
illicitonion committed Aug 8, 2023
1 parent 573376c commit 40d3e19
Showing 1 changed file with 46 additions and 14 deletions.
60 changes: 46 additions & 14 deletions oci/private/tarball.sh.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,7 @@ cp_f_with_mkdir() {
cp -f "${SRC}" "${DST}"
}

# Replace newlines (unix or windows line endings) with % character.
# We can't pass newlines to yq due to https://github.com/mikefarah/yq/issues/1430 and
# we can't update YQ at the moment because structure_test depends on a specific version:
# see https://github.com/bazel-contrib/rules_oci/issues/212
REPOTAGS="$(tr -d '\r' < "${TAGS_FILE}" | tr '\n' '%')"
REPOTAGS=($(cat "${TAGS_FILE}"))

MANIFESTS_LENGTH=$("${YQ}" eval '.manifests | length' "${INDEX_FILE}")
if [[ "${MANIFESTS_LENGTH}" != 1 ]]; then
Expand All @@ -33,13 +29,6 @@ if [[ "${MEDIA_TYPE}" == "application/vnd.oci.image.index.v1+json" ]]; then
# Handle multi-architecture image indexes.
# Ideally the toolchains we rely on would output these for us, but they don't seem to.

if [[ -n "${REPOTAGS}" ]]; then
echo >&2 "OCI image indexes don't support setting repo tags"
echo >&2 "Repo tags can only be set for single-architecture docker-packed images"
exit 1
fi

cp "${IMAGE_DIR}/index.json" "${STAGING_DIR}/index.json"
echo -n '{"imageLayoutVersion": "1.0.0"}' > "${STAGING_DIR}/oci-layout"

INDEX_FILE_MANIFEST_DIGEST=$("${YQ}" eval '.manifests[0].digest | sub(":"; "/")' "${INDEX_FILE}" | tr -d '"')
Expand All @@ -62,6 +51,49 @@ if [[ "${MEDIA_TYPE}" == "application/vnd.oci.image.index.v1+json" ]]; then
cp_f_with_mkdir "${IMAGE_DIR}/blobs/${LAYER_DIGEST}" ${BLOBS_DIR}/${LAYER_DIGEST}
done
done

# Fill in repo tags as per https://github.com/opencontainers/image-spec/issues/796
# If there's more than one repo tag, we need to duplicate the manifest entry, so we have one copy per repo tag.
MANIFEST_COPIES=".manifests"
if [[ "${#REPOTAGS[@]}" -gt 1 ]]; then
for i in $(seq 2 "${#REPOTAGS[@]}"); do
MANIFEST_COPIES="${MANIFEST_COPIES} + .manifests"
done
fi
# Convert:
# {
# "schemaVersion": 2,
# "manifests": [
# {
# "mediaType": "application/vnd.oci.image.index.v1+json",
# "size": 668,
# "digest": "sha256:41981de3b7207f5260fd94fac77272218518d58a6335d843136d88d91341e3d9"
# }
# ]
# }
# Into:
# {
# "schemaVersion": 2,
# "manifests": [
# {
# "mediaType": "application/vnd.oci.image.index.v1+json",
# "size": 668,
# "digest": "sha256:41981de3b7207f5260fd94fac77272218518d58a6335d843136d88d91341e3d9",
# "annotations": {
# "org.opencontainers.image.ref.name": "repo-tag:1"
# }
# },
# {
# "mediaType": "application/vnd.oci.image.index.v1+json",
# "size": 668,
# "digest": "sha256:41981de3b7207f5260fd94fac77272218518d58a6335d843136d88d91341e3d9",
# "annotations": {
# "org.opencontainers.image.ref.name": "repo-tag:2"
# }
# }
# ]
# }
repo_tags="${REPOTAGS[@]}" "${YQ}" -o json eval "(.manifests = ${MANIFEST_COPIES}) *d {\"manifests\": (env(repo_tags) | split \" \" | map {\"annotations\": {\"org.opencontainers.image.ref.name\": .}})}" "${INDEX_FILE}" > "${STAGING_DIR}/index.json"
else
# Assume we're dealing with a single application/vnd.docker.distribution.manifest.list.v2+json manifest.

Expand All @@ -79,11 +111,11 @@ else
cp_f_with_mkdir "${IMAGE_DIR}/blobs/${LAYER}" "${BLOBS_DIR}/${LAYER}.tar.gz"
done

repo_tags="${REPOTAGS}" \
repo_tags="${REPOTAGS[@]}" \
config="blobs/${CONFIG_DIGEST}" \
layers="${LAYERS}" \
"${YQ}" eval \
--null-input '.[0] = {"Config": env(config), "RepoTags": "${repo_tags}" | envsubst | split("%") | map(select(. != "")) , "Layers": env(layers) | map( "blobs/" + . + ".tar.gz") }' \
--null-input '.[0] = {"Config": env(config), "RepoTags": "${repo_tags}" | envsubst | split(" ") | map(select(. != "")) , "Layers": env(layers) | map( "blobs/" + . + ".tar.gz") }' \
--output-format json > "${STAGING_DIR}/manifest.json"
fi

Expand Down

0 comments on commit 40d3e19

Please sign in to comment.