From 749f6c157935ee4578e656119b3a7526862c8ad7 Mon Sep 17 00:00:00 2001 From: Ashwini Kumar Date: Tue, 10 Feb 2026 17:50:20 +0530 Subject: [PATCH 1/2] feat(utils): add function to fetch first image architecture This function uses skopeo inspect --raw to identify the first available architecture in a manifest list. Signed-off-by: Ashwini Kumar --- test/utils.sh | 22 ++++++++++++++++++++++ unittests_bash/test_utils.bats | 30 ++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/test/utils.sh b/test/utils.sh index 5371c9b1..95bdfe08 100755 --- a/test/utils.sh +++ b/test/utils.sh @@ -1924,3 +1924,25 @@ get_image_mirror_list() { printf "%s\n" "${mirrors[@]}" | sort -u } + +# Fetch first architecture for the image +get_first_arch() { + local image="$1" + local raw_output + local arch + + if ! raw_output=$(retry skopeo inspect --raw "docker://${image}"); then + echo "get_first_arch: Error fetching raw manifest for ${image}" >&2 + exit 1 + fi + + # Fetch the architecture from the first entry in the manifest list + arch=$(echo "${raw_output}" | jq -r '.manifests[0].platform.architecture // empty') + + if [[ -z "$arch" || "$arch" == "null" ]]; then + echo "get_first_arch: No architecture found in .manifests[0] for ${image}" >&2 + exit 1 + fi + + echo "$arch" +} diff --git a/unittests_bash/test_utils.bats b/unittests_bash/test_utils.bats index 15f8a627..3b72435f 100644 --- a/unittests_bash/test_utils.bats +++ b/unittests_bash/test_utils.bats @@ -165,6 +165,15 @@ EOF return 0 + elif [[ $1 == "inspect" && $2 == "--raw" && $3 == "docker://registry/image@valid-url" ]]; then + echo '{"manifests":[{"platform":{"architecture":"arm64"}},{"platform":{"architecture":"amd64"}}]}' + return 0 + + # Mock for single-arch manifest + elif [[ $1 == "inspect" && $2 == "--raw" && $3 == "docker://registry/image-manifest@valid" ]]; then + echo '{"manifests":[{"platform":{"architecture":"amd64"}}]}' + return 0 + # Some skopeo commands fail else echo 'Unrecognized call to mock skopeo' @@ -2150,3 +2159,24 @@ EOF EXPECTED_RESPONSE=$(echo 'brew.registry.redhat.io/rh-osbs/salami-operator-bundle*quay.io/salami/operator-bundle'| tr '*' '\n') [[ "${EXPECTED_RESPONSE}" = "${output}" && "${status}" -eq 0 ]] } + +@test "Get first arch: multi-arch index (registry/image@valid-url)" { + run get_first_arch "registry/image@valid-url" + + [ "$status" -eq 0 ]|| { echo "Status was $status. Output: $output"; return 1; } + [[ "${output}" == *"arm64"* ]] +} + +@test "Get first arch: single-arch manifest (registry/image-manifest@valid)" { + run get_first_arch "registry/image-manifest@valid" + + [ "$status" -eq 0 ] + [[ "${output}" == *"amd64"* ]] +} + +@test "Get first arch: invalid image" { + run get_first_arch "registry/non-existent@image" + + [ "$status" -eq 1 ] + [[ "$output" == *"get_first_arch: Error fetching raw manifest"* ]] +} \ No newline at end of file From 51e3a423e0a49331079ee2c9439d5a9d44ff3fbb Mon Sep 17 00:00:00 2001 From: Ashwini Kumar Date: Wed, 11 Feb 2026 17:07:23 +0530 Subject: [PATCH 2/2] feat(labels): integrate get_first_arch and enhance retry testing - Update get_image_labels to use get_first_arch. - Add test for updated get_image_labels. Signed-off-by: Ashwini Kumar --- test/utils.sh | 21 +++++++++++---------- unittests_bash/test_utils.bats | 34 +++++++++++++++++++++++----------- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/test/utils.sh b/test/utils.sh index 95bdfe08..f50b1596 100755 --- a/test/utils.sh +++ b/test/utils.sh @@ -938,22 +938,18 @@ get_image_labels() { exit 2 fi - local image_labels # Ensure that we don't have a tag and digest for skopeo image=$(get_image_registry_repository_digest "$image") - # Fetch first arch using --raw as skopeo may fail when - # the image does not have build for arch same as base system. - local raw_output - - if ! raw_output=$(retry skopeo inspect --raw "docker://${image}"); then - echo "get_image_labels: raw inspect failed after retries" >&2 + first_arch=$(get_first_arch "${image}") + if [ -z "${first_arch}" ] || [ "${first_arch}" == "null" ]; then + echo "get_image_labels: architecture could not be determined for ${image}" >&2 + exit 1 fi - first_arch=$(echo "${raw_output}" | jq -r '.manifests[].platform.architecture' | head -n 1) echo "get_image_labels: First architecture found: ${first_arch}" - + local image_labels if ! image_labels=$(retry skopeo inspect --override-arch="${first_arch}" --no-tags docker://"${image}"); then echo "get_image_labels: failed to inspect the image" >&2 exit 1 @@ -1936,9 +1932,14 @@ get_first_arch() { exit 1 fi - # Fetch the architecture from the first entry in the manifest list + # Fetch the architecture from the first entry in the Manifest List arch=$(echo "${raw_output}" | jq -r '.manifests[0].platform.architecture // empty') + # If arch is empty try fetching arch for Signle Arch Manifest + if [[ -z "${arch}" ]]; then + arch=$(echo "${raw_output}" | jq -r '.Architecture // empty') + fi + if [[ -z "$arch" || "$arch" == "null" ]]; then echo "get_first_arch: No architecture found in .manifests[0] for ${image}" >&2 exit 1 diff --git a/unittests_bash/test_utils.bats b/unittests_bash/test_utils.bats index 3b72435f..05108fc2 100644 --- a/unittests_bash/test_utils.bats +++ b/unittests_bash/test_utils.bats @@ -170,8 +170,8 @@ EOF return 0 # Mock for single-arch manifest - elif [[ $1 == "inspect" && $2 == "--raw" && $3 == "docker://registry/image-manifest@valid" ]]; then - echo '{"manifests":[{"platform":{"architecture":"amd64"}}]}' + elif [[ $1 == "inspect" && $3 == "docker://registry/image-manifest@valid" ]]; then + echo '{"Name": "quay.io/ashwkuma/ashwkuma-rhoai","Architecture": "ppc64le","Os": "linux"}' return 0 # Some skopeo commands fail @@ -836,14 +836,12 @@ EOF @test "Get Image Labels: registry/image-manifest:tag@invalid" { run get_image_labels registry/image-manifest:tag@invalid - local EXPECTED_LINE_1="get_image_labels: First architecture found:" - local EXPECTED_LINE_2="get_image_labels: failed to inspect the image" - local EXPECTED_ERROR_LINE="Invalid numeric literal at line 1, column 13" + local EXPECTED_LINE_1="get_first_arch: Error fetching raw manifest for registry/image-manifest@invalid" + local EXPECTED_LINE_2="get_image_labels: architecture could not be determined for registry/image-manifest@invalid" [[ "$status" -eq 1 \ && "${output}" == *"${EXPECTED_LINE_1}"* \ - && "${output}" == *"${EXPECTED_LINE_2}"* \ - && "${output}" == *"${EXPECTED_ERROR_LINE}"* ]] + && "${output}" == *"${EXPECTED_LINE_2}"* ]] } @test "Get relatedImages from operator bundle: valid-operator-bundle-1" { @@ -1514,12 +1512,12 @@ EOF } -@test "Retry Get Image Labels: registry/image:tag@invalid-url" { +@test "Retry Get Image Labels: registry/image-manifest@valid" { RETRY_COUNT=1 RETRY_INTERVAL=1 retry_output=$(get_retry_expected_output) - run get_image_labels registry/image:tag@invalid-url - EXPECTED_RESPONSE=$(echo -e -n "get_image_labels: First architecture found: \n${retry_output}get_image_labels: failed to inspect the image") + run get_image_labels registry/image-manifest@valid + EXPECTED_RESPONSE=$(echo -e -n "get_image_labels: First architecture found: ppc64le\n${retry_output}get_image_labels: failed to inspect the image") [[ "${output}" == *"${EXPECTED_RESPONSE}"* && "$status" -eq 1 ]] } @@ -2171,7 +2169,7 @@ EOF run get_first_arch "registry/image-manifest@valid" [ "$status" -eq 0 ] - [[ "${output}" == *"amd64"* ]] + [[ "${output}" == *"ppc64le"* ]] } @test "Get first arch: invalid image" { @@ -2179,4 +2177,18 @@ EOF [ "$status" -eq 1 ] [[ "$output" == *"get_first_arch: Error fetching raw manifest"* ]] +} +@test "Retry get_first_arch: registry/invalid-image:lates" { + RETRY_COUNT=1 + RETRY_INTERVAL=1 + + retry_output=$(get_retry_expected_output) + + run get_first_arch "registry/invalid-image:latest" + + local EXPECTED_FINAL_ERROR="get_first_arch: Error fetching raw manifest for ${image}" + EXPECTED_RESPONSE=$(echo -e "${retry_output}\n${FINAL_ERROR}") + echo "$EXPECTED_RESPONSE" + [[ "${output}" == *"${EXPECTED_RESPONSE}"* && "$status" -eq 1 ]] + } \ No newline at end of file