From 05e74005abd863627421b2f40bb5352ea58fa1ed Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Thu, 28 Nov 2024 15:16:03 +0100 Subject: [PATCH] Task to build a builder image using the paketo pack tool Review the wording of the intro text Signed-off-by: cmoulliard Changing the OWNERS Signed-off-by: cmoulliard Use kerberios username for cmoulliard Signed-off-by: cmoulliard Fix username typo error Signed-off-by: cmoulliard Remove ubi from name, README and task definition Signed-off-by: cmoulliard Removing the default value image as name will change Signed-off-by: cmoulliard Removing #rsync comments Signed-off-by: cmoulliard Remove from message printed: Signed-off-by: cmoulliard Use buildah --retry parameter Signed-off-by: cmoulliard Rename the task to include the suffic: -oci-ta Signed-off-by: cmoulliard Change owner from cmoullia to cmoulliard Signed-off-by: cmoulliard Double quote to prevent globbing and word splitting Signed-off-by: cmoulliard Double quote to prevent globbing and word splitting Signed-off-by: cmoulliard Double quote to prevent word splitting Signed-off-by: cmoulliard Declare and assign separately to avoid masking return values. Signed-off-by: cmoulliard Useless cat. Consider 'cmd < file | ..' or 'cmd file | ..' instead. Signed-off-by: cmoulliard Remove trailing spaces and wrong indentation: expected 4 but found 6 Signed-off-by: cmoulliard Fixing: Assigning an array to a string! Assign as array, or use * instead of @ to concatenate Signed-off-by: cmoulliard Fixing: Expanding an array without an index only gives the first element. Signed-off-by: cmoulliard Fixing: Use braces when expanding arrays. Signed-off-by: cmoulliard Remove double quote for ${BUILD_ARGS[@]} Signed-off-by: cmoulliard Rename the task to include the suffix: -oci-ta Signed-off-by: cmoulliard Replace @ with * for the array Signed-off-by: cmoulliard Replace @ with * for the array Signed-off-by: cmoulliard Removing some additional comments Signed-off-by: cmoulliard Moving from OWNERS to CODEOWNERS Signed-off-by: cmoulliard Add missing task of paketo to the renovate.json file Signed-off-by: cmoulliard Updating renovate.json using update_renovate_json_based_on_codeowners.py script Signed-off-by: cmoulliard Create a new renovate group for paketo => buildpack Signed-off-by: cmoulliard Set -x to debug the bash script and review the logic to set the args passed to BUILD_ARGS Signed-off-by: cmoulliard Remove set +x to understand why the bash script fails Signed-off-by: cmoulliard Remove double quotes around argument: SSH_ARGS and echo BUILD_ARGS Signed-off-by: cmoulliard Remove set +x to understand why the bash script fails Signed-off-by: cmoulliard Declare the SSH_ARGS using an array Signed-off-by: cmoulliard Remove set -x as non needed and fix wrong path to get image_digest Signed-off-by: cmoulliard Remove trailling spaces Signed-off-by: cmoulliard Removing ##### from echo commands Signed-off-by: cmoulliard Generate the SBOM of the base image Signed-off-by: cmoulliard Remove trailing space reported by yamllint Signed-off-by: cmoulliard Remove trailing ## Signed-off-by: cmoulliard Removing the BUILDER_IMAGE parameter Signed-off-by: cmoulliard --- CODEOWNERS | 3 + renovate.json | 6 + .../0.1/README.md | 6 +- .../0.1/build-paketo-builder-oci-ta.yaml | 490 ++++++++++++++++ .../0.1/build-paketo-ubi-builder.yaml | 527 ------------------ task/build-paketo-ubi-builder/OWNERS | 5 - 6 files changed, 502 insertions(+), 535 deletions(-) rename task/{build-paketo-ubi-builder => build-paketo-builder-oci-ta}/0.1/README.md (87%) create mode 100644 task/build-paketo-builder-oci-ta/0.1/build-paketo-builder-oci-ta.yaml delete mode 100644 task/build-paketo-ubi-builder/0.1/build-paketo-ubi-builder.yaml delete mode 100644 task/build-paketo-ubi-builder/OWNERS diff --git a/CODEOWNERS b/CODEOWNERS index f02c79814a..d58df983de 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -112,6 +112,9 @@ /task/oci-copy @ralphbean /task/oci-copy-oci-ta @ralphbean +# renovate groupName=buildpack +/task/build-paketo-builder-oci-ta @cmoulliard + # These are auto-generated and often require changes when tasks change. # Allow anyone with write access to approve the changes. /pipelines/*/README.md diff --git a/renovate.json b/renovate.json index 648ef3f51b..fc3c6e36e9 100644 --- a/renovate.json +++ b/renovate.json @@ -176,6 +176,12 @@ "task/rpms-signature-scan/**", "task/verify-signed-rpms/**" ] + }, + { + "groupName": "buildpack", + "matchFileNames": [ + "task/build-paketo-builder-oci-ta/**" + ] } ], "postUpdateOptions": [ diff --git a/task/build-paketo-ubi-builder/0.1/README.md b/task/build-paketo-builder-oci-ta/0.1/README.md similarity index 87% rename from task/build-paketo-ubi-builder/0.1/README.md rename to task/build-paketo-builder-oci-ta/0.1/README.md index 329a3e9f74..3efbbe1a39 100644 --- a/task/build-paketo-ubi-builder/0.1/README.md +++ b/task/build-paketo-builder-oci-ta/0.1/README.md @@ -1,13 +1,13 @@ -# build-paketo-ubi-builder task +# build-paketo-builder-oci-ta task -The `build-paketo-ubi-builder` task builds an ubi image for a paketo builder using as input the [builder.toml](https://buildpacks.io/docs/reference/config/builder-config/) file. The image is build using the pack tool packaged part of the [paketo-container](https://github.com/konflux-ci/paketo-container/) image. +The `build-paketo-builder-oci-ta` task builds a builder image (e.g. https://github.com/paketo-community/builder-ubi-base) for paketo using as input the [builder.toml](https://buildpacks.io/docs/reference/config/builder-config/) file. The image is build using the pack tool packaged part of the [paketo-container](https://github.com/konflux-ci/paketo-container/) image. The task also produces the SBOM which is signed and added to the image. ## Parameters | name | description | default value | required | |----------------------|-------------------------------------------------------------------------------------|----------------------------------------------------------------------------|----------| | BUILD_ARGS | Array of --build-arg values ("arg=value" strings) | [] | false | -| BUILDER_NAME | Name of the paketo builder image containing the tools as: pack, jam, create-package | quay.io/redhat-user-workloads/konflux-build-pipeli-tenant/paketo-container | false | +| BUILDER_NAME | Name of the paketo builder image containing the tools as: pack, jam, create-package | | true | | CACHI2_ARTIFACT | The Trusted Artifact URI pointing to the artifact with the prefetched dependencies. | "" | false | | CONTEXT | Path to the directory to use as context. | . | false | | HERMETIC | Determines if build will be executed without network access. | false | false | diff --git a/task/build-paketo-builder-oci-ta/0.1/build-paketo-builder-oci-ta.yaml b/task/build-paketo-builder-oci-ta/0.1/build-paketo-builder-oci-ta.yaml new file mode 100644 index 0000000000..43412abbe0 --- /dev/null +++ b/task/build-paketo-builder-oci-ta/0.1/build-paketo-builder-oci-ta.yaml @@ -0,0 +1,490 @@ +--- +apiVersion: tekton.dev/v1 +kind: Task +metadata: + name: build-paketo-builder-oci-ta + annotations: + tekton.dev/pipelines.minVersion: 0.12.1 + tekton.dev/tags: image-build, buildpack, paketo, konflux + labels: + app.kubernetes.io/version: "0.1" + build.appstudio.redhat.com/build_type: pack +spec: + description: |- + build-paketo-builder-oci-ta task builds an image of a paketo builder project using as input the builder.toml file. + The task also produces the SBOM which is signed and added to the image. + params: + - name: BUILD_ARGS + description: the arguments to be passed to the pack command to build the image + type: array + default: [] + - name: CACHI2_ARTIFACT + description: The Trusted Artifact URI pointing to the artifact with the prefetched + dependencies. + default: "" + type: string + - name: CONTEXT + description: Path to the directory to use as context. + default: . + type: string + - name: HERMETIC + description: Determines if build will be executed without network access. + default: "false" + type: string + - name: IMAGE + description: Reference of the image that pack will produce. + type: string + - name: PLATFORM + description: The VM OS type to be used to run the podman container doing the build + default: "linux-mlarge/amd64" + type: string + - name: SOURCE_ARTIFACT + description: The Trusted Artifact URI pointing to the artifact with + the application source code. + type: string + - name: SOURCE_CODE_DIR + description: The directory containing the code source + default: . + type: string + - name: STORAGE_DRIVER + description: Storage driver to configure for buildah + default: vfs + type: string + - name: TLSVERIFY + description: Verify the TLS on the registry endpoint (for push/pull to a non-TLS registry) + type: string + default: "true" + - name: caTrustConfigMapKey + description: The name of the key in the ConfigMap that contains the CA bundle + data. + type: string + default: ca-bundle.crt + - name: caTrustConfigMapName + description: The name of the ConfigMap to read CA bundle data from. + type: string + default: trusted-ca + results: + - name: "IMAGE_URL" + description: "Image repository and tag where the built image was pushed" + type: string + - name: "IMAGE_DIGEST" + description: "Digest of the image just built" + type: string + - name: "IMAGE_REF" + description: "Image reference of the built image" + type: string + - name: "BASE_IMAGES_DIGESTS" + description: "Digests of the base images used for build" + type: string + - name: "SBOM_BLOB_URL" + description: "SBOM Image URL" + type: string + volumes: + - name: ssh + secret: + secretName: "multi-platform-ssh-$(context.taskRun.name)" + - name: shared + emptyDir: {} + - name: varlibcontainers + emptyDir: {} + - configMap: + items: + - key: $(params.caTrustConfigMapKey) + path: ca-bundle.crt + name: $(params.caTrustConfigMapName) + optional: true + name: trusted-ca + - name: workdir + emptyDir: {} + stepTemplate: + env: + - name: BUILDER_IMAGE + value: "quay.io/redhat-user-workloads/konflux-build-pipeli-tenant/paketo-container:ea8ddb8818bb4a55546927e7674b0362dabd6342" + - name: CONTEXT + value: $(params.CONTEXT) + - name: HERMETIC + value: $(params.HERMETIC) + - name: IMAGE + value: $(params.IMAGE) + - name: PLATFORM + value: $(params.PLATFORM) + - name: SOURCE_CODE_DIR + value: $(params.SOURCE_CODE_DIR) + - name: STORAGE_DRIVER + value: $(params.STORAGE_DRIVER) + - name: TLSVERIFY + value: $(params.TLSVERIFY) + + volumeMounts: + - mountPath: /shared + name: shared + - mountPath: /var/workdir + name: workdir + steps: + - name: use-trusted-artifact + image: quay.io/redhat-appstudio/build-trusted-artifacts:latest@sha256:81c4864dae6bb11595f657be887e205262e70086a05ed16ada827fd6391926ac + args: + - use + - $(params.SOURCE_ARTIFACT)=/var/workdir/source + - $(params.CACHI2_ARTIFACT)=/var/workdir/cachi2 + - args: + - "$(params.BUILD_ARGS[*])" + image: "quay.io/konflux-ci/buildah-task:latest" + name: "run-script" + script: |- + #!/usr/bin/env bash + set -eu + set -o pipefail + + echo "Step 1 :: Configure SSH and rsync folders from tekton to the VM" + mkdir -p ~/.ssh + if [ -e "/ssh/error" ]; then + #no server could be provisioned + cat /ssh/error + exit 1 + elif [ -e "/ssh/otp" ]; then + curl --cacert /ssh/otp-ca -XPOST -d @/ssh/otp "$(cat /ssh/otp-server)" >~/.ssh/id_rsa + echo "" >> ~/.ssh/id_rsa + else + cp /ssh/id_rsa ~/.ssh + fi + chmod 0400 ~/.ssh/id_rsa + + SSH_HOST=$(cat /ssh/host) + BUILD_DIR=$(cat /ssh/user-dir) + export SSH_HOST + export BUILD_DIR + export SSH_ARGS=(-o StrictHostKeyChecking=no -o ServerAliveInterval=60 -o ServerAliveCountMax=10) + + echo "Export different variables which are used within the script like args, etc" + BUILD_ARGS=() + while [[ $# -gt 0 ]]; do BUILD_ARGS+=("$1"); shift; done + export BUILD_ARGS + echo "Build args: $BUILD_ARGS" + + ssh "${SSH_ARGS[@]}" "$SSH_HOST" mkdir -p "$BUILD_DIR/workspaces" "$BUILD_DIR/scripts" "$BUILD_DIR/volumes" + + export PORT_FORWARD="" + export PODMAN_PORT_FORWARD="" + + echo "Rsync folders from pod to VM ..." + rsync -ra "/var/workdir/" "$SSH_HOST:$BUILD_DIR/volumes/workdir/" + rsync -ra "/shared/" "$SSH_HOST:$BUILD_DIR/volumes/shared/" + rsync -ra "/mnt/trusted-ca/" "$SSH_HOST:$BUILD_DIR/volumes/trusted-ca/" + rsync -ra "/tekton/results/" "$SSH_HOST:$BUILD_DIR/results/" + + echo "Step 2 :: Create the bash script to be executed within the VM" + mkdir -p scripts + + cat >scripts/script-setup.sh <<'REMOTESSHEOF' + #!/bin/sh + + echo "Start podman.socket and show podman info" + systemctl --user start podman.socket + sleep 10s + + echo "Podman version" + podman version + + echo "Podman info" + podman info + REMOTESSHEOF + chmod +x scripts/script-setup.sh + + cat >scripts/script-build.sh <<'REMOTESSHEOF' + #!/bin/sh + + cd /var/workdir + + echo "Build the builder image using pack" + for build_arg in "${BUILD_ARGS[@]}"; do + PACK_ARGS+=" $build_arg" + done + + echo "Pack extra args: $PACK_ARGS" + + echo "Execute: pack builder create ..." + export DOCKER_HOST=unix:///workdir/podman.sock + pack config experimental true + + UNSHARE_ARGS=() + if [ "${HERMETIC}" == "true" ]; then + UNSHARE_ARGS+=("--net") + fi + + echo "pack builder create ${IMAGE} --config builder.toml ${PACK_ARGS}" + unshare -Uf "${UNSHARE_ARGS[@]}" --keep-caps -r --map-users 1,1,65536 --map-groups 1,1,65536 -w source -- \ + pack builder create ${IMAGE} --config builder.toml ${PACK_ARGS} + + BASE_IMAGE=$(tomljson source/builder.toml | jq '.stack."build-image"') + podman inspect ${BASE_IMAGE} | jq -r '.[].Digest' > /shared/BASE_IMAGES_DIGESTS + echo "$BASE_IMAGE" >/shared/base_images_from_dockerfile + + REMOTESSHEOF + chmod +x scripts/script-build.sh + + cat >scripts/script-post-build.sh <<'REMOTESSHEOF' + #!/bin/sh + + echo "Push the image produced and generate its digest: $IMAGE" + podman push \ + --digestfile $BUILD_DIR/volumes/shared/IMAGE_DIGEST \ + "$IMAGE" + + echo "Export the image as OCI" + podman push "${IMAGE}" "oci:$BUILD_DIR/volumes/shared/konflux-final-image:$IMAGE" + + echo "Export: IMAGE_URL" + echo -n "$IMAGE" > $BUILD_DIR/volumes/shared/IMAGE_URL + REMOTESSHEOF + chmod +x scripts/script-post-build.sh + + + echo "Step 3 :: Execute the bash script on the VM" + + rsync -ra scripts "$SSH_HOST:$BUILD_DIR" + rsync -ra "$HOME/.docker/" "$SSH_HOST:$BUILD_DIR/.docker/" + + echo "Setup VM environment: podman, etc within the VM ..." + ssh "${SSH_ARGS[@]}" "$SSH_HOST" scripts/script-setup.sh + + # Remark: Adding security-opt to by pass: dial unix /workdir/podman.sock: connect: permission denied + ssh "${SSH_ARGS[@]}" "$SSH_HOST" "$PORT_FORWARD" podman run "$PODMAN_PORT_FORWARD" \ + -e BUILDER_IMAGE="$BUILDER_IMAGE" \ + -e HERMETIC="$HERMETIC" \ + -e PLATFORM="$PLATFORM" \ + -e STORAGE_DRIVER="$STORAGE_DRIVER" \ + -e IMAGE="$IMAGE" \ + -e BUILD_ARGS="${BUILD_ARGS[*]}" \ + -e BUILD_DIR="$BUILD_DIR" \ + -v "$BUILD_DIR/volumes/workdir:/var/workdir:Z" \ + -v "$BUILD_DIR/volumes/shared:/shared:Z" \ + -v "$BUILD_DIR/.docker:/root/.docker:Z" \ + -v "$BUILD_DIR/volumes/trusted-ca:/mnt/trusted-ca:Z" \ + -v "$BUILD_DIR/scripts:/scripts:Z" \ + -v "/run/user/1001/podman/podman.sock:/workdir/podman.sock:Z" \ + --user=0 \ + --security-opt label=disable \ + --rm "$BUILDER_IMAGE" /scripts/script-build.sh "$@" + + echo "Execute post build steps within the VM ..." + ssh "${SSH_ARGS[@]}" "$SSH_HOST" \ + BUILD_DIR="$BUILD_DIR" \ + IMAGE="$IMAGE" \ + scripts/script-post-build.sh + + echo "Rsync folders from VM to pod" + rsync -ra "$SSH_HOST:$BUILD_DIR/volumes/workdir/" /var/workdir/ + rsync -ra "$SSH_HOST:$BUILD_DIR/volumes/shared/" "/shared/" + rsync -ra "$SSH_HOST:$BUILD_DIR/results/" "/tekton/results/" + securityContext: + capabilities: + add: + - SETFCAP + volumeMounts: + - name: ssh + mountPath: "/ssh" + readOnly: true + - name: shared + mountPath: "/shared" + readOnly: false + - name: trusted-ca + mountPath: /mnt/trusted-ca + readOnly: true + workingDir: /var/workdir + - computeResources: + limits: + cpu: "2" + memory: 4Gi + requests: + cpu: 500m + memory: 1Gi + image: registry.access.redhat.com/rh-syft-tech-preview/syft-rhel9:1.4.1@sha256:34d7065427085a31dc4949bd283c001b91794d427e1e4cdf1b21ea4faf9fee3f + name: sbom-syft-generate + script: | + #!/bin/bash + set -e + if [ "${IMAGE_APPEND_PLATFORM}" == "true" ]; then + IMAGE="${IMAGE}-${PLATFORM//[^a-zA-Z0-9]/-}" + export IMAGE + fi + + 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 scan oci-dir:/shared/konflux-final-image -o cyclonedx-json > /var/workdir/sbom-image.json + volumeMounts: + - mountPath: /shared + name: shared + workingDir: /var/workdir/source + - computeResources: + limits: + cpu: 200m + memory: 512Mi + requests: + cpu: 100m + memory: 256Mi + image: quay.io/redhat-appstudio/sbom-utility-scripts-image@sha256:11851ba63f63dfdcf722e47993f41a1f5f31a7a0dc8aa85b810ce2466daf23af + name: prepare-sboms + script: | + #!/bin/bash + set -e + if [ "${IMAGE_APPEND_PLATFORM}" == "true" ]; then + IMAGE="${IMAGE}-${PLATFORM//[^a-zA-Z0-9]/-}" + export IMAGE + fi + + + 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 + securityContext: + runAsUser: 0 + volumeMounts: + - mountPath: /shared + name: shared + 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 + + 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 + + + echo "Pull the image from the OCI storage." + + buildah --storage-driver "$STORAGE_DRIVER" pull "$IMAGE" + + + echo "Copy within the container of the image the sbom files" + + container=$(buildah --storage-driver "$STORAGE_DRIVER" from --pull-never "$IMAGE") + buildah --storage-driver "$STORAGE_DRIVER" copy "$container" sbom-cyclonedx.json sbom-purl.json /root/buildinfo/content_manifests/ + + BUILDAH_ARGS=() + if [ "${SQUASH}" == "true" ]; then + BUILDAH_ARGS+=("--squash") + fi + + buildah --storage-driver "$STORAGE_DRIVER" commit "${BUILDAH_ARGS[@]}" "$container" "$IMAGE" + + + echo "Pushing to ${IMAGE%:*}:${TASKRUN_NAME}" + + retries=5 + if ! buildah push \ + --retry "$retries" \ + --storage-driver "$STORAGE_DRIVER" \ + --tls-verify="$TLSVERIFY" \ + "$IMAGE" \ + "docker://${IMAGE%:*}:$(context.taskRun.name)"; then + echo "Failed to push sbom image to ${IMAGE%:*}:$(context.taskRun.name) after ${retries} tries" + exit 1 + fi + + + echo "Pushing to ${IMAGE}" + + if ! buildah push \ + --retry "$retries" \ + --storage-driver "$STORAGE_DRIVER" \ + --tls-verify="$TLSVERIFY" \ + --digestfile "/var/workdir/image-digest" "$IMAGE" \ + "docker://$IMAGE"; then + echo "Failed to push sbom image to $IMAGE after ${retries} tries" + exit 1 + fi + + + echo "Save the different results" + + tee "$(results.IMAGE_DIGEST.path)" < "/var/workdir/image-digest" + echo -n "$IMAGE" | tee "$(results.IMAGE_URL.path)" + { + 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)" + + tee "$(results.BASE_IMAGES_DIGESTS.path)" < /shared/BASE_IMAGES_DIGESTS + securityContext: + capabilities: + add: + - SETFCAP + runAsUser: 0 + volumeMounts: + - mountPath: /var/lib/containers + name: varlibcontainers + - mountPath: /shared + name: shared + - mountPath: /mnt/trusted-ca + name: trusted-ca + readOnly: true + workingDir: /var/workdir + - computeResources: + limits: + cpu: 200m + memory: 512Mi + requests: + cpu: 100m + memory: 256Mi + image: quay.io/konflux-ci/appstudio-utils:48c311af02858e2422d6229600e9959e496ddef1@sha256:91ddd999271f65d8ec8487b10f3dd378f81aa894e11b9af4d10639fd52bba7e8 + name: upload-sbom + script: | + #!/bin/bash + set -e + if [ "${IMAGE_APPEND_PLATFORM}" == "true" ]; then + IMAGE="${IMAGE}-${PLATFORM//[^a-zA-Z0-9]/-}" + export IMAGE + fi + 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 + + cosign attach sbom --sbom sbom-cyclonedx.json --type cyclonedx "$(cat "$(results.IMAGE_REF.path)")" + volumeMounts: + - mountPath: /mnt/trusted-ca + name: trusted-ca + readOnly: true + workingDir: /var/workdir diff --git a/task/build-paketo-ubi-builder/0.1/build-paketo-ubi-builder.yaml b/task/build-paketo-ubi-builder/0.1/build-paketo-ubi-builder.yaml deleted file mode 100644 index 56a0ce972e..0000000000 --- a/task/build-paketo-ubi-builder/0.1/build-paketo-ubi-builder.yaml +++ /dev/null @@ -1,527 +0,0 @@ ---- -apiVersion: tekton.dev/v1 -kind: Task -metadata: - name: build-paketo-ubi-builder - annotations: - tekton.dev/pipelines.minVersion: 0.12.1 - tekton.dev/tags: image-build, buildpack, paketo, konflux - labels: - app.kubernetes.io/version: "0.1" - build.appstudio.redhat.com/build_type: pack -spec: - description: |- - Build-paketo-ubi-builder task builds a ubi image of a paketo builder project using as input the builder.toml file. - The task also produces the SBOM which is signed and added to the image. - params: - - name: BUILD_ARGS - description: the arguments to be passed to the pack command to build the image - type: array - default: [] - - name: BUILDER_IMAGE - description: The image packaging the paketo tools and to be used to build - type: string - default: "quay.io/redhat-user-workloads/konflux-build-pipeli-tenant/paketo-container:ea8ddb8818bb4a55546927e7674b0362dabd6342" - - name: CACHI2_ARTIFACT - description: The Trusted Artifact URI pointing to the artifact with the prefetched - dependencies. - default: "" - type: string - - name: CONTEXT - description: Path to the directory to use as context. - default: . - type: string - - name: HERMETIC - description: Determines if build will be executed without network access. - default: "false" - type: string - - name: IMAGE - description: Reference of the image that pack will produce. - type: string - - name: PLATFORM - description: The VM OS type to be used to run the podman container doing the build - default: "linux-mlarge/amd64" - type: string - - name: SOURCE_ARTIFACT - description: The Trusted Artifact URI pointing to the artifact with - the application source code. - type: string - - name: SOURCE_CODE_DIR - description: The directory containing the code source - default: . - type: string - - name: STORAGE_DRIVER - description: Storage driver to configure for buildah - default: vfs - type: string - - name: TLSVERIFY - description: Verify the TLS on the registry endpoint (for push/pull to a non-TLS registry) - type: string - default: "true" - - name: caTrustConfigMapKey - description: The name of the key in the ConfigMap that contains the CA bundle - data. - type: string - default: ca-bundle.crt - - name: caTrustConfigMapName - description: The name of the ConfigMap to read CA bundle data from. - type: string - default: trusted-ca - results: - - name: "IMAGE_URL" - description: "Image repository and tag where the built image was pushed" - type: string - - name: "IMAGE_DIGEST" - description: "Digest of the image just built" - type: string - - name: "IMAGE_REF" - description: "Image reference of the built image" - type: string - - name: "BASE_IMAGES_DIGESTS" - description: "Digests of the base images used for build" - type: string - - name: "SBOM_BLOB_URL" - description: "SBOM Image URL" - type: string - volumes: - - name: ssh - secret: - secretName: "multi-platform-ssh-$(context.taskRun.name)" - - name: shared - emptyDir: {} - - name: varlibcontainers - emptyDir: {} - - configMap: - items: - - key: $(params.caTrustConfigMapKey) - path: ca-bundle.crt - name: $(params.caTrustConfigMapName) - optional: true - name: trusted-ca - - name: workdir - emptyDir: {} - stepTemplate: - env: - - name: BUILDER_IMAGE - value: $(params.BUILDER_IMAGE) - - name: CONTEXT - value: $(params.CONTEXT) - - name: HERMETIC - value: $(params.HERMETIC) - - name: IMAGE - value: $(params.IMAGE) - - name: PLATFORM - value: $(params.PLATFORM) - - name: SOURCE_CODE_DIR - value: $(params.SOURCE_CODE_DIR) - - name: STORAGE_DRIVER - value: $(params.STORAGE_DRIVER) - - name: TLSVERIFY - value: $(params.TLSVERIFY) - - volumeMounts: - - mountPath: /shared - name: shared - - mountPath: /var/workdir - name: workdir - steps: - - name: use-trusted-artifact - image: quay.io/redhat-appstudio/build-trusted-artifacts:latest@sha256:81c4864dae6bb11595f657be887e205262e70086a05ed16ada827fd6391926ac - args: - - use - - $(params.SOURCE_ARTIFACT)=/var/workdir/source - - $(params.CACHI2_ARTIFACT)=/var/workdir/cachi2 - - args: - - "$(params.BUILD_ARGS[*])" - image: "quay.io/konflux-ci/buildah-task:latest" - name: "run-script" - script: |- - #!/usr/bin/env bash - set -eu - set -o pipefail - - echo "##########################################################################################" - echo "### Step 1 :: Configure SSH and rsync folders from tekton to the VM" - echo "##########################################################################################" - mkdir -p ~/.ssh - if [ -e "/ssh/error" ]; then - #no server could be provisioned - cat /ssh/error - exit 1 - elif [ -e "/ssh/otp" ]; then - curl --cacert /ssh/otp-ca -XPOST -d @/ssh/otp $(cat /ssh/otp-server) >~/.ssh/id_rsa - echo "" >> ~/.ssh/id_rsa - else - cp /ssh/id_rsa ~/.ssh - fi - chmod 0400 ~/.ssh/id_rsa - - export SSH_HOST=$(cat /ssh/host) - export BUILD_DIR=$(cat /ssh/user-dir) - export SSH_ARGS="-o StrictHostKeyChecking=no -o ServerAliveInterval=60 -o ServerAliveCountMax=10" - - echo "### Export different variables which are used within the script like args, etc" - export BUILD_ARGS="$@" - - ssh $SSH_ARGS "$SSH_HOST" mkdir -p "$BUILD_DIR/workspaces" "$BUILD_DIR/scripts" "$BUILD_DIR/volumes" - - export PORT_FORWARD="" - export PODMAN_PORT_FORWARD="" - - echo "### rsync folders from pod to VM ..." - #rsync -ra $(workspaces.source.path)/ "$SSH_HOST:$BUILD_DIR/volumes/workdir/" - rsync -ra "/var/workdir/" "$SSH_HOST:$BUILD_DIR/volumes/workdir/" - rsync -ra "/shared/" "$SSH_HOST:$BUILD_DIR/volumes/shared/" - rsync -ra "/mnt/trusted-ca/" "$SSH_HOST:$BUILD_DIR/volumes/trusted-ca/" - rsync -ra "/tekton/results/" "$SSH_HOST:$BUILD_DIR/results/" - - echo "##########################################################################################" - echo "### Step 2 :: Create the bash script to be executed within the VM" - echo "##########################################################################################" - mkdir -p scripts - - cat >scripts/script-setup.sh <<'REMOTESSHEOF' - #!/bin/sh - - echo "### Start podman.socket and show podman info ##" - systemctl --user start podman.socket - sleep 10s - - echo "## Podman version" - podman version - - echo "## Podman info" - podman info - REMOTESSHEOF - chmod +x scripts/script-setup.sh - - cat >scripts/script-build.sh <<'REMOTESSHEOF' - #!/bin/sh - - cd /var/workdir - - echo "### Build the builder image using pack" - for build_arg in "${BUILD_ARGS[@]}"; do - PACK_ARGS+=" $build_arg" - done - - echo "### Pack extra args: $PACK_ARGS" - - echo "### Execute: pack builder create ..." - export DOCKER_HOST=unix:///workdir/podman.sock - pack config experimental true - - UNSHARE_ARGS=() - if [ "${HERMETIC}" == "true" ]; then - UNSHARE_ARGS+=("--net") - fi - - echo "pack builder create ${IMAGE} --config builder.toml ${PACK_ARGS}" - unshare -Uf "${UNSHARE_ARGS[@]}" --keep-caps -r --map-users 1,1,65536 --map-groups 1,1,65536 -w source -- \ - pack builder create ${IMAGE} --config builder.toml ${PACK_ARGS} - - BASE_IMAGE=$(tomljson source/builder.toml | jq '.stack."build-image"') - podman inspect ${BASE_IMAGE} | jq -r '.[].Digest' > /shared/BASE_IMAGES_DIGESTS - - REMOTESSHEOF - chmod +x scripts/script-build.sh - - cat >scripts/script-post-build.sh <<'REMOTESSHEOF' - #!/bin/sh - - echo "###########################################################" - - echo "### Push the image produced and generate its digest: $IMAGE" - podman push \ - --digestfile $BUILD_DIR/volumes/shared/IMAGE_DIGEST \ - "$IMAGE" - - echo "###########################################################" - echo "### Export the image as OCI" - podman push "${IMAGE}" "oci:$BUILD_DIR/volumes/shared/konflux-final-image:$IMAGE" - echo "###########################################################" - - echo "###########################################################" - echo "### Export: IMAGE_URL" - echo "###########################################################" - echo -n "$IMAGE" > $BUILD_DIR/volumes/shared/IMAGE_URL - REMOTESSHEOF - chmod +x scripts/script-post-build.sh - - echo "##########################################################################################" - echo "### Step 3 :: Execute the bash script on the VM" - echo "##########################################################################################" - rsync -ra scripts "$SSH_HOST:$BUILD_DIR" - rsync -ra "$HOME/.docker/" "$SSH_HOST:$BUILD_DIR/.docker/" - - echo "### Setup VM environment: podman, etc within the VM ..." - ssh $SSH_ARGS "$SSH_HOST" scripts/script-setup.sh - - # Adding security-opt to by pass: dial unix /workdir/podman.sock: connect: permission denied - ssh $SSH_ARGS "$SSH_HOST" $PORT_FORWARD podman run $PODMAN_PORT_FORWARD \ - -e BUILDER_IMAGE=$BUILDER_IMAGE \ - -e HERMETIC="$HERMETIC" \ - -e PLATFORM=$PLATFORM \ - -e STORAGE_DRIVER="$STORAGE_DRIVER" \ - -e IMAGE=$IMAGE \ - -e BUILD_ARGS=$BUILD_ARGS \ - -e BUILD_DIR=$BUILD_DIR \ - -v "$BUILD_DIR/volumes/workdir:/var/workdir:Z" \ - -v "$BUILD_DIR/volumes/shared:/shared:Z" \ - -v "$BUILD_DIR/.docker:/root/.docker:Z" \ - -v "$BUILD_DIR/volumes/trusted-ca:/mnt/trusted-ca:Z" \ - -v "$BUILD_DIR/scripts:/scripts:Z" \ - -v "/run/user/1001/podman/podman.sock:/workdir/podman.sock:Z" \ - --user=0 \ - --security-opt label=disable \ - --rm "$BUILDER_IMAGE" /scripts/script-build.sh "$@" - - echo "### Execute post build steps within the VM ..." - ssh $SSH_ARGS "$SSH_HOST" \ - BUILD_DIR=$BUILD_DIR \ - IMAGE=$IMAGE \ - scripts/script-post-build.sh - - echo "### rsync folders from VM to pod" - #rsync -ra "$SSH_HOST:$BUILD_DIR/volumes/workdir/" "$(workspaces.source.path)/" - rsync -ra "$SSH_HOST:$BUILD_DIR/volumes/workdir/" /var/workdir/ - rsync -ra "$SSH_HOST:$BUILD_DIR/volumes/shared/" "/shared/" - rsync -ra "$SSH_HOST:$BUILD_DIR/results/" "/tekton/results/" - - securityContext: - capabilities: - add: - - SETFCAP - volumeMounts: - - name: ssh - mountPath: "/ssh" - readOnly: true - - name: shared - mountPath: "/shared" - readOnly: false - - name: trusted-ca - mountPath: /mnt/trusted-ca - readOnly: true - workingDir: /var/workdir - - computeResources: - limits: - cpu: "2" - memory: 4Gi - requests: - cpu: 500m - memory: 1Gi - image: registry.access.redhat.com/rh-syft-tech-preview/syft-rhel9:1.4.1@sha256:34d7065427085a31dc4949bd283c001b91794d427e1e4cdf1b21ea4faf9fee3f - name: sbom-syft-generate - script: | - #!/bin/bash - set -e - if [ "${IMAGE_APPEND_PLATFORM}" == "true" ]; then - IMAGE="${IMAGE}-${PLATFORM//[^a-zA-Z0-9]/-}" - export IMAGE - fi - echo "##########################################################################################" - echo "### Running syft on the source directory" - echo "##########################################################################################" - syft dir:"/var/workdir/$SOURCE_CODE_DIR/$CONTEXT" --output cyclonedx-json="/var/workdir/sbom-source.json" - - echo "##########################################################################################" - echo "### Running syft on the image filesystem" - echo "##########################################################################################" - # syft dir:"$(cat /shared/container_path)" --output cyclonedx-json="/var/workdir/sbom-image.json" - syft scan oci-dir:/shared/konflux-final-image -o cyclonedx-json > /var/workdir/sbom-image.json - volumeMounts: - - mountPath: /shared - name: shared - workingDir: /var/workdir/source - - computeResources: - limits: - cpu: 200m - memory: 512Mi - requests: - cpu: 100m - memory: 256Mi - image: quay.io/redhat-appstudio/sbom-utility-scripts-image@sha256:11851ba63f63dfdcf722e47993f41a1f5f31a7a0dc8aa85b810ce2466daf23af - name: prepare-sboms - script: | - #!/bin/bash - set -e - if [ "${IMAGE_APPEND_PLATFORM}" == "true" ]; then - IMAGE="${IMAGE}-${PLATFORM//[^a-zA-Z0-9]/-}" - export IMAGE - fi - - echo "##########################################################################################" - echo "## Merging contents of sbom-source.json and sbom-image.json into sbom-cyclonedx.json" - echo "##########################################################################################" - python3 /scripts/merge_syft_sboms.py - - if [ -f "sbom-cachi2.json" ]; then - echo "##########################################################################################" - echo "## Merging contents of sbom-cachi2.json into sbom-cyclonedx.json" - echo "##########################################################################################" - python3 /scripts/merge_cachi2_sboms.py sbom-cachi2.json sbom-cyclonedx.json >sbom-temp.json - mv sbom-temp.json sbom-cyclonedx.json - fi - - echo "##########################################################################################" - echo "Creating sbom-purl.json" - echo "##########################################################################################" - python3 /scripts/create_purl_sbom.py - - # TODO: How can we get for the paketo stuffs: base_images_from_dockerfile - # echo "##########################################################################################" - # echo "Adding base images data to sbom-cyclonedx.json" - # echo "##########################################################################################" - # 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 - securityContext: - runAsUser: 0 - volumeMounts: - - mountPath: /shared - name: shared - 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 - - echo "##########################################################################################" - echo "Pull the image from the OCI storage." - echo "##########################################################################################" - buildah --storage-driver $STORAGE_DRIVER pull $IMAGE - - echo "##########################################################################################" - echo "## Copy within the container of the image the sbom files" - echo "##########################################################################################" - #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 --storage-driver $STORAGE_DRIVER from --pull-never $IMAGE) - buildah --storage-driver $STORAGE_DRIVER copy $container sbom-cyclonedx.json sbom-purl.json /root/buildinfo/content_manifests/ - - # The image build don't include "ImageAnnotations" as "null" - #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 --storage-driver $STORAGE_DRIVER commit "${BUILDAH_ARGS[@]}" $container $IMAGE - set +x - echo "######################################################$TLSVERIFY####################################" - echo "Pushing to ${IMAGE%:*}:${TASKRUN_NAME}" - echo "##########################################################################################" - if ! retry buildah --storage-driver $STORAGE_DRIVER 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 "##########################################################################################" - echo "Pushing to ${IMAGE}" - echo "##########################################################################################" - if ! retry buildah --storage-driver $STORAGE_DRIVER 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 "##########################################################################################" - echo "## Save the different results" - echo "##########################################################################################" - cat "/shared"/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)" - - # 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)" - - cat "/shared"/BASE_IMAGES_DIGESTS | tee $(results.BASE_IMAGES_DIGESTS.path) - securityContext: - capabilities: - add: - - SETFCAP - runAsUser: 0 - volumeMounts: - - mountPath: /var/lib/containers - name: varlibcontainers - - mountPath: /shared - name: shared - - mountPath: /mnt/trusted-ca - name: trusted-ca - readOnly: true - workingDir: /var/workdir - - computeResources: - limits: - cpu: 200m - memory: 512Mi - requests: - cpu: 100m - memory: 256Mi - image: quay.io/konflux-ci/appstudio-utils:48c311af02858e2422d6229600e9959e496ddef1@sha256:91ddd999271f65d8ec8487b10f3dd378f81aa894e11b9af4d10639fd52bba7e8 - name: upload-sbom - script: | - #!/bin/bash - set -e - if [ "${IMAGE_APPEND_PLATFORM}" == "true" ]; then - IMAGE="${IMAGE}-${PLATFORM//[^a-zA-Z0-9]/-}" - export IMAGE - fi - 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 - - cosign attach sbom --sbom sbom-cyclonedx.json --type cyclonedx "$(cat "$(results.IMAGE_REF.path)")" - volumeMounts: - - mountPath: /mnt/trusted-ca - name: trusted-ca - readOnly: true - workingDir: /var/workdir \ No newline at end of file diff --git a/task/build-paketo-ubi-builder/OWNERS b/task/build-paketo-ubi-builder/OWNERS deleted file mode 100644 index d3f0ff4a7e..0000000000 --- a/task/build-paketo-ubi-builder/OWNERS +++ /dev/null @@ -1,5 +0,0 @@ -# See the OWNERS docs: https://go.k8s.io/owners -approvers: - - build-team -reviewers: - - build-team