diff --git a/tasks/get-ocp-version/README.md b/tasks/get-ocp-version/README.md index 6544ce56b..dfdbb5e22 100644 --- a/tasks/get-ocp-version/README.md +++ b/tasks/get-ocp-version/README.md @@ -8,6 +8,10 @@ Tekton task to collect OCP version tag from FBC fragment using `skopeo inspect`. |-------------|-----------------------|----------|---------------| | fbcFragment | A FBC container Image | No | - | + +## Changes in 0.5.1 +* Task updated to handle multi-arch fbc fragments + ## Changes in 0.5.0 * Updated the base image used in this task diff --git a/tasks/get-ocp-version/get-ocp-version.yaml b/tasks/get-ocp-version/get-ocp-version.yaml index dd3e3c0ec..7bb7b28c4 100644 --- a/tasks/get-ocp-version/get-ocp-version.yaml +++ b/tasks/get-ocp-version/get-ocp-version.yaml @@ -4,7 +4,7 @@ kind: Task metadata: name: get-ocp-version labels: - app.kubernetes.io/version: "0.5.0" + app.kubernetes.io/version: "0.5.1" annotations: tekton.dev/pipelines.minVersion: "0.12.1" tekton.dev/tags: release @@ -23,20 +23,43 @@ spec: - name: get-ocp-version image: quay.io/konflux-ci/release-service-utils:e633d51cd41d73e4b3310face21bb980af7a662f script: | - #!/usr/bin/env sh - set -eux + #!/usr/bin/env bash + set -eux - # The value to be checked - value=$(skopeo inspect --raw docker://"$(params.fbcFragment)" \ - | jq '.annotations."org.opencontainers.image.base.name"' | cut -d: -f2 | sed 's/"//g') + fbc_fragment="$(params.fbcFragment)" + + # get the media type + media_type=$(skopeo inspect --raw "docker://${fbc_fragment}" | jq -r .mediaType) + + # multiplatform images will not contain the base name with the OCP version, so it should fetch + # the manifest image + if [[ "$media_type" == "application/vnd.oci.image.index.v1+json" ]]; then + # image is an index of multiplatform components + arch_json=$(get-image-architectures "${fbc_fragment}") + + # it is not required to loop all images as they are all built for the same OCP version + manifest_image_sha="$(jq -rs 'map(.platform.digest)[0]' <<< "$arch_json")" + + # replace the image sha with the manifests's one + manifest_image="${fbc_fragment%@*}@${manifest_image_sha}" + + # fetch the image base name containing the version for the found manifest image + image_base_name=$(skopeo inspect --raw docker://"${manifest_image}" \ + | jq '.annotations."org.opencontainers.image.base.name"' | cut -d: -f2 | sed 's/"//g') + + else + # fetch the image base name containing the version for a manifest image + image_base_name=$(skopeo inspect --raw docker://"${fbc_fragment}" \ + | jq '.annotations."org.opencontainers.image.base.name"' | cut -d: -f2 | sed 's/"//g') + fi # Define the regular expression pattern="^v[0-9]\.[0-9]+$" # Check if the value matches the pattern - if ! echo "${value}" | grep -Eq "${pattern}"; then + if ! echo "${image_base_name}" | grep -Eq "${pattern}"; then echo "Invalid format or value does not exist or does not match the required pattern." exit 1 fi echo "Valid format." - printf "%s" "$value" | tee "$(results.stored-version.path)" + printf "%s" "$image_base_name" | tee "$(results.stored-version.path)" diff --git a/tasks/get-ocp-version/tests/mocks.sh b/tasks/get-ocp-version/tests/mocks.sh new file mode 100644 index 000000000..1bea91951 --- /dev/null +++ b/tasks/get-ocp-version/tests/mocks.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +set -eux + +function oras() { + echo "sha256:manifest" +} + +function skopeo() { + if [[ "$*" == "inspect --raw docker://quay.io/fbc/multi-arch@sha256:index" ]]; then + echo '{ "mediaType": "application/vnd.oci.image.index.v1+json" }' + else + echo '{ "mediaType": "application/vnd.oci.image.manifest.v1+json", + "annotations": { + "org.opencontainers.image.base.digest": "sha256:manifest", + "org.opencontainers.image.base.name": "registry.redhat.io/openshift4/ose-operator-registry-rhel9:v4.12" + } + }' + fi +} + +function get-image-architectures() { + echo '{"platform":{"digest": "sha256:manifest", "architecture": "amd64", "os": "linux"}}' + echo '{"platform":{"digest": "sha256:manifest", "architecture": "ppc64le", "os": "linux"}}' +} diff --git a/tasks/get-ocp-version/tests/pre-apply-task-hook.sh b/tasks/get-ocp-version/tests/pre-apply-task-hook.sh new file mode 100755 index 000000000..06c31e60f --- /dev/null +++ b/tasks/get-ocp-version/tests/pre-apply-task-hook.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +# +# Add mocks to the beginning of task step script +TASK_PATH="$1" +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +yq -i '.spec.steps[0].script = load_str("'$SCRIPT_DIR'/mocks.sh") + .spec.steps[0].script' "$TASK_PATH" diff --git a/tasks/get-ocp-version/tests/test-get-ocp-version-multi-arch.yaml b/tasks/get-ocp-version/tests/test-get-ocp-version-multi-arch.yaml new file mode 100644 index 000000000..cbe0a2ace --- /dev/null +++ b/tasks/get-ocp-version/tests/test-get-ocp-version-multi-arch.yaml @@ -0,0 +1,39 @@ +--- +apiVersion: tekton.dev/v1 +kind: Pipeline +metadata: + name: test-get-ocp-version-multi-arch +spec: + description: | + Run the get-ocp-version task with a multi-arch fbcFragment FBC Image + and verify that OCP-Version is been stored as expected + workspaces: + - name: tests-workspace + tasks: + - name: run-task + taskRef: + name: get-ocp-version + params: + - name: fbcFragment + value: quay.io/fbc/multi-arch@sha256:index + - name: check-result + params: + - name: stored-version + value: $(tasks.run-task.results.stored-version) + runAfter: + - run-task + taskSpec: + params: + - name: stored-version + steps: + - name: check-result + image: quay.io/konflux-ci/release-service-utils:e633d51cd41d73e4b3310face21bb980af7a662f + env: + - name: "OCP_VERSION" + value: '$(params.stored-version)' + script: | + #!/usr/bin/env sh + set -eux + + echo "Task result contains the valid OCP version number" + test $(echo $OCP_VERSION) == "v4.12"