From 352a1e770b19ab9b671e7437062d03e8f063aa14 Mon Sep 17 00:00:00 2001 From: arewm Date: Thu, 21 Nov 2024 19:59:21 -0500 Subject: [PATCH 1/2] change to multi-arch-oci-ta pipeline Signed-off-by: arewm --- .tekton/build-pipeline.yaml | 962 ++++++++--------------- .tekton/oras-container-pull-request.yaml | 44 +- .tekton/oras-container-push.yaml | 44 +- 3 files changed, 367 insertions(+), 683 deletions(-) diff --git a/.tekton/build-pipeline.yaml b/.tekton/build-pipeline.yaml index 34766ac..a48213a 100644 --- a/.tekton/build-pipeline.yaml +++ b/.tekton/build-pipeline.yaml @@ -3,699 +3,342 @@ kind: Pipeline metadata: name: build-pipeline spec: - finally: - - name: show-sbom - params: - - name: IMAGE_URL - value: $(tasks.build-container.results.IMAGE_URL) - taskRef: - params: - - name: name - value: show-sbom - - name: bundle - value: quay.io/redhat-appstudio-tekton-catalog/task-show-sbom:0.1@sha256:8062d5b13b5236030407cbd620a75cb7c091f43be178eeefea58d2e3dddcaa74 - - name: kind - value: task - resolver: bundles - - name: show-summary - params: - - name: pipelinerun-name - value: $(context.pipelineRun.name) - - name: git-url - value: $(tasks.clone-repository-amd64.results.url)?rev=$(tasks.clone-repository-amd64.results.commit) - - name: image-url - value: $(params.output-image) - - name: build-task-status - value: $(tasks.build-container.status) - taskRef: - params: - - name: name - value: summary - - name: bundle - value: quay.io/redhat-appstudio-tekton-catalog/task-summary:0.2@sha256:ac5b078500566c204eaa23e3aea1e2f7e003ac750514198419cb322a2eaf177a - - name: kind - value: task - resolver: bundles - workspaces: - - name: workspace - workspace: workspace - params: - - description: Source Repository URL - name: git-url - type: string - - default: "" - description: Revision of the Source Repository - name: revision - type: string - - description: Fully Qualified Output Image - name: output-image - type: string - - default: . - description: Path to the source code of an application's component from where to build image. - name: path-context - type: string - - default: Dockerfile - description: Path to the Dockerfile inside the context specified by parameter path-context - name: dockerfile - type: string - - default: "false" - description: Force rebuild image - name: rebuild - type: string - - default: "false" - description: Skip checks against built image - name: skip-checks - type: string - - default: "false" - description: Execute the build with network isolation - name: hermetic - type: string - - default: "" - description: Build dependencies to be prefetched by Cachi2 - name: prefetch-input - type: string - - default: "false" - description: Java build - name: java - type: string - - default: "" - description: Image tag expiration time, time values could be something like 1h, 2d, 3w for hours, days, and weeks, respectively. - name: image-expires-after - - default: "false" - description: Build a source image. - name: build-source-image - type: string - - default: "" - description: Path to a file with build arguments which will be passed to podman during build - name: build-args-file - type: string - results: - - description: "" - name: IMAGE_URL - value: $(tasks.build-container.results.IMAGE_URL) - - description: "" - name: IMAGE_DIGEST - value: $(tasks.build-container.results.IMAGE_DIGEST) - - description: "" - name: CHAINS-GIT_URL - value: $(tasks.clone-repository-amd64.results.url) - - description: "" - name: CHAINS-GIT_COMMIT - value: $(tasks.clone-repository-amd64.results.commit) - tasks: + tasks: - name: init params: - - name: image-url - value: $(params.output-image) - - name: rebuild - value: $(params.rebuild) - - name: skip-checks - value: $(params.skip-checks) - taskRef: - params: - - name: name - value: init - - name: bundle - value: quay.io/redhat-appstudio-tekton-catalog/task-init:0.2@sha256:07b8eb6a9533525a397c296246d3eb6ec4771b520a1bfee817ce2b7ede25c43d - - name: kind - value: task - resolver: bundles - - name: clone-repository-amd64 - params: - - name: url - value: $(params.git-url) - - name: revision - value: $(params.revision) - runAfter: - - init - taskRef: - params: - - name: name - value: git-clone - - name: bundle - value: quay.io/redhat-appstudio-tekton-catalog/task-git-clone:0.1@sha256:a3e22f57fbf8398fbe93fbeeb38e03756cd073182d6d109fe8e8cde57b561603 - - name: kind - value: task - resolver: bundles - when: - - input: $(tasks.init.results.build) - operator: in - values: - - "true" - workspaces: - - name: output - workspace: workspace-amd64 - - name: basic-auth - workspace: git-auth - - name: prefetch-dependencies-amd64 - params: - - name: input - value: $(params.prefetch-input) - runAfter: - - clone-repository-amd64 - taskRef: - params: - - name: name - value: prefetch-dependencies - - name: bundle - value: quay.io/redhat-appstudio-tekton-catalog/task-prefetch-dependencies:0.1@sha256:566dfa9cf802e78ee26f8aae57c70cb6aa90f84dfdc929e176db4bc67d596df4 - - name: kind - value: task - resolver: bundles - when: - - input: $(params.prefetch-input) - operator: notin - values: - - "" - workspaces: - - name: source - workspace: workspace-amd64 - - name: git-basic-auth - workspace: git-auth - - name: build-container-amd64 - params: - - name: IMAGE - value: $(params.output-image)-amd64 - - name: DOCKERFILE - value: $(params.dockerfile) - - name: CONTEXT - value: $(params.path-context) - - name: HERMETIC - value: $(params.hermetic) - - name: PREFETCH_INPUT - value: $(params.prefetch-input) - - name: IMAGE_EXPIRES_AFTER - value: $(params.image-expires-after) - - name: COMMIT_SHA - value: $(tasks.clone-repository-amd64.results.commit) - - name: BUILD_ARGS_FILE - value: $(params.build-args-file) - runAfter: - - prefetch-dependencies-amd64 - taskRef: - params: - - name: name - value: buildah - - name: bundle - value: quay.io/redhat-appstudio-tekton-catalog/task-buildah:0.2@sha256:60c99bd62dbdb0edcd8606639f653adf115433f47f0deb43e7eb3a847c10392f - - name: kind - value: task - resolver: bundles - when: - - input: $(tasks.init.results.build) - operator: in - values: - - "true" - workspaces: - - name: source - workspace: workspace-amd64 - - name: clone-repository-arm64 - params: - - name: url - value: $(params.git-url) - - name: revision - value: $(params.revision) - runAfter: - - init - taskRef: - params: - - name: name - value: git-clone - - name: bundle - value: quay.io/redhat-appstudio-tekton-catalog/task-git-clone:0.1@sha256:a3e22f57fbf8398fbe93fbeeb38e03756cd073182d6d109fe8e8cde57b561603 - - name: kind - value: task - resolver: bundles - when: - - input: $(tasks.init.results.build) - operator: in - values: - - "true" - workspaces: - - name: output - workspace: workspace-arm64 - - name: basic-auth - workspace: git-auth - - name: prefetch-dependencies-arm64 - params: - - name: input - value: $(params.prefetch-input) - runAfter: - - clone-repository-arm64 + - name: image-url + value: $(params.output-image) + - name: rebuild + value: $(params.rebuild) + - name: skip-checks + value: $(params.skip-checks) taskRef: params: - - name: name - value: prefetch-dependencies - - name: bundle - value: quay.io/redhat-appstudio-tekton-catalog/task-prefetch-dependencies:0.1@sha256:566dfa9cf802e78ee26f8aae57c70cb6aa90f84dfdc929e176db4bc67d596df4 - - name: kind - value: task + - name: name + value: init + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-init:0.2@sha256:0523b51c28375a3f222da91690e22eff11888ebc98a0c73c468af44762265c69 + - name: kind + value: task resolver: bundles - when: - - input: $(params.prefetch-input) - operator: notin - values: - - "" - workspaces: - - name: source - workspace: workspace-arm64 - - name: git-basic-auth - workspace: git-auth - - name: build-container-arm64 + - name: clone-repository params: - - name: IMAGE - value: $(params.output-image)-arm64 - - name: DOCKERFILE - value: $(params.dockerfile) - - name: CONTEXT - value: $(params.path-context) - - name: HERMETIC - value: $(params.hermetic) - - name: PREFETCH_INPUT - value: $(params.prefetch-input) - - name: IMAGE_EXPIRES_AFTER - value: $(params.image-expires-after) - - name: COMMIT_SHA - value: $(tasks.clone-repository-arm64.results.commit) - - name: BUILD_ARGS_FILE - value: $(params.build-args-file) - - name: PLATFORM - value: linux/arm64 + - name: url + value: $(params.git-url) + - name: revision + value: $(params.revision) + - name: ociStorage + value: $(params.output-image).git + - name: ociArtifactExpiresAfter + value: $(params.image-expires-after) runAfter: - - prefetch-dependencies-arm64 + - init taskRef: params: - - name: name - value: buildah-remote - - name: bundle - value: quay.io/redhat-appstudio-tekton-catalog/task-buildah-remote:0.2@sha256:aa3b73079eff0e5b21caee387f4922e1499ad60914987a7e8002df40f776751e - - name: kind - value: task + - name: name + value: git-clone-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-git-clone-oci-ta:0.1@sha256:4bf48d038ff12d25bdeb5ab3e98dc2271818056f454c83d7393ebbd413028147 + - name: kind + value: task resolver: bundles when: - - input: $(tasks.init.results.build) - operator: in - values: - - "true" + - input: $(tasks.init.results.build) + operator: in + values: + - "true" workspaces: - - name: source - workspace: workspace-arm64 - - name: clone-repository-ppc64le + - name: basic-auth + workspace: git-auth + - name: prefetch-dependencies params: - - name: url - value: $(params.git-url) - - name: revision - value: $(params.revision) + - name: input + value: $(params.prefetch-input) + - name: SOURCE_ARTIFACT + value: $(tasks.clone-repository.results.SOURCE_ARTIFACT) + - name: ociStorage + value: $(params.output-image).prefetch + - name: ociArtifactExpiresAfter + value: $(params.image-expires-after) runAfter: - - init + - clone-repository taskRef: params: - - name: name - value: git-clone - - name: bundle - value: quay.io/redhat-appstudio-tekton-catalog/task-git-clone:0.1@sha256:a3e22f57fbf8398fbe93fbeeb38e03756cd073182d6d109fe8e8cde57b561603 - - name: kind - value: task + - name: name + value: prefetch-dependencies-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-prefetch-dependencies-oci-ta:0.1@sha256:4072f732119864d12ec8e2ff075f01487aaee9df4440166dbe85fdd447865161 + - name: kind + value: task resolver: bundles - when: - - input: $(tasks.init.results.build) - operator: in - values: - - "true" workspaces: - - name: output - workspace: workspace-ppc64le - - name: basic-auth - workspace: git-auth - - name: prefetch-dependencies-ppc64le - params: - - name: input - value: $(params.prefetch-input) - runAfter: - - clone-repository-ppc64le - taskRef: + - name: git-basic-auth + workspace: git-auth + - name: netrc + workspace: netrc + - matrix: params: - - name: name - value: prefetch-dependencies - - name: bundle - value: quay.io/redhat-appstudio-tekton-catalog/task-prefetch-dependencies:0.1@sha256:566dfa9cf802e78ee26f8aae57c70cb6aa90f84dfdc929e176db4bc67d596df4 - - name: kind - value: task - resolver: bundles - when: - - input: $(params.prefetch-input) - operator: notin - values: - - "" - workspaces: - - name: source - workspace: workspace-ppc64le - - name: git-basic-auth - workspace: git-auth - - name: build-container-ppc64le - params: - - name: IMAGE - value: $(params.output-image)-ppc64le - - name: DOCKERFILE - value: $(params.dockerfile) - - name: CONTEXT - value: $(params.path-context) - - name: HERMETIC - value: $(params.hermetic) - - name: PREFETCH_INPUT - value: $(params.prefetch-input) - - name: IMAGE_EXPIRES_AFTER - value: $(params.image-expires-after) - - name: COMMIT_SHA - value: $(tasks.clone-repository-ppc64le.results.commit) - - name: BUILD_ARGS_FILE - value: $(params.build-args-file) - name: PLATFORM - value: linux/ppc64le - runAfter: - - prefetch-dependencies-ppc64le - taskRef: - params: - - name: name - value: buildah-remote - - name: bundle - value: quay.io/redhat-appstudio-tekton-catalog/task-buildah-remote:0.2@sha256:aa3b73079eff0e5b21caee387f4922e1499ad60914987a7e8002df40f776751e - - name: kind - value: task - resolver: bundles - when: - - input: $(tasks.init.results.build) - operator: in - values: - - "true" - workspaces: - - name: source - workspace: workspace-ppc64le - - name: clone-repository-s390x - params: - - name: url - value: $(params.git-url) - - name: revision - value: $(params.revision) - runAfter: - - init - taskRef: - params: - - name: name - value: git-clone - - name: bundle - value: quay.io/redhat-appstudio-tekton-catalog/task-git-clone:0.1@sha256:a3e22f57fbf8398fbe93fbeeb38e03756cd073182d6d109fe8e8cde57b561603 - - name: kind - value: task - resolver: bundles - when: - - input: $(tasks.init.results.build) - operator: in - values: - - "true" - workspaces: - - name: output - workspace: workspace-s390x - - name: basic-auth - workspace: git-auth - - name: prefetch-dependencies-s390x + value: + - $(params.build-platforms) + name: build-images params: - - name: input - value: $(params.prefetch-input) + - name: IMAGE + value: $(params.output-image) + - name: DOCKERFILE + value: $(params.dockerfile) + - name: CONTEXT + value: $(params.path-context) + - name: HERMETIC + value: $(params.hermetic) + - name: PREFETCH_INPUT + value: $(params.prefetch-input) + - name: IMAGE_EXPIRES_AFTER + value: $(params.image-expires-after) + - name: COMMIT_SHA + value: $(tasks.clone-repository.results.commit) + - name: BUILD_ARGS + value: + - $(params.build-args[*]) + - name: BUILD_ARGS_FILE + value: $(params.build-args-file) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) + - name: IMAGE_APPEND_PLATFORM + value: "true" runAfter: - - clone-repository-s390x + - prefetch-dependencies taskRef: params: - - name: name - value: prefetch-dependencies - - name: bundle - value: quay.io/redhat-appstudio-tekton-catalog/task-prefetch-dependencies:0.1@sha256:566dfa9cf802e78ee26f8aae57c70cb6aa90f84dfdc929e176db4bc67d596df4 - - name: kind - value: task + - name: name + value: buildah-remote-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-buildah-remote-oci-ta:0.2@sha256:389e6691834144113987cd669a6b510e47d2cee55332b940eeb06ce24a9a57a2 + - name: kind + value: task resolver: bundles when: - - input: $(params.prefetch-input) - operator: notin - values: - - "" - workspaces: - - name: source - workspace: workspace-s390x - - name: git-basic-auth - workspace: git-auth - - name: build-container-s390x + - input: $(tasks.init.results.build) + operator: in + values: + - "true" + - name: build-image-index params: - - name: IMAGE - value: $(params.output-image)-s390x - - name: DOCKERFILE - value: $(params.dockerfile) - - name: CONTEXT - value: $(params.path-context) - - name: HERMETIC - value: $(params.hermetic) - - name: PREFETCH_INPUT - value: $(params.prefetch-input) - - name: IMAGE_EXPIRES_AFTER - value: $(params.image-expires-after) - - name: COMMIT_SHA - value: $(tasks.clone-repository-s390x.results.commit) - - name: BUILD_ARGS_FILE - value: $(params.build-args-file) - - name: PLATFORM - value: linux/s390x + - name: IMAGE + value: $(params.output-image) + - name: COMMIT_SHA + value: $(tasks.clone-repository.results.commit) + - name: IMAGE_EXPIRES_AFTER + value: $(params.image-expires-after) + - name: ALWAYS_BUILD_INDEX + value: $(params.build-image-index) + - name: IMAGES + value: + - $(tasks.build-images.results.IMAGE_REF[*]) runAfter: - - prefetch-dependencies-s390x + - build-images taskRef: params: - - name: name - value: buildah-remote - - name: bundle - value: quay.io/redhat-appstudio-tekton-catalog/task-buildah-remote:0.2@sha256:aa3b73079eff0e5b21caee387f4922e1499ad60914987a7e8002df40f776751e - - name: kind - value: task + - name: name + value: build-image-index + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-build-image-index:0.1@sha256:a89c141c8d35b2e9d9904c92c9b128f7ccf36681adac7f7422b4537b8bb077e7 + - name: kind + value: task resolver: bundles when: - - input: $(tasks.init.results.build) - operator: in - values: - - "true" - workspaces: - - name: source - workspace: workspace-s390x - - name: build-container - params: - - name: IMAGE - value: $(params.output-image) - - name: COMMIT_SHA - value: $(tasks.clone-repository-amd64.results.commit) - - name: IMAGES - value: - - $(tasks.build-container-amd64.results.IMAGE_URL)@$(tasks.build-container-amd64.results.IMAGE_DIGEST) - - $(tasks.build-container-arm64.results.IMAGE_URL)@$(tasks.build-container-arm64.results.IMAGE_DIGEST) - - $(tasks.build-container-s390x.results.IMAGE_URL)@$(tasks.build-container-s390x.results.IMAGE_DIGEST) - - $(tasks.build-container-ppc64le.results.IMAGE_URL)@$(tasks.build-container-ppc64le.results.IMAGE_DIGEST) - runAfter: - - build-container-amd64 - - build-container-arm64 - - build-container-s390x - - build-container-ppc64le - taskRef: - params: - - name: name - value: build-image-manifest - - name: bundle - value: quay.io/redhat-appstudio-tekton-catalog/task-build-image-manifest:0.1@sha256:2a0760e9c0ba179c233094b85b35af2fd4db9e3688c231be3cc76fa27c326ae5 - - name: kind - value: task - resolver: bundles - when: - - input: $(tasks.init.results.build) - operator: in - values: - - "true" + - input: $(tasks.init.results.build) + operator: in + values: + - "true" - name: build-source-image params: - - name: BINARY_IMAGE - value: $(params.output-image) + - name: BINARY_IMAGE + value: $(params.output-image) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) runAfter: - - build-container + - build-image-index taskRef: params: - - name: name - value: source-build - - name: bundle - value: quay.io/redhat-appstudio-tekton-catalog/task-source-build:0.1@sha256:a964e3b02902735fe7f6a5398d9a7caddf5c0a7cc9f01792c849ca6d69d5d1a1 - - name: kind - value: task + - name: name + value: source-build-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-source-build-oci-ta:0.1@sha256:6686b885af277e7b912143a080d6af7a0372a12c33d66924bbd9bb1aa4d8d0dc + - name: kind + value: task resolver: bundles when: - - input: $(tasks.init.results.build) - operator: in - values: - - "true" - - input: $(params.build-source-image) - operator: in - values: - - "true" - workspaces: - - name: workspace - workspace: workspace-amd64 + - input: $(tasks.init.results.build) + operator: in + values: + - "true" + - input: $(params.build-source-image) + operator: in + values: + - "true" - name: deprecated-base-image-check params: - - name: IMAGE_URL - value: $(tasks.build-container.results.IMAGE_URL) - - name: IMAGE_DIGEST - value: $(tasks.build-container.results.IMAGE_DIGEST) + - name: IMAGE_URL + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: IMAGE_DIGEST + value: $(tasks.build-image-index.results.IMAGE_DIGEST) runAfter: - - build-container + - build-image-index taskRef: params: - - name: name - value: deprecated-image-check - - name: bundle - value: quay.io/redhat-appstudio-tekton-catalog/task-deprecated-image-check:0.4@sha256:566ae0df80f8447558595a996627bf0b5482dc0eaa9fbc33b8154587aed51a05 - - name: kind - value: task + - name: name + value: deprecated-image-check + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-deprecated-image-check:0.4@sha256:5a1a165fa02270f0a947d8a2131ee9d8be0b8e9d34123828c2bef589e504ee84 + - name: kind + value: task resolver: bundles when: - - input: $(params.skip-checks) - operator: in - values: - - "false" + - input: $(params.skip-checks) + operator: in + values: + - "false" - name: clair-scan params: - - name: image-digest - value: $(tasks.build-container.results.IMAGE_DIGEST) - - name: image-url - value: $(tasks.build-container.results.IMAGE_URL) + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) runAfter: - - build-container + - build-image-index taskRef: params: - - name: name - value: clair-scan - - name: bundle - value: quay.io/redhat-appstudio-tekton-catalog/task-clair-scan:0.2@sha256:bcc01fe4689fbb87ca335d7efea88ec800e05d8796f0828fca984349b7844b09 - - name: kind - value: task + - name: name + value: clair-scan + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-clair-scan:0.2@sha256:0a5421111e7092740398691d5bd7c125cc0896f29531d19414bb5724ae41692a + - name: kind + value: task resolver: bundles when: - - input: $(params.skip-checks) - operator: in - values: - - "false" + - input: $(params.skip-checks) + operator: in + values: + - "false" - name: ecosystem-cert-preflight-checks params: - - name: image-url - value: $(tasks.build-container.results.IMAGE_URL) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) runAfter: - - build-container + - build-image-index taskRef: params: - - name: name - value: ecosystem-cert-preflight-checks - - name: bundle - value: quay.io/redhat-appstudio-tekton-catalog/task-ecosystem-cert-preflight-checks:0.1@sha256:13a1013abebdd8dc398c41d2c72da41664086d390ea6ab9912905c1dfee08fbf - - name: kind - value: task + - name: name + value: ecosystem-cert-preflight-checks + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-ecosystem-cert-preflight-checks:0.1@sha256:df8a25a3431a70544172ed4844f9d0c6229d39130633960729f825a031a7dea9 + - name: kind + value: task resolver: bundles when: - - input: $(params.skip-checks) - operator: in - values: - - "false" + - input: $(params.skip-checks) + operator: in + values: + - "false" - name: sast-snyk-check + params: + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) runAfter: - - build-container + - build-image-index taskRef: params: - - name: name - value: sast-snyk-check - - name: bundle - value: quay.io/redhat-appstudio-tekton-catalog/task-sast-snyk-check:0.3@sha256:4ada9949fd195b50e33605ef06bb52a9bfb523d88529392972ac7a051d5bb549 - - name: kind - value: task + - name: name + value: sast-snyk-check-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-sast-snyk-check-oci-ta:0.3@sha256:65a213322ea7c64159e37071d369d74b6378b23403150e29537865cada90f022 + - name: kind + value: task resolver: bundles when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - workspaces: - - name: workspace - workspace: workspace-amd64 - params: - - name: image-digest - value: $(tasks.build-container.results.IMAGE_DIGEST) - - name: image-url - value: $(tasks.build-container.results.IMAGE_URL) + - input: $(params.skip-checks) + operator: in + values: + - "false" - name: clamav-scan params: - - name: image-digest - value: $(tasks.build-container.results.IMAGE_DIGEST) - - name: image-url - value: $(tasks.build-container.results.IMAGE_URL) + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) runAfter: - - build-container + - build-image-index taskRef: params: - - name: name - value: clamav-scan - - name: bundle - value: quay.io/redhat-appstudio-tekton-catalog/task-clamav-scan:0.1@sha256:3e2891c232dc03fb5c7746fc615e1827afbd6931843e42b19cb8a6c04276ed32 - - name: kind - value: task + - name: name + value: clamav-scan + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-clamav-scan:0.2@sha256:6e08cf608240f57442ca5458f3c0dade3558f4f2953be8ea939232f5d5378d58 + - name: kind + value: task resolver: bundles when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - - name: sbom-json-check + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: apply-tags params: - - name: IMAGE_URL - value: $(tasks.build-container.results.IMAGE_URL) - - name: IMAGE_DIGEST - value: $(tasks.build-container.results.IMAGE_DIGEST) + - name: IMAGE + value: $(tasks.build-image-index.results.IMAGE_URL) runAfter: - - build-container + - build-image-index taskRef: params: - - name: name - value: sbom-json-check - - name: bundle - value: quay.io/redhat-appstudio-tekton-catalog/task-sbom-json-check:0.2@sha256:a8f1748144a51dbb90d140ae788a95e05d65dcdd0625efceedce2f5ae755c654 - - name: kind - value: task + - name: name + value: apply-tags + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-apply-tags:0.1@sha256:87fd7fc0e937aad1a8db9b6e377d7e444f53394dafde512d68adbea6966a4702 + - name: kind + value: task resolver: bundles - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - - name: apply-tags + - name: push-dockerfile params: - - name: IMAGE - value: $(tasks.build-container.results.IMAGE_URL) + - name: IMAGE + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: IMAGE_DIGEST + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: DOCKERFILE + value: $(params.dockerfile) + - name: CONTEXT + value: $(params.path-context) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) runAfter: - - build-container + - build-image-index taskRef: params: - - name: name - value: apply-tags - - name: bundle - value: quay.io/redhat-appstudio-tekton-catalog/task-apply-tags:0.1@sha256:362e24943d5db3e6001b079f081b575784e8f88bc6c5b64998038b55311a3306 - - name: kind - value: task + - name: name + value: push-dockerfile-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-push-dockerfile-oci-ta:0.1@sha256:80d48a1b9d2707490309941ec9f79338533938f959ca9a207b481b0e8a5e7a93 + - name: kind + value: task resolver: bundles - name: rpms-signature-scan params: - - name: image-url - value: $(tasks.build-container.results.IMAGE_URL) - - name: image-digest - value: $(tasks.build-container.results.IMAGE_DIGEST) - - name: fail-unsigned - value: true + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + runAfter: + - build-image-index taskRef: params: - name: name @@ -705,10 +348,103 @@ spec: - name: kind value: task resolver: bundles - workspaces: - - name: workspace-amd64 - - name: workspace-arm64 - - name: workspace-ppc64le - - name: workspace-s390x + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + params: + - description: Source Repository URL + name: git-url + type: string + - default: "" + description: Revision of the Source Repository + name: revision + type: string + - description: Fully Qualified Output Image + name: output-image + type: string + - default: . + description: Path to the source code of an application's component from where + to build image. + name: path-context + type: string + - default: Dockerfile + description: Path to the Dockerfile inside the context specified by parameter + path-context + name: dockerfile + type: string + - default: "false" + description: Force rebuild image + name: rebuild + type: string + - default: "false" + description: Skip checks against built image + name: skip-checks + type: string + - default: "false" + description: Execute the build with network isolation + name: hermetic + type: string + - default: "" + description: Build dependencies to be prefetched by Cachi2 + name: prefetch-input + type: string + - default: "" + description: Image tag expiration time, time values could be something like + 1h, 2d, 3w for hours, days, and weeks, respectively. + name: image-expires-after + - default: "false" + description: Build a source image. + name: build-source-image + type: string + - default: "true" + description: Add built image into an OCI image index + name: build-image-index + type: string + - default: [] + description: Array of --build-arg values ("arg=value" strings) for buildah + name: build-args + type: array + - default: "" + description: Path to a file with build arguments for buildah, see https://www.mankier.com/1/buildah-build#--build-arg-file + name: build-args-file + type: string + - default: + - linux/x86_64 + description: List of platforms to build the container images on. The available + set of values is determined by the configuration of the multi-platform-controller. + name: build-platforms + type: array + workspaces: - name: git-auth optional: true + - name: netrc + optional: true + results: + - description: "" + name: IMAGE_URL + value: $(tasks.build-image-index.results.IMAGE_URL) + - description: "" + name: IMAGE_DIGEST + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - description: "" + name: CHAINS-GIT_URL + value: $(tasks.clone-repository.results.url) + - description: "" + name: CHAINS-GIT_COMMIT + value: $(tasks.clone-repository.results.commit) + # finally: + # - name: show-sbom + # params: + # - name: IMAGE_URL + # value: $(tasks.build-image-index.results.IMAGE_URL) + # taskRef: + # params: + # - name: name + # value: show-sbom + # - name: bundle + # value: quay.io/konflux-ci/tekton-catalog/task-show-sbom:0.1@sha256:945a7c9066d3e0a95d3fddb7e8a6992e4d632a2a75d8f3a9bd2ff2fef0ec9aa0 + # - name: kind + # value: task + # resolver: bundles \ No newline at end of file diff --git a/.tekton/oras-container-pull-request.yaml b/.tekton/oras-container-pull-request.yaml index bb1997c..1c52c6e 100644 --- a/.tekton/oras-container-pull-request.yaml +++ b/.tekton/oras-container-pull-request.yaml @@ -30,41 +30,15 @@ spec: value: . - name: revision value: '{{revision}}' + - name: build-platforms + value: + - localhost + - linux/arm64 + - linux/ppc64le + - linux/s390x pipelineRef: name: build-pipeline workspaces: - - name: workspace-amd64 - volumeClaimTemplate: - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi - - name: workspace-arm64 - volumeClaimTemplate: - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi - - name: workspace-ppc64le - volumeClaimTemplate: - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi - - name: workspace-s390x - volumeClaimTemplate: - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi - - name: git-auth - secret: - secretName: '{{ git_auth_secret }}' + - name: git-auth + secret: + secretName: '{{ git_auth_secret }}' diff --git a/.tekton/oras-container-push.yaml b/.tekton/oras-container-push.yaml index 2ed6dd4..6539d24 100644 --- a/.tekton/oras-container-push.yaml +++ b/.tekton/oras-container-push.yaml @@ -27,41 +27,15 @@ spec: value: . - name: revision value: '{{revision}}' + - name: build-platforms + value: + - localhost + - linux/arm64 + - linux/ppc64le + - linux/s390x pipelineRef: name: build-pipeline workspaces: - - name: workspace-amd64 - volumeClaimTemplate: - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi - - name: workspace-arm64 - volumeClaimTemplate: - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi - - name: workspace-ppc64le - volumeClaimTemplate: - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi - - name: workspace-s390x - volumeClaimTemplate: - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi - - name: git-auth - secret: - secretName: '{{ git_auth_secret }}' + - name: git-auth + secret: + secretName: '{{ git_auth_secret }}' From 902cfe99a808e78a08a796f56571c0e12a08024c Mon Sep 17 00:00:00 2001 From: arewm Date: Thu, 21 Nov 2024 16:05:18 -0500 Subject: [PATCH 2/2] Add attach helper script In order to make oras attach operations easier, an attach script has been added with a modified interface. This includes: * Auto-selecting the oci auth for repository-specific tokens * Use of a common artifactType * Storing the digest of the produced manifest An additional helper script is added, get-reference-base.sh, to provide a common way to remove tags and digests from OCI object references. Signed-off-by: arewm --- .tekton/test.yaml | 221 ++++++++++++++++++++++++++++++++++++- Containerfile | 21 ++-- hack/attach.sh | 121 ++++++++++++++++++++ hack/get-reference-base.sh | 38 +++++++ hack/oras-options.sh | 11 ++ hack/select-oci-auth.sh | 7 +- 6 files changed, 400 insertions(+), 19 deletions(-) create mode 100755 hack/attach.sh create mode 100755 hack/get-reference-base.sh create mode 100755 hack/oras-options.sh diff --git a/.tekton/test.yaml b/.tekton/test.yaml index 213f569..9e9e870 100644 --- a/.tekton/test.yaml +++ b/.tekton/test.yaml @@ -15,15 +15,19 @@ spec: params: - name: SNAPSHOT steps: - - image: registry.redhat.io/openshift4/ose-cli:latest + - name: test + image: registry.redhat.io/openshift4/ose-cli:latest env: - name: SNAPSHOT value: $(params.SNAPSHOT) script: | + #!/bin/bash echo -e "Grabbing a copy of yq" oc image extract --confirm quay.io/konflux-ci/yq:latest --path=/usr/bin/yq:/usr/bin/. && chmod +x /usr/bin/yq echo -e "Testing Snapshot:\n ${SNAPSHOT}" + TESTS_FAILED="false" + failure_num=0 IMAGE=$(echo ${SNAPSHOT} | yq -r '.components[].containerImage') echo -e "Found image ${IMAGE}" @@ -33,28 +37,233 @@ spec: oc image extract --confirm ${IMAGE} --path=/usr/bin/yq:/usr/bin/. && chmod +x /usr/bin/yq oc image extract --confirm ${IMAGE} --path=/usr/local/bin/retry:/usr/local/bin/. && chmod +x /usr/local/bin/retry oc image extract --confirm ${IMAGE} --path=/usr/local/bin/select-oci-auth:/usr/local/bin/. && chmod +x /usr/local/bin/select-oci-auth + oc image extract --confirm ${IMAGE} --path=/usr/local/bin/attach-helper:/usr/local/bin/. && chmod +x /usr/local/bin/attach-helper + oc image extract --confirm ${IMAGE} --path=/usr/local/bin/oras-options:/usr/local/bin/. && chmod +x /usr/local/bin/oras-options + oc image extract --confirm ${IMAGE} --path=/usr/local/bin/get-reference-base:/usr/local/bin/. && chmod +x /usr/local/bin/get-reference-base REPO=$(echo ${IMAGE} | awk -F '@' '{ print $1 }') TAG="$(echo ${IMAGE} | awk -F '@' '{print $2 }' | sed s/:/-/).test" + ## Test isolating the OCI object registry and repository + echo -n "quay.io/test/foo" > base_reference + echo -n "quay.io:443/test/foo" > base_reference_port + get-reference-base quay.io:443/test/foo:bar > test_base1 + get-reference-base quay.io:443/test/foo@sha256:aaaa > test_base2 + get-reference-base quay.io:443/test/foo:bar@sha256:aaaa > test_base3 + get-reference-base quay.io/test/foo:bar@sha256:aaaa > test_base4 + get-reference-base quay.io/test/foo:bar > test_base5 + get-reference-base quay.io/test/foo@sha256:aaaa > test_base6 + + if [[ $(cmp -s base_reference_port test_base1) -ne 0 ]]; then + echo "ERROR: Incorrect reference isolation with registry port and tag" + TESTS_FAILED="true" + failure_num=$((failure_num + 1)) + fi + if [[ $(cmp -s base_reference_port test_base2) -ne 0 ]]; then + echo "ERROR: Incorrect reference isolation with registry port and digest" + TESTS_FAILED="true" + failure_num=$((failure_num + 1)) + fi + if [[ $(cmp -s base_reference_port test_base3) -ne 0 ]]; then + echo "ERROR: Incorrect reference isolation with registry port, tag, and digest" + TESTS_FAILED="true" + failure_num=$((failure_num + 1)) + fi + if [[ $(cmp -s base_reference test_base4) -ne 0 ]]; then + echo "ERROR: Incorrect reference isolation with tag and digest" + TESTS_FAILED="true" + failure_num=$((failure_num + 1)) + fi + if [[ $(cmp -s base_reference test_base5) -ne 0 ]]; then + echo "ERROR: Incorrect reference isolation with tag" + TESTS_FAILED="true" + failure_num=$((failure_num + 1)) + fi + if [[ $(cmp -s base_reference test_base6) -ne 0 ]]; then + echo "ERROR: Incorrect reference isolation with digest" + TESTS_FAILED="true" + failure_num=$((failure_num + 1)) + fi + + ## Test isolating registry auth and pushing echo "Extracting relevant OCI auth for $REPO" select-oci-auth $REPO > auth.json + # Test pushing directly with oras echo "Pushing foo.txt to $REPO:$TAG" echo -n "hello world" > foo.txt oras push --no-tty --registry-config auth.json $REPO:$TAG foo.txt:text/plain - rm foo.txt + mv foo.txt check.txt + # Test pulling directly with oras, ensuring that the file content is unchanged echo "Pulling foo.txt to $REPO:$TAG" oras pull --no-tty --registry-config auth.json $REPO:$TAG OUTPUT=$(cat foo.txt) - echo "Expecting hello world" - echo "Received ${OUTPUT}" + diff foo.txt check.txt > diff.txt + if [ $? -eq 0 ]; then + echo "Recieved the expected output" + else + TESTS_FAILED="true" + failure_num=$((failure_num + 1)) + echo "ERROR: Expecting hello world" + echo "Received ${OUTPUT}" + fi + + ## Test attaching simple files + attach-helper --subject $REPO:$TAG --digestfile foo-digest.txt foo.txt + attach-helper --subject $REPO:$TAG --artifact-type "application/vnd.konflux-ci.test-artifact" --media-type-name "foobar" check.txt - if [ "$OUTPUT" == "hello world" ]; then - exit 0 + ## Ensure that the files are unmodified and that the digest is set properly + diff foo.txt check.txt > diff.txt + if [ ! $? -eq 0 ]; then + TESTS_FAILED="true" + failure_num=$((failure_num + 1)) + echo "ERROR: Files were modified when attaching." + fi + + ## Check to make sure that all attachments have happened properly. Looking at both the total number + ## and the number for each artifact type (one custom, one default) + mkdir discoveries + oras discover -v --format tree $REPO:$TAG | tee discoveries/all_attached + oras discover -v --format tree --artifact-type "application/vnd.konflux-ci.attached-artifact" $REPO:$TAG > discoveries/default_attached + oras discover -v --format tree --artifact-type "application/vnd.konflux-ci.test-artifact" $REPO:$TAG > discoveries/custom_attached + + if [[ "$(cat discoveries/all_attached | wc -l)" == "7" ]]; then + echo "Two artifacts attached" else + echo "ERROR: All attached artifacts not found" + TESTS_FAILED="true" + failure_num=$((failure_num + 1)) + fi + if [[ "$(cat discoveries/default_attached | wc -l)" == "4" ]]; then + echo "One artifact attached with type application/vnd.konflux-ci.attached-artifact" + else + echo "ERROR: Artifact attachment application/vnd.konflux-ci.attached-artifact not found" + TESTS_FAILED="true" + failure_num=$((failure_num + 1)) + fi + if [[ "$(cat discoveries/custom_attached | wc -l)" == "4" ]]; then + echo "One artifact attached with type application/vnd.konflux-ci.test-artifact" + else + echo "ERROR: Artifact attachment application/vnd.konflux-ci.test-artifact not found" + TESTS_FAILED="true" + failure_num=$((failure_num + 1)) + fi + + ## Check to make sure that we have found each of the media types used. One is custom, another is auto. + oras manifest fetch --pretty $REPO:$TAG + referenced_artifacts=$( oras discover --format json $REPO:$TAG | yq -e '.manifests[].reference') + found_type1="false" + found_type2="false" + echo "Looking at mediaType for all referenced artifacts" + for artifact in ${referenced_artifacts[@]}; do + oras manifest fetch --pretty $artifact + mediaType=$(oras manifest fetch --pretty $artifact | yq -e '.layers[].mediaType') + if [[ "$mediaType" == "application/vnd.konflux-ci.attached-artifact.foo+txt" ]]; then + found_type1="true" + fi + if [[ "$mediaType" == "application/vnd.konflux-ci.test-artifact.foobar" ]]; then + found_type2="true" + fi + done + if [[ "$found_type1" == "true" ]]; then + echo "Found one application/vnd.konflux-ci.attached-artifact.foo+txt mediaType" + else + echo "ERROR: Didn't find application/vnd.konflux-ci.attached-artifact.foo+txt mediaType" + TESTS_FAILED="true" + failure_num=$((failure_num + 1)) + fi + if [[ "$found_type2" == "true" ]]; then + echo "Found one application/vnd.konflux-ci.test-artifact.foobar mediaType" + else + echo "ERROR: Didn't find application/vnd.konflux-ci.test-artifact.foobar mediaType" + TESTS_FAILED="true" + failure_num=$((failure_num + 1)) + fi + + ## Test to make sure that digest matches + digest_pullspec=$(oras discover --format json --artifact-type "application/vnd.konflux-ci.attached-artifact" $REPO:$TAG | yq -e '.manifests[].reference') + digestfile_content=$(cat foo-digest.txt) + if [ "${digest_pullspec}" == "${REPO}@sha256:${digestfile_content}" ]; then + echo "Digestfile properly created" + else + echo "ERROR: Reported digest ${digestfile_content} doesn't match ${digest_pullspec}" + cat foo-digest.txt + TESTS_FAILED="true" + failure_num=$((failure_num + 1)) + fi + + # Test attaching directories + attach-helper --subject $REPO:$TAG --artifact-type "application/vnd.konflux-ci.test-directory" --digestfile discoveries-digest.txt discoveries + mv discoveries discoveries-reference + + ## Ensure that the the artifact (custom) and media (auto) types are as expected for directories + directory_digest=$(cat discoveries-digest.txt) + oras discover --format json --artifact-type "application/vnd.konflux-ci.test-directory" $REPO:$TAG | yq -e '.manifests[].reference' > referenced_directory_artifacts + if [ ! "$(cat referenced_directory_artifacts | wc -l)" == "1" ]; then + echo "ERROR: Improper number of referenced artifacts for type application/vnd.konflux-ci.test-directory" + cat referenced_directory_artifacts + TESTS_FAILED="true" + failure_num=$((failure_num + 1)) + fi + artifactType=$(oras manifest fetch --pretty $(cat referenced_directory_artifacts | head -n 1) | yq -e '.artifactType') + mediaType=$(oras manifest fetch --pretty $(cat referenced_directory_artifacts | head -n 1) | yq -e '.layers[].mediaType') + if [[ "$artifactType" == "application/vnd.konflux-ci.test-directory" ]]; then + echo "Directory artifactType matches" + else + echo "ERROR: Directory artifact type was ${artifactType}/nexpected: application/vnd.konflux-ci.test-directory" + TESTS_FAILED="true" + failure_num=$((failure_num + 1)) + fi + if [[ "$mediaType" == "application/vnd.konflux-ci.test-directory.discoveries" ]]; then + echo "Directory mediaType matches" + else + echo "ERROR: Directory media type was ${mediaType}/nexpected: application/vnd.konflux-ci.test-directory.discoveries" + TESTS_FAILED="true" + failure_num=$((failure_num + 1)) + fi + + # Ensure that the manifest digest matches for a directory + directory_shasum=$(oras manifest fetch $(cat referenced_directory_artifacts | head -n 1) | sha256sum | tr -d "[:space:]-") + if [ "${directory_shasum}" == "${directory_digest}" ]; then + echo "Directory blob digests match" + else + echo "ERROR: Directory blob digest does not match returned value" + TESTS_FAILED="true" + failure_num=$((failure_num + 1)) + fi + + ## Ensure that directory content matches + oras pull ${REPO}@sha256:${directory_digest} + diff discoveries discoveries-reference > dir_diff.txt + if [ $? -eq 0 ]; then + echo "Fetched directory matches" + else + TESTS_FAILED="true" + failure_num=$((failure_num + 1)) + echo "ERROR: Fetched directory does not match" + cat dir_diff.txt + fi + + ## No need to test this right now. If it doesn't work, the script will error out. If it does, we will support it! + # ## Test attaching multiple files + # echo "one" > one.txt + # echo "two" > two.txt + # attach-helper --subject $REPO:$TAG --artifact-type "application/vnd.konflux-ci.multiple-artifacts" one.txt two.txt 2>/dev/null + # if [ "$?" == "2" ]; then + # echo "Attaching multiple artifacts correctly failed." + # else + # echo "ERROR: We shouldn't be able to attach multiple artifacts" + # TESTS_FAILED="true" + # failure_num=$((failure_num + 1)) + # fi + + if [ "$TESTS_FAILED" == "true" ]; then + echo "$failure_num tests failed." exit 1 + else + echo "All tests passed, congrats!" + exit 0 fi diff --git a/Containerfile b/Containerfile index 752fa17..bb32f52 100644 --- a/Containerfile +++ b/Containerfile @@ -11,27 +11,32 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM brew.registry.redhat.io/rh-osbs/openshift-golang-builder:rhel_9_1.22 as builder +ARG ORASPKG=/oras + +FROM registry.access.redhat.com/ubi9/go-toolset:1.22.5 as builder ARG TARGETPLATFORM +ARG ORASPKG #RUN dnf -y install git make && dnf -y clean all -ENV ORASPKG /oras -ADD . ${ORASPKG} -WORKDIR ${ORASPKG}/oras +ADD --chown=default oras ${ORASPKG} +WORKDIR ${ORASPKG} RUN go mod vendor RUN make "build-$(echo $TARGETPLATFORM | sed s/\\/v8// | tr / -)" -RUN mv ${ORASPKG}/oras/bin/$(echo $TARGETPLATFORM | sed s/\\/v8//)/oras /usr/bin/oras -RUN mkdir /licenses && mv LICENSE /licenses/LICENSE +RUN mv ${ORASPKG}/bin/$(echo $TARGETPLATFORM | sed s/\\/v8//)/oras ${ORASPKG}/bin/oras FROM quay.io/konflux-ci/yq:latest@sha256:15a4bff3229069034b1fc7d6d3a7c9b06edf8c1c5f6f27d49bf4b31de823168a as yq FROM registry.access.redhat.com/ubi9:latest@sha256:1057dab827c782abcfb9bda0c3900c0966b5066e671d54976a7bcb3a2d1a5e53 +ARG ORASPKG RUN mkdir /licenses RUN useradd -r --uid=65532 --create-home --shell /bin/bash oras COPY --from=yq /usr/bin/yq /usr/bin/yq -COPY --from=builder /usr/bin/oras /usr/bin/oras -COPY --from=builder /licenses/LICENSE /licenses/LICENSE +COPY --from=builder ${ORASPKG}/bin/oras /usr/bin/oras +COPY --from=builder ${ORASPKG}/LICENSE /licenses/LICENSE +COPY hack/attach.sh /usr/local/bin/attach-helper +COPY hack/get-reference-base.sh /usr/local/bin/get-reference-base +COPY hack/oras-options.sh /usr/local/bin/oras-options COPY hack/retry.sh /usr/local/bin/retry COPY hack/select-oci-auth.sh /usr/local/bin/select-oci-auth diff --git a/hack/attach.sh b/hack/attach.sh new file mode 100755 index 0000000..35979e0 --- /dev/null +++ b/hack/attach.sh @@ -0,0 +1,121 @@ +#!/bin/bash +# Helper function to use oras attach +# +# This script can be used to easily attach artifacts. It will reduce the authentication scope +# so that oras will work when there are repository-specific tokens. It also provides a template +# for specifying the artifactType when attaching. +# +# The --subject parameter is the subject to attach the artifact to, e.g. +# registry.local/org/repo. +# +# The --artifact-type (optional) parameter can be used to define an artifactType for the attached artifact. +# If absent, "application/vnd.konflux-ci.attached-artifact" will be used. +# +# The --media-type-name (optional) parameter can be used to define a mediaType for the attached artifact. +# The type will be appended to the artifact type as determined from the "--artifact-type" parameter. If +# absent, the filename+extension will be used. +# +# The --distribution-spec (optional) parameter can be used to use a specific distribution spec. Oras supports +# the values `v1.1-referrers-api` and `v1.1-referrers-tag`. If absent the system default will be used. +# +# The --digestfile (optional) parameter can be used to provide a file to store the digest for the pushed +# image manifest. This will NOT be the digest of the attached artifact blob itself. +# +# Positional parameters are artifacts that need to be attached. These are either relative or absolute path strings. +# Only one artifact can be attached per invocation. +# +# NOTE: if a directory is passed, timestamps are not modified in the gzipped directory. +# +# Example: +# attach.sh --subject quay.io:443/arewm/foo:bar local.file + +set -o errexit +set -o nounset +set -o pipefail + +# contains pairs of artifacts to attach and (optionally) paths to output the blob digest +artifacts=() +artifact_type="application/vnd.konflux-ci.attached-artifact" +# distribution_spec="v1.1-referrers-api" +distribution_spec="" +media_type_name="" +digest_file="/dev/null" + +while [[ $# -gt 0 ]]; do + case $1 in + --subject) + subject="$2" + shift + shift + ;; + --artifact-type) + artifact_type="$2" + shift + shift + ;; + --media-type-name) + media_type_name="$2" + shift + shift + ;; + --distribution-spec) + distribution_spec="$2" + shift + shift + ;; + --digestfile) + digest_file="$2" + shift + shift + ;; + -*) + >&2 echo "Unknown option $1" + exit 1 + ;; + *) + artifacts+=("$1") + shift + ;; + esac +done + +if [[ -z "${subject:-}" ]]; then + >&2 echo "ERROR: --subject cannot be empty when attaching OCI artifacts" + exit 1 +fi + +if [ ${#artifacts[@]} != 1 ]; then + >&2 echo "ERROR: Only one artifact can be attached: found ${#artifacts[@]}" + exit 2 +fi + +# read in any oras options +source oras-options + +artifact="${artifacts[0]}" +# change to the artifact directory so we don't have to use absolute paths +pushd "$(dirname ${artifact})" > /dev/null +media_type="${artifact_type}" +file_name="$(basename ${artifact})" +if [ -n "${media_type_name}" ]; then + media_type="${artifact_type}.${media_type_name}" +else + file_base="${file_name%.*}" + file_extension="${file_name##*.}" + type_descriptor="${file_base}" + if [[ "${file_base}" != "${file_extension}" ]]; then + type_descriptor="${file_base}+${file_extension}" + fi + media_type="${artifact_type}.${type_descriptor}" +fi +echo "attaching artifact:" +echo "${file_name}:${media_type}" +use_distribution_spec=() +if [ -n "${distribution_spec}" ]; then + use_distribution_spec+=(--distribution-spec ${distribution_spec}) +fi +oras attach "${oras_opts[@]}" --no-tty --registry-config <(select-oci-auth ${subject}) --artifact-type "${artifact_type}" \ + "${use_distribution_spec[@]}" "${subject}" "${file_name}:${media_type}" | tail -n 1 | cut -d: -f3 > "${digest_file}" +popd > /dev/null + +echo 'Artifacts attached' diff --git a/hack/get-reference-base.sh b/hack/get-reference-base.sh new file mode 100755 index 0000000..2fe1c3e --- /dev/null +++ b/hack/get-reference-base.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# Outputs the registry and repository for an OCI object reference +# +# An OCI object reference can contain a registry port, tag, and digest in addition to the repository itself. +# Some scripts might handle the definition of an object reference differently and ignore various parts of the +# [specification](https://github.com/opencontainers/distribution-spec/blob/main/spec.md) +# +# Usage: +# get-reference-base.sh +# +# Example: +# get-reference-base.sh quay.io:443/arewm/foo:bar +# +set -o errexit +set -o nounset +set -o pipefail + +original_ref="$1" + +# Trim off digest +repo="$(echo -n $original_ref | cut -d@ -f1)" +if [[ $(echo -n "$repo" | tr -cd ":" | wc -c | tr -d '[:space:]') == 2 ]]; then + # format is now registry:port/repository:tag + # trim off everything after the last colon + repo=${repo%:*} +elif [[ $(echo -n "$repo" | tr -cd ":" | wc -c | tr -d '[:space:]') == 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 + repo=$(echo -n "$repo" | cut -d: -f1) + fi +fi + +echo -n "$repo" diff --git a/hack/oras-options.sh b/hack/oras-options.sh new file mode 100755 index 0000000..c643d4a --- /dev/null +++ b/hack/oras-options.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +oras_opts=(${ORAS_OPTIONS:-}) + +if [[ -v CA_FILE ]]; then + oras_opts+=(--ca-file=${CA_FILE}) +fi + +if [[ -v DEBUG ]]; then + oras_opts+=(--debug) +fi diff --git a/hack/select-oci-auth.sh b/hack/select-oci-auth.sh index e75dcc1..2a5476a 100755 --- a/hack/select-oci-auth.sh +++ b/hack/select-oci-auth.sh @@ -22,11 +22,8 @@ set -o pipefail original_ref="$1" -# Remove digest from image reference -ref="${original_ref/@*}" - -# Remove tag from image reference while making sure optional registry port is taken into account -ref="$(echo -n $ref | sed 's_/\(.*\):\(.*\)_/\1_g')" +# Get the OCI object reference without a tag and digest +ref="$(get-reference-base ${original_ref})" registry="${ref/\/*}"