From f46c52bfeca5612a374c4245d904a4d1aff3e094 Mon Sep 17 00:00:00 2001 From: Jack Green Date: Tue, 3 Dec 2024 16:09:28 +0000 Subject: [PATCH] Improve `publish-rhel` script [DI-343][5.4.z] (#841) Backport of https://github.com/hazelcast/hazelcast-docker/pull/823 The action [failed](https://github.com/hazelcast/hazelcast-docker/actions/runs/11831672090/attempts/1) but without providing enough information to understand _why_. Changes: - Log the `get_image` function response (JSON) in case of failure - Improve failure annotation reporting (as per https://github.com/hazelcast/hazelcast-docker/pull/821) - Address all Shellcheck warnings in case related - [`Declare and assign separately to avoid masking return values`](https://www.shellcheck.net/wiki/SC2155) - [`Prefer putting braces around variable references even when not strictly required`](https://www.shellcheck.net/wiki/SC2250) - [`Quote the rhs of = in [[ ]] to prevent glob matchingQuote the rhs of = in [[ ]] to prevent glob matching`](https://www.shellcheck.net/wiki/SC2053) _Partially addresses_ [DI-343](https://hazelcast.atlassian.net/browse/DI-342) [DI-342]: https://hazelcast.atlassian.net/browse/DI-342?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ [DI-343]: https://hazelcast.atlassian.net/browse/DI-343?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ --- .github/scripts/publish-rhel.sh | 134 +++++++++++++++++++++----------- 1 file changed, 88 insertions(+), 46 deletions(-) diff --git a/.github/scripts/publish-rhel.sh b/.github/scripts/publish-rhel.sh index 01829d67..8b97fdeb 100755 --- a/.github/scripts/publish-rhel.sh +++ b/.github/scripts/publish-rhel.sh @@ -1,6 +1,6 @@ #!/bin/bash -set -euo pipefail ${RUNNER_DEBUG:+-x} +set -o errexit -o nounset -o pipefail ${RUNNER_DEBUG:+-x} get_image() { @@ -9,19 +9,24 @@ get_image() local VERSION=$3 local RHEL_API_KEY=$4 - if [[ $PUBLISHED == "published" ]]; then + case "${PUBLISHED}" in + "published") local PUBLISHED_FILTER="repositories.published==true" - elif [[ $PUBLISHED == "not_published" ]]; then + ;; + "not_published") local PUBLISHED_FILTER="repositories.published!=true" - else - echo "Need first parameter as 'published' or 'not_published'." ; return 1 - fi + ;; + *) + echoerr "Need first parameter as 'published' or 'not_published', not '${PUBLISHED}'." ; return 1 + ;; + esac local FILTER="filter=deleted==false;${PUBLISHED_FILTER};repositories.tags=em=(name=='${VERSION}')" local INCLUDE="include=total,data.repositories.tags.name,data.certified,data.container_grades,data._id,data.creation_date" local SORT_BY='sort_by=creation_date\[desc\]' - local RESPONSE=$( \ + local RESPONSE + RESPONSE=$( \ curl --silent \ --request GET \ --header "X-API-KEY: ${RHEL_API_KEY}" \ @@ -36,36 +41,48 @@ wait_for_container_scan() local VERSION=$2 local RHEL_API_KEY=$3 local TIMEOUT_IN_MINS=$4 + + local IMAGE + local IS_PUBLISHED + + IMAGE=$(get_image published "${RHEL_PROJECT_ID}" "${VERSION}" "${RHEL_API_KEY}") + IS_PUBLISHED=$(echo "${IMAGE}" | jq -r '.total') - local IS_PUBLISHED=$(get_image published "${RHEL_PROJECT_ID}" "${VERSION}" "${RHEL_API_KEY}" | jq -r '.total') - if [[ $IS_PUBLISHED == "1" ]]; then + if [[ ${IS_PUBLISHED} == "1" ]]; then echo "Image is already published, exiting" return 0 fi - local NOF_RETRIES=$(( $TIMEOUT_IN_MINS / 2 )) + local NOF_RETRIES=$(( TIMEOUT_IN_MINS / 2 )) # Wait until the image is scanned - for i in `seq 1 ${NOF_RETRIES}`; do - local IMAGE=$(get_image not_published "${RHEL_PROJECT_ID}" "${VERSION}" "${RHEL_API_KEY}") - local SCAN_STATUS=$(echo "$IMAGE" | jq -r '.data[0].container_grades.status') - local IMAGE_CERTIFIED=$(echo "$IMAGE" | jq -r '.data[0].certified') + for i in $(seq 1 "${NOF_RETRIES}"); do + local IMAGE + local SCAN_STATUS + local IMAGE_CERTIFIED - if [[ $SCAN_STATUS == "pending" ]]; then + IMAGE=$(get_image not_published "${RHEL_PROJECT_ID}" "${VERSION}" "${RHEL_API_KEY}") + SCAN_STATUS=$(echo "${IMAGE}" | jq -r '.data[0].container_grades.status') + IMAGE_CERTIFIED=$(echo "${IMAGE}" | jq -r '.data[0].certified') + + if [[ ${SCAN_STATUS} == "pending" ]]; then echo "Scanning pending, waiting..." - elif [[ $SCAN_STATUS == "in progress" ]]; then + elif [[ ${SCAN_STATUS} == "in progress" ]]; then echo "Scanning in progress, waiting..." - elif [[ $SCAN_STATUS == "null" ]]; then + elif [[ ${SCAN_STATUS} == "null" ]]; then echo "Image is still not present in the registry!" - elif [[ $SCAN_STATUS == "completed" && "$IMAGE_CERTIFIED" == "true" ]]; then + elif [[ ${SCAN_STATUS} == "completed" && "${IMAGE_CERTIFIED}" == "true" ]]; then echo "Scan passed!" ; return 0 else - echo "Scan failed!" ; return 1 + echoerr "Scan failed with '${SCAN_STATUS}!" + echoerr "${IMAGE}" + return 1 fi sleep 120 - if [[ $i == $NOF_RETRIES ]]; then - echo "Timeout! Scan could not be finished" + if [[ ${i} == "${NOF_RETRIES}" ]]; then + echoerr "Timeout! Scan could not be finished" + echoerr "${IMAGE}" return 42 fi done @@ -77,25 +94,35 @@ publish_the_image() local VERSION=$2 local RHEL_API_KEY=$3 - echo "Starting publishing the image for $VERSION" + echo "Starting publishing the image for ${VERSION}" + + local IMAGE + local IMAGE_EXISTS + + IMAGE=$(get_image not_published "${RHEL_PROJECT_ID}" "${VERSION}" "${RHEL_API_KEY}") + IMAGE_EXISTS=$(echo "${IMAGE}" | jq -r '.total') - local IMAGE=$(get_image not_published "${RHEL_PROJECT_ID}" "${VERSION}" "${RHEL_API_KEY}") - local IMAGE_EXISTS=$(echo $IMAGE | jq -r '.total') - if [[ $IMAGE_EXISTS == "1" ]]; then - local SCAN_STATUS=$(echo "$IMAGE" | jq -r '.data[0].container_grades.status') - local IMAGE_CERTIFIED=$(echo "$IMAGE" | jq -r '.data[0].certified') - if [[ $SCAN_STATUS != "completed" || "$IMAGE_CERTIFIED" != "true" ]]; then - echo "Image you are trying to publish did not pass the certification test, its status is \"${SCAN_STATUS}\" and certified is \"${IMAGE_CERTIFIED}\"" + if [[ ${IMAGE_EXISTS} == "1" ]]; then + local SCAN_STATUS + local IMAGE_CERTIFIED + + SCAN_STATUS=$(echo "${IMAGE}" | jq -r '.data[0].container_grades.status') + IMAGE_CERTIFIED=$(echo "${IMAGE}" | jq -r '.data[0].certified') + + if [[ ${SCAN_STATUS} != "completed" || "${IMAGE_CERTIFIED}" != "true" ]]; then + echoerr "Image you are trying to publish did not pass the certification test, its status is \"${SCAN_STATUS}\" and certified is \"${IMAGE_CERTIFIED}\"" return 1 fi else - echo "Image you are trying to publish does not exist." + echoerr "Image you are trying to publish does not exist." + echoerr "${IMAGE}" return 1 fi - local IMAGE_ID=$(echo "$IMAGE" | jq -r '.data[0]._id') + local IMAGE_ID + IMAGE_ID=$(echo "${IMAGE}" | jq -r '.data[0]._id') - echo "Publishing the image $IMAGE_ID..." + echo "Publishing the image ${IMAGE_ID}..." RESPONSE=$( \ curl --silent \ --retry 5 --retry-all-errors \ @@ -105,7 +132,7 @@ publish_the_image() --header 'Content-Type: application/json' \ --data "{\"image_id\":\"${IMAGE_ID}\" , \"operation\" : \"publish\" }" \ "https://catalog.redhat.com/api/containers/v1/projects/certification/id/${RHEL_PROJECT_ID}/requests/images") - echo "Response: $RESPONSE" + echo "Response: ${RESPONSE}" echo "Created a publish request, please check if the image is published." } @@ -116,18 +143,23 @@ sync_tags() local VERSION=$2 local RHEL_API_KEY=$3 - echo "Starting sync tags for $VERSION" + echo "Starting sync tags for ${VERSION}" + + local IMAGE + local IMAGE_EXISTS + + IMAGE=$(get_image published "${RHEL_PROJECT_ID}" "${VERSION}" "${RHEL_API_KEY}") + IMAGE_EXISTS=$(echo "${IMAGE}" | jq -r '.total') - local IMAGE=$(get_image published "${RHEL_PROJECT_ID}" "${VERSION}" "${RHEL_API_KEY}") - local IMAGE_EXISTS=$(echo $IMAGE | jq -r '.total') - if [[ $IMAGE_EXISTS == "0" ]]; then + if [[ ${IMAGE_EXISTS} == "0" ]]; then echo "Image you are trying to sync does not exist." return 1 fi - local IMAGE_ID=$(echo "$IMAGE" | jq -r '.data[0]._id') + local IMAGE_ID + IMAGE_ID=$(echo "${IMAGE}" | jq -r '.data[0]._id') - echo "Syncing tags of the image $IMAGE_ID..." + echo "Syncing tags of the image ${IMAGE_ID}..." RESPONSE=$( \ curl --silent \ --retry 5 --retry-all-errors \ @@ -137,7 +169,7 @@ sync_tags() --header 'Content-Type: application/json' \ --data "{\"image_id\":\"${IMAGE_ID}\" , \"operation\" : \"sync-tags\" }" \ "https://catalog.redhat.com/api/containers/v1/projects/certification/id/${RHEL_PROJECT_ID}/requests/images") - echo "Response: $RESPONSE" + echo "Response: ${RESPONSE}" echo "Created a sync-tags request, please check if the tags image are in sync." } @@ -148,12 +180,16 @@ wait_for_container_publish() local RHEL_API_KEY=$3 local TIMEOUT_IN_MINS=$4 - local NOF_RETRIES=$(( $TIMEOUT_IN_MINS * 2 )) + local NOF_RETRIES=$(( TIMEOUT_IN_MINS * 2 )) # Wait until the image is published - for i in `seq 1 ${NOF_RETRIES}`; do - local IS_PUBLISHED=$(get_image published "${RHEL_PROJECT_ID}" "${VERSION}" "${RHEL_API_KEY}" | jq -r '.total') + for i in $(seq 1 "${NOF_RETRIES}"); do + local IMAGE + local IS_PUBLISHED - if [[ $IS_PUBLISHED == "1" ]]; then + IMAGE=$(get_image published "${RHEL_PROJECT_ID}" "${VERSION}" "${RHEL_API_KEY}") + IS_PUBLISHED=$(echo "${IMAGE}" | jq -r '.total') + + if [[ ${IS_PUBLISHED} == "1" ]]; then echo "Image is published, exiting." return 0 else @@ -162,9 +198,15 @@ wait_for_container_publish() sleep 30 - if [[ $i == $NOF_RETRIES ]]; then - echo "Timeout! Publish could not be finished" + if [[ ${i} == "${NOF_RETRIES}" ]]; then + echoerr "Timeout! Publish could not be finished" + echoerr "${IMAGE}" return 42 fi done } + +# Prints the given message to stderr +function echoerr() { + echo "::error::ERROR - $*" 1>&2; +}