From 38a69b1e491ec66f702a13eadb3e75588c59cc3a Mon Sep 17 00:00:00 2001 From: Johnny Bieren Date: Tue, 10 Dec 2024 15:06:52 -0500 Subject: [PATCH] chore(RELEASE-1042): add publish-index-image internal task and pipeline This commit moves the publish-index-image pipeline and task from the app-interface repo to the internal directory of this repo. It also adds tests and a README with it. Signed-off-by: Johnny Bieren --- .../publish-index-image-pipeline/README.md | 13 ++++ .../publish-index-image-pipeline.yaml | 49 +++++++++++++ .../publish-index-image-pipeline.yaml | 1 + .../resources/publish-index-image-task.yaml | 1 + .../tasks/publish-index-image-task/README.md | 13 ++++ .../publish-index-image-task.yaml | 72 +++++++++++++++++++ .../publish-index-image-task/tests/mocks.sh | 22 ++++++ .../tests/pre-apply-task-hook.sh | 11 +++ .../tests/test-publish-index-image-fail.yaml | 22 ++++++ ...st-publish-index-image-registry-proxy.yaml | 41 +++++++++++ .../tests/test-publish-index-image.yaml | 40 +++++++++++ 11 files changed, 285 insertions(+) create mode 100644 internal/pipelines/publish-index-image-pipeline/README.md create mode 100644 internal/pipelines/publish-index-image-pipeline/publish-index-image-pipeline.yaml create mode 120000 internal/resources/publish-index-image-pipeline.yaml create mode 120000 internal/resources/publish-index-image-task.yaml create mode 100644 internal/tasks/publish-index-image-task/README.md create mode 100644 internal/tasks/publish-index-image-task/publish-index-image-task.yaml create mode 100644 internal/tasks/publish-index-image-task/tests/mocks.sh create mode 100755 internal/tasks/publish-index-image-task/tests/pre-apply-task-hook.sh create mode 100644 internal/tasks/publish-index-image-task/tests/test-publish-index-image-fail.yaml create mode 100644 internal/tasks/publish-index-image-task/tests/test-publish-index-image-registry-proxy.yaml create mode 100644 internal/tasks/publish-index-image-task/tests/test-publish-index-image.yaml diff --git a/internal/pipelines/publish-index-image-pipeline/README.md b/internal/pipelines/publish-index-image-pipeline/README.md new file mode 100644 index 000000000..376a4bafa --- /dev/null +++ b/internal/pipelines/publish-index-image-pipeline/README.md @@ -0,0 +1,13 @@ +# publish-index-image-pipeline + +Tekton pipeline to publish a built FBC index image using skopeo + +## Parameters + +| Name | Description | Optional | Default value | +|-----------------------|-----------------------------------------------|----------|---------------| +| sourceIndex | sourceIndex signing image | No | - | +| targetIndex | targetIndex signing image | No | - | +| retries | Number of skopeo retries | Yes | 0 | +| publishingCredentials | The credentials used to access the registries | No | - | +| requestUpdateTimeout | Max seconds waiting for the status update | Yes | 360 | diff --git a/internal/pipelines/publish-index-image-pipeline/publish-index-image-pipeline.yaml b/internal/pipelines/publish-index-image-pipeline/publish-index-image-pipeline.yaml new file mode 100644 index 000000000..37232ba0d --- /dev/null +++ b/internal/pipelines/publish-index-image-pipeline/publish-index-image-pipeline.yaml @@ -0,0 +1,49 @@ +--- +apiVersion: tekton.dev/v1 +kind: Pipeline +metadata: + name: publish-index-image-pipeline + labels: + app.kubernetes.io/version: "0.1" + annotations: + tekton.dev/pipelines.minVersion: "0.12.1" + tekton.dev/tags: release +spec: + description: >- + Pipeline to publish a built FBC index image using skopeo + params: + - name: sourceIndex + type: string + description: sourceIndex signing image + - name: targetIndex + type: string + description: targetIndex signing image + - name: retries + type: string + default: "0" + description: Number of skopeo retries + - name: publishingCredentials + type: string + description: The credentials used to access the registries + - name: requestUpdateTimeout + type: string + default: "360" + description: Max seconds waiting for the status update + tasks: + - name: publish-index-image-task + taskRef: + name: publish-index-image-task + params: + - name: sourceIndex + value: $(params.sourceIndex) + - name: targetIndex + value: $(params.targetIndex) + - name: retries + value: $(params.retries) + - name: publishingCredentials + value: $(params.publishingCredentials) + - name: requestUpdateTimeout + value: $(params.requestUpdateTimeout) + results: + - name: requestMessage + value: $(tasks.publish-index-image-task.results.requestMessage) diff --git a/internal/resources/publish-index-image-pipeline.yaml b/internal/resources/publish-index-image-pipeline.yaml new file mode 120000 index 000000000..f77548d68 --- /dev/null +++ b/internal/resources/publish-index-image-pipeline.yaml @@ -0,0 +1 @@ +../pipelines/publish-index-image-pipeline/publish-index-image-pipeline.yaml \ No newline at end of file diff --git a/internal/resources/publish-index-image-task.yaml b/internal/resources/publish-index-image-task.yaml new file mode 120000 index 000000000..aaeddb30a --- /dev/null +++ b/internal/resources/publish-index-image-task.yaml @@ -0,0 +1 @@ +../tasks/publish-index-image-task/publish-index-image-task.yaml \ No newline at end of file diff --git a/internal/tasks/publish-index-image-task/README.md b/internal/tasks/publish-index-image-task/README.md new file mode 100644 index 000000000..42d60f6b4 --- /dev/null +++ b/internal/tasks/publish-index-image-task/README.md @@ -0,0 +1,13 @@ +# publish-index-image-task + +Tekton task to publish a built FBC index image using skopeo + +## Parameters + +| Name | Description | Optional | Default value | +|-----------------------|-----------------------------------------------|----------|---------------| +| sourceIndex | sourceIndex signing image | No | - | +| targetIndex | targetIndex signing image | No | - | +| retries | Number of skopeo retries | Yes | 0 | +| publishingCredentials | The credentials used to access the registries | No | - | +| requestUpdateTimeout | Max seconds waiting for the status update | Yes | 360 | diff --git a/internal/tasks/publish-index-image-task/publish-index-image-task.yaml b/internal/tasks/publish-index-image-task/publish-index-image-task.yaml new file mode 100644 index 000000000..77e4d90a4 --- /dev/null +++ b/internal/tasks/publish-index-image-task/publish-index-image-task.yaml @@ -0,0 +1,72 @@ +--- +apiVersion: tekton.dev/v1 +kind: Task +metadata: + name: publish-index-image-task + labels: + app.kubernetes.io/version: "0.1.1" + annotations: + tekton.dev/pipelines.minVersion: "0.12.1" + tekton.dev/tags: release +spec: + description: >- + Task to publish a built FBC index image using skopeo + params: + - name: sourceIndex + type: string + description: sourceIndex signing image + - name: targetIndex + type: string + description: targetIndex signing image + - name: retries + type: string + default: "0" + description: Number of skopeo retries + - name: publishingCredentials + type: string + default: "fbc-publishing-credentials" + description: The credentials used to access the registries + - name: requestUpdateTimeout + type: string + default: "360" + description: Max seconds waiting for the status update + results: + - name: requestMessage + steps: + - name: publish-index-image + env: + - name: SOURCE_INDEX_CREDENTIAL + valueFrom: + secretKeyRef: + key: sourceIndexCredential + name: $(params.publishingCredentials) + - name: TARGET_INDEX_CREDENTIAL + valueFrom: + secretKeyRef: + key: targetIndexCredential + name: $(params.publishingCredentials) + image: >- + quay.io/konflux-ci/release-service-utils:e633d51cd41d73e4b3310face21bb980af7a662f + script: | + #!/usr/bin/env bash + PATH=/bin:/usr/bin:/usr/local/bin + export PATH + + # do not authenticate if the source is redhat's "registry-proxy" which is unauthenticated. + if [[ ! "$(params.sourceIndex)" =~ ^registry-proxy(\-stage)?.engineering.redhat.com ]]; then + AUTH_PARAM=("--src-creds" "${SOURCE_INDEX_CREDENTIAL}") + fi + + (skopeo copy \ + --all \ + --preserve-digests \ + --retry-times "$(params.retries)" \ + --src-tls-verify=false "${AUTH_PARAM[@]}" \ + "docker://$(params.sourceIndex)" \ + --dest-creds "${TARGET_INDEX_CREDENTIAL}" \ + "docker://$(params.targetIndex)" && \ + echo -n "Index Image Published successfully" || \ + echo -n "Failed publishing Index Image" ) | tee "$(results.requestMessage.path)" + + # trick to get the proper exit status + grep "success" "$(results.requestMessage.path)" >/dev/null diff --git a/internal/tasks/publish-index-image-task/tests/mocks.sh b/internal/tasks/publish-index-image-task/tests/mocks.sh new file mode 100644 index 000000000..e2bd6c3d2 --- /dev/null +++ b/internal/tasks/publish-index-image-task/tests/mocks.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +set -x + +# mocks to be injected into task step scripts + +function skopeo() { + echo Mock skopeo called with: $* >&2 + + if [[ "$*" == *"--src-tls-verify=false --src-creds source docker://quay.io/source"* ]] + then + return 0 + elif [[ "$*" == *"--src-tls-verify=false docker://registry-proxy.engineering.redhat.com/foo"* ]] + then + return 0 + elif [[ "$*" == *"--src-tls-verify=false docker://registry-proxy.engineering.redhat.com/fail"* ]] + then + return 1 + else + echo Error: Unexpected call + exit 1 + fi +} diff --git a/internal/tasks/publish-index-image-task/tests/pre-apply-task-hook.sh b/internal/tasks/publish-index-image-task/tests/pre-apply-task-hook.sh new file mode 100755 index 000000000..d9fbe0b65 --- /dev/null +++ b/internal/tasks/publish-index-image-task/tests/pre-apply-task-hook.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +TASK_PATH="$1" +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +# Add mocks to the beginning of task step script +yq -i '.spec.steps[0].script = load_str("'$SCRIPT_DIR'/mocks.sh") + .spec.steps[0].script' "$TASK_PATH" + +# Create a dummy secret (and delete it first if it exists) +kubectl delete secret publish-index-image-secret --ignore-not-found +kubectl create secret generic publish-index-image-secret --from-literal=sourceIndexCredential=source --from-literal=targetIndexCredential=target diff --git a/internal/tasks/publish-index-image-task/tests/test-publish-index-image-fail.yaml b/internal/tasks/publish-index-image-task/tests/test-publish-index-image-fail.yaml new file mode 100644 index 000000000..d11bdb3c4 --- /dev/null +++ b/internal/tasks/publish-index-image-task/tests/test-publish-index-image-fail.yaml @@ -0,0 +1,22 @@ +--- +apiVersion: tekton.dev/v1 +kind: Pipeline +metadata: + name: test-publish-index-image-fail + annotations: + test/assert-task-failure: "run-task" +spec: + description: | + Run the publish-index-image task with a failing sourceIndex. The grep at the end of the task sets the task + status to that of the skopeo command, and here the mock will make the skopeo command fail due to the sourceIndex + tasks: + - name: run-task + taskRef: + name: publish-index-image-task + params: + - name: sourceIndex + value: "registry-proxy.engineering.redhat.com/fail" + - name: targetIndex + value: "quay.io/target" + - name: publishingCredentials + value: "publish-index-image-secret" diff --git a/internal/tasks/publish-index-image-task/tests/test-publish-index-image-registry-proxy.yaml b/internal/tasks/publish-index-image-task/tests/test-publish-index-image-registry-proxy.yaml new file mode 100644 index 000000000..830cf2cbe --- /dev/null +++ b/internal/tasks/publish-index-image-task/tests/test-publish-index-image-registry-proxy.yaml @@ -0,0 +1,41 @@ +--- +apiVersion: tekton.dev/v1 +kind: Pipeline +metadata: + name: test-publish-index-image-registry-proxy +spec: + description: | + Run the publish-index-image task with a registry-proxy sourceIndex. Ensure the task succeeds, which can + only happen if --src-creds is properly added (due to the mocks.sh) + tasks: + - name: run-task + taskRef: + name: publish-index-image-task + params: + - name: sourceIndex + value: "registry-proxy.engineering.redhat.com/foo" + - name: targetIndex + value: "quay.io/target" + - name: publishingCredentials + value: "publish-index-image-secret" + - name: check-result + runAfter: + - run-task + params: + - name: requestMessage + value: $(tasks.run-task.results.requestMessage) + taskSpec: + params: + - name: requestMessage + type: string + steps: + - name: check-result + image: quay.io/konflux-ci/release-service-utils:e633d51cd41d73e4b3310face21bb980af7a662f + script: | + #!/usr/bin/env bash + set -ex + + if [[ "$(params.requestMessage)" != "Index Image Published successfully" ]]; then + echo Error: requestMessage task result is not correct + exit 1 + fi diff --git a/internal/tasks/publish-index-image-task/tests/test-publish-index-image.yaml b/internal/tasks/publish-index-image-task/tests/test-publish-index-image.yaml new file mode 100644 index 000000000..131803d97 --- /dev/null +++ b/internal/tasks/publish-index-image-task/tests/test-publish-index-image.yaml @@ -0,0 +1,40 @@ +--- +apiVersion: tekton.dev/v1 +kind: Pipeline +metadata: + name: test-publish-index-image +spec: + description: | + Run the publish-index-image task with a non registry-proxy sourceIndex + tasks: + - name: run-task + taskRef: + name: publish-index-image-task + params: + - name: sourceIndex + value: "quay.io/source" + - name: targetIndex + value: "quay.io/target" + - name: publishingCredentials + value: "publish-index-image-secret" + - name: check-result + runAfter: + - run-task + params: + - name: requestMessage + value: $(tasks.run-task.results.requestMessage) + taskSpec: + params: + - name: requestMessage + type: string + steps: + - name: check-result + image: quay.io/konflux-ci/release-service-utils:e633d51cd41d73e4b3310face21bb980af7a662f + script: | + #!/usr/bin/env bash + set -ex + + if [[ "$(params.requestMessage)" != "Index Image Published successfully" ]]; then + echo Error: requestMessage task result is not correct + exit 1 + fi