From df45fab0c4036fda9974c8e24694a2f22e4cc779 Mon Sep 17 00:00:00 2001 From: Zoran Regvart Date: Wed, 5 Jun 2024 13:11:33 +0200 Subject: [PATCH] Regenerate Trusted Artifacts Task Run `hack/generate-ta-tasks.sh` to regenerate the Trusted Artifacts Task variants. --- task/buildah-oci-ta/0.1/README.md | 30 +- task/buildah-oci-ta/0.1/buildah-oci-ta.yaml | 942 +++++++++--------- task/git-clone-oci-ta/0.1/README.md | 30 +- .../0.1/git-clone-oci-ta.yaml | 556 +++++------ .../0.1/README.md | 16 +- .../0.1/prefetch-dependencies-oci-ta.yaml | 306 +++--- task/sast-snyk-check-oci-ta/0.1/README.md | 4 +- .../0.1/sast-snyk-check-oci-ta.yaml | 192 ++-- task/source-build-oci-ta/0.1/README.md | 8 +- .../0.1/source-build-oci-ta.yaml | 204 ++-- 10 files changed, 1157 insertions(+), 1131 deletions(-) diff --git a/task/buildah-oci-ta/0.1/README.md b/task/buildah-oci-ta/0.1/README.md index 7349528798..6df7de9dfe 100644 --- a/task/buildah-oci-ta/0.1/README.md +++ b/task/buildah-oci-ta/0.1/README.md @@ -8,31 +8,33 @@ When prefetch-dependencies task was activated it is using its artifacts to run b ## Parameters |name|description|default value|required| |---|---|---|---| -|IMAGE|Reference of the image buildah will produce.||true| -|SOURCE_ARTIFACT|The trusted artifact URI containing the application source code.||true| -|CACHI2_ARTIFACT|The trusted artifact URI containing the prefetched dependencies.|""|false| -|DOCKERFILE|Path to the Dockerfile to build.|./Dockerfile|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| +|CACHI2_ARTIFACT|The Trusted Artifact URI pointing to the artifact with the prefetched dependencies.|""|false| +|COMMIT_SHA|The image is built from this commit.|""|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| +|DOCKERFILE|Path to the Dockerfile to build.|./Dockerfile|false| |DOCKER_AUTH|unused, should be removed in next task version|""|false| +|ENTITLEMENT_SECRET|Name of secret which contains the entitlement certificates|etc-pki-entitlement|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|Reference of the image buildah will produce.||true| |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| +|PREFETCH_INPUT|In case it is not empty, the prefetched content should be made available to the build.|""|false| +|SOURCE_ARTIFACT|The Trusted Artifact URI pointing to the artifact with the application source code.||true| +|TARGET_STAGE|Target stage in Dockerfile to build. If not specified, the Dockerfile is processed entirely to (and including) its last stage.|""|false| +|TLSVERIFY|Verify the TLS on the registry endpoint (for push/pull to a non-TLS registry)|true|false| |YUM_REPOS_D_FETCHED|Path in source workspace where dynamically-fetched repos are present|fetched.repos.d|false| +|YUM_REPOS_D_SRC|Path in the git repository in which yum repository files are stored|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| -|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| +|caTrustConfigMapKey|The name of the key in the ConfigMap that contains the CA bundle data.|ca-bundle.crt|false| +|caTrustConfigMapName|The name of the ConfigMap to read CA bundle data from.|trusted-ca|false| ## Results |name|description| |---|---| +|BASE_IMAGES_DIGESTS|Digests of the base images used for build| |IMAGE_DIGEST|Digest of the image just built| |IMAGE_URL|Image repository where the built image was pushed| -|BASE_IMAGES_DIGESTS|Digests of the base images used for build| -|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.| +|SBOM_JAVA_COMPONENTS_COUNT|The counting of Java components by publisher in JSON format| diff --git a/task/buildah-oci-ta/0.1/buildah-oci-ta.yaml b/task/buildah-oci-ta/0.1/buildah-oci-ta.yaml index 1c61de7488..379b85e822 100644 --- a/task/buildah-oci-ta/0.1/buildah-oci-ta.yaml +++ b/task/buildah-oci-ta/0.1/buildah-oci-ta.yaml @@ -2,462 +2,488 @@ apiVersion: tekton.dev/v1 kind: Task metadata: - labels: - app.kubernetes.io/version: "0.1" - build.appstudio.redhat.com/build_type: "docker" - annotations: - tekton.dev/pipelines.minVersion: "0.12.1" - tekton.dev/tags: "image-build, appstudio, hacbs" - name: buildah-oci-ta + name: buildah-oci-ta + annotations: + tekton.dev/pipelines.minVersion: 0.12.1 + tekton.dev/tags: image-build, appstudio, hacbs + labels: + app.kubernetes.io/version: "0.1" + build.appstudio.redhat.com/build_type: docker spec: - description: |- - Buildah task builds source code into a container image and pushes the image into container registry using buildah tool. - In addition it generates a SBOM file, injects the SBOM file into final container image and pushes the SBOM file as separate image using cosign tool. - When [Java dependency rebuild](https://redhat-appstudio.github.io/docs.stonesoup.io/Documentation/main/cli/proc_enabled_java_dependencies.html) is enabled it triggers rebuilds of Java artifacts. - When prefetch-dependencies task was activated it is using its artifacts to run build in hermetic environment. - params: - - description: Reference of the image buildah will produce. - name: IMAGE - type: string - - description: The Trusted Artifact URI pointing to the artifact with the application source code. - name: SOURCE_ARTIFACT - type: string - - description: The Trusted Artifact URI pointing to the artifact with the prefetched dependencies. - name: CACHI2_ARTIFACT - type: string - default: "" - - default: ./Dockerfile - description: Path to the Dockerfile to build. - name: DOCKERFILE - type: string - - default: . - description: Path to the directory to use as context. - name: CONTEXT - type: string - - default: "true" - description: Verify the TLS on the registry endpoint (for push/pull to a non-TLS registry) - name: TLSVERIFY - type: string - - description: unused, should be removed in next task version - name: DOCKER_AUTH - type: string - default: "" - - default: "false" - description: Determines if build will be executed without network access. - name: HERMETIC - type: string - - default: "" - description: In case it is not empty, the prefetched content should be made available to the build. - name: PREFETCH_INPUT - type: string - - default: "" - description: 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. - name: IMAGE_EXPIRES_AFTER - type: string - - name: COMMIT_SHA - description: The image is built from this commit. - type: string - default: "" - - name: YUM_REPOS_D_SRC - description: Path in the git repository in which yum repository files are stored - default: repos.d - - name: YUM_REPOS_D_FETCHED - description: Path in source workspace where dynamically-fetched repos are present - default: fetched.repos.d - - name: YUM_REPOS_D_TARGET - description: Target path on the container in which yum repository files should be made available - default: /etc/yum.repos.d - - name: TARGET_STAGE - description: Target stage in Dockerfile to build. If not specified, the Dockerfile is processed entirely to (and including) its last stage. - type: string - default: "" - - name: ENTITLEMENT_SECRET - description: Name of secret which contains the entitlement certificates - type: string - default: "etc-pki-entitlement" - - name: BUILD_ARGS - description: Array of --build-arg values ("arg=value" strings) - type: array - default: [] - - name: BUILD_ARGS_FILE - description: Path to a file with build arguments, see https://www.mankier.com/1/buildah-build#--build-arg-file - type: string - default: "" - - results: - - description: Digest of the image just built - name: IMAGE_DIGEST - - description: Image repository where the built image was pushed - name: IMAGE_URL - - description: Digests of the base images used for build - name: BASE_IMAGES_DIGESTS - - name: SBOM_JAVA_COMPONENTS_COUNT - description: The counting of Java components by publisher in JSON format - type: string - - name: JAVA_COMMUNITY_DEPENDENCIES - description: The Java dependencies that came from community sources such as Maven central. - stepTemplate: - env: - - name: BUILDAH_FORMAT - value: oci - - name: STORAGE_DRIVER - value: vfs - - name: HERMETIC - value: $(params.HERMETIC) - - name: CONTEXT - value: $(params.CONTEXT) - - name: DOCKERFILE - value: $(params.DOCKERFILE) - - name: IMAGE - value: $(params.IMAGE) - - name: TLSVERIFY - value: $(params.TLSVERIFY) - - name: IMAGE_EXPIRES_AFTER - value: $(params.IMAGE_EXPIRES_AFTER) - - name: YUM_REPOS_D_SRC - value: $(params.YUM_REPOS_D_SRC) - - name: YUM_REPOS_D_FETCHED - value: $(params.YUM_REPOS_D_FETCHED) - - name: YUM_REPOS_D_TARGET - value: $(params.YUM_REPOS_D_TARGET) - - name: TARGET_STAGE - value: $(params.TARGET_STAGE) - - name: ENTITLEMENT_SECRET - value: $(params.ENTITLEMENT_SECRET) - - name: BUILD_ARGS_FILE - value: $(params.BUILD_ARGS_FILE) - volumeMounts: - - mountPath: /var/workdir - name: workdir - steps: - - image: quay.io/redhat-appstudio/build-trusted-artifacts:latest@sha256:4e39fb97f4444c2946944482df47b39c5bbc195c54c6560b0647635f553ab23d - name: use-trusted-artifact - args: - - use - - $(params.SOURCE_ARTIFACT)=/var/workdir/source - - $(params.CACHI2_ARTIFACT)=/var/workdir/cachi2 - - image: quay.io/redhat-appstudio/buildah:v1.31.0@sha256:34f12c7b72ec2c28f1ded0c494b428df4791c909f1f174dd21b8ed6a57cf5ddb - name: build - computeResources: - limits: - memory: 4Gi - requests: - memory: 512Mi - cpu: 250m - env: - - name: COMMIT_SHA - value: $(params.COMMIT_SHA) - args: - - $(params.BUILD_ARGS[*]) - script: | - SOURCE_CODE_DIR=source - if [ -e "$SOURCE_CODE_DIR/$CONTEXT/$DOCKERFILE" ]; then - dockerfile_path="$(pwd)/$SOURCE_CODE_DIR/$CONTEXT/$DOCKERFILE" - elif [ -e "$SOURCE_CODE_DIR/$DOCKERFILE" ]; then - dockerfile_path="$(pwd)/$SOURCE_CODE_DIR/$DOCKERFILE" - elif echo "$DOCKERFILE" | grep -q "^https\?://"; then - echo "Fetch Dockerfile from $DOCKERFILE" - dockerfile_path=$(mktemp --suffix=-Dockerfile) - http_code=$(curl -s -L -w "%{http_code}" --output "$dockerfile_path" "$DOCKERFILE") - if [ $http_code != 200 ]; then - echo "No Dockerfile is fetched. Server responds $http_code" - exit 1 - fi - http_code=$(curl -s -L -w "%{http_code}" --output "$dockerfile_path.dockerignore.tmp" "$DOCKERFILE.dockerignore") - if [ $http_code = 200 ]; then - echo "Fetched .dockerignore from $DOCKERFILE.dockerignore" - mv "$dockerfile_path.dockerignore.tmp" $SOURCE_CODE_DIR/$CONTEXT/.dockerignore - fi - else - echo "Cannot find Dockerfile $DOCKERFILE" - exit 1 - fi - if [ -n "$JVM_BUILD_WORKSPACE_ARTIFACT_CACHE_PORT_80_TCP_ADDR" ] && grep -q '^\s*RUN \(./\)\?mvn' "$dockerfile_path"; then - sed -i -e "s|^\s*RUN \(\(./\)\?mvn\)\(.*\)|RUN echo \"mirror.defaulthttp://$JVM_BUILD_WORKSPACE_ARTIFACT_CACHE_PORT_80_TCP_ADDR/v1/cache/default/0/*\" > /tmp/settings.yaml; \1 -s /tmp/settings.yaml \3|g" "$dockerfile_path" - touch /var/lib/containers/java - fi - - # Fixing group permission on /var/lib/containers - chown root:root /var/lib/containers - - sed -i 's/^\s*short-name-mode\s*=\s*.*/short-name-mode = "disabled"/' /etc/containers/registries.conf - - # Setting new namespace to run buildah - 2^32-2 - echo 'root:1:4294967294' | tee -a /etc/subuid >> /etc/subgid - - BUILDAH_ARGS=() - - BASE_IMAGES=$(grep -i '^\s*FROM' "$dockerfile_path" | sed 's/--platform=\S*//' | awk '{print $2}') - if [ "${HERMETIC}" == "true" ]; then - BUILDAH_ARGS+=("--pull=never") - UNSHARE_ARGS="--net" - for image in $BASE_IMAGES; do - if [ "${image}" != "scratch" ]; then - unshare -Ufp --keep-caps -r --map-users 1,1,65536 --map-groups 1,1,65536 -- buildah pull $image - fi - done - echo "Build will be executed with network isolation" - fi - - if [ -n "${TARGET_STAGE}" ]; then - BUILDAH_ARGS+=("--target=${TARGET_STAGE}") - fi - - if [ -n "${BUILD_ARGS_FILE}" ]; then - BUILDAH_ARGS+=("--build-arg-file=$(pwd)/$SOURCE_CODE_DIR/${BUILD_ARGS_FILE}") - fi - - for build_arg in "$@"; do - BUILDAH_ARGS+=("--build-arg=$build_arg") - done - - if [ -f "/var/workdir/cachi2/cachi2.env" ]; then - cp -r "/var/workdir/cachi2" /tmp/ - chmod -R go+rwX /tmp/cachi2 - VOLUME_MOUNTS="--volume /tmp/cachi2:/cachi2" - sed -i 's|^\s*run |RUN . /cachi2/cachi2.env \&\& \\\n |i' "$dockerfile_path" - echo "Prefetched content will be made available" - - prefetched_repo_for_my_arch="/tmp/cachi2/output/deps/rpm/$(uname -m)/repos.d/cachi2.repo" - if [ -f "$prefetched_repo_for_my_arch" ]; then - echo "Adding $prefetched_repo_for_my_arch to $YUM_REPOS_D_FETCHED" - mkdir -p "$YUM_REPOS_D_FETCHED" - cp --no-clobber "$prefetched_repo_for_my_arch" "$YUM_REPOS_D_FETCHED" - fi - fi - - # if yum repofiles stored in git, copy them to mount point outside the source dir - if [ -d "${SOURCE_CODE_DIR}/${YUM_REPOS_D_SRC}" ]; then - mkdir -p ${YUM_REPOS_D_FETCHED} - cp -r ${SOURCE_CODE_DIR}/${YUM_REPOS_D_SRC}/* ${YUM_REPOS_D_FETCHED} - fi - - # if anything in the repofiles mount point (either fetched or from git), mount it - if [ -d "${YUM_REPOS_D_FETCHED}" ]; then - chmod -R go+rwX ${YUM_REPOS_D_FETCHED} - mount_point=$(realpath ${YUM_REPOS_D_FETCHED}) - VOLUME_MOUNTS="${VOLUME_MOUNTS} --volume ${mount_point}:${YUM_REPOS_D_TARGET}" - fi - - LABELS=( - "--label" "build-date=$(date -u +'%Y-%m-%dT%H:%M:%S')" - "--label" "architecture=$(uname -m)" - "--label" "vcs-type=git" - ) - [ -n "$COMMIT_SHA" ] && LABELS+=("--label" "vcs-ref=$COMMIT_SHA") - [ -n "$IMAGE_EXPIRES_AFTER" ] && LABELS+=("--label" "quay.expires-after=$IMAGE_EXPIRES_AFTER") - - ENTITLEMENT_PATH="/entitlement" - if [ -d "$ENTITLEMENT_PATH" ]; then - cp -r --preserve=mode "$ENTITLEMENT_PATH" /tmp/entitlement - VOLUME_MOUNTS="${VOLUME_MOUNTS} --volume /tmp/entitlement:/etc/pki/entitlement" - echo "Adding the entitlement to the build" - fi - - unshare -Uf $UNSHARE_ARGS --keep-caps -r --map-users 1,1,65536 --map-groups 1,1,65536 -w ${SOURCE_CODE_DIR}/$CONTEXT -- buildah build \ - $VOLUME_MOUNTS \ - "${BUILDAH_ARGS[@]}" \ - "${LABELS[@]}" \ - --tls-verify=$TLSVERIFY --no-cache \ - --ulimit nofile=4096:4096 \ - -f "$dockerfile_path" -t $IMAGE . - - container=$(buildah from --pull-never $IMAGE) - buildah mount $container | tee /var/workdir/container_path - echo $container > /var/workdir/container_name - - # Save the SBOM produced by Cachi2 so it can be merged into the final SBOM later - if [ -f "/tmp/cachi2/output/bom.json" ]; then - cp /tmp/cachi2/output/bom.json ./sbom-cachi2.json - fi - - # Expose base image digests - for image in $BASE_IMAGES; do - if [ "${image}" != "scratch" ]; then - buildah images --format '{{ .Name }}:{{ .Tag }}@{{ .Digest }}' --filter reference="$image" >> $(results.BASE_IMAGES_DIGESTS.path) - fi - done - - # Needed to generate base images SBOM - echo "$BASE_IMAGES" > /var/workdir/base_images_from_dockerfile - - securityContext: - capabilities: - add: - - SETFCAP - volumeMounts: - - mountPath: /var/lib/containers - name: varlibcontainers - - mountPath: "/entitlement" - name: etc-pki-entitlement - workingDir: /var/workdir - - - name: sbom-syft-generate - image: quay.io/redhat-appstudio/syft:v0.105.1@sha256:1910b829997650c696881e5fc2fc654ddf3184c27edb1b2024e9cb2ba51ac431 - # 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: /var/workdir/source - script: | - echo "Running syft on the source directory" - syft dir:/var/workdir/source --output cyclonedx-json=/var/workdir/sbom-source.json - find $(cat /var/workdir/container_path) -xtype l -delete - echo "Running syft on the image filesystem" - syft dir:$(cat /var/workdir/container_path) --output cyclonedx-json=/var/workdir/sbom-image.json - volumeMounts: - - mountPath: /var/lib/containers - name: varlibcontainers - - name: analyse-dependencies-java-sbom - image: quay.io/redhat-appstudio/hacbs-jvm-build-request-processor:127ee0c223a2b56a9bd20a6f2eaeed3bd6015f77 - script: | - if [ -f /var/lib/containers/java ]; then - /opt/jboss/container/java/run/run-java.sh analyse-dependencies path $(cat /var/workdir/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 - volumeMounts: - - mountPath: /var/lib/containers - name: varlibcontainers - securityContext: - runAsUser: 0 - - - name: merge-syft-sboms - image: registry.access.redhat.com/ubi9/python-39:1-172.1712567222@sha256:c96f839e927c52990143df4efb2872946fcd5de9e1ed2014947bb2cf3084c27a - script: | - #!/bin/python3 - import json - - # load SBOMs - with open("./sbom-image.json") as f: - image_sbom = json.load(f) - - with open("./sbom-source.json") as f: - source_sbom = json.load(f) - - # fetch unique components from available SBOMs - def get_identifier(component): - return component["name"] + '@' + component.get("version", "") - - image_sbom_components = image_sbom.get("components", []) - existing_components = [get_identifier(component) for component in image_sbom_components] - - source_sbom_components = source_sbom.get("components", []) - for component in source_sbom_components: - if get_identifier(component) not in existing_components: - image_sbom_components.append(component) - existing_components.append(get_identifier(component)) - - image_sbom_components.sort(key=lambda c: get_identifier(c)) - - # write the CycloneDX unified SBOM - with open("./sbom-cyclonedx.json", "w") as f: - json.dump(image_sbom, f, indent=4) - workingDir: /var/workdir - securityContext: - runAsUser: 0 - - - name: merge-cachi2-sbom - image: quay.io/redhat-appstudio/cachi2:0.7.0@sha256:1fc772aa3636fd0b43d62120d832e5913843e028e8cac42814b487c3a0a32bd8 - script: | - if [ -f "/var/workdir/sbom-cachi2.json" ]; then - echo "Merging contents of sbom-cachi2.json into sbom-cyclonedx.json" - /src/utils/merge_syft_sbom.py sbom-cachi2.json sbom-cyclonedx.json > sbom-temp.json - mv sbom-temp.json sbom-cyclonedx.json - else - echo "Skipping step since no Cachi2 SBOM was produced" - fi - workingDir: /var/workdir - securityContext: - runAsUser: 0 - - - name: create-purl-sbom - image: registry.access.redhat.com/ubi9/python-39:1-172.1712567222@sha256:c96f839e927c52990143df4efb2872946fcd5de9e1ed2014947bb2cf3084c27a - script: | - #!/bin/python3 - import json - - with open("./sbom-cyclonedx.json") as f: - cyclonedx_sbom = json.load(f) - - purls = [{"purl": component["purl"]} for component in cyclonedx_sbom.get("components", []) if "purl" in component] - purl_content = {"image_contents": {"dependencies": purls}} - - with open("sbom-purl.json", "w") as output_file: - json.dump(purl_content, output_file, indent=4) - workingDir: /var/workdir - securityContext: - runAsUser: 0 - - - name: create-base-images-sbom - image: quay.io/redhat-appstudio/base-images-sbom-script@sha256:667669e3def018f9dbb8eaf8868887a40bc07842221e9a98f6787edcff021840 - env: - - name: BASE_IMAGES_DIGESTS_PATH - value: $(results.BASE_IMAGES_DIGESTS.path) - script: | - python3 /app/base_images_sbom_script.py --sbom=sbom-cyclonedx.json --base-images-from-dockerfile=base_images_from_dockerfile --base-images-digests=$BASE_IMAGES_DIGESTS_PATH - workingDir: /var/workdir - securityContext: - runAsUser: 0 - - - name: inject-sbom-and-push - image: quay.io/redhat-appstudio/buildah:v1.31.0@sha256:34f12c7b72ec2c28f1ded0c494b428df4791c909f1f174dd21b8ed6a57cf5ddb - computeResources: {} - script: | - 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 commit $container $IMAGE - - status=-1 - max_run=5 - sleep_sec=10 - for run in $(seq 1 $max_run); do - status=0 - [ "$run" -gt 1 ] && sleep $sleep_sec - echo "Pushing sbom image to registry" - buildah push \ - --tls-verify=$TLSVERIFY \ - --digestfile /var/workdir/image-digest $IMAGE \ - docker://$IMAGE && break || status=$? - done - if [ "$status" -ne 0 ]; then - echo "Failed to push sbom image to registry 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) - - securityContext: - runAsUser: 0 - capabilities: - add: - - SETFCAP - volumeMounts: - - mountPath: /var/lib/containers - name: varlibcontainers - workingDir: /var/workdir - - - name: upload-sbom - image: quay.io/redhat-appstudio/cosign:v2.1.1@sha256:c883d6f8d39148f2cea71bff4622d196d89df3e510f36c140c097b932f0dd5d5 - args: - - attach - - sbom - - --sbom - - sbom-cyclonedx.json - - --type - - cyclonedx - - $(params.IMAGE) - workingDir: /var/workdir - - volumes: - - name: varlibcontainers - emptyDir: {} - - name: workdir - emptyDir: {} - - name: etc-pki-entitlement - secret: - secretName: $(params.ENTITLEMENT_SECRET) - optional: true + description: |- + Buildah task builds source code into a container image and pushes the image into container registry using buildah tool. + In addition it generates a SBOM file, injects the SBOM file into final container image and pushes the SBOM file as separate image using cosign tool. + When [Java dependency rebuild](https://redhat-appstudio.github.io/docs.stonesoup.io/Documentation/main/cli/proc_enabled_java_dependencies.html) is enabled it triggers rebuilds of Java artifacts. + When prefetch-dependencies task was activated it is using its artifacts to run build in hermetic environment. + params: + - name: BUILD_ARGS + description: Array of --build-arg values ("arg=value" strings) + type: array + default: [] + - name: BUILD_ARGS_FILE + description: Path to a file with build arguments, see https://www.mankier.com/1/buildah-build#--build-arg-file + type: string + default: "" + - name: CACHI2_ARTIFACT + description: The Trusted Artifact URI pointing to the artifact with + the prefetched dependencies. + type: string + default: "" + - name: COMMIT_SHA + description: The image is built from this commit. + type: string + default: "" + - name: CONTEXT + description: Path to the directory to use as context. + type: string + default: . + - name: DOCKERFILE + description: Path to the Dockerfile to build. + type: string + default: ./Dockerfile + - name: DOCKER_AUTH + description: unused, should be removed in next task version + type: string + default: "" + - name: ENTITLEMENT_SECRET + description: Name of secret which contains the entitlement certificates + type: string + default: etc-pki-entitlement + - name: HERMETIC + description: Determines if build will be executed without network + access. + type: string + default: "false" + - name: IMAGE + description: Reference of the image buildah will produce. + type: string + - name: IMAGE_EXPIRES_AFTER + description: 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. + type: string + default: "" + - name: PREFETCH_INPUT + description: In case it is not empty, the prefetched content should + be made available to the build. + type: string + default: "" + - name: SOURCE_ARTIFACT + description: The Trusted Artifact URI pointing to the artifact with + the application source code. + type: string + - name: TARGET_STAGE + description: Target stage in Dockerfile to build. If not specified, + the Dockerfile is processed entirely to (and including) its last + stage. + type: string + default: "" + - name: TLSVERIFY + description: Verify the TLS on the registry endpoint (for push/pull + to a non-TLS registry) + type: string + default: "true" + - name: YUM_REPOS_D_FETCHED + description: Path in source workspace where dynamically-fetched + repos are present + default: fetched.repos.d + - name: YUM_REPOS_D_SRC + description: Path in the git repository in which yum repository + files are stored + default: repos.d + - name: YUM_REPOS_D_TARGET + description: Target path on the container in which yum repository + files should be made available + default: /etc/yum.repos.d + - 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: BASE_IMAGES_DIGESTS + description: Digests of the base images used for build + - name: IMAGE_DIGEST + description: Digest of the image just built + - name: IMAGE_URL + description: Image repository where the built image was pushed + - name: JAVA_COMMUNITY_DEPENDENCIES + description: The Java dependencies that came from community sources + such as Maven central. + - name: SBOM_JAVA_COMPONENTS_COUNT + description: The counting of Java components by publisher in JSON + format + type: string + volumes: + - name: etc-pki-entitlement + secret: + optional: true + secretName: $(params.ENTITLEMENT_SECRET) + - name: trusted-ca + configMap: + items: + - key: $(params.caTrustConfigMapKey) + path: ca-bundle.crt + name: $(params.caTrustConfigMapName) + optional: true + - name: varlibcontainers + emptyDir: {} + - name: workdir + emptyDir: {} + stepTemplate: + env: + - name: BUILDAH_FORMAT + value: oci + - name: BUILD_ARGS_FILE + value: $(params.BUILD_ARGS_FILE) + - name: CONTEXT + value: $(params.CONTEXT) + - name: DOCKERFILE + value: $(params.DOCKERFILE) + - name: ENTITLEMENT_SECRET + value: $(params.ENTITLEMENT_SECRET) + - name: HERMETIC + value: $(params.HERMETIC) + - name: IMAGE + value: $(params.IMAGE) + - name: IMAGE_EXPIRES_AFTER + value: $(params.IMAGE_EXPIRES_AFTER) + - name: STORAGE_DRIVER + value: vfs + - name: TARGET_STAGE + value: $(params.TARGET_STAGE) + - name: TLSVERIFY + value: $(params.TLSVERIFY) + - name: YUM_REPOS_D_FETCHED + value: $(params.YUM_REPOS_D_FETCHED) + - name: YUM_REPOS_D_SRC + value: $(params.YUM_REPOS_D_SRC) + - name: YUM_REPOS_D_TARGET + value: $(params.YUM_REPOS_D_TARGET) + volumeMounts: + - mountPath: /var/workdir + name: workdir + steps: + - name: use-trusted-artifact + image: quay.io/redhat-appstudio/build-trusted-artifacts:latest@sha256:4e39fb97f4444c2946944482df47b39c5bbc195c54c6560b0647635f553ab23d + args: + - use + - $(params.SOURCE_ARTIFACT)=/var/workdir/source + - $(params.CACHI2_ARTIFACT)=/var/workdir/cachi2 + - name: build + image: quay.io/redhat-appstudio/buildah:v1.31.0@sha256:34f12c7b72ec2c28f1ded0c494b428df4791c909f1f174dd21b8ed6a57cf5ddb + args: + - $(params.BUILD_ARGS[*]) + workingDir: /var/workdir + volumeMounts: + - mountPath: /var/lib/containers + name: varlibcontainers + - mountPath: /entitlement + name: etc-pki-entitlement + - mountPath: /mnt/trusted-ca + name: trusted-ca + readOnly: true + env: + - name: COMMIT_SHA + value: $(params.COMMIT_SHA) + script: | + 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 + + SOURCE_CODE_DIR=source + if [ -e "$SOURCE_CODE_DIR/$CONTEXT/$DOCKERFILE" ]; then + dockerfile_path="$(pwd)/$SOURCE_CODE_DIR/$CONTEXT/$DOCKERFILE" + elif [ -e "$SOURCE_CODE_DIR/$DOCKERFILE" ]; then + dockerfile_path="$(pwd)/$SOURCE_CODE_DIR/$DOCKERFILE" + elif echo "$DOCKERFILE" | grep -q "^https\?://"; then + echo "Fetch Dockerfile from $DOCKERFILE" + dockerfile_path=$(mktemp --suffix=-Dockerfile) + http_code=$(curl -s -L -w "%{http_code}" --output "$dockerfile_path" "$DOCKERFILE") + if [ $http_code != 200 ]; then + echo "No Dockerfile is fetched. Server responds $http_code" + exit 1 + fi + http_code=$(curl -s -L -w "%{http_code}" --output "$dockerfile_path.dockerignore.tmp" "$DOCKERFILE.dockerignore") + if [ $http_code = 200 ]; then + echo "Fetched .dockerignore from $DOCKERFILE.dockerignore" + mv "$dockerfile_path.dockerignore.tmp" $SOURCE_CODE_DIR/$CONTEXT/.dockerignore + fi + else + echo "Cannot find Dockerfile $DOCKERFILE" + exit 1 + fi + if [ -n "$JVM_BUILD_WORKSPACE_ARTIFACT_CACHE_PORT_80_TCP_ADDR" ] && grep -q '^\s*RUN \(./\)\?mvn' "$dockerfile_path"; then + sed -i -e "s|^\s*RUN \(\(./\)\?mvn\)\(.*\)|RUN echo \"mirror.defaulthttp://$JVM_BUILD_WORKSPACE_ARTIFACT_CACHE_PORT_80_TCP_ADDR/v1/cache/default/0/*\" > /tmp/settings.yaml; \1 -s /tmp/settings.yaml \3|g" "$dockerfile_path" + touch /var/lib/containers/java + fi + + # Fixing group permission on /var/lib/containers + chown root:root /var/lib/containers + + sed -i 's/^\s*short-name-mode\s*=\s*.*/short-name-mode = "disabled"/' /etc/containers/registries.conf + + # Setting new namespace to run buildah - 2^32-2 + echo 'root:1:4294967294' | tee -a /etc/subuid >>/etc/subgid + + BUILDAH_ARGS=() + + BASE_IMAGES=$(grep -i '^\s*FROM' "$dockerfile_path" | sed 's/--platform=\S*//' | awk '{print $2}') + if [ "${HERMETIC}" == "true" ]; then + BUILDAH_ARGS+=("--pull=never") + UNSHARE_ARGS="--net" + for image in $BASE_IMAGES; do + if [ "${image}" != "scratch" ]; then + unshare -Ufp --keep-caps -r --map-users 1,1,65536 --map-groups 1,1,65536 -- buildah pull $image + fi + done + echo "Build will be executed with network isolation" + fi + + if [ -n "${TARGET_STAGE}" ]; then + BUILDAH_ARGS+=("--target=${TARGET_STAGE}") + fi + + if [ -n "${BUILD_ARGS_FILE}" ]; then + BUILDAH_ARGS+=("--build-arg-file=$(pwd)/$SOURCE_CODE_DIR/${BUILD_ARGS_FILE}") + fi + + for build_arg in "$@"; do + BUILDAH_ARGS+=("--build-arg=$build_arg") + done + + if [ -f "/var/workdir/cachi2/cachi2.env" ]; then + cp -r "/var/workdir/cachi2" /tmp/ + chmod -R go+rwX /tmp/cachi2 + VOLUME_MOUNTS="--volume /tmp/cachi2:/cachi2" + sed -i 's|^\s*run |RUN . /cachi2/cachi2.env \&\& \\\n |i' "$dockerfile_path" + echo "Prefetched content will be made available" + + prefetched_repo_for_my_arch="/tmp/cachi2/output/deps/rpm/$(uname -m)/repos.d/cachi2.repo" + if [ -f "$prefetched_repo_for_my_arch" ]; then + echo "Adding $prefetched_repo_for_my_arch to $YUM_REPOS_D_FETCHED" + mkdir -p "$YUM_REPOS_D_FETCHED" + cp --no-clobber "$prefetched_repo_for_my_arch" "$YUM_REPOS_D_FETCHED" + fi + fi + + # if yum repofiles stored in git, copy them to mount point outside the source dir + if [ -d "${SOURCE_CODE_DIR}/${YUM_REPOS_D_SRC}" ]; then + mkdir -p ${YUM_REPOS_D_FETCHED} + cp -r ${SOURCE_CODE_DIR}/${YUM_REPOS_D_SRC}/* ${YUM_REPOS_D_FETCHED} + fi + + # if anything in the repofiles mount point (either fetched or from git), mount it + if [ -d "${YUM_REPOS_D_FETCHED}" ]; then + chmod -R go+rwX ${YUM_REPOS_D_FETCHED} + mount_point=$(realpath ${YUM_REPOS_D_FETCHED}) + VOLUME_MOUNTS="${VOLUME_MOUNTS} --volume ${mount_point}:${YUM_REPOS_D_TARGET}" + fi + + LABELS=( + "--label" "build-date=$(date -u +'%Y-%m-%dT%H:%M:%S')" + "--label" "architecture=$(uname -m)" + "--label" "vcs-type=git" + ) + [ -n "$COMMIT_SHA" ] && LABELS+=("--label" "vcs-ref=$COMMIT_SHA") + [ -n "$IMAGE_EXPIRES_AFTER" ] && LABELS+=("--label" "quay.expires-after=$IMAGE_EXPIRES_AFTER") + + ENTITLEMENT_PATH="/entitlement" + if [ -d "$ENTITLEMENT_PATH" ]; then + cp -r --preserve=mode "$ENTITLEMENT_PATH" /tmp/entitlement + VOLUME_MOUNTS="${VOLUME_MOUNTS} --volume /tmp/entitlement:/etc/pki/entitlement" + echo "Adding the entitlement to the build" + fi + + unshare -Uf $UNSHARE_ARGS --keep-caps -r --map-users 1,1,65536 --map-groups 1,1,65536 -w ${SOURCE_CODE_DIR}/$CONTEXT -- buildah build \ + $VOLUME_MOUNTS \ + "${BUILDAH_ARGS[@]}" \ + "${LABELS[@]}" \ + --tls-verify=$TLSVERIFY --no-cache \ + --ulimit nofile=4096:4096 \ + -f "$dockerfile_path" -t $IMAGE . + + container=$(buildah from --pull-never $IMAGE) + buildah mount $container | tee /var/workdir/container_path + echo $container >/var/workdir/container_name + + # Save the SBOM produced by Cachi2 so it can be merged into the final SBOM later + if [ -f "/tmp/cachi2/output/bom.json" ]; then + cp /tmp/cachi2/output/bom.json ./sbom-cachi2.json + fi + + # Expose base image digests + for image in $BASE_IMAGES; do + if [ "${image}" != "scratch" ]; then + buildah images --format '{{ .Name }}:{{ .Tag }}@{{ .Digest }}' --filter reference="$image" >>$( results.BASE_IMAGES_DIGESTS.path) + fi + done + + # Needed to generate base images SBOM + echo "$BASE_IMAGES" >/var/workdir/base_images_from_dockerfile + computeResources: + limits: + memory: 4Gi + requests: + cpu: 250m + memory: 512Mi + securityContext: + capabilities: + add: + - SETFCAP + - name: sbom-syft-generate + image: quay.io/redhat-appstudio/syft:v0.105.1@sha256:1910b829997650c696881e5fc2fc654ddf3184c27edb1b2024e9cb2ba51ac431 + workingDir: /var/workdir/source + volumeMounts: + - mountPath: /var/lib/containers + name: varlibcontainers + script: | + echo "Running syft on the source directory" + syft dir:/var/workdir/source --output cyclonedx-json=/var/workdir/sbom-source.json + find $(cat /var/workdir/container_path) -xtype l -delete + echo "Running syft on the image filesystem" + syft dir:$(cat /var/workdir/container_path) --output cyclonedx-json=/var/workdir/sbom-image.json + - name: analyse-dependencies-java-sbom + image: quay.io/redhat-appstudio/hacbs-jvm-build-request-processor:127ee0c223a2b56a9bd20a6f2eaeed3bd6015f77 + volumeMounts: + - mountPath: /var/lib/containers + name: varlibcontainers + script: | + if [ -f /var/lib/containers/java ]; then + /opt/jboss/container/java/run/run-java.sh analyse-dependencies path $(cat /var/workdir/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 + securityContext: + runAsUser: 0 + - name: merge-syft-sboms + image: registry.access.redhat.com/ubi9/python-39:1-172.1712567222@sha256:c96f839e927c52990143df4efb2872946fcd5de9e1ed2014947bb2cf3084c27a + workingDir: /var/workdir + script: | + #!/bin/python3 + import json + + # load SBOMs + with open("./sbom-image.json") as f: + image_sbom = json.load(f) + + with open("./sbom-source.json") as f: + source_sbom = json.load(f) + + # fetch unique components from available SBOMs + def get_identifier(component): + return component["name"] + '@' + component.get("version", "") + + image_sbom_components = image_sbom.get("components", []) + existing_components = [get_identifier(component) for component in image_sbom_components] + + source_sbom_components = source_sbom.get("components", []) + for component in source_sbom_components: + if get_identifier(component) not in existing_components: + image_sbom_components.append(component) + existing_components.append(get_identifier(component)) + + image_sbom_components.sort(key=lambda c: get_identifier(c)) + + # write the CycloneDX unified SBOM + with open("./sbom-cyclonedx.json", "w") as f: + json.dump(image_sbom, f, indent=4) + securityContext: + runAsUser: 0 + - name: merge-cachi2-sbom + image: quay.io/redhat-appstudio/cachi2:0.7.0@sha256:1fc772aa3636fd0b43d62120d832e5913843e028e8cac42814b487c3a0a32bd8 + workingDir: /var/workdir + script: | + if [ -f "sbom-cachi2.json" ]; then + echo "Merging contents of sbom-cachi2.json into sbom-cyclonedx.json" + /src/utils/merge_syft_sbom.py sbom-cachi2.json sbom-cyclonedx.json >sbom-temp.json + mv sbom-temp.json sbom-cyclonedx.json + else + echo "Skipping step since no Cachi2 SBOM was produced" + fi + securityContext: + runAsUser: 0 + - name: create-purl-sbom + image: registry.access.redhat.com/ubi9/python-39:1-172.1712567222@sha256:c96f839e927c52990143df4efb2872946fcd5de9e1ed2014947bb2cf3084c27a + workingDir: /var/workdir + script: | + #!/bin/python3 + import json + + with open("./sbom-cyclonedx.json") as f: + cyclonedx_sbom = json.load(f) + + purls = [{"purl": component["purl"]} for component in cyclonedx_sbom.get("components", []) if "purl" in component] + purl_content = {"image_contents": {"dependencies": purls}} + + with open("sbom-purl.json", "w") as output_file: + json.dump(purl_content, output_file, indent=4) + securityContext: + runAsUser: 0 + - name: create-base-images-sbom + image: quay.io/redhat-appstudio/base-images-sbom-script@sha256:667669e3def018f9dbb8eaf8868887a40bc07842221e9a98f6787edcff021840 + workingDir: /var/workdir + env: + - name: BASE_IMAGES_DIGESTS_PATH + value: $(results.BASE_IMAGES_DIGESTS.path) + script: | + python3 /app/base_images_sbom_script.py --sbom=sbom-cyclonedx.json --base-images-from-dockerfile=base_images_from_dockerfile --base-images-digests=$BASE_IMAGES_DIGESTS_PATH + securityContext: + runAsUser: 0 + - name: inject-sbom-and-push + image: quay.io/redhat-appstudio/buildah:v1.31.0@sha256:34f12c7b72ec2c28f1ded0c494b428df4791c909f1f174dd21b8ed6a57cf5ddb + workingDir: /var/workdir + volumeMounts: + - mountPath: /var/lib/containers + name: varlibcontainers + script: | + 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 commit $container $IMAGE + + status=-1 + max_run=5 + sleep_sec=10 + for run in $(seq 1 $max_run); do + status=0 + [ "$run" -gt 1 ] && sleep $sleep_sec + echo "Pushing sbom image to registry" + buildah push \ + --tls-verify=$TLSVERIFY \ + --digestfile /var/workdir/image-digest $IMAGE \ + docker://$IMAGE && break || status=$? + done + if [ "$status" -ne 0 ]; then + echo "Failed to push sbom image to registry 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) + securityContext: + capabilities: + add: + - SETFCAP + runAsUser: 0 + - name: upload-sbom + image: quay.io/redhat-appstudio/cosign:v2.1.1@sha256:c883d6f8d39148f2cea71bff4622d196d89df3e510f36c140c097b932f0dd5d5 + args: + - attach + - sbom + - --sbom + - sbom-cyclonedx.json + - --type + - cyclonedx + - $(params.IMAGE) + workingDir: /var/workdir diff --git a/task/git-clone-oci-ta/0.1/README.md b/task/git-clone-oci-ta/0.1/README.md index fe1cbd9a91..d87ea24e7d 100644 --- a/task/git-clone-oci-ta/0.1/README.md +++ b/task/git-clone-oci-ta/0.1/README.md @@ -5,34 +5,34 @@ The git-clone-oci-ta Task will clone a repo from the provided url and store it a ## Parameters |name|description|default value|required| |---|---|---|---| -|url|Repository URL to clone from.||true| -|revision|Revision to checkout. (branch, tag, sha, ref, etc...)|""|false| -|refspec|Refspec to fetch before checking out revision.|""|false| -|submodules|Initialize and fetch git submodules.|true|false| +|caTrustConfigMapKey|The name of the key in the ConfigMap that contains the CA bundle data.|ca-bundle.crt|false| +|caTrustConfigMapName|The name of the ConfigMap to read CA bundle data from.|trusted-ca|false| |depth|Perform a shallow clone, fetching only the most recent N commits.|1|false| -|sslVerify|Set the `http.sslVerify` global git config. Setting this to `false` is not advised unless you are sure that you trust your git remote.|true|false| -|sparseCheckoutDirectories|Define the directory patterns to match or exclude when performing a sparse checkout.|""|false| +|enableSymlinkCheck|Check symlinks in the repo. If they're pointing outside of the repo, the build will fail. |true|false| +|fetchTags|Fetch all tags for the repo.|false|false| |httpProxy|HTTP proxy server for non-SSL requests.|""|false| |httpsProxy|HTTPS proxy server for SSL requests.|""|false| |noProxy|Opt out of proxying HTTP/HTTPS requests.|""|false| -|verbose|Log the commands that are executed during `git-clone`'s operation.|false|false| +|ociArtifactExpiresAfter|Expiration date for the trusted artifacts created in the OCI repository. An empty string means the artifacts do not expire.|""|false| +|ociStorage|The OCI repository where the Trusted Artifacts are stored.||true| +|refspec|Refspec to fetch before checking out revision.|""|false| +|revision|Revision to checkout. (branch, tag, sha, ref, etc...)|""|false| +|sparseCheckoutDirectories|Define the directory patterns to match or exclude when performing a sparse checkout.|""|false| +|sslVerify|Set the `http.sslVerify` global git config. Setting this to `false` is not advised unless you are sure that you trust your git remote.|true|false| +|submodules|Initialize and fetch git submodules.|true|false| +|url|Repository URL to clone from.||true| |userHome|Absolute path to the user's home directory. Set this explicitly if you are running the image as a non-root user. |/tekton/home|false| -|enableSymlinkCheck|Check symlinks in the repo. If they're pointing outside of the repo, the build will fail. |true|false| -|fetchTags|Fetch all tags for the repo.|false|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| -|ociStorage|The OCI repository where the clone repository will be stored.||true| -|ociArtifactExpiresAfter|Expiration date for the artifacts created in the OCI repository.|""|false| +|verbose|Log the commands that are executed during `git-clone`'s operation.|false|false| ## Results |name|description| |---|---| +|SOURCE_ARTIFACT|The Trusted Artifact URI pointing to the artifact with the application source code.| |commit|The precise commit SHA that was fetched by this Task.| |url|The precise URL that was fetched by this Task.| -|sourceArtifact|The OCI reference to the trusted source artifact containing the cloned git repo.| ## Workspaces |name|description|optional| |---|---|---| -|ssh-directory|A .ssh directory with private key, known_hosts, config, etc. Copied to the user's home before git commands are executed. Used to authenticate with the git remote when performing the clone. Binding a Secret to this Workspace is strongly recommended over other volume types. |true| |basic-auth|A Workspace containing a .gitconfig and .git-credentials file or username and password. These will be copied to the user's home before any git commands are run. Any other files in this Workspace are ignored. It is strongly recommended to use ssh-directory over basic-auth whenever possible and to bind a Secret to this Workspace over other volume types. |true| +|ssh-directory|A .ssh directory with private key, known_hosts, config, etc. Copied to the user's home before git commands are executed. Used to authenticate with the git remote when performing the clone. Binding a Secret to this Workspace is strongly recommended over other volume types. |true| diff --git a/task/git-clone-oci-ta/0.1/git-clone-oci-ta.yaml b/task/git-clone-oci-ta/0.1/git-clone-oci-ta.yaml index 0161d2e499..e928b27131 100644 --- a/task/git-clone-oci-ta/0.1/git-clone-oci-ta.yaml +++ b/task/git-clone-oci-ta/0.1/git-clone-oci-ta.yaml @@ -2,291 +2,291 @@ apiVersion: tekton.dev/v1 kind: Task metadata: - labels: - app.kubernetes.io/version: "0.1" - annotations: - tekton.dev/categories: Git - tekton.dev/displayName: git clone oci trusted artifacts - tekton.dev/pipelines.minVersion: 0.21.0 - tekton.dev/platforms: linux/amd64,linux/s390x,linux/ppc64le,linux/arm64 - tekton.dev/tags: git - name: git-clone-oci-ta + name: git-clone-oci-ta + annotations: + tekton.dev/categories: Git + tekton.dev/displayName: git clone oci trusted artifacts + tekton.dev/pipelines.minVersion: 0.21.0 + tekton.dev/platforms: linux/amd64,linux/s390x,linux/ppc64le,linux/arm64 + tekton.dev/tags: git + labels: + app.kubernetes.io/version: "0.1" spec: - description: >- - The git-clone-oci-ta Task will clone a repo from the provided url and store it as a trusted - artifact in the provided OCI repository. - params: - - description: Repository URL to clone from. - name: url - type: string - - default: "" - description: Revision to checkout. (branch, tag, sha, ref, etc...) - name: revision - type: string - - default: "" - description: Refspec to fetch before checking out revision. - name: refspec - type: string - - default: "true" - description: Initialize and fetch git submodules. - name: submodules - type: string - - default: "1" - description: Perform a shallow clone, fetching only the most recent N commits. - name: depth - type: string - - default: "true" - description: Set the `http.sslVerify` global git config. Setting this to `false` is not advised unless you are sure that you trust your git remote. - name: sslVerify - type: string - - default: "" - description: Define the directory patterns to match or exclude when performing a sparse checkout. - name: sparseCheckoutDirectories - type: string - - default: "" - description: HTTP proxy server for non-SSL requests. - name: httpProxy - type: string - - default: "" - description: HTTPS proxy server for SSL requests. - name: httpsProxy - type: string - - default: "" - description: Opt out of proxying HTTP/HTTPS requests. - name: noProxy - type: string - - default: "false" - description: Log the commands that are executed during `git-clone`'s operation. - name: verbose - type: string - - default: /tekton/home - description: | - Absolute path to the user's home directory. Set this explicitly if you are running the image as a non-root user. - name: userHome - type: string - - default: "true" - description: | - Check symlinks in the repo. If they're pointing outside of the repo, the build will fail. - name: enableSymlinkCheck - type: string - - default: "false" - description: Fetch all tags for the repo. - name: fetchTags - type: string - - name: caTrustConfigMapName - type: string - description: The name of the ConfigMap to read CA bundle data from. - default: trusted-ca - - name: caTrustConfigMapKey - type: string - description: The name of the key in the ConfigMap that contains the CA bundle data. - default: ca-bundle.crt - - name: ociStorage - type: string - description: The OCI repository where the Trusted Artifacts are stored. - - name: ociArtifactExpiresAfter - type: string - description: >- - Expiration date for the trusted artifacts created in the OCI repository. An empty string means - the artifacts do not expire. - default: "" + description: The git-clone-oci-ta Task will clone a repo from the provided + url and store it as a trusted artifact in the provided OCI repository. + params: + - 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 + - name: depth + description: Perform a shallow clone, fetching only the most recent + N commits. + type: string + default: "1" + - name: enableSymlinkCheck + description: | + Check symlinks in the repo. If they're pointing outside of the repo, the build will fail. + type: string + default: "true" + - name: fetchTags + description: Fetch all tags for the repo. + type: string + default: "false" + - name: httpProxy + description: HTTP proxy server for non-SSL requests. + type: string + default: "" + - name: httpsProxy + description: HTTPS proxy server for SSL requests. + type: string + default: "" + - name: noProxy + description: Opt out of proxying HTTP/HTTPS requests. + type: string + default: "" + - name: ociArtifactExpiresAfter + description: Expiration date for the trusted artifacts created in + the OCI repository. An empty string means the artifacts do not + expire. + type: string + default: "" + - name: ociStorage + description: The OCI repository where the Trusted Artifacts are + stored. + type: string + - name: refspec + description: Refspec to fetch before checking out revision. + type: string + default: "" + - name: revision + description: Revision to checkout. (branch, tag, sha, ref, etc...) + type: string + default: "" + - name: sparseCheckoutDirectories + description: Define the directory patterns to match or exclude when + performing a sparse checkout. + type: string + default: "" + - name: sslVerify + description: Set the `http.sslVerify` global git config. Setting + this to `false` is not advised unless you are sure that you trust + your git remote. + type: string + default: "true" + - name: submodules + description: Initialize and fetch git submodules. + type: string + default: "true" + - name: url + description: Repository URL to clone from. + type: string + - name: userHome + description: | + Absolute path to the user's home directory. Set this explicitly if you are running the image as a non-root user. + type: string + default: /tekton/home + - name: verbose + description: Log the commands that are executed during `git-clone`'s + operation. + type: string + default: "false" + results: + - name: SOURCE_ARTIFACT + description: The Trusted Artifact URI pointing to the artifact with + the application source code. + type: string + - name: commit + description: The precise commit SHA that was fetched by this Task. + - name: url + description: The precise URL that was fetched by this Task. + volumes: + - name: trusted-ca + configMap: + items: + - key: $(params.caTrustConfigMapKey) + path: ca-bundle.crt + name: $(params.caTrustConfigMapName) + optional: true + - name: workdir + emptyDir: {} + workspaces: + - name: basic-auth + description: | + A Workspace containing a .gitconfig and .git-credentials file or username and password. + These will be copied to the user's home before any git commands are run. Any + other files in this Workspace are ignored. It is strongly recommended + to use ssh-directory over basic-auth whenever possible and to bind a + Secret to this Workspace over other volume types. + optional: true + - name: ssh-directory + description: | + A .ssh directory with private key, known_hosts, config, etc. Copied to + the user's home before git commands are executed. Used to authenticate + with the git remote when performing the clone. Binding a Secret to this + Workspace is strongly recommended over other volume types. + optional: true + steps: + - name: clone + image: quay.io/konflux-ci/git-clone@sha256:005487d3967e7a90490f96b2ff3b0c6d0463b647d212cd809683b494e20146a8 + volumeMounts: + - mountPath: /mnt/trusted-ca + name: trusted-ca + readOnly: true + - mountPath: /var/workdir + name: workdir + env: + - name: HOME + value: $(params.userHome) + - name: PARAM_URL + value: $(params.url) + - name: PARAM_REVISION + value: $(params.revision) + - name: PARAM_REFSPEC + value: $(params.refspec) + - name: PARAM_SUBMODULES + value: $(params.submodules) + - name: PARAM_DEPTH + value: $(params.depth) + - name: PARAM_SSL_VERIFY + value: $(params.sslVerify) + - name: PARAM_HTTP_PROXY + value: $(params.httpProxy) + - name: PARAM_HTTPS_PROXY + value: $(params.httpsProxy) + - name: PARAM_NO_PROXY + value: $(params.noProxy) + - name: PARAM_VERBOSE + value: $(params.verbose) + - name: PARAM_SPARSE_CHECKOUT_DIRECTORIES + value: $(params.sparseCheckoutDirectories) + - name: PARAM_USER_HOME + value: $(params.userHome) + - name: PARAM_FETCH_TAGS + value: $(params.fetchTags) + - name: WORKSPACE_SSH_DIRECTORY_BOUND + value: $(workspaces.ssh-directory.bound) + - name: WORKSPACE_SSH_DIRECTORY_PATH + value: $(workspaces.ssh-directory.path) + - name: WORKSPACE_BASIC_AUTH_DIRECTORY_BOUND + value: $(workspaces.basic-auth.bound) + - name: WORKSPACE_BASIC_AUTH_DIRECTORY_PATH + value: $(workspaces.basic-auth.path) + - name: CHECKOUT_DIR + value: /var/workdir/source + script: | + #!/usr/bin/env sh + set -eu - results: - - description: The precise commit SHA that was fetched by this Task. - name: commit - - description: The precise URL that was fetched by this Task. - name: url - - description: The Trusted Artifact URI pointing to the artifact with the application source code. - name: SOURCE_ARTIFACT - type: string - steps: - - name: clone - env: - - name: HOME - value: $(params.userHome) - - name: PARAM_URL - value: $(params.url) - - name: PARAM_REVISION - value: $(params.revision) - - name: PARAM_REFSPEC - value: $(params.refspec) - - name: PARAM_SUBMODULES - value: $(params.submodules) - - name: PARAM_DEPTH - value: $(params.depth) - - name: PARAM_SSL_VERIFY - value: $(params.sslVerify) - - name: PARAM_HTTP_PROXY - value: $(params.httpProxy) - - name: PARAM_HTTPS_PROXY - value: $(params.httpsProxy) - - name: PARAM_NO_PROXY - value: $(params.noProxy) - - name: PARAM_VERBOSE - value: $(params.verbose) - - name: PARAM_SPARSE_CHECKOUT_DIRECTORIES - value: $(params.sparseCheckoutDirectories) - - name: PARAM_USER_HOME - value: $(params.userHome) - - name: PARAM_FETCH_TAGS - value: $(params.fetchTags) - - name: WORKSPACE_SSH_DIRECTORY_BOUND - value: $(workspaces.ssh-directory.bound) - - name: WORKSPACE_SSH_DIRECTORY_PATH - value: $(workspaces.ssh-directory.path) - - name: WORKSPACE_BASIC_AUTH_DIRECTORY_BOUND - value: $(workspaces.basic-auth.bound) - - name: WORKSPACE_BASIC_AUTH_DIRECTORY_PATH - value: $(workspaces.basic-auth.path) - - name: CHECKOUT_DIR - value: /var/workdir/source - image: registry.redhat.io/openshift-pipelines/pipelines-git-init-rhel8:v1.8.2-8@sha256:a538c423e7a11aae6ae582a411fdb090936458075f99af4ce5add038bb6983e8 - computeResources: {} - securityContext: - runAsUser: 0 - volumeMounts: - - name: trusted-ca - mountPath: /mnt/trusted-ca - readOnly: true - - name: workdir - mountPath: /var/workdir - script: | - #!/usr/bin/env sh - set -eu + if [ "${PARAM_VERBOSE}" = "true" ]; then + set -x + fi - if [ "${PARAM_VERBOSE}" = "true" ] ; then - set -x - fi + if [ "${WORKSPACE_BASIC_AUTH_DIRECTORY_BOUND}" = "true" ]; then + if [ -f "${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/.git-credentials" ] && [ -f "${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/.gitconfig" ]; then + cp "${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/.git-credentials" "${PARAM_USER_HOME}/.git-credentials" + cp "${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/.gitconfig" "${PARAM_USER_HOME}/.gitconfig" + # Compatibility with kubernetes.io/basic-auth secrets + elif [ -f "${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/username" ] && [ -f "${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/password" ]; then + HOSTNAME=$(echo $PARAM_URL | awk -F/ '{print $3}') + echo "https://$(cat ${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/username):$(cat ${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/password)@$HOSTNAME" >"${PARAM_USER_HOME}/.git-credentials" + echo -e "[credential \"https://$HOSTNAME\"]\n helper = store" >"${PARAM_USER_HOME}/.gitconfig" + else + echo "Unknown basic-auth workspace format" + exit 1 + fi + chmod 400 "${PARAM_USER_HOME}/.git-credentials" + chmod 400 "${PARAM_USER_HOME}/.gitconfig" + fi - if [ "${WORKSPACE_BASIC_AUTH_DIRECTORY_BOUND}" = "true" ] ; then - if [ -f "${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/.git-credentials" ] && [ -f "${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/.gitconfig" ]; then - cp "${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/.git-credentials" "${PARAM_USER_HOME}/.git-credentials" - cp "${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/.gitconfig" "${PARAM_USER_HOME}/.gitconfig" - # Compatibility with kubernetes.io/basic-auth secrets - elif [ -f "${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/username" ] && [ -f "${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/password" ]; then - HOSTNAME=$(echo $PARAM_URL | awk -F/ '{print $3}') - echo "https://$(cat ${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/username):$(cat ${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/password)@$HOSTNAME" > "${PARAM_USER_HOME}/.git-credentials" - echo -e "[credential \"https://$HOSTNAME\"]\n helper = store" > "${PARAM_USER_HOME}/.gitconfig" - else - echo "Unknown basic-auth workspace format" - exit 1 - fi - chmod 400 "${PARAM_USER_HOME}/.git-credentials" - chmod 400 "${PARAM_USER_HOME}/.gitconfig" - fi + # Should be called after the gitconfig is copied from the repository secret + ca_bundle=/mnt/trusted-ca/ca-bundle.crt + if [ -f "$ca_bundle" ]; then + echo "INFO: Using mounted CA bundle: $ca_bundle" + git config --global http.sslCAInfo "$ca_bundle" + fi - # Should be called after the gitconfig is copied from the repository secret - ca_bundle=/mnt/trusted-ca/ca-bundle.crt - if [ -f "$ca_bundle" ]; then - echo "INFO: Using mounted CA bundle: $ca_bundle" - git config --global http.sslCAInfo "$ca_bundle" - fi + if [ "${WORKSPACE_SSH_DIRECTORY_BOUND}" = "true" ]; then + cp -R "${WORKSPACE_SSH_DIRECTORY_PATH}" "${PARAM_USER_HOME}"/.ssh + chmod 700 "${PARAM_USER_HOME}"/.ssh + chmod -R 400 "${PARAM_USER_HOME}"/.ssh/* + fi - if [ "${WORKSPACE_SSH_DIRECTORY_BOUND}" = "true" ] ; then - cp -R "${WORKSPACE_SSH_DIRECTORY_PATH}" "${PARAM_USER_HOME}"/.ssh - chmod 700 "${PARAM_USER_HOME}"/.ssh - chmod -R 400 "${PARAM_USER_HOME}"/.ssh/* - fi + test -z "${PARAM_HTTP_PROXY}" || export HTTP_PROXY="${PARAM_HTTP_PROXY}" + test -z "${PARAM_HTTPS_PROXY}" || export HTTPS_PROXY="${PARAM_HTTPS_PROXY}" + test -z "${PARAM_NO_PROXY}" || export NO_PROXY="${PARAM_NO_PROXY}" - test -z "${PARAM_HTTP_PROXY}" || export HTTP_PROXY="${PARAM_HTTP_PROXY}" - test -z "${PARAM_HTTPS_PROXY}" || export HTTPS_PROXY="${PARAM_HTTPS_PROXY}" - test -z "${PARAM_NO_PROXY}" || export NO_PROXY="${PARAM_NO_PROXY}" + /ko-app/git-init \ + -url="${PARAM_URL}" \ + -revision="${PARAM_REVISION}" \ + -refspec="${PARAM_REFSPEC}" \ + -path="${CHECKOUT_DIR}" \ + -sslVerify="${PARAM_SSL_VERIFY}" \ + -submodules="${PARAM_SUBMODULES}" \ + -depth="${PARAM_DEPTH}" \ + -sparseCheckoutDirectories="${PARAM_SPARSE_CHECKOUT_DIRECTORIES}" + cd "${CHECKOUT_DIR}" + RESULT_SHA="$(git rev-parse HEAD)" + EXIT_CODE="$?" + if [ "${EXIT_CODE}" != 0 ]; then + exit "${EXIT_CODE}" + fi + printf "%s" "${RESULT_SHA}" >"$( results.commit.path)" + printf "%s" "${PARAM_URL}" >"$( results.url.path)" - /ko-app/git-init \ - -url="${PARAM_URL}" \ - -revision="${PARAM_REVISION}" \ - -refspec="${PARAM_REFSPEC}" \ - -path="${CHECKOUT_DIR}" \ - -sslVerify="${PARAM_SSL_VERIFY}" \ - -submodules="${PARAM_SUBMODULES}" \ - -depth="${PARAM_DEPTH}" \ - -sparseCheckoutDirectories="${PARAM_SPARSE_CHECKOUT_DIRECTORIES}" - cd "${CHECKOUT_DIR}" - RESULT_SHA="$(git rev-parse HEAD)" - EXIT_CODE="$?" - if [ "${EXIT_CODE}" != 0 ] ; then - exit "${EXIT_CODE}" - fi - printf "%s" "${RESULT_SHA}" > "$(results.commit.path)" - printf "%s" "${PARAM_URL}" > "$(results.url.path)" + if [ "${PARAM_FETCH_TAGS}" = "true" ]; then + echo "Fetching tags" + git fetch --tags + fi + securityContext: + runAsUser: 0 + - name: symlink-check + image: quay.io/konflux-ci/git-clone@sha256:005487d3967e7a90490f96b2ff3b0c6d0463b647d212cd809683b494e20146a8 + volumeMounts: + - mountPath: /var/workdir + name: workdir + env: + - name: PARAM_ENABLE_SYMLINK_CHECK + value: $(params.enableSymlinkCheck) + - name: CHECKOUT_DIR + value: /var/workdir/source + script: | + #!/usr/bin/env bash + set -euo pipefail - if [ "${PARAM_FETCH_TAGS}" = "true" ] ; then - echo "Fetching tags" - git fetch --tags - fi + check_symlinks() { + FOUND_SYMLINK_POINTING_OUTSIDE_OF_REPO=false + while read symlink; do + target=$(readlink -f "$symlink") + if ! [[ "$target" =~ ^$CHECKOUT_DIR ]]; then + echo "The cloned repository contains symlink pointing outside of the cloned repository: $symlink" + FOUND_SYMLINK_POINTING_OUTSIDE_OF_REPO=true + fi + done < <(find $CHECKOUT_DIR -type l -print) + if [ "$FOUND_SYMLINK_POINTING_OUTSIDE_OF_REPO" = true ]; then + return 1 + fi + } - - name: symlink-check - image: registry.redhat.io/ubi9:9.2-696@sha256:089bd3b82a78ac45c0eed231bb58bfb43bfcd0560d9bba240fc6355502c92976 - env: - - name: PARAM_ENABLE_SYMLINK_CHECK - value: $(params.enableSymlinkCheck) - - name: CHECKOUT_DIR - value: /var/workdir/source - volumeMounts: - - name: workdir - mountPath: /var/workdir - computeResources: {} - script: | - #!/usr/bin/env bash - set -euo pipefail - - check_symlinks() { - FOUND_SYMLINK_POINTING_OUTSIDE_OF_REPO=false - while read symlink - do - target=$(readlink -f "$symlink") - if ! [[ "$target" =~ ^$CHECKOUT_DIR ]]; then - echo "The cloned repository contains symlink pointing outside of the cloned repository: $symlink" - FOUND_SYMLINK_POINTING_OUTSIDE_OF_REPO=true - fi - done < <(find $CHECKOUT_DIR -type l -print) - if [ "$FOUND_SYMLINK_POINTING_OUTSIDE_OF_REPO" = true ] ; then - return 1 - fi - } - - if [ "${PARAM_ENABLE_SYMLINK_CHECK}" = "true" ] ; then - echo "Running symlink check" - check_symlinks - fi - - - name: create-trusted-artifact - image: quay.io/redhat-appstudio/build-trusted-artifacts:latest@sha256:4e39fb97f4444c2946944482df47b39c5bbc195c54c6560b0647635f553ab23d - env: - - name: IMAGE_EXPIRES_AFTER - value: $(params.ociArtifactExpiresAfter) - volumeMounts: - - name: workdir - mountPath: /var/workdir - args: - - create - - --store - - $(params.ociStorage) - - $(results.SOURCE_ARTIFACT.path)=/var/workdir/source - - workspaces: - - description: | - A .ssh directory with private key, known_hosts, config, etc. Copied to - the user's home before git commands are executed. Used to authenticate - with the git remote when performing the clone. Binding a Secret to this - Workspace is strongly recommended over other volume types. - name: ssh-directory - optional: true - - description: | - A Workspace containing a .gitconfig and .git-credentials file or username and password. - These will be copied to the user's home before any git commands are run. Any - other files in this Workspace are ignored. It is strongly recommended - to use ssh-directory over basic-auth whenever possible and to bind a - Secret to this Workspace over other volume types. - name: basic-auth - optional: true - volumes: - - name: workdir - emptyDir: {} - - name: trusted-ca - configMap: - name: $(params.caTrustConfigMapName) - items: - - key: $(params.caTrustConfigMapKey) - path: ca-bundle.crt - optional: true + if [ "${PARAM_ENABLE_SYMLINK_CHECK}" = "true" ]; then + echo "Running symlink check" + check_symlinks + fi + - name: create-trusted-artifact + image: quay.io/redhat-appstudio/build-trusted-artifacts:latest@sha256:4e39fb97f4444c2946944482df47b39c5bbc195c54c6560b0647635f553ab23d + args: + - create + - --store + - $(params.ociStorage) + - $(results.SOURCE_ARTIFACT.path)=/var/workdir/source + volumeMounts: + - mountPath: /var/workdir + name: workdir + env: + - name: IMAGE_EXPIRES_AFTER + value: $(params.ociArtifactExpiresAfter) diff --git a/task/prefetch-dependencies-oci-ta/0.1/README.md b/task/prefetch-dependencies-oci-ta/0.1/README.md index d98fd692ee..7bc339170a 100644 --- a/task/prefetch-dependencies-oci-ta/0.1/README.md +++ b/task/prefetch-dependencies-oci-ta/0.1/README.md @@ -8,20 +8,20 @@ https://github.com/containerbuildsystem/cachi2#basic-usage. ## Parameters |name|description|default value|required| |---|---|---|---| -|input|Configures project packages that will have their dependencies prefetched.||true| -|source-artifact|The trusted artifact URI containing the application source code.||true| -|oci-storage|The OCI repository where the trusted artifacts with the modified cloned repository and the prefetched depedencies will be stored.||true| -|oci-artifact-expires-after|Expiration date for the trusted artifacts created in the OCI repository. An empty string means the artifacts do not expire.|""|false| +|SOURCE_ARTIFACT|The Trusted Artifact URI pointing to the artifact with the application source code.||true| +|caTrustConfigMapKey|The name of the key in the ConfigMap that contains the CA bundle data.|ca-bundle.crt|false| +|caTrustConfigMapName|The name of the ConfigMap to read CA bundle data from.|trusted-ca|false| |dev-package-managers|Enable in-development package managers. WARNING: the behavior may change at any time without notice. Use at your own risk. |false|false| +|input|Configures project packages that will have their dependencies prefetched.||true| |log-level|Set cachi2 log level (debug, info, warning, error)|info|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| +|ociArtifactExpiresAfter|Expiration date for the trusted artifacts created in the OCI repository. An empty string means the artifacts do not expire.|""|false| +|ociStorage|The OCI repository where the Trusted Artifacts are stored.||true| ## Results |name|description| |---|---| -|source-artifact|The trusted artifact URI containing the modified application source.| -|cachi2-artifact|The trusted artifact URI containing the fetched dependencies.| +|CACHI2_ARTIFACT|The Trusted Artifact URI pointing to the artifact with the prefetched dependencies.| +|SOURCE_ARTIFACT|The Trusted Artifact URI pointing to the artifact with the application source code.| ## Workspaces |name|description|optional| diff --git a/task/prefetch-dependencies-oci-ta/0.1/prefetch-dependencies-oci-ta.yaml b/task/prefetch-dependencies-oci-ta/0.1/prefetch-dependencies-oci-ta.yaml index 69eed7fdb1..b399f123c4 100644 --- a/task/prefetch-dependencies-oci-ta/0.1/prefetch-dependencies-oci-ta.yaml +++ b/task/prefetch-dependencies-oci-ta/0.1/prefetch-dependencies-oci-ta.yaml @@ -2,161 +2,165 @@ apiVersion: tekton.dev/v1 kind: Task metadata: - labels: - app.kubernetes.io/version: "0.1" - annotations: - tekton.dev/pipelines.minVersion: "0.12.1" - tekton.dev/tags: "image-build, hacbs" - name: prefetch-dependencies-oci-ta + name: prefetch-dependencies-oci-ta + annotations: + tekton.dev/pipelines.minVersion: 0.12.1 + tekton.dev/tags: image-build, hacbs + labels: + app.kubernetes.io/version: "0.1" spec: - description: |- - Task that uses Cachi2 to prefetch build dependencies. The fetched dependencies and the - application source code are stored as a trusted artifact in the provided OCI repository. - For additional info on Cachi2, see docs at - https://github.com/containerbuildsystem/cachi2#basic-usage. - params: - - description: Configures project packages that will have their dependencies prefetched. - name: input - - description: The Trusted Artifact URI pointing to the artifact with the application source code. - name: SOURCE_ARTIFACT - type: string - - description: The OCI repository where the Trusted Artifacts are stored. - name: ociStorage - type: string - - description: >- - Expiration date for the trusted artifacts created in the OCI repository. An empty string means - the artifacts do not expire. - name: ociArtifactExpiresAfter - type: string - default: "" - - description: > - Enable in-development package managers. WARNING: the behavior may change at any time without - notice. Use at your own risk. - name: dev-package-managers - default: "false" - - description: Set cachi2 log level (debug, info, warning, error) - name: log-level - default: "info" - - name: caTrustConfigMapName - type: string - description: The name of the ConfigMap to read CA bundle data from. - default: trusted-ca - - name: caTrustConfigMapKey - type: string - description: The name of the key in the ConfigMap that contains the CA bundle data. - default: ca-bundle.crt - results: - - description: The Trusted Artifact URI pointing to the artifact with the application source code. - name: SOURCE_ARTIFACT - type: string - - description: The Trusted Artifact URI pointing to the artifact with the prefetched dependencies. - name: CACHI2_ARTIFACT - type: string - stepTemplate: - volumeMounts: - - mountPath: /var/workdir - name: workdir - steps: - - image: quay.io/redhat-appstudio/build-trusted-artifacts:latest@sha256:4e39fb97f4444c2946944482df47b39c5bbc195c54c6560b0647635f553ab23d - name: use-trusted-artifact - args: - - use - - $(params.SOURCE_ARTIFACT)=/var/workdir/source - - image: quay.io/redhat-appstudio/cachi2:0.7.0@sha256:1fc772aa3636fd0b43d62120d832e5913843e028e8cac42814b487c3a0a32bd8 - name: prefetch-dependencies - env: - - name: INPUT - value: $(params.input) - - name: DEV_PACKAGE_MANAGERS - value: $(params.dev-package-managers) - - name: LOG_LEVEL - value: $(params.log-level) - - name: WORKSPACE_GIT_AUTH_BOUND - value: $(workspaces.git-basic-auth.bound) - - name: WORKSPACE_GIT_AUTH_PATH - value: $(workspaces.git-basic-auth.path) - volumeMounts: - - name: trusted-ca - mountPath: /mnt/trusted-ca - readOnly: true - script: | - if [ -z "${INPUT}" ] - then - # Confirm input was provided though it's likely the whole task would be skipped if it wasn't - echo "No prefetch will be performed because no input was provided for cachi2 fetch-deps" - exit 0 - fi + description: |- + Task that uses Cachi2 to prefetch build dependencies. The fetched dependencies and the + application source code are stored as a trusted artifact in the provided OCI repository. + For additional info on Cachi2, see docs at + https://github.com/containerbuildsystem/cachi2#basic-usage. + params: + - name: SOURCE_ARTIFACT + description: The Trusted Artifact URI pointing to the artifact with + the application source code. + type: string + - 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 + - name: dev-package-managers + description: | + Enable in-development package managers. WARNING: the behavior may change at any time without notice. Use at your own risk. + default: "false" + - name: input + description: Configures project packages that will have their dependencies + prefetched. + - name: log-level + description: Set cachi2 log level (debug, info, warning, error) + default: info + - name: ociArtifactExpiresAfter + description: Expiration date for the trusted artifacts created in + the OCI repository. An empty string means the artifacts do not + expire. + type: string + default: "" + - name: ociStorage + description: The OCI repository where the Trusted Artifacts are + stored. + type: string + results: + - name: CACHI2_ARTIFACT + description: The Trusted Artifact URI pointing to the artifact with + the prefetched dependencies. + type: string + - name: SOURCE_ARTIFACT + description: The Trusted Artifact URI pointing to the artifact with + the application source code. + type: string + volumes: + - name: trusted-ca + configMap: + items: + - key: $(params.caTrustConfigMapKey) + path: ca-bundle.crt + name: $(params.caTrustConfigMapName) + optional: true + - name: workdir + emptyDir: {} + workspaces: + - name: git-basic-auth + description: | + A Workspace containing a .gitconfig and .git-credentials file or username and password. + These will be copied to the user's home before any cachi2 commands are run. Any + other files in this Workspace are ignored. It is strongly recommended + to bind a Secret to this Workspace over other volume types. + optional: true + stepTemplate: + volumeMounts: + - mountPath: /var/workdir + name: workdir + steps: + - name: use-trusted-artifact + image: quay.io/redhat-appstudio/build-trusted-artifacts:latest@sha256:4e39fb97f4444c2946944482df47b39c5bbc195c54c6560b0647635f553ab23d + args: + - use + - $(params.SOURCE_ARTIFACT)=/var/workdir/source + - name: prefetch-dependencies + image: quay.io/redhat-appstudio/cachi2:0.7.0@sha256:1fc772aa3636fd0b43d62120d832e5913843e028e8cac42814b487c3a0a32bd8 + volumeMounts: + - mountPath: /mnt/trusted-ca + name: trusted-ca + readOnly: true + env: + - name: INPUT + value: $(params.input) + - name: DEV_PACKAGE_MANAGERS + value: $(params.dev-package-managers) + - name: LOG_LEVEL + value: $(params.log-level) + - name: WORKSPACE_GIT_AUTH_BOUND + value: $(workspaces.git-basic-auth.bound) + - name: WORKSPACE_GIT_AUTH_PATH + value: $(workspaces.git-basic-auth.path) + script: | + if [ -z "${INPUT}" ]; then + # Confirm input was provided though it's likely the whole task would be skipped if it wasn't + echo "No prefetch will be performed because no input was provided for cachi2 fetch-deps" + exit 0 + fi - if [ "$DEV_PACKAGE_MANAGERS" = "true" ]; then - dev_pacman_flag=--dev-package-managers - else - dev_pacman_flag="" - fi + if [ "$DEV_PACKAGE_MANAGERS" = "true" ]; then + dev_pacman_flag=--dev-package-managers + else + dev_pacman_flag="" + fi - # Copied from https://github.com/konflux-ci/build-definitions/blob/main/task/git-clone/0.1/git-clone.yaml - if [ "${WORKSPACE_GIT_AUTH_BOUND}" = "true" ] ; then - if [ -f "${WORKSPACE_GIT_AUTH_PATH}/.git-credentials" ] && [ -f "${WORKSPACE_GIT_AUTH_PATH}/.gitconfig" ]; then - cp "${WORKSPACE_GIT_AUTH_PATH}/.git-credentials" "${HOME}/.git-credentials" - cp "${WORKSPACE_GIT_AUTH_PATH}/.gitconfig" "${HOME}/.gitconfig" - # Compatibility with kubernetes.io/basic-auth secrets - elif [ -f "${WORKSPACE_GIT_AUTH_PATH}/username" ] && [ -f "${WORKSPACE_GIT_AUTH_PATH}/password" ]; then - HOSTNAME=$(cd "/var/workdir/source" && git remote get-url origin | awk -F/ '{print $3}') - echo "https://$(cat ${WORKSPACE_GIT_AUTH_PATH}/username):$(cat ${WORKSPACE_GIT_AUTH_PATH}/password)@$HOSTNAME" > "${HOME}/.git-credentials" - echo -e "[credential \"https://$HOSTNAME\"]\n helper = store" > "${HOME}/.gitconfig" - else - echo "Unknown git-basic-auth workspace format" - exit 1 - fi - chmod 400 "${HOME}/.git-credentials" - chmod 400 "${HOME}/.gitconfig" - fi + # Copied from https://github.com/konflux-ci/build-definitions/blob/main/task/git-clone/0.1/git-clone.yaml + if [ "${WORKSPACE_GIT_AUTH_BOUND}" = "true" ]; then + if [ -f "${WORKSPACE_GIT_AUTH_PATH}/.git-credentials" ] && [ -f "${WORKSPACE_GIT_AUTH_PATH}/.gitconfig" ]; then + cp "${WORKSPACE_GIT_AUTH_PATH}/.git-credentials" "${HOME}/.git-credentials" + cp "${WORKSPACE_GIT_AUTH_PATH}/.gitconfig" "${HOME}/.gitconfig" + # Compatibility with kubernetes.io/basic-auth secrets + elif [ -f "${WORKSPACE_GIT_AUTH_PATH}/username" ] && [ -f "${WORKSPACE_GIT_AUTH_PATH}/password" ]; then + HOSTNAME=$(cd "/var/workdir/source" && git remote get-url origin | awk -F/ '{print $3}') + echo "https://$(cat ${WORKSPACE_GIT_AUTH_PATH}/username):$(cat ${WORKSPACE_GIT_AUTH_PATH}/password)@$HOSTNAME" >"${HOME}/.git-credentials" + echo -e "[credential \"https://$HOSTNAME\"]\n helper = store" >"${HOME}/.gitconfig" + else + echo "Unknown git-basic-auth workspace format" + exit 1 + fi + chmod 400 "${HOME}/.git-credentials" + chmod 400 "${HOME}/.gitconfig" + 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 + 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 - cachi2 --log-level="$LOG_LEVEL" fetch-deps \ - $dev_pacman_flag \ - --source=/var/workdir/source \ - --output=/var/workdir/cachi2/output \ - "${INPUT}" + cachi2 --log-level="$LOG_LEVEL" fetch-deps \ + $dev_pacman_flag \ + --source=/var/workdir/source \ + --output=/var/workdir/cachi2/output \ + "${INPUT}" - cachi2 --log-level="$LOG_LEVEL" generate-env /var/workdir/cachi2/output \ - --format env \ - --for-output-dir=/cachi2/output \ - --output /var/workdir/cachi2/cachi2.env + cachi2 --log-level="$LOG_LEVEL" generate-env /var/workdir/cachi2/output \ + --format env \ + --for-output-dir=/cachi2/output \ + --output /var/workdir/cachi2/cachi2.env - cachi2 --log-level="$LOG_LEVEL" inject-files /var/workdir/cachi2/output \ - --for-output-dir=/cachi2/output - - image: quay.io/redhat-appstudio/build-trusted-artifacts:latest@sha256:4e39fb97f4444c2946944482df47b39c5bbc195c54c6560b0647635f553ab23d - name: create-trusted-artifact - env: - - name: IMAGE_EXPIRES_AFTER - value: $(params.ociArtifactExpiresAfter) - args: - - create - - --store - - $(params.ociStorage) - - $(results.SOURCE_ARTIFACT.path)=/var/workdir/source - - $(results.CACHI2_ARTIFACT.path)=/var/workdir/cachi2 - workspaces: - - name: git-basic-auth - description: | - A Workspace containing a .gitconfig and .git-credentials file or username and password. - These will be copied to the user's home before any cachi2 commands are run. Any - other files in this Workspace are ignored. It is strongly recommended - to bind a Secret to this Workspace over other volume types. - optional: true - volumes: - - name: workdir - emptyDir: {} - - name: trusted-ca - configMap: - name: $(params.caTrustConfigMapName) - items: - - key: $(params.caTrustConfigMapKey) - path: ca-bundle.crt - optional: true + cachi2 --log-level="$LOG_LEVEL" inject-files /var/workdir/cachi2/output \ + --for-output-dir=/cachi2/output + - name: create-trusted-artifact + image: quay.io/redhat-appstudio/build-trusted-artifacts:latest@sha256:4e39fb97f4444c2946944482df47b39c5bbc195c54c6560b0647635f553ab23d + args: + - create + - --store + - $(params.ociStorage) + - $(results.SOURCE_ARTIFACT.path)=/var/workdir/source + - $(results.CACHI2_ARTIFACT.path)=/var/workdir/cachi2 + env: + - name: IMAGE_EXPIRES_AFTER + value: $(params.ociArtifactExpiresAfter) diff --git a/task/sast-snyk-check-oci-ta/0.1/README.md b/task/sast-snyk-check-oci-ta/0.1/README.md index 227286f85c..77cdd4e86a 100644 --- a/task/sast-snyk-check-oci-ta/0.1/README.md +++ b/task/sast-snyk-check-oci-ta/0.1/README.md @@ -11,9 +11,9 @@ See https://snyk.io/product/snyk-code/ and https://snyk.io/ for more information ## Parameters |name|description|default value|required| |---|---|---|---| -|SOURCE_ARTIFACT|The trusted artifact URI containing the application source code.||true| -|SNYK_SECRET|Name of secret which contains Snyk token.|snyk-secret|false| |ARGS|Append arguments.|--all-projects --exclude=test*,vendor,deps|false| +|SNYK_SECRET|Name of secret which contains Snyk token.|snyk-secret|false| +|SOURCE_ARTIFACT|The Trusted Artifact URI pointing to the artifact with the application source code.||true| ## Results |name|description| diff --git a/task/sast-snyk-check-oci-ta/0.1/sast-snyk-check-oci-ta.yaml b/task/sast-snyk-check-oci-ta/0.1/sast-snyk-check-oci-ta.yaml index 7bd2be6403..591c27abc6 100644 --- a/task/sast-snyk-check-oci-ta/0.1/sast-snyk-check-oci-ta.yaml +++ b/task/sast-snyk-check-oci-ta/0.1/sast-snyk-check-oci-ta.yaml @@ -2,113 +2,105 @@ apiVersion: tekton.dev/v1 kind: Task metadata: - labels: - app.kubernetes.io/version: "0.1" - annotations: - tekton.dev/pipelines.minVersion: "0.12.1" - tekton.dev/tags: "appstudio, hacbs" - name: sast-snyk-check-oci-ta + name: sast-snyk-check-oci-ta + annotations: + tekton.dev/pipelines.minVersion: 0.12.1 + tekton.dev/tags: appstudio, hacbs + labels: + app.kubernetes.io/version: "0.1" spec: - description: >- - Scans source code for security vulnerabilities, including common issues such as SQL injection, - cross-site scripting (XSS), and code injection attacks using Snyk Code, a Static Application - Security Testing (SAST) tool. + description: |- + Scans source code for security vulnerabilities, including common issues such as SQL injection, cross-site scripting (XSS), and code injection attacks using Snyk Code, a Static Application Security Testing (SAST) tool. + Follow the steps given [here](https://redhat-appstudio.github.io/docs.appstudio.io/Documentation/main/how-to-guides/testing_applications/enable_snyk_check_for_a_product/) to obtain a snyk-token and to enable the snyk task in a Pipeline. - Follow the steps given - [here](https://redhat-appstudio.github.io/docs.appstudio.io/Documentation/main/how-to-guides/testing_applications/enable_snyk_check_for_a_product/) - to obtain a snyk-token and to enable the snyk task in a Pipeline. + The snyk binary used in this Task comes from a container image defined in https://github.com/konflux-ci/konflux-test - - The snyk binary used in this Task comes from a container image defined in - https://github.com/konflux-ci/konflux-test - - - See https://snyk.io/product/snyk-code/ and https://snyk.io/ for more information about the snyk - tool. - results: - - description: Tekton task test output. - name: TEST_OUTPUT - params: - - name: SOURCE_ARTIFACT - type: string - description: The Trusted Artifact URI pointing to the artifact with the application source code. - - name: SNYK_SECRET - description: Name of secret which contains Snyk token. - default: snyk-secret - - name: ARGS - type: string - description: Append arguments. - default: "--all-projects --exclude=test*,vendor,deps" - volumes: - - name: snyk-secret - secret: - secretName: $(params.SNYK_SECRET) - optional: true - - name: workdir - emptyDir: {} - stepTemplate: - volumeMounts: - - mountPath: /var/workdir - name: workdir - steps: - - name: use-trusted-artifact - image: quay.io/redhat-appstudio/build-trusted-artifacts:latest@sha256:4e39fb97f4444c2946944482df47b39c5bbc195c54c6560b0647635f553ab23d - args: - - use - - $(params.SOURCE_ARTIFACT)=/var/workdir/source - - name: sast-snyk-check - image: quay.io/redhat-appstudio/konflux-test:v1.4.0@sha256:54d49b37c9a2e280d42961a57e4f7a16c171d6b065559f1329b548db85300bea - workingDir: /var/workdir/source - volumeMounts: - - name: snyk-secret - mountPath: "/etc/secrets" - readOnly: true - env: - - name: SNYK_SECRET - value: $(params.SNYK_SECRET) + See https://snyk.io/product/snyk-code/ and https://snyk.io/ for more information about the snyk tool. + params: - name: ARGS - value: $(params.ARGS) - script: | - #!/usr/bin/env bash - set -euo pipefail - . /utils.sh - trap 'handle_error $(results.TEST_OUTPUT.path)' EXIT + description: Append arguments. + type: string + default: --all-projects --exclude=test*,vendor,deps + - name: SNYK_SECRET + description: Name of secret which contains Snyk token. + default: snyk-secret + - name: SOURCE_ARTIFACT + description: The Trusted Artifact URI pointing to the artifact with + the application source code. + type: string + results: + - name: TEST_OUTPUT + description: Tekton task test output. + volumes: + - name: snyk-secret + secret: + optional: true + secretName: $(params.SNYK_SECRET) + - name: workdir + emptyDir: {} + stepTemplate: + volumeMounts: + - mountPath: /var/workdir + name: workdir + steps: + - name: use-trusted-artifact + image: quay.io/redhat-appstudio/build-trusted-artifacts:latest@sha256:4e39fb97f4444c2946944482df47b39c5bbc195c54c6560b0647635f553ab23d + args: + - use + - $(params.SOURCE_ARTIFACT)=/var/workdir/source + - name: sast-snyk-check + image: quay.io/redhat-appstudio/konflux-test:v1.4.0@sha256:54d49b37c9a2e280d42961a57e4f7a16c171d6b065559f1329b548db85300bea + workingDir: /var/workdir/source + volumeMounts: + - mountPath: /etc/secrets + name: snyk-secret + readOnly: true + env: + - name: SNYK_SECRET + value: $(params.SNYK_SECRET) + - name: ARGS + value: $(params.ARGS) + script: | + #!/usr/bin/env bash + set -euo pipefail + . /utils.sh + trap 'handle_error $(results.TEST_OUTPUT.path)' EXIT - SNYK_TOKEN_PATH="/etc/secrets/snyk_token" + SNYK_TOKEN_PATH="/etc/secrets/snyk_token" - if [ -f "${SNYK_TOKEN_PATH}" ] && [ -s "${SNYK_TOKEN_PATH}" ]; then - # SNYK token is provided - SNYK_TOKEN="$(cat ${SNYK_TOKEN_PATH})" - export SNYK_TOKEN - else - to_enable_snyk='[here](https://redhat-appstudio.github.io/docs.appstudio.io/Documentation/main/how-to-guides/testing_applications/enable_snyk_check_for_a_product/)' - note="Task $(context.task.name) skipped: If you wish to use the Snyk code SAST task, please create a secret name snyk-secret with the key "snyk_token" containing the Snyk token by following the steps given ${to_enable_snyk}" - TEST_OUTPUT=$(make_result_json -r SKIPPED -t "$note") - echo "${TEST_OUTPUT}" | tee "$(results.TEST_OUTPUT.path)" - exit 0 - fi + if [ -f "${SNYK_TOKEN_PATH}" ] && [ -s "${SNYK_TOKEN_PATH}" ]; then + # SNYK token is provided + SNYK_TOKEN="$(cat ${SNYK_TOKEN_PATH})" + export SNYK_TOKEN + else + to_enable_snyk='[here](https://redhat-appstudio.github.io/docs.appstudio.io/Documentation/main/how-to-guides/testing_applications/enable_snyk_check_for_a_product/)' + note="Task $(context.task.name) skipped: If you wish to use the Snyk code SAST task, please create a secret name snyk-secret with the key "snyk_token" containing the Snyk token by following the steps given ${to_enable_snyk}" + TEST_OUTPUT=$(make_result_json -r SKIPPED -t "$note") + echo "${TEST_OUTPUT}" | tee "$(results.TEST_OUTPUT.path)" + exit 0 + fi - SNYK_EXIT_CODE=0 - SOURCE_CODE_DIR=/var/workdir/source - snyk code test $ARGS $SOURCE_CODE_DIR --sarif-file-output=sast_snyk_check_out.json 1>&2>> stdout.txt || SNYK_EXIT_CODE=$? - test_not_skipped=0 - SKIP_MSG="We found 0 supported files" - grep -q "$SKIP_MSG" stdout.txt || test_not_skipped=$? + SNYK_EXIT_CODE=0 + SOURCE_CODE_DIR=/var/workdir/source + snyk code test $ARGS $SOURCE_CODE_DIR --sarif-file-output=sast_snyk_check_out.json 1>&2 >>stdout.txt || SNYK_EXIT_CODE=$? + test_not_skipped=0 + SKIP_MSG="We found 0 supported files" + grep -q "$SKIP_MSG" stdout.txt || test_not_skipped=$? - if [[ "$SNYK_EXIT_CODE" -eq 0 ]] || [[ "$SNYK_EXIT_CODE" -eq 1 ]]; then - cat sast_snyk_check_out.json - TEST_OUTPUT= - parse_test_output $(context.task.name) sarif sast_snyk_check_out.json || true + if [[ "$SNYK_EXIT_CODE" -eq 0 ]] || [[ "$SNYK_EXIT_CODE" -eq 1 ]]; then + cat sast_snyk_check_out.json + TEST_OUTPUT= + parse_test_output $(context.task.name) sarif sast_snyk_check_out.json || true - # When the test is skipped, the "SNYK_EXIT_CODE" is 3 and it can also be 3 in some other situation - elif [[ "$test_not_skipped" -eq 0 ]]; then - note="Task $(context.task.name) success: Snyk code test found zero supported files." - ERROR_OUTPUT=$(make_result_json -r SUCCESS -t "$note") - else - echo "sast-snyk-check test failed because of the following issues:" - cat stdout.txt - note="Task $(context.task.name) failed: For details, check Tekton task log." - ERROR_OUTPUT=$(make_result_json -r ERROR -t "$note") - fi - echo "${TEST_OUTPUT:-${ERROR_OUTPUT}}" | tee $(results.TEST_OUTPUT.path) + # When the test is skipped, the "SNYK_EXIT_CODE" is 3 and it can also be 3 in some other situation + elif [[ "$test_not_skipped" -eq 0 ]]; then + note="Task $(context.task.name) success: Snyk code test found zero supported files." + ERROR_OUTPUT=$(make_result_json -r SUCCESS -t "$note") + else + echo "sast-snyk-check test failed because of the following issues:" + cat stdout.txt + note="Task $(context.task.name) failed: For details, check Tekton task log." + ERROR_OUTPUT=$(make_result_json -r ERROR -t "$note") + fi + echo "${TEST_OUTPUT:-${ERROR_OUTPUT}}" | tee $(results.TEST_OUTPUT.path) diff --git a/task/source-build-oci-ta/0.1/README.md b/task/source-build-oci-ta/0.1/README.md index 6f7b3ee2c4..43bf1b2d43 100644 --- a/task/source-build-oci-ta/0.1/README.md +++ b/task/source-build-oci-ta/0.1/README.md @@ -5,15 +5,15 @@ Source image build. ## Parameters |name|description|default value|required| |---|---|---|---| -|BINARY_IMAGE|Binary image name from which to generate the source image name.||true| |BASE_IMAGES|Base images used to build the binary image. Each image per line in the same order of FROM instructions specified in a multistage Dockerfile. Default to an empty string, which means to skip handling a base image.|""|false| -|SOURCE_ARTIFACT|The trusted artifact URI containing the application source code.||true| -|CACHI2_ARTIFACT|The trusted artifact URI containing the prefetched dependencies.|""|false| +|BINARY_IMAGE|Binary image name from which to generate the source image name.||true| +|CACHI2_ARTIFACT|The Trusted Artifact URI pointing to the artifact with the prefetched dependencies.|""|false| +|SOURCE_ARTIFACT|The Trusted Artifact URI pointing to the artifact with the application source code.||true| ## Results |name|description| |---|---| |BUILD_RESULT|Build result.| -|SOURCE_IMAGE_URL|The source image url.| |SOURCE_IMAGE_DIGEST|The source image digest.| +|SOURCE_IMAGE_URL|The source image url.| diff --git a/task/source-build-oci-ta/0.1/source-build-oci-ta.yaml b/task/source-build-oci-ta/0.1/source-build-oci-ta.yaml index de09be39cc..786b28422c 100644 --- a/task/source-build-oci-ta/0.1/source-build-oci-ta.yaml +++ b/task/source-build-oci-ta/0.1/source-build-oci-ta.yaml @@ -2,111 +2,113 @@ apiVersion: tekton.dev/v1 kind: Task metadata: - name: source-build-oci-ta - labels: - app.kubernetes.io/version: "0.1" - annotations: - tekton.dev/pipelines.minVersion: "0.12.1" - tekton.dev/tags: "appstudio" + name: source-build-oci-ta + annotations: + tekton.dev/pipelines.minVersion: 0.12.1 + tekton.dev/tags: appstudio + labels: + app.kubernetes.io/version: "0.1" spec: - description: Source image build. - params: - - name: BINARY_IMAGE - description: Binary image name from which to generate the source image name. - type: string - - name: BASE_IMAGES - description: >- - Base images used to build the binary image. Each image per line in the same order of FROM - instructions specified in a multistage Dockerfile. Default to an empty string, which means - to skip handling a base image. - type: string - default: "" - - name: SOURCE_ARTIFACT - description: The Trusted Artifact URI pointing to the artifact with the application source code. - type: string - - name: CACHI2_ARTIFACT - description: The Trusted Artifact URI pointing to the artifact with the prefetched dependencies. - type: string - default: "" - - results: - - name: BUILD_RESULT - description: Build result. - - name: SOURCE_IMAGE_URL - description: The source image url. - - name: SOURCE_IMAGE_DIGEST - description: The source image digest. - volumes: - - name: workdir - emptyDir: {} - stepTemplate: - volumeMounts: - - name: workdir - mountPath: /var/workdir - steps: - - name: use-trusted-artifact - image: quay.io/redhat-appstudio/build-trusted-artifacts:latest@sha256:4e39fb97f4444c2946944482df47b39c5bbc195c54c6560b0647635f553ab23d - args: - - use - - $(params.SOURCE_ARTIFACT)=/var/workdir/source - - $(params.CACHI2_ARTIFACT)=/var/workdir/cachi2 - - name: build - image: quay.io/redhat-appstudio/build-definitions-source-image-build-utils@sha256:cd87bbe51f1c22ff7578f5c9caf19db4f9ee7aefd0307288383b9bd478cdf856 - computeResources: - limits: - memory: 2Gi - requests: - memory: 512Mi - cpu: 250m - workingDir: "/var/workdir" - securityContext: - runAsUser: 0 - capabilities: - add: - - SETFCAP - env: - - name: BINARY_IMAGE - value: "$(params.BINARY_IMAGE)" - - name: SOURCE_DIR - value: "/var/workdir/source" + description: Source image build. + params: - name: BASE_IMAGES - value: "$(params.BASE_IMAGES)" - - name: RESULT_FILE - value: "$(results.BUILD_RESULT.path)" - - name: CACHI2_ARTIFACTS_DIR - value: "/var/workdir/cachi2" - - name: RESULT_SOURCE_IMAGE_URL - value: "$(results.SOURCE_IMAGE_URL.path)" - - name: RESULT_SOURCE_IMAGE_DIGEST - value: "$(results.SOURCE_IMAGE_DIGEST.path)" - - name: WS_BUILD_RESULT_FILE - value: "/var/workdir/source_build_result.json" - script: | - #!/usr/bin/env bash - set -euo pipefail + description: Base images used to build the binary image. Each image + per line in the same order of FROM instructions specified in a + multistage Dockerfile. Default to an empty string, which means + to skip handling a base image. + type: string + default: "" + - name: BINARY_IMAGE + description: Binary image name from which to generate the source + image name. + type: string + - name: CACHI2_ARTIFACT + description: The Trusted Artifact URI pointing to the artifact with + the prefetched dependencies. + type: string + default: "" + - name: SOURCE_ARTIFACT + description: The Trusted Artifact URI pointing to the artifact with + the application source code. + type: string + results: + - name: BUILD_RESULT + description: Build result. + - name: SOURCE_IMAGE_DIGEST + description: The source image digest. + - name: SOURCE_IMAGE_URL + description: The source image url. + volumes: + - name: workdir + emptyDir: {} + stepTemplate: + volumeMounts: + - mountPath: /var/workdir + name: workdir + steps: + - name: use-trusted-artifact + image: quay.io/redhat-appstudio/build-trusted-artifacts:latest@sha256:4e39fb97f4444c2946944482df47b39c5bbc195c54c6560b0647635f553ab23d + args: + - use + - $(params.SOURCE_ARTIFACT)=/var/workdir/source + - $(params.CACHI2_ARTIFACT)=/var/workdir/cachi2 + - name: build + image: quay.io/redhat-appstudio/build-definitions-source-image-build-utils@sha256:cd87bbe51f1c22ff7578f5c9caf19db4f9ee7aefd0307288383b9bd478cdf856 + workingDir: /var/workdir + env: + - name: BINARY_IMAGE + value: $(params.BINARY_IMAGE) + - name: SOURCE_DIR + value: /var/workdir/source + - name: BASE_IMAGES + value: $(params.BASE_IMAGES) + - name: RESULT_FILE + value: $(results.BUILD_RESULT.path) + - name: CACHI2_ARTIFACTS_DIR + value: /var/workdir/cachi2 + - name: RESULT_SOURCE_IMAGE_URL + value: $(results.SOURCE_IMAGE_URL.path) + - name: RESULT_SOURCE_IMAGE_DIGEST + value: $(results.SOURCE_IMAGE_DIGEST.path) + - name: WS_BUILD_RESULT_FILE + value: /var/workdir/source_build_result.json + script: | + #!/usr/bin/env bash + set -euo pipefail - app_dir=/opt/source_build - registry_allowlist=" - registry.access.redhat.com - registry.redhat.io - " + app_dir=/opt/source_build + registry_allowlist=" + registry.access.redhat.com + registry.redhat.io + " - ## This is needed for the builds performed by the rpm-ostree task - ## otherwise, we can see this error: - ## "fatal: detected dubious ownership in repository at '/var/workdir/source'" - ## - git config --global --add safe.directory $SOURCE_DIR + ## This is needed for the builds performed by the rpm-ostree task + ## otherwise, we can see this error: + ## "fatal: detected dubious ownership in repository at '/var/workdir/source'" + ## + git config --global --add safe.directory $SOURCE_DIR - ${app_dir}/appenv/bin/python3 ${app_dir}/source_build.py \ - --output-binary-image "$BINARY_IMAGE" \ - --workspace /var/workdir \ - --source-dir "$SOURCE_DIR" \ - --base-images "$BASE_IMAGES" \ - --write-result-to "$RESULT_FILE" \ - --cachi2-artifacts-dir "$CACHI2_ARTIFACTS_DIR" \ - --registry-allowlist="$registry_allowlist" + ${app_dir}/appenv/bin/python3 ${app_dir}/source_build.py \ + --output-binary-image "$BINARY_IMAGE" \ + --workspace /var/workdir \ + --source-dir "$SOURCE_DIR" \ + --base-images "$BASE_IMAGES" \ + --write-result-to "$RESULT_FILE" \ + --cachi2-artifacts-dir "$CACHI2_ARTIFACTS_DIR" \ + --registry-allowlist="$registry_allowlist" - cat "$RESULT_FILE" | jq -r ".image_url" >"$RESULT_SOURCE_IMAGE_URL" - cat "$RESULT_FILE" | jq -r ".image_digest" >"$RESULT_SOURCE_IMAGE_DIGEST" + cat "$RESULT_FILE" | jq -r ".image_url" >"$RESULT_SOURCE_IMAGE_URL" + cat "$RESULT_FILE" | jq -r ".image_digest" >"$RESULT_SOURCE_IMAGE_DIGEST" - cp "$RESULT_FILE" "$WS_BUILD_RESULT_FILE" + cp "$RESULT_FILE" "$WS_BUILD_RESULT_FILE" + computeResources: + limits: + memory: 2Gi + requests: + cpu: 250m + memory: 512Mi + securityContext: + capabilities: + add: + - SETFCAP + runAsUser: 0