diff --git a/task/git-clone-oci-ta/0.1/README.md b/task/git-clone-oci-ta/0.1/README.md new file mode 100644 index 0000000000..fe1cbd9a91 --- /dev/null +++ b/task/git-clone-oci-ta/0.1/README.md @@ -0,0 +1,38 @@ +# git-clone-oci-ta task + +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. + +## 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| +|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| +|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| +|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| + +## Results +|name|description| +|---|---| +|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| 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 new file mode 100644 index 0000000000..fdd96a9c9e --- /dev/null +++ b/task/git-clone-oci-ta/0.1/git-clone-oci-ta.yaml @@ -0,0 +1,290 @@ +--- +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 +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 clone repository will be stored. + - name: ociArtifactExpiresAfter + type: string + description: Expiration date for the artifacts created in the OCI repository. + default: "" + + 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 OCI reference to the trusted source artifact containing the cloned git repo. + name: sourceArtifact + 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/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: source + mountPath: /var/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 + 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}" + + /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 + + - 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/source + volumeMounts: + - name: source + mountPath: /var/source + 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: source + mountPath: /var/source + args: + - create + - --store + - $(params.ociStorage) + - $(results.sourceArtifact.path)=/var/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: source + emptyDir: {} + - name: trusted-ca + configMap: + name: $(params.caTrustConfigMapName) + items: + - key: $(params.caTrustConfigMapKey) + path: ca-bundle.crt + optional: true diff --git a/task/git-clone-oci-ta/OWNERS b/task/git-clone-oci-ta/OWNERS new file mode 100644 index 0000000000..aa72b50760 --- /dev/null +++ b/task/git-clone-oci-ta/OWNERS @@ -0,0 +1 @@ +Stonesoup Build Team