From bde32c297b153c393f1b2de400d06a0f7079b038 Mon Sep 17 00:00:00 2001 From: Ales Raszka Date: Wed, 20 Nov 2024 16:14:32 +0100 Subject: [PATCH] Add image reference to SBOM The SBOM generated by the buildah task now contains the reference to the image itself. The new script supports both spdx and cyclonedx format. In order to inject the image reference to the SBOM steps were rearanged to push first and then generate SBOM. The code that stored the sbom into image itself was removed as not used anymore. JIRA: ISV-5411 Signed-off-by: Ales Raszka --- task/buildah-oci-ta/0.2/buildah-oci-ta.yaml | 175 ++++++++-------- .../0.2/buildah-remote-oci-ta.yaml | 193 +++++++++-------- task/buildah-remote/0.2/buildah-remote.yaml | 197 +++++++++--------- task/buildah/0.2/README.md | 78 +++---- task/buildah/0.2/buildah.yaml | 184 ++++++++-------- 5 files changed, 439 insertions(+), 388 deletions(-) diff --git a/task/buildah-oci-ta/0.2/buildah-oci-ta.yaml b/task/buildah-oci-ta/0.2/buildah-oci-ta.yaml index a9dc0ed2b6..8b866a69d2 100644 --- a/task/buildah-oci-ta/0.2/buildah-oci-ta.yaml +++ b/task/buildah-oci-ta/0.2/buildah-oci-ta.yaml @@ -7,7 +7,7 @@ metadata: tekton.dev/pipelines.minVersion: 0.12.1 tekton.dev/tags: image-build, konflux labels: - app.kubernetes.io/version: "0.2" + app.kubernetes.io/version: 0.2.1 build.appstudio.redhat.com/build_type: docker spec: description: |- @@ -546,80 +546,7 @@ spec: capabilities: add: - SETFCAP - - name: sbom-syft-generate - image: registry.access.redhat.com/rh-syft-tech-preview/syft-rhel9:1.4.1@sha256:34d7065427085a31dc4949bd283c001b91794d427e1e4cdf1b21ea4faf9fee3f - workingDir: /var/workdir/source - volumeMounts: - - mountPath: /var/lib/containers - name: varlibcontainers - - mountPath: /shared - name: shared - script: | - echo "Running syft on the source directory" - syft dir:"/var/workdir/$SOURCE_CODE_DIR/$CONTEXT" --output cyclonedx-json="/var/workdir/sbom-source.json" - echo "Running syft on the image filesystem" - syft dir:"$(cat /shared/container_path)" --output cyclonedx-json="/var/workdir/sbom-image.json" - computeResources: - limits: - cpu: "2" - memory: 4Gi - requests: - cpu: 500m - memory: 1Gi - - name: analyse-dependencies-java-sbom - image: quay.io/redhat-appstudio/hacbs-jvm-build-request-processor:127ee0c223a2b56a9bd20a6f2eaeed3bd6015f77 - volumeMounts: - - mountPath: /var/lib/containers - name: varlibcontainers - - mountPath: /shared - name: shared - script: | - if [ -f /var/lib/containers/java ]; then - /opt/jboss/container/java/run/run-java.sh analyse-dependencies path $(cat /shared/container_path) -s /var/workdir/sbom-image.json --task-run-name $(context.taskRun.name) --publishers $(results.SBOM_JAVA_COMPONENTS_COUNT.path) - sed -i 's/^/ /' $(results.SBOM_JAVA_COMPONENTS_COUNT.path) # Workaround for SRVKP-2875 - else - touch $(results.JAVA_COMMUNITY_DEPENDENCIES.path) - fi - computeResources: - limits: - cpu: 200m - memory: 512Mi - requests: - cpu: 100m - memory: 256Mi - securityContext: - runAsUser: 0 - - name: prepare-sboms - image: quay.io/redhat-appstudio/sbom-utility-scripts-image@sha256:ff25ba051a6d583e5b85e635d39f0e804e2ac65def51ba17b0d487a1c00ce9cd - workingDir: /var/workdir - script: | - echo "Merging contents of sbom-source.json and sbom-image.json into sbom-cyclonedx.json" - python3 /scripts/merge_syft_sboms.py - - if [ -f "sbom-cachi2.json" ]; then - echo "Merging contents of sbom-cachi2.json into sbom-cyclonedx.json" - python3 /scripts/merge_cachi2_sboms.py sbom-cachi2.json sbom-cyclonedx.json >sbom-temp.json - mv sbom-temp.json sbom-cyclonedx.json - fi - - echo "Creating sbom-purl.json" - python3 /scripts/create_purl_sbom.py - - echo "Adding base images data to sbom-cyclonedx.json" - python3 /scripts/base_images_sbom_script.py \ - --sbom=sbom-cyclonedx.json \ - --base-images-from-dockerfile=/shared/base_images_from_dockerfile \ - --base-images-digests=/shared/base_images_digests - computeResources: - limits: - cpu: 200m - memory: 512Mi - requests: - cpu: 100m - memory: 256Mi - securityContext: - runAsUser: 0 - - name: inject-sbom-and-push + - name: push image: quay.io/konflux-ci/buildah-task:latest@sha256:b2d6c32d1e05e91920cd4475b2761d58bb7ee11ad5dff3ecb59831c7572b4d0c workingDir: /var/workdir volumeMounts: @@ -655,7 +582,6 @@ spec: base_image_name=$(buildah inspect --format '{{ index .ImageAnnotations "org.opencontainers.image.base.name"}}' $IMAGE | cut -f1 -d'@') base_image_digest=$(buildah inspect --format '{{ index .ImageAnnotations "org.opencontainers.image.base.digest"}}' $IMAGE) container=$(buildah from --pull-never $IMAGE) - buildah copy $container sbom-cyclonedx.json sbom-purl.json /root/buildinfo/content_manifests/ buildah config -a org.opencontainers.image.base.name=${base_image_name} -a org.opencontainers.image.base.digest=${base_image_digest} $container BUILDAH_ARGS=() @@ -689,12 +615,6 @@ spec: echo -n "${IMAGE}@" cat "/var/workdir/image-digest" } >"$(results.IMAGE_REF.path)" - - # Remove tag from IMAGE while allowing registry to contain a port number. - sbom_repo="${IMAGE%:*}" - sbom_digest="$(sha256sum sbom-cyclonedx.json | cut -d' ' -f1)" - # The SBOM_BLOB_URL is created by `cosign attach sbom`. - echo -n "${sbom_repo}@sha256:${sbom_digest}" | tee "$(results.SBOM_BLOB_URL.path)" computeResources: limits: cpu: "4" @@ -707,6 +627,91 @@ spec: add: - SETFCAP runAsUser: 0 + - name: sbom-syft-generate + image: registry.access.redhat.com/rh-syft-tech-preview/syft-rhel9:1.4.1@sha256:34d7065427085a31dc4949bd283c001b91794d427e1e4cdf1b21ea4faf9fee3f + workingDir: /var/workdir/source + volumeMounts: + - mountPath: /var/lib/containers + name: varlibcontainers + - mountPath: /shared + name: shared + script: | + echo "Running syft on the source directory" + syft dir:"/var/workdir/$SOURCE_CODE_DIR/$CONTEXT" --output cyclonedx-json="/var/workdir/sbom-source.json" + echo "Running syft on the image filesystem" + syft dir:"$(cat /shared/container_path)" --output cyclonedx-json="/var/workdir/sbom-image.json" + computeResources: + limits: + cpu: "2" + memory: 4Gi + requests: + cpu: 500m + memory: 1Gi + - name: analyse-dependencies-java-sbom + image: quay.io/redhat-appstudio/hacbs-jvm-build-request-processor:127ee0c223a2b56a9bd20a6f2eaeed3bd6015f77 + volumeMounts: + - mountPath: /var/lib/containers + name: varlibcontainers + - mountPath: /shared + name: shared + script: | + if [ -f /var/lib/containers/java ]; then + /opt/jboss/container/java/run/run-java.sh analyse-dependencies path $(cat /shared/container_path) -s /var/workdir/sbom-image.json --task-run-name $(context.taskRun.name) --publishers $(results.SBOM_JAVA_COMPONENTS_COUNT.path) + sed -i 's/^/ /' $(results.SBOM_JAVA_COMPONENTS_COUNT.path) # Workaround for SRVKP-2875 + else + touch $(results.JAVA_COMMUNITY_DEPENDENCIES.path) + fi + computeResources: + limits: + cpu: 200m + memory: 512Mi + requests: + cpu: 100m + memory: 256Mi + securityContext: + runAsUser: 0 + - name: prepare-sboms + image: quay.io/redhat-appstudio/sbom-utility-scripts-image@sha256:11851ba63f63dfdcf722e47993f41a1f5f31a7a0dc8aa85b810ce2466daf23af + workingDir: /var/workdir + script: | + echo "Merging contents of sbom-source.json and sbom-image.json into sbom-cyclonedx.json" + python3 /scripts/merge_syft_sboms.py + + if [ -f "sbom-cachi2.json" ]; then + echo "Merging contents of sbom-cachi2.json into sbom-cyclonedx.json" + python3 /scripts/merge_cachi2_sboms.py sbom-cachi2.json sbom-cyclonedx.json >sbom-temp.json + mv sbom-temp.json sbom-cyclonedx.json + fi + + echo "Creating sbom-purl.json" + python3 /scripts/create_purl_sbom.py + + echo "Adding base images data to sbom-cyclonedx.json" + python3 /scripts/base_images_sbom_script.py \ + --sbom=sbom-cyclonedx.json \ + --base-images-from-dockerfile=/shared/base_images_from_dockerfile \ + --base-images-digests=/shared/base_images_digests + + echo "Adding image reference to sbom" + IMAGE_URL="$(cat "$(results.IMAGE_URL.path)")" + IMAGE_DIGEST="$(cat "$(results.IMAGE_DIGEST.path)")" + + python3 /scripts/add_image_reference.py \ + --image-url "$IMAGE_URL" \ + --image-digest "$IMAGE_DIGEST" \ + --input-file sbom-cyclonedx.json \ + --output-file /tmp/sbom-cyclonedx.tmp.json + + mv /tmp/sbom-cyclonedx.tmp.json sbom-cyclonedx.json + computeResources: + limits: + cpu: 200m + memory: 512Mi + requests: + cpu: 100m + memory: 256Mi + securityContext: + runAsUser: 0 - name: upload-sbom image: quay.io/konflux-ci/appstudio-utils:48c311af02858e2422d6229600e9959e496ddef1@sha256:91ddd999271f65d8ec8487b10f3dd378f81aa894e11b9af4d10639fd52bba7e8 workingDir: /var/workdir @@ -723,6 +728,12 @@ spec: fi cosign attach sbom --sbom sbom-cyclonedx.json --type cyclonedx "$(cat "$(results.IMAGE_REF.path)")" + + # Remove tag from IMAGE while allowing registry to contain a port number. + sbom_repo="${IMAGE%:*}" + sbom_digest="$(sha256sum sbom-cyclonedx.json | cut -d' ' -f1)" + # The SBOM_BLOB_URL is created by `cosign attach sbom`. + echo -n "${sbom_repo}@sha256:${sbom_digest}" | tee "$(results.SBOM_BLOB_URL.path)" computeResources: limits: cpu: 200m diff --git a/task/buildah-remote-oci-ta/0.2/buildah-remote-oci-ta.yaml b/task/buildah-remote-oci-ta/0.2/buildah-remote-oci-ta.yaml index 98e7b72cc5..a2df0b9277 100644 --- a/task/buildah-remote-oci-ta/0.2/buildah-remote-oci-ta.yaml +++ b/task/buildah-remote-oci-ta/0.2/buildah-remote-oci-ta.yaml @@ -6,7 +6,7 @@ metadata: tekton.dev/tags: image-build, konflux creationTimestamp: null labels: - app.kubernetes.io/version: "0.2" + app.kubernetes.io/version: 0.2.1 build.appstudio.redhat.com/build_type: docker name: buildah-remote-oci-ta spec: @@ -647,6 +647,91 @@ spec: name: ssh readOnly: true workingDir: /var/workdir + - computeResources: + limits: + cpu: "4" + memory: 4Gi + requests: + cpu: "1" + memory: 1Gi + image: quay.io/konflux-ci/buildah-task:latest@sha256:b2d6c32d1e05e91920cd4475b2761d58bb7ee11ad5dff3ecb59831c7572b4d0c + name: push + script: | + #!/bin/bash + set -e + if [ "${IMAGE_APPEND_PLATFORM}" == "true" ]; then + IMAGE="${IMAGE}-${PLATFORM//[^a-zA-Z0-9]/-}" + export IMAGE + fi + + retry() { + status=-1 + max_run=5 + sleep_sec=10 + + for run in $(seq 1 $max_run); do + status=0 + [ "$run" -gt 1 ] && sleep $sleep_sec + "$@" && break || status=$? + done + return $status + } + + ca_bundle=/mnt/trusted-ca/ca-bundle.crt + if [ -f "$ca_bundle" ]; then + echo "INFO: Using mounted CA bundle: $ca_bundle" + cp -vf $ca_bundle /etc/pki/ca-trust/source/anchors + update-ca-trust + fi + + base_image_name=$(buildah inspect --format '{{ index .ImageAnnotations "org.opencontainers.image.base.name"}}' $IMAGE | cut -f1 -d'@') + base_image_digest=$(buildah inspect --format '{{ index .ImageAnnotations "org.opencontainers.image.base.digest"}}' $IMAGE) + container=$(buildah from --pull-never $IMAGE) + buildah config -a org.opencontainers.image.base.name=${base_image_name} -a org.opencontainers.image.base.digest=${base_image_digest} $container + + BUILDAH_ARGS=() + if [ "${SQUASH}" == "true" ]; then + BUILDAH_ARGS+=("--squash") + fi + + buildah commit "${BUILDAH_ARGS[@]}" $container $IMAGE + + echo "Pushing to ${IMAGE%:*}:${TASKRUN_NAME}" + if ! retry buildah push \ + --tls-verify="$TLSVERIFY" \ + "$IMAGE" \ + "docker://${IMAGE%:*}:$(context.taskRun.name)"; then + echo "Failed to push sbom image to ${IMAGE%:*}:$(context.taskRun.name) after ${max_run} tries" + exit 1 + fi + + echo "Pushing to ${IMAGE}" + if ! retry buildah push \ + --tls-verify="$TLSVERIFY" \ + --digestfile "/var/workdir/image-digest" "$IMAGE" \ + "docker://$IMAGE"; then + echo "Failed to push sbom image to $IMAGE after ${max_run} tries" + exit 1 + fi + + cat "/var/workdir"/image-digest | tee $(results.IMAGE_DIGEST.path) + echo -n "$IMAGE" | tee $(results.IMAGE_URL.path) + { + echo -n "${IMAGE}@" + cat "/var/workdir/image-digest" + } >"$(results.IMAGE_REF.path)" + securityContext: + capabilities: + add: + - SETFCAP + runAsUser: 0 + volumeMounts: + - mountPath: /var/lib/containers + name: varlibcontainers + - mountPath: /mnt/trusted-ca + name: trusted-ca + readOnly: true + workingDir: /var/workdir - computeResources: limits: cpu: "2" @@ -709,7 +794,7 @@ spec: requests: cpu: 100m memory: 256Mi - image: quay.io/redhat-appstudio/sbom-utility-scripts-image@sha256:ff25ba051a6d583e5b85e635d39f0e804e2ac65def51ba17b0d487a1c00ce9cd + image: quay.io/redhat-appstudio/sbom-utility-scripts-image@sha256:11851ba63f63dfdcf722e47993f41a1f5f31a7a0dc8aa85b810ce2466daf23af name: prepare-sboms script: | #!/bin/bash @@ -735,100 +820,20 @@ spec: --sbom=sbom-cyclonedx.json \ --base-images-from-dockerfile=/shared/base_images_from_dockerfile \ --base-images-digests=/shared/base_images_digests - securityContext: - runAsUser: 0 - workingDir: /var/workdir - - computeResources: - limits: - cpu: "4" - memory: 4Gi - requests: - cpu: "1" - memory: 1Gi - image: quay.io/konflux-ci/buildah-task:latest@sha256:b2d6c32d1e05e91920cd4475b2761d58bb7ee11ad5dff3ecb59831c7572b4d0c - name: inject-sbom-and-push - script: | - #!/bin/bash - set -e - if [ "${IMAGE_APPEND_PLATFORM}" == "true" ]; then - IMAGE="${IMAGE}-${PLATFORM//[^a-zA-Z0-9]/-}" - export IMAGE - fi - - retry() { - status=-1 - max_run=5 - sleep_sec=10 - - for run in $(seq 1 $max_run); do - status=0 - [ "$run" -gt 1 ] && sleep $sleep_sec - "$@" && break || status=$? - done - return $status - } - - ca_bundle=/mnt/trusted-ca/ca-bundle.crt - if [ -f "$ca_bundle" ]; then - echo "INFO: Using mounted CA bundle: $ca_bundle" - cp -vf $ca_bundle /etc/pki/ca-trust/source/anchors - update-ca-trust - fi - - base_image_name=$(buildah inspect --format '{{ index .ImageAnnotations "org.opencontainers.image.base.name"}}' $IMAGE | cut -f1 -d'@') - base_image_digest=$(buildah inspect --format '{{ index .ImageAnnotations "org.opencontainers.image.base.digest"}}' $IMAGE) - container=$(buildah from --pull-never $IMAGE) - buildah copy $container sbom-cyclonedx.json sbom-purl.json /root/buildinfo/content_manifests/ - buildah config -a org.opencontainers.image.base.name=${base_image_name} -a org.opencontainers.image.base.digest=${base_image_digest} $container - - BUILDAH_ARGS=() - if [ "${SQUASH}" == "true" ]; then - BUILDAH_ARGS+=("--squash") - fi - - buildah commit "${BUILDAH_ARGS[@]}" $container $IMAGE - echo "Pushing to ${IMAGE%:*}:${TASKRUN_NAME}" - if ! retry buildah push \ - --tls-verify="$TLSVERIFY" \ - "$IMAGE" \ - "docker://${IMAGE%:*}:$(context.taskRun.name)"; then - echo "Failed to push sbom image to ${IMAGE%:*}:$(context.taskRun.name) after ${max_run} tries" - exit 1 - fi - - echo "Pushing to ${IMAGE}" - if ! retry buildah push \ - --tls-verify="$TLSVERIFY" \ - --digestfile "/var/workdir/image-digest" "$IMAGE" \ - "docker://$IMAGE"; then - echo "Failed to push sbom image to $IMAGE after ${max_run} tries" - exit 1 - fi + echo "Adding image reference to sbom" + IMAGE_URL="$(cat "$(results.IMAGE_URL.path)")" + IMAGE_DIGEST="$(cat "$(results.IMAGE_DIGEST.path)")" - cat "/var/workdir"/image-digest | tee $(results.IMAGE_DIGEST.path) - echo -n "$IMAGE" | tee $(results.IMAGE_URL.path) - { - echo -n "${IMAGE}@" - cat "/var/workdir/image-digest" - } >"$(results.IMAGE_REF.path)" + python3 /scripts/add_image_reference.py \ + --image-url "$IMAGE_URL" \ + --image-digest "$IMAGE_DIGEST" \ + --input-file sbom-cyclonedx.json \ + --output-file /tmp/sbom-cyclonedx.tmp.json - # Remove tag from IMAGE while allowing registry to contain a port number. - sbom_repo="${IMAGE%:*}" - sbom_digest="$(sha256sum sbom-cyclonedx.json | cut -d' ' -f1)" - # The SBOM_BLOB_URL is created by `cosign attach sbom`. - echo -n "${sbom_repo}@sha256:${sbom_digest}" | tee "$(results.SBOM_BLOB_URL.path)" + mv /tmp/sbom-cyclonedx.tmp.json sbom-cyclonedx.json securityContext: - capabilities: - add: - - SETFCAP runAsUser: 0 - volumeMounts: - - mountPath: /var/lib/containers - name: varlibcontainers - - mountPath: /mnt/trusted-ca - name: trusted-ca - readOnly: true workingDir: /var/workdir - computeResources: limits: @@ -854,6 +859,12 @@ spec: fi cosign attach sbom --sbom sbom-cyclonedx.json --type cyclonedx "$(cat "$(results.IMAGE_REF.path)")" + + # Remove tag from IMAGE while allowing registry to contain a port number. + sbom_repo="${IMAGE%:*}" + sbom_digest="$(sha256sum sbom-cyclonedx.json | cut -d' ' -f1)" + # The SBOM_BLOB_URL is created by `cosign attach sbom`. + echo -n "${sbom_repo}@sha256:${sbom_digest}" | tee "$(results.SBOM_BLOB_URL.path)" volumeMounts: - mountPath: /mnt/trusted-ca name: trusted-ca diff --git a/task/buildah-remote/0.2/buildah-remote.yaml b/task/buildah-remote/0.2/buildah-remote.yaml index 107c1427d6..6ddbd1a1ab 100644 --- a/task/buildah-remote/0.2/buildah-remote.yaml +++ b/task/buildah-remote/0.2/buildah-remote.yaml @@ -6,7 +6,7 @@ metadata: tekton.dev/tags: image-build, konflux creationTimestamp: null labels: - app.kubernetes.io/version: "0.2" + app.kubernetes.io/version: 0.2.1 build.appstudio.redhat.com/build_type: docker name: buildah-remote spec: @@ -625,6 +625,93 @@ spec: name: ssh readOnly: true workingDir: $(workspaces.source.path) + - computeResources: + limits: + cpu: "4" + memory: 4Gi + requests: + cpu: "1" + memory: 1Gi + image: quay.io/konflux-ci/buildah-task:latest@sha256:b2d6c32d1e05e91920cd4475b2761d58bb7ee11ad5dff3ecb59831c7572b4d0c + name: push + script: | + #!/bin/bash + set -e + if [ "${IMAGE_APPEND_PLATFORM}" == "true" ]; then + IMAGE="${IMAGE}-${PLATFORM//[^a-zA-Z0-9]/-}" + export IMAGE + fi + + retry () { + status=-1 + max_run=5 + sleep_sec=10 + + for run in $(seq 1 $max_run); do + status=0 + [ "$run" -gt 1 ] && sleep $sleep_sec + "$@" && break || status=$? + done + return $status + } + + ca_bundle=/mnt/trusted-ca/ca-bundle.crt + if [ -f "$ca_bundle" ]; then + echo "INFO: Using mounted CA bundle: $ca_bundle" + cp -vf $ca_bundle /etc/pki/ca-trust/source/anchors + update-ca-trust + fi + + base_image_name=$(buildah inspect --format '{{ index .ImageAnnotations "org.opencontainers.image.base.name"}}' $IMAGE | cut -f1 -d'@') + base_image_digest=$(buildah inspect --format '{{ index .ImageAnnotations "org.opencontainers.image.base.digest"}}' $IMAGE) + container=$(buildah from --pull-never $IMAGE) + buildah config -a org.opencontainers.image.base.name=${base_image_name} -a org.opencontainers.image.base.digest=${base_image_digest} $container + + BUILDAH_ARGS=() + if [ "${SQUASH}" == "true" ]; then + BUILDAH_ARGS+=("--squash") + fi + + buildah commit "${BUILDAH_ARGS[@]}" $container $IMAGE + + echo "Pushing to ${IMAGE%:*}:${TASKRUN_NAME}" + if ! retry buildah push \ + --tls-verify="$TLSVERIFY" \ + "$IMAGE" \ + "docker://${IMAGE%:*}:$(context.taskRun.name)"; + then + echo "Failed to push sbom image to ${IMAGE%:*}:$(context.taskRun.name) after ${max_run} tries" + exit 1 + fi + + echo "Pushing to ${IMAGE}" + if ! retry buildah push \ + --tls-verify="$TLSVERIFY" \ + --digestfile "$(workspaces.source.path)/image-digest" "$IMAGE" \ + "docker://$IMAGE"; + then + echo "Failed to push sbom image to $IMAGE after ${max_run} tries" + exit 1 + fi + + cat "$(workspaces.source.path)"/image-digest | tee $(results.IMAGE_DIGEST.path) + echo -n "$IMAGE" | tee $(results.IMAGE_URL.path) + { + echo -n "${IMAGE}@" + cat "$(workspaces.source.path)/image-digest" + } > "$(results.IMAGE_REF.path)" + securityContext: + capabilities: + add: + - SETFCAP + runAsUser: 0 + volumeMounts: + - mountPath: /var/lib/containers + name: varlibcontainers + - mountPath: /mnt/trusted-ca + name: trusted-ca + readOnly: true + workingDir: $(workspaces.source.path) - computeResources: limits: cpu: "2" @@ -687,7 +774,7 @@ spec: requests: cpu: 100m memory: 256Mi - image: quay.io/redhat-appstudio/sbom-utility-scripts-image@sha256:ff25ba051a6d583e5b85e635d39f0e804e2ac65def51ba17b0d487a1c00ce9cd + image: quay.io/redhat-appstudio/sbom-utility-scripts-image@sha256:11851ba63f63dfdcf722e47993f41a1f5f31a7a0dc8aa85b810ce2466daf23af name: prepare-sboms script: | #!/bin/bash @@ -713,102 +800,20 @@ spec: --sbom=sbom-cyclonedx.json \ --base-images-from-dockerfile=/shared/base_images_from_dockerfile \ --base-images-digests=/shared/base_images_digests - securityContext: - runAsUser: 0 - workingDir: $(workspaces.source.path) - - computeResources: - limits: - cpu: "4" - memory: 4Gi - requests: - cpu: "1" - memory: 1Gi - image: quay.io/konflux-ci/buildah-task:latest@sha256:b2d6c32d1e05e91920cd4475b2761d58bb7ee11ad5dff3ecb59831c7572b4d0c - name: inject-sbom-and-push - script: | - #!/bin/bash - set -e - if [ "${IMAGE_APPEND_PLATFORM}" == "true" ]; then - IMAGE="${IMAGE}-${PLATFORM//[^a-zA-Z0-9]/-}" - export IMAGE - fi - - retry () { - status=-1 - max_run=5 - sleep_sec=10 - - for run in $(seq 1 $max_run); do - status=0 - [ "$run" -gt 1 ] && sleep $sleep_sec - "$@" && break || status=$? - done - return $status - } - - ca_bundle=/mnt/trusted-ca/ca-bundle.crt - if [ -f "$ca_bundle" ]; then - echo "INFO: Using mounted CA bundle: $ca_bundle" - cp -vf $ca_bundle /etc/pki/ca-trust/source/anchors - update-ca-trust - fi - - base_image_name=$(buildah inspect --format '{{ index .ImageAnnotations "org.opencontainers.image.base.name"}}' $IMAGE | cut -f1 -d'@') - base_image_digest=$(buildah inspect --format '{{ index .ImageAnnotations "org.opencontainers.image.base.digest"}}' $IMAGE) - container=$(buildah from --pull-never $IMAGE) - buildah copy $container sbom-cyclonedx.json sbom-purl.json /root/buildinfo/content_manifests/ - buildah config -a org.opencontainers.image.base.name=${base_image_name} -a org.opencontainers.image.base.digest=${base_image_digest} $container - - BUILDAH_ARGS=() - if [ "${SQUASH}" == "true" ]; then - BUILDAH_ARGS+=("--squash") - fi - - buildah commit "${BUILDAH_ARGS[@]}" $container $IMAGE - echo "Pushing to ${IMAGE%:*}:${TASKRUN_NAME}" - if ! retry buildah push \ - --tls-verify="$TLSVERIFY" \ - "$IMAGE" \ - "docker://${IMAGE%:*}:$(context.taskRun.name)"; - then - echo "Failed to push sbom image to ${IMAGE%:*}:$(context.taskRun.name) after ${max_run} tries" - exit 1 - fi + echo "Adding image reference to sbom" + IMAGE_URL="$(cat "$(results.IMAGE_URL.path)")" + IMAGE_DIGEST="$(cat "$(results.IMAGE_DIGEST.path)")" - echo "Pushing to ${IMAGE}" - if ! retry buildah push \ - --tls-verify="$TLSVERIFY" \ - --digestfile "$(workspaces.source.path)/image-digest" "$IMAGE" \ - "docker://$IMAGE"; - then - echo "Failed to push sbom image to $IMAGE after ${max_run} tries" - exit 1 - fi + python3 /scripts/add_image_reference.py \ + --image-url "$IMAGE_URL" \ + --image-digest "$IMAGE_DIGEST" \ + --input-file sbom-cyclonedx.json \ + --output-file /tmp/sbom-cyclonedx.tmp.json - cat "$(workspaces.source.path)"/image-digest | tee $(results.IMAGE_DIGEST.path) - echo -n "$IMAGE" | tee $(results.IMAGE_URL.path) - { - echo -n "${IMAGE}@" - cat "$(workspaces.source.path)/image-digest" - } > "$(results.IMAGE_REF.path)" - - # Remove tag from IMAGE while allowing registry to contain a port number. - sbom_repo="${IMAGE%:*}" - sbom_digest="$(sha256sum sbom-cyclonedx.json | cut -d' ' -f1)" - # The SBOM_BLOB_URL is created by `cosign attach sbom`. - echo -n "${sbom_repo}@sha256:${sbom_digest}" | tee "$(results.SBOM_BLOB_URL.path)" + mv /tmp/sbom-cyclonedx.tmp.json sbom-cyclonedx.json securityContext: - capabilities: - add: - - SETFCAP runAsUser: 0 - volumeMounts: - - mountPath: /var/lib/containers - name: varlibcontainers - - mountPath: /mnt/trusted-ca - name: trusted-ca - readOnly: true workingDir: $(workspaces.source.path) - computeResources: limits: @@ -834,6 +839,12 @@ spec: fi cosign attach sbom --sbom sbom-cyclonedx.json --type cyclonedx "$(cat "$(results.IMAGE_REF.path)")" + + # Remove tag from IMAGE while allowing registry to contain a port number. + sbom_repo="${IMAGE%:*}" + sbom_digest="$(sha256sum sbom-cyclonedx.json | cut -d' ' -f1)" + # The SBOM_BLOB_URL is created by `cosign attach sbom`. + echo -n "${sbom_repo}@sha256:${sbom_digest}" | tee "$(results.SBOM_BLOB_URL.path)" volumeMounts: - mountPath: /mnt/trusted-ca name: trusted-ca diff --git a/task/buildah/0.2/README.md b/task/buildah/0.2/README.md index 4ad54020df..6be68eb10e 100644 --- a/task/buildah/0.2/README.md +++ b/task/buildah/0.2/README.md @@ -6,43 +6,49 @@ When [Java dependency rebuild](https://redhat-appstudio.github.io/docs.stonesoup When prefetch-dependencies task was activated it is using its artifacts to run build in hermetic environment. ## Parameters -|name|description|default value|required| -|---|---|---|---| -|IMAGE|Reference of the image buildah will produce.||true| -|DOCKERFILE|Path to the Dockerfile to build.|./Dockerfile|false| -|CONTEXT|Path to the directory to use as context.|.|false| -|TLSVERIFY|Verify the TLS on the registry endpoint (for push/pull to a non-TLS registry)|true|false| -|HERMETIC|Determines if build will be executed without network access.|false|false| -|PREFETCH_INPUT|In case it is not empty, the prefetched content should be made available to the build.|""|false| -|IMAGE_EXPIRES_AFTER|Delete image tag after specified time. Empty means to keep the image tag. Time values could be something like 1h, 2d, 3w for hours, days, and weeks, respectively.|""|false| -|COMMIT_SHA|The image is built from this commit.|""|false| -|YUM_REPOS_D_SRC|Path in the git repository in which yum repository files are stored|repos.d|false| -|YUM_REPOS_D_FETCHED|Path in source workspace where dynamically-fetched repos are present|fetched.repos.d|false| -|YUM_REPOS_D_TARGET|Target path on the container in which yum repository files should be made available|/etc/yum.repos.d|false| -|TARGET_STAGE|Target stage in Dockerfile to build. If not specified, the Dockerfile is processed entirely to (and including) its last stage.|""|false| -|ENTITLEMENT_SECRET|Name of secret which contains the entitlement certificates|etc-pki-entitlement|false| -|ACTIVATION_KEY|Name of secret which contains subscription activation key|activation-key|false| -|ADDITIONAL_SECRET|Name of a secret which will be made available to the build with 'buildah build --secret' at /run/secrets/$ADDITIONAL_SECRET|does-not-exist|false| -|BUILD_ARGS|Array of --build-arg values ("arg=value" strings)|[]|false| -|BUILD_ARGS_FILE|Path to a file with build arguments, see https://www.mankier.com/1/buildah-build#--build-arg-file|""|false| -|caTrustConfigMapName|The name of the ConfigMap to read CA bundle data from.|trusted-ca|false| -|caTrustConfigMapKey|The name of the key in the ConfigMap that contains the CA bundle data.|ca-bundle.crt|false| -|ADD_CAPABILITIES|Comma separated list of extra capabilities to add when running 'buildah build'|""|false| -|SQUASH|Squash all new and previous layers added as a part of this build, as per --squash|false|false| -|STORAGE_DRIVER|Storage driver to configure for buildah|vfs|false| -|SKIP_UNUSED_STAGES|Whether to skip stages in Containerfile that seem unused by subsequent stages|true|false| +| name | description | default value | required | +| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------- | -------- | +| IMAGE | Reference of the image buildah will produce. | | true | +| DOCKERFILE | Path to the Dockerfile to build. | ./Dockerfile | false | +| CONTEXT | Path to the directory to use as context. | . | false | +| TLSVERIFY | Verify the TLS on the registry endpoint (for push/pull to a non-TLS registry) | true | false | +| HERMETIC | Determines if build will be executed without network access. | false | false | +| PREFETCH_INPUT | In case it is not empty, the prefetched content should be made available to the build. | "" | false | +| IMAGE_EXPIRES_AFTER | Delete image tag after specified time. Empty means to keep the image tag. Time values could be something like 1h, 2d, 3w for hours, days, and weeks, respectively. | "" | false | +| COMMIT_SHA | The image is built from this commit. | "" | false | +| YUM_REPOS_D_SRC | Path in the git repository in which yum repository files are stored | repos.d | false | +| YUM_REPOS_D_FETCHED | Path in source workspace where dynamically-fetched repos are present | fetched.repos.d | false | +| YUM_REPOS_D_TARGET | Target path on the container in which yum repository files should be made available | /etc/yum.repos.d | false | +| TARGET_STAGE | Target stage in Dockerfile to build. If not specified, the Dockerfile is processed entirely to (and including) its last stage. | "" | false | +| ENTITLEMENT_SECRET | Name of secret which contains the entitlement certificates | etc-pki-entitlement | false | +| ACTIVATION_KEY | Name of secret which contains subscription activation key | activation-key | false | +| ADDITIONAL_SECRET | Name of a secret which will be made available to the build with 'buildah build --secret' at /run/secrets/$ADDITIONAL_SECRET | does-not-exist | false | +| BUILD_ARGS | Array of --build-arg values ("arg=value" strings) | [] | false | +| BUILD_ARGS_FILE | Path to a file with build arguments, see https://www.mankier.com/1/buildah-build#--build-arg-file | "" | false | +| caTrustConfigMapName | The name of the ConfigMap to read CA bundle data from. | trusted-ca | false | +| caTrustConfigMapKey | The name of the key in the ConfigMap that contains the CA bundle data. | ca-bundle.crt | false | +| ADD_CAPABILITIES | Comma separated list of extra capabilities to add when running 'buildah build' | "" | false | +| SQUASH | Squash all new and previous layers added as a part of this build, as per --squash | false | false | +| STORAGE_DRIVER | Storage driver to configure for buildah | vfs | false | +| SKIP_UNUSED_STAGES | Whether to skip stages in Containerfile that seem unused by subsequent stages | true | false | ## Results -|name|description| -|---|---| -|IMAGE_DIGEST|Digest of the image just built| -|IMAGE_URL|Image repository and tag where the built image was pushed| -|IMAGE_REF|Image reference of the built image| -|SBOM_BLOB_URL|Reference of SBOM blob digest to enable digest-based verification from provenance| -|SBOM_JAVA_COMPONENTS_COUNT|The counting of Java components by publisher in JSON format| -|JAVA_COMMUNITY_DEPENDENCIES|The Java dependencies that came from community sources such as Maven central.| +| name | description | +| --------------------------- | --------------------------------------------------------------------------------- | +| IMAGE_DIGEST | Digest of the image just built | +| IMAGE_URL | Image repository and tag where the built image was pushed | +| IMAGE_REF | Image reference of the built image | +| SBOM_BLOB_URL | Reference of SBOM blob digest to enable digest-based verification from provenance | +| SBOM_JAVA_COMPONENTS_COUNT | The counting of Java components by publisher in JSON format | +| JAVA_COMMUNITY_DEPENDENCIES | The Java dependencies that came from community sources such as Maven central. | ## Workspaces -|name|description|optional| -|---|---|---| -|source|Workspace containing the source code to build.|false| +| name | description | optional | +| ------ | ---------------------------------------------- | -------- | +| source | Workspace containing the source code to build. | false | + + +## Changes in 0.2.1 +- Added image reference to the SBOM output file. +- Re-arranged steps to push image first and then generate and push SBOM file. +- Remove SBOM file stored in the image under `/root/buildinfo/content_manifests/` diff --git a/task/buildah/0.2/buildah.yaml b/task/buildah/0.2/buildah.yaml index 3ca3167367..09172a5a71 100644 --- a/task/buildah/0.2/buildah.yaml +++ b/task/buildah/0.2/buildah.yaml @@ -2,7 +2,7 @@ apiVersion: tekton.dev/v1 kind: Task metadata: labels: - app.kubernetes.io/version: "0.2" + app.kubernetes.io/version: "0.2.1" build.appstudio.redhat.com/build_type: "docker" annotations: tekton.dev/pipelines.minVersion: "0.12.1" @@ -487,84 +487,7 @@ spec: readOnly: true workingDir: $(workspaces.source.path) - - name: sbom-syft-generate - image: registry.access.redhat.com/rh-syft-tech-preview/syft-rhel9:1.4.1@sha256:34d7065427085a31dc4949bd283c001b91794d427e1e4cdf1b21ea4faf9fee3f - # Respect Syft configuration if the user has it in the root of their repository - # (need to set the workdir, see https://github.com/anchore/syft/issues/2465) - workingDir: $(workspaces.source.path)/source - computeResources: - limits: - memory: 4Gi - cpu: '2' - requests: - memory: 1Gi - cpu: 500m - script: | - echo "Running syft on the source directory" - syft dir:"$(workspaces.source.path)/$SOURCE_CODE_DIR/$CONTEXT" --output cyclonedx-json="$(workspaces.source.path)/sbom-source.json" - echo "Running syft on the image filesystem" - syft dir:"$(cat /shared/container_path)" --output cyclonedx-json="$(workspaces.source.path)/sbom-image.json" - volumeMounts: - - mountPath: /var/lib/containers - name: varlibcontainers - - mountPath: /shared - name: shared - - name: analyse-dependencies-java-sbom - image: quay.io/redhat-appstudio/hacbs-jvm-build-request-processor:127ee0c223a2b56a9bd20a6f2eaeed3bd6015f77 - computeResources: - limits: - memory: 512Mi - cpu: 200m - requests: - memory: 256Mi - cpu: 100m - script: | - if [ -f /var/lib/containers/java ]; then - /opt/jboss/container/java/run/run-java.sh analyse-dependencies path $(cat /shared/container_path) -s $(workspaces.source.path)/sbom-image.json --task-run-name $(context.taskRun.name) --publishers $(results.SBOM_JAVA_COMPONENTS_COUNT.path) - sed -i 's/^/ /' $(results.SBOM_JAVA_COMPONENTS_COUNT.path) # Workaround for SRVKP-2875 - else - touch $(results.JAVA_COMMUNITY_DEPENDENCIES.path) - fi - volumeMounts: - - mountPath: /var/lib/containers - name: varlibcontainers - - mountPath: /shared - name: shared - securityContext: - runAsUser: 0 - - - name: prepare-sboms - image: quay.io/redhat-appstudio/sbom-utility-scripts-image@sha256:ff25ba051a6d583e5b85e635d39f0e804e2ac65def51ba17b0d487a1c00ce9cd - computeResources: - limits: - memory: 512Mi - cpu: 200m - requests: - memory: 256Mi - cpu: 100m - script: | - echo "Merging contents of sbom-source.json and sbom-image.json into sbom-cyclonedx.json" - python3 /scripts/merge_syft_sboms.py - - if [ -f "sbom-cachi2.json" ]; then - echo "Merging contents of sbom-cachi2.json into sbom-cyclonedx.json" - python3 /scripts/merge_cachi2_sboms.py sbom-cachi2.json sbom-cyclonedx.json > sbom-temp.json - mv sbom-temp.json sbom-cyclonedx.json - fi - - echo "Creating sbom-purl.json" - python3 /scripts/create_purl_sbom.py - - echo "Adding base images data to sbom-cyclonedx.json" - python3 /scripts/base_images_sbom_script.py \ - --sbom=sbom-cyclonedx.json \ - --base-images-from-dockerfile=/shared/base_images_from_dockerfile \ - --base-images-digests=/shared/base_images_digests - workingDir: $(workspaces.source.path) - securityContext: - runAsUser: 0 - - - name: inject-sbom-and-push + - name: push image: quay.io/konflux-ci/buildah-task:latest@sha256:b2d6c32d1e05e91920cd4475b2761d58bb7ee11ad5dff3ecb59831c7572b4d0c computeResources: limits: @@ -600,7 +523,6 @@ spec: base_image_name=$(buildah inspect --format '{{ index .ImageAnnotations "org.opencontainers.image.base.name"}}' $IMAGE | cut -f1 -d'@') base_image_digest=$(buildah inspect --format '{{ index .ImageAnnotations "org.opencontainers.image.base.digest"}}' $IMAGE) container=$(buildah from --pull-never $IMAGE) - buildah copy $container sbom-cyclonedx.json sbom-purl.json /root/buildinfo/content_manifests/ buildah config -a org.opencontainers.image.base.name=${base_image_name} -a org.opencontainers.image.base.digest=${base_image_digest} $container BUILDAH_ARGS=() @@ -636,12 +558,6 @@ spec: echo -n "${IMAGE}@" cat "$(workspaces.source.path)/image-digest" } > "$(results.IMAGE_REF.path)" - - # Remove tag from IMAGE while allowing registry to contain a port number. - sbom_repo="${IMAGE%:*}" - sbom_digest="$(sha256sum sbom-cyclonedx.json | cut -d' ' -f1)" - # The SBOM_BLOB_URL is created by `cosign attach sbom`. - echo -n "${sbom_repo}@sha256:${sbom_digest}" | tee "$(results.SBOM_BLOB_URL.path)" securityContext: runAsUser: 0 capabilities: @@ -655,6 +571,96 @@ spec: readOnly: true workingDir: $(workspaces.source.path) + - name: sbom-syft-generate + image: registry.access.redhat.com/rh-syft-tech-preview/syft-rhel9:1.4.1@sha256:34d7065427085a31dc4949bd283c001b91794d427e1e4cdf1b21ea4faf9fee3f + # Respect Syft configuration if the user has it in the root of their repository + # (need to set the workdir, see https://github.com/anchore/syft/issues/2465) + workingDir: $(workspaces.source.path)/source + computeResources: + limits: + memory: 4Gi + cpu: '2' + requests: + memory: 1Gi + cpu: 500m + script: | + echo "Running syft on the source directory" + syft dir:"$(workspaces.source.path)/$SOURCE_CODE_DIR/$CONTEXT" --output cyclonedx-json="$(workspaces.source.path)/sbom-source.json" + echo "Running syft on the image filesystem" + syft dir:"$(cat /shared/container_path)" --output cyclonedx-json="$(workspaces.source.path)/sbom-image.json" + volumeMounts: + - mountPath: /var/lib/containers + name: varlibcontainers + - mountPath: /shared + name: shared + + - name: analyse-dependencies-java-sbom + image: quay.io/redhat-appstudio/hacbs-jvm-build-request-processor:127ee0c223a2b56a9bd20a6f2eaeed3bd6015f77 + computeResources: + limits: + memory: 512Mi + cpu: 200m + requests: + memory: 256Mi + cpu: 100m + script: | + if [ -f /var/lib/containers/java ]; then + /opt/jboss/container/java/run/run-java.sh analyse-dependencies path $(cat /shared/container_path) -s $(workspaces.source.path)/sbom-image.json --task-run-name $(context.taskRun.name) --publishers $(results.SBOM_JAVA_COMPONENTS_COUNT.path) + sed -i 's/^/ /' $(results.SBOM_JAVA_COMPONENTS_COUNT.path) # Workaround for SRVKP-2875 + else + touch $(results.JAVA_COMMUNITY_DEPENDENCIES.path) + fi + volumeMounts: + - mountPath: /var/lib/containers + name: varlibcontainers + - mountPath: /shared + name: shared + securityContext: + runAsUser: 0 + + - name: prepare-sboms + image: quay.io/redhat-appstudio/sbom-utility-scripts-image@sha256:11851ba63f63dfdcf722e47993f41a1f5f31a7a0dc8aa85b810ce2466daf23af + computeResources: + limits: + memory: 512Mi + cpu: 200m + requests: + memory: 256Mi + cpu: 100m + script: | + echo "Merging contents of sbom-source.json and sbom-image.json into sbom-cyclonedx.json" + python3 /scripts/merge_syft_sboms.py + + if [ -f "sbom-cachi2.json" ]; then + echo "Merging contents of sbom-cachi2.json into sbom-cyclonedx.json" + python3 /scripts/merge_cachi2_sboms.py sbom-cachi2.json sbom-cyclonedx.json > sbom-temp.json + mv sbom-temp.json sbom-cyclonedx.json + fi + + echo "Creating sbom-purl.json" + python3 /scripts/create_purl_sbom.py + + echo "Adding base images data to sbom-cyclonedx.json" + python3 /scripts/base_images_sbom_script.py \ + --sbom=sbom-cyclonedx.json \ + --base-images-from-dockerfile=/shared/base_images_from_dockerfile \ + --base-images-digests=/shared/base_images_digests + + echo "Adding image reference to sbom" + IMAGE_URL="$(cat "$(results.IMAGE_URL.path)")" + IMAGE_DIGEST="$(cat "$(results.IMAGE_DIGEST.path)")" + + python3 /scripts/add_image_reference.py \ + --image-url "$IMAGE_URL" \ + --image-digest "$IMAGE_DIGEST" \ + --input-file sbom-cyclonedx.json \ + --output-file /tmp/sbom-cyclonedx.tmp.json + + mv /tmp/sbom-cyclonedx.tmp.json sbom-cyclonedx.json + workingDir: $(workspaces.source.path) + securityContext: + runAsUser: 0 + - name: upload-sbom image: quay.io/konflux-ci/appstudio-utils:48c311af02858e2422d6229600e9959e496ddef1@sha256:91ddd999271f65d8ec8487b10f3dd378f81aa894e11b9af4d10639fd52bba7e8 script: | @@ -666,6 +672,12 @@ spec: fi cosign attach sbom --sbom sbom-cyclonedx.json --type cyclonedx "$(cat "$(results.IMAGE_REF.path)")" + + # Remove tag from IMAGE while allowing registry to contain a port number. + sbom_repo="${IMAGE%:*}" + sbom_digest="$(sha256sum sbom-cyclonedx.json | cut -d' ' -f1)" + # The SBOM_BLOB_URL is created by `cosign attach sbom`. + echo -n "${sbom_repo}@sha256:${sbom_digest}" | tee "$(results.SBOM_BLOB_URL.path)" computeResources: limits: memory: 512Mi