From a2b080fd71ee37be4eba719ad23e3e6632f697ad 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 | 887 +++++++++--------- task/git-clone-oci-ta/0.1/README.md | 30 +- .../0.1/git-clone-oci-ta.yaml | 532 ++++++----- .../0.1/README.md | 16 +- .../0.1/prefetch-dependencies-oci-ta.yaml | 270 +++--- task/sast-snyk-check-oci-ta/0.1/README.md | 4 +- .../0.1/sast-snyk-check-oci-ta.yaml | 52 +- task/source-build-oci-ta/0.1/README.md | 8 +- .../0.1/source-build-oci-ta.yaml | 78 +- 10 files changed, 962 insertions(+), 945 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 1e4b564159..fb349fa64b 100644 --- a/task/buildah-oci-ta/0.1/buildah-oci-ta.yaml +++ b/task/buildah-oci-ta/0.1/buildah-oci-ta.yaml @@ -2,13 +2,13 @@ apiVersion: tekton.dev/v1 kind: Task metadata: + 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" - annotations: - tekton.dev/pipelines.minVersion: "0.12.1" - tekton.dev/tags: "image-build, appstudio, hacbs" - name: buildah-oci-ta + 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. @@ -16,459 +16,480 @@ spec: 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: 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 - value: $(params.CONTEXT) + description: Path to the directory to use as context. + type: string + default: . - name: DOCKERFILE - value: $(params.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 - value: $(params.IMAGE) - - name: TLSVERIFY - value: $(params.TLSVERIFY) + description: Reference of the image buildah will produce. + type: string - name: IMAGE_EXPIRES_AFTER - value: $(params.IMAGE_EXPIRES_AFTER) - - name: YUM_REPOS_D_SRC - value: $(params.YUM_REPOS_D_SRC) + 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 - value: $(params.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 - 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) + 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: shared + emptyDir: {} + - 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: /shared name: shared - 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" + - 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 - 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 + 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 - 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 + # 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 + 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 + # Setting new namespace to run buildah - 2^32-2 + echo 'root:1:4294967294' | tee -a /etc/subuid >>/etc/subgid - BUILDAH_ARGS=() + 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 + 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 - 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" + + 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 - 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 /shared/container_path - echo $container > /shared/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 - touch $(results.BASE_IMAGES_DIGESTS.path) - for image in $BASE_IMAGES; do - if [ "${image}" != "scratch" ]; then - buildah images --format '{{ .Name }}:{{ .Tag }}@{{ .Digest }}' --filter reference="$image" >> $(results.BASE_IMAGES_DIGESTS.path) + + # 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 - done - # Needed to generate base images SBOM - echo "$BASE_IMAGES" > /var/workdir/base_images_from_dockerfile + # 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 - securityContext: - capabilities: - add: - - SETFCAP - volumeMounts: - - mountPath: /var/lib/containers - name: varlibcontainers - - mountPath: "/entitlement" - name: etc-pki-entitlement - - name: shared - mountPath: "/shared" - 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 /shared/container_path) -xtype l -delete - echo "Running syft on the image filesystem" - syft dir:$(cat /shared/container_path) --output cyclonedx-json=/var/workdir/sbom-image.json - volumeMounts: - - mountPath: /var/lib/containers - name: varlibcontainers - - name: shared - mountPath: "/shared" - - 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 /shared/container_path) -s /var/workdir/sbom-image.json --task-run-name $(context.taskRun.name) --publishers $(results.SBOM_JAVA_COMPONENTS_COUNT.path) - sed -i 's/^/ /' $(results.SBOM_JAVA_COMPONENTS_COUNT.path) # Workaround for SRVKP-2875 - else - touch $(results.JAVA_COMMUNITY_DEPENDENCIES.path) - fi - volumeMounts: - - mountPath: /var/lib/containers - name: varlibcontainers - - name: shared - mountPath: "/shared" - 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 + 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 - cat "/var/workdir"/image-digest | tee $(results.IMAGE_DIGEST.path) - echo -n "$IMAGE" | tee $(results.IMAGE_URL.path) + 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 /shared/container_path + echo $container >/shared/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 - 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 + # Expose base image digests + touch $(results.BASE_IMAGES_DIGESTS.path) + 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 - volumes: - - name: varlibcontainers - emptyDir: {} - - name: shared - emptyDir: {} - - name: workdir - emptyDir: {} - - name: etc-pki-entitlement - secret: - secretName: $(params.ENTITLEMENT_SECRET) - optional: true + # 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 + - mountPath: /shared + name: shared + script: | + echo "Running syft on the source directory" + syft dir:/var/workdir/source --output cyclonedx-json=/var/workdir/sbom-source.json + find $(cat /shared/container_path) -xtype l -delete + echo "Running syft on the image filesystem" + syft dir:$(cat /shared/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 + - mountPath: /shared + name: shared + script: | + if [ -f /var/lib/containers/java ]; then + /opt/jboss/container/java/run/run-java.sh analyse-dependencies path $(cat /shared/container_path) -s /var/workdir/sbom-image.json --task-run-name $(context.taskRun.name) --publishers $(results.SBOM_JAVA_COMPONENTS_COUNT.path) + sed -i 's/^/ /' $(results.SBOM_JAVA_COMPONENTS_COUNT.path) # Workaround for SRVKP-2875 + else + touch $(results.JAVA_COMMUNITY_DEPENDENCIES.path) + fi + 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..b7c05abfd0 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,289 @@ apiVersion: tekton.dev/v1 kind: Task metadata: - labels: - app.kubernetes.io/version: "0.1" + 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 - name: git-clone-oci-ta + 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. + 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: "" - + - 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: - - 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 + - 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 - 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 + - 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 - 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 + if [ "${PARAM_VERBOSE}" = "true" ]; then + set -x 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 - 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}" + 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 - /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)" + # 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 [ "${PARAM_FETCH_TAGS}" = "true" ] ; then - echo "Fetching tags" - git fetch --tags - 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 - - 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 + 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}" - 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 + /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_ENABLE_SYMLINK_CHECK}" = "true" ] ; then - echo "Running symlink check" - check_symlinks - fi + 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 - - 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 + 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 + } - 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..2bb99bca20 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,12 +2,12 @@ apiVersion: tekton.dev/v1 kind: Task metadata: + 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" - annotations: - tekton.dev/pipelines.minVersion: "0.12.1" - tekton.dev/tags: "image-build, hacbs" - name: prefetch-dependencies-oci-ta spec: description: |- Task that uses Cachi2 to prefetch build dependencies. The fetched dependencies and the @@ -15,148 +15,150 @@ spec: 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 + - 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: - - description: The Trusted Artifact URI pointing to the artifact with the application source code. - name: SOURCE_ARTIFACT + - name: CACHI2_ARTIFACT + description: The Trusted Artifact URI pointing to the artifact with + the prefetched dependencies. type: string - - description: The Trusted Artifact URI pointing to the artifact with the prefetched dependencies. - name: CACHI2_ARTIFACT + - 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: - - 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 - - if [ "$DEV_PACKAGE_MANAGERS" = "true" ]; then - dev_pacman_flag=--dev-package-managers - else - dev_pacman_flag="" - fi + - 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 - # 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" + if [ "$DEV_PACKAGE_MANAGERS" = "true" ]; then + dev_pacman_flag=--dev-package-managers else - echo "Unknown git-basic-auth workspace format" - exit 1 + dev_pacman_flag="" 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 + # 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 - cachi2 --log-level="$LOG_LEVEL" fetch-deps \ - $dev_pacman_flag \ - --source=/var/workdir/source \ - --output=/var/workdir/cachi2/output \ - "${INPUT}" + 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" generate-env /var/workdir/cachi2/output \ - --format env \ - --for-output-dir=/cachi2/output \ - --output /var/workdir/cachi2/cachi2.env + 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" 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" 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 + - 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..a35c8abf01 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,49 +2,41 @@ apiVersion: tekton.dev/v1 kind: Task metadata: + 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" - annotations: - tekton.dev/pipelines.minVersion: "0.12.1" - tekton.dev/tags: "appstudio, hacbs" - name: sast-snyk-check-oci-ta 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 + See https://snyk.io/product/snyk-code/ and https://snyk.io/ for more information about the snyk tool. params: - - name: SOURCE_ARTIFACT + - name: ARGS + description: Append arguments. type: string - description: The Trusted Artifact URI pointing to the artifact with the application source code. + default: --all-projects --exclude=test*,vendor,deps - name: SNYK_SECRET description: Name of secret which contains Snyk token. default: snyk-secret - - name: ARGS + - name: SOURCE_ARTIFACT + description: The Trusted Artifact URI pointing to the artifact with + the application source code. type: string - description: Append arguments. - default: "--all-projects --exclude=test*,vendor,deps" + results: + - name: TEST_OUTPUT + description: Tekton task test output. volumes: - name: snyk-secret secret: - secretName: $(params.SNYK_SECRET) optional: true + secretName: $(params.SNYK_SECRET) - name: workdir emptyDir: {} stepTemplate: @@ -61,8 +53,8 @@ spec: image: quay.io/redhat-appstudio/konflux-test:v1.4.0@sha256:54d49b37c9a2e280d42961a57e4f7a16c171d6b065559f1329b548db85300bea workingDir: /var/workdir/source volumeMounts: - - name: snyk-secret - mountPath: "/etc/secrets" + - mountPath: /etc/secrets + name: snyk-secret readOnly: true env: - name: SNYK_SECRET @@ -91,7 +83,7 @@ spec: 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=$? + 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=$? 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..44c9d64555 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 @@ -3,46 +3,48 @@ apiVersion: tekton.dev/v1 kind: Task metadata: name: source-build-oci-ta + annotations: + tekton.dev/pipelines.minVersion: 0.12.1 + tekton.dev/tags: appstudio labels: app.kubernetes.io/version: "0.1" - annotations: - tekton.dev/pipelines.minVersion: "0.12.1" - tekton.dev/tags: "appstudio" 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. + 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. + - 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. + 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_URL - description: The source image url. - name: SOURCE_IMAGE_DIGEST description: The source image digest. + - name: SOURCE_IMAGE_URL + description: The source image url. volumes: - name: workdir emptyDir: {} stepTemplate: volumeMounts: - - name: workdir - mountPath: /var/workdir + - mountPath: /var/workdir + name: workdir steps: - name: use-trusted-artifact image: quay.io/redhat-appstudio/build-trusted-artifacts:latest@sha256:4e39fb97f4444c2946944482df47b39c5bbc195c54c6560b0647635f553ab23d @@ -52,35 +54,24 @@ spec: - $(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 + workingDir: /var/workdir env: - name: BINARY_IMAGE - value: "$(params.BINARY_IMAGE)" + value: $(params.BINARY_IMAGE) - name: SOURCE_DIR - value: "/var/workdir/source" + value: /var/workdir/source - name: BASE_IMAGES - value: "$(params.BASE_IMAGES)" + value: $(params.BASE_IMAGES) - name: RESULT_FILE - value: "$(results.BUILD_RESULT.path)" + value: $(results.BUILD_RESULT.path) - name: CACHI2_ARTIFACTS_DIR - value: "/var/workdir/cachi2" + value: /var/workdir/cachi2 - name: RESULT_SOURCE_IMAGE_URL - value: "$(results.SOURCE_IMAGE_URL.path)" + value: $(results.SOURCE_IMAGE_URL.path) - name: RESULT_SOURCE_IMAGE_DIGEST - value: "$(results.SOURCE_IMAGE_DIGEST.path)" + value: $(results.SOURCE_IMAGE_DIGEST.path) - name: WS_BUILD_RESULT_FILE - value: "/var/workdir/source_build_result.json" + value: /var/workdir/source_build_result.json script: | #!/usr/bin/env bash set -euo pipefail @@ -110,3 +101,14 @@ spec: cat "$RESULT_FILE" | jq -r ".image_digest" >"$RESULT_SOURCE_IMAGE_DIGEST" cp "$RESULT_FILE" "$WS_BUILD_RESULT_FILE" + computeResources: + limits: + memory: 2Gi + requests: + cpu: 250m + memory: 512Mi + securityContext: + capabilities: + add: + - SETFCAP + runAsUser: 0