Skip to content

Commit

Permalink
feat: expanding the functionality of utils.sh
Browse files Browse the repository at this point in the history
Adding more functionality to the utils scripts in order to then reduce
the amount of duplication in task scripts within build-definitions.

fixes #353

Signed-off-by: arewm <arewm@users.noreply.github.com>
  • Loading branch information
arewm committed Jan 21, 2025
1 parent deedbf9 commit 4bf45e7
Showing 1 changed file with 130 additions and 10 deletions.
140 changes: 130 additions & 10 deletions test/utils.sh
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,99 @@ handle_error()
fi
}

# The function can be used to parse an image url. It will return a json
# object with keys:
#
# `repository` - The repository of the image including an the registry and its optional port
# `tag` - The tag of the image reference
# `digest` - The digest of the image reference
#
# If an image tag or digest is not found then the values will be empty.
parse_image_url() {
local image_url=$1

if [ -z "$image_url" ]; then
echo "Missing image pull spec" >&2
exit 2
fi


digest=""
tag=""
repo="$(echo -n "$image_url" | cut -d@ -f1)"

# Digest will be the last portion after an "@"
at_number=$(echo -n "$image_url" | tr -cd "@" | wc -c | tr -d '[:space:]')
colon_number=$(echo -n "$repo" | tr -cd ":" | wc -c | tr -d '[:space:]')
if [[ $at_number == 1 ]]; then
digest="$(echo -n "${image_url}" | cut -d@ -f2)"
elif [[ $at_number != 0 ]]; then
# The only other supported format is registry/repository
echo "$image_url does not match the format registry(:port)/repository(:tag)(@digest)"
exit 3
fi

# Isolate to find the tag and name
# Trim off digest
repo="$(echo -n "$image_url" | cut -d@ -f1)"
if [[ $colon_number == 2 ]]; then
# format is now registry:port/repository:tag
# trim off everything after the last colon
tag=${repo##*:}
repo=${repo%:*}
elif [[ $colon_number == 1 ]]; then
# we have either a port or a tag so inspect the content after
# the colon to determine if it is a valid tag.
# https://github.com/opencontainers/distribution-spec/blob/main/spec.md
# [a-zA-Z0-9_][a-zA-Z0-9._-]{0,127} is the regex for a valid tag
# If not a valid tag, leave the colon alone.
if [[ "$(echo -n "$repo" | cut -d: -f2 | tr -d '[:space:]')" =~ ^([a-zA-Z0-9_][a-zA-Z0-9._-]{0,127})$ ]]; then
# We match a tag so trim it off
tag=$(echo -n "$repo" | cut -d: -f2)
repo=$(echo -n "$repo" | cut -d: -f1)
fi
elif [[ $colon_number != 0 ]]; then
# The only other supported format is registry/repository
echo "$image_url does not match the format registry(:port)/repository(:tag)(@digest)"
exit 3
fi

echo -n "{\"repository\": \"$repo\", \"tag\": \"$tag\", \"digest\": \"$digest\"}"
}

# Helper function to just get the pullspec in repository:tag format
get_image_repository_tag() {
local image_url=$1

if [ -z "$image_url" ]; then
echo "Missing image pull spec" >&2
exit 2
fi
parse_image_url "$image_url" | jq -jr '.repository + if .tag != "" then ":" + .tag else "" end'
}

# Helper function to just get the pullspec in repository:tag@digest format
get_image_repository_tag_digest() {
local image_url=$1

if [ -z "$image_url" ]; then
echo "Missing image pull spec" >&2
exit 2
fi
parse_image_url "$image_url" | jq -jr '.repository + if .tag != "" then ":" + .tag else "" end + if .digest != "" then "@" + .digest else "" end'
}

# Helper function to just get the pullspec in repository@digest format
get_image_repository_digest() {
local image_url=$1

if [ -z "$image_url" ]; then
echo "Missing image pull spec" >&2
exit 2
fi
parse_image_url "$image_url" | jq -jr '.repository + if .digest != "" then "@" + .digest else "" end'
}


# The function will be used by the tekton tasks of build-definitions
# It returns a map of {arch:digest} for the given image_url
Expand Down Expand Up @@ -208,6 +301,8 @@ get_image_manifests() {
exit 2
fi

# Ensure that we don't have a tag and digest for skopeo
image_url=$(get_image_repository_digest "$image_url")
if ! raw_inspect_output=$(skopeo inspect --no-tags --raw docker://"${image_url}"); then
echo "The raw image inspect command failed" >&2
exit 1
Expand Down Expand Up @@ -238,15 +333,20 @@ get_ocp_version_from_fbc_fragment() {
exit 2
fi

# Ensure that we have an image manifest
fbc_manifest_digest=$(get_image_manifests -i "$FBC_FRAGMENT" | jq -er ".amd64")
fbc_manifest=$(parse_image_url "$FBC_FRAGMENT" | jq -ej ".repository + \"@$fbc_manifest_digest\"")
#Get target ocp version from the fragment
local ocp_version
if ! ocp_version=$(skopeo inspect --no-tags --raw docker://"$FBC_FRAGMENT"); then
if ! ocp_version=$(skopeo inspect --no-tags docker://"$FBC_FRAGMENT"); then
echo "Could not inspect image $FBC_FRAGMENT"
exit 1
fi

ocp_version=$(echo "$ocp_version" | jq -r '.annotations."org.opencontainers.image.base.name"' | sed -e "s/@.*$//" -e "s/^.*://")
echo "$ocp_version"
# strips hash first due to greedy match
base_image=$(get_image_annotations "$fbc_manifest" | grep 'org.opencontainers.image.base.name=' | cut -d= -f2 || true)
ocp_version=$(parse_image_url "$base_image" | jq -ej '.tag')
echo -n "$ocp_version"
}

# Given output of `opm render` command and package name, this function returns
Expand Down Expand Up @@ -340,9 +440,7 @@ get_unreleased_bundle() {

# If the index image is provided and has a tag, remove it.
# The target ocp version is determined from the fragment
if [[ "$INDEX_IMAGE" == *:* ]]; then
INDEX_IMAGE="${INDEX_IMAGE%%:*}"
fi
IMAGE_INDEX=$(parse_image_url "$IMAGE_INDEX" | jq -jr '.repository')

#Get target ocp version from the fragment
local ocp_version
Expand Down Expand Up @@ -416,9 +514,7 @@ get_unreleased_fbc_related_images() {

# If the index image is provided and has a tag, remove it.
# The target ocp version is determined from the fragment
if [[ "$INDEX_IMAGE" == *:* ]]; then
INDEX_IMAGE="${INDEX_IMAGE%%:*}"
fi
IMAGE_INDEX=$(parse_image_url "$IMAGE_INDEX" | jq -jr '.repository')

#Get target ocp version from the fragment
local ocp_version
Expand Down Expand Up @@ -478,7 +574,31 @@ get_image_labels() {
exit 1
fi

echo "${image_labels}" | jq -r '.config.Labels // {} | to_entries[] | "\(.key)=\(.value)"'
echo "${image_labels}" | jq -jr '.config.Labels // {} | to_entries[] | "\(.key)=\(.value)"'

}

# This function will be used by tekton tasks in build-definitions
# It returns a list of annotations on the image
# If no annotations exist, it returns an empty string
get_image_annotations() {
local image=$1

if [ -z "$image" ]; then
echo "Missing image pull spec" >&2
exit 2
fi

# Ensure that we don't have a tag and digest for skopeo
image=$(get_image_repository_digest "$image")

local image_annotations
if ! image_annotations=$(skopeo inspect --raw docker://"${image}"); then
echo "Failed to inspect the image" >&2
exit 1
fi

echo "${image_annotations}" | jq -jr 'if .annotations != null then .annotations | to_entries[] | "\(.key)=\(.value)" else "" end'

}

Expand Down

0 comments on commit 4bf45e7

Please sign in to comment.