참조 : https://tekton.dev/docs/how-to-guides/clone-repository/
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: clone-read-run- # make name automate with random index ( for re use pipelinerun yaml )
spec:
#serviceAccountName: git-sa # sa for git credientials -> pipeline will use for clone private repo
pipelineRef: # select pipeline
name: clone-read
podTemplate: # setting taskpod
securityContext: # pod security
fsGroup: 65532 # set volume owner gid = 65532
workspaces: # volume for clone code
- name: shared-data
volumeClaimTemplate: # automatically create pvc -> create pv
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
params: # git address
- name: repo-url
value: "https://github.com/lijahong/tektontest"
- PipelineRun은 위와 같다. Clone할 repo url을 파라미터로 Pipeline에게 넘겨준다
- generateName을 이용하여 PipelineRun을 생성할 때마다 새로운 이름으로 생성하여, 새로운 PipelineRun이 생성되게 한다. 이를 통해 동일한 PipelineRun 매니페스트 파일을 이용하여 Pipeline을 여러번 실행 가능하다
- workspaces 정의시 volumeclaimtemplate을 정의하면, 자동으로 pvc가 만들진다
- podtemplate은 실행될 TaskRun Pod에 대한 설정이다
- security context는 쿠버네티스의 파드나 컨테이너에 대한 접근제어 설정이나 특수 권한과 같은 보안을 설정한다
- 쿠버네티스는 볼륨이 마운트 될 때, pod의 fsgroup에 지정된 것과 일치하도록 볼륨의 소유권 ( 볼륨 소유자 gid ) 을 지속적으로 변경한다
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: clone-read
spec:
params:
- name: repo-url
type: string
workspaces:
- name: shared-data
tasks:
- name: fetch-source
taskRef:
name: git-clone
workspaces:
- name: output
workspace: shared-data
params:
- name: url
value: $(params.repo-url)
- name: show-readme
runAfter: ["fetch-source"]
taskRef:
name: show-readme
workspaces:
- name: source
workspace: shared-data
- Pipeline은 2 개의 Task로 구성된다
- repo를 clone할 git-clone과 clone한 README.md를 출력할 show-readme로 구성된다
- runAfter를 통해 순서를 지정할 수 있다. runAfter는 특정 작업이 완료되면 실행하도록 하는 옵션이다. show-readme는 git-clone이 완료되면 실행된다
tkn hub install task git-clone
- tkn 명령어를 이용하여 TEKTON HUB에서 git-clone용 Task를 생성하자
kubectl apply -f \ https://raw.githubusercontent.com/tektoncd/catalog/main/task/git-clone/0.6/git-clone.yaml
- Kubectl을 사용하여 생성할 수도 있다
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: git-clone
labels:
app.kubernetes.io/version: "0.6"
annotations:
tekton.dev/pipelines.minVersion: "0.29.0"
tekton.dev/categories: Git
tekton.dev/tags: git
tekton.dev/displayName: "git clone"
tekton.dev/platforms: "linux/amd64,linux/s390x,linux/ppc64le,linux/arm64"
spec:
workspaces: # we only use output workspace for save clone file
- name: output # volume for save clone file
# following workspace is for authentication, which for clone private repo. each workspace contains authentication file
- name: ssh-directory # workspace for using ssh
optional: True
- name: basic-auth # workspace for using git credentials
optional: True
- name: ssl-ca-directory # workspace for using ca certificate ( https )
optional: True
params:
- name: url # repo url
description: Repository URL to clone from.
type: string
- name: revision
description: Revision to checkout. (branch, tag, sha, ref, etc...)
type: string
default: ""
- name: refspec
description: Refspec to fetch before checking out revision.
default: ""
- name: submodules
description: Initialize and fetch git submodules.
type: string
default: "true"
- name: depth
description: Perform a shallow clone, fetching only the most recent N commits.
type: string
default: "1"
- 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: subdirectory
description: Subdirectory inside the `output` Workspace to clone the repo into.
type: string
default: ""
- name: sparseCheckoutDirectories
description: Define the directory patterns to match or exclude when performing a sparse checkout.
type: string
default: ""
- name: deleteExisting
description: Clean out the contents of the destination directory if it already exists before cloning.
type: string
default: "true"
- 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: verbose
description: Log the commands that are executed during `git-clone`'s operation.
type: string
default: "true"
- name: gitInitImage # image for git init
description: The image providing the git-init binary that this Task runs.
type: string
default: "gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init:v0.29.0"
- 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 or have overridden
the gitInitImage param with an image containing custom user configuration.
type: string
default: "/tekton/home"
results:
- 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.
steps:
- name: clone
image: "$(params.gitInitImage)"
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_SUBDIRECTORY
value: $(params.subdirectory)
- name: PARAM_DELETE_EXISTING
value: $(params.deleteExisting)
- 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: WORKSPACE_OUTPUT_PATH
value: $(workspaces.output.path)
- 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: WORKSPACE_SSL_CA_DIRECTORY_BOUND
value: $(workspaces.ssl-ca-directory.bound)
- name: WORKSPACE_SSL_CA_DIRECTORY_PATH
value: $(workspaces.ssl-ca-directory.path)
script: |
#!/usr/bin/env sh
set -eu
if [ "${PARAM_VERBOSE}" = "true" ] ; then
set -x
fi
if [ "${WORKSPACE_BASIC_AUTH_DIRECTORY_BOUND}" = "true" ] ; 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"
chmod 400 "${PARAM_USER_HOME}/.git-credentials"
chmod 400 "${PARAM_USER_HOME}/.gitconfig"
fi
if [ "${WORKSPACE_SSH_DIRECTORY_BOUND}" = "true" ] ; then
cp -R "${WORKSPACE_SSH_DIRECTORY_PATH}" "${PARAM_USER_HOME}"/.ssh
chmod 700 "${PARAM_USER_HOME}"/.ssh
chmod -R 400 "${PARAM_USER_HOME}"/.ssh/*
fi
if [ "${WORKSPACE_SSL_CA_DIRECTORY_BOUND}" = "true" ] ; then
export GIT_SSL_CAPATH="${WORKSPACE_SSL_CA_DIRECTORY_PATH}"
fi
CHECKOUT_DIR="${WORKSPACE_OUTPUT_PATH}/${PARAM_SUBDIRECTORY}"
cleandir() {
# Delete any existing contents of the repo directory if it exists.
#
# We don't just "rm -rf ${CHECKOUT_DIR}" because ${CHECKOUT_DIR} might be "/"
# or the root of a mounted volume.
if [ -d "${CHECKOUT_DIR}" ] ; then
# Delete non-hidden files and directories
rm -rf "${CHECKOUT_DIR:?}"/*
# Delete files and directories starting with . but excluding ..
rm -rf "${CHECKOUT_DIR}"/.[!.]*
# Delete files and directories starting with .. plus any other character
rm -rf "${CHECKOUT_DIR}"/..?*
fi
}
if [ "${PARAM_DELETE_EXISTING}" = "true" ] ; then
cleandir
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)"
- Task 파일은 위와 같다. 전체 작업 순서는 다음과 같다
- git init이 가능한 환경이 구성된 이미지를 사용하여 컨테이너를 배포
- 배포된 컨테이너에서 shell script를 실행하여 workspace에 git init 및 clone 실행
- 작업 완료 후 컨테이너 종료
- 사용할 파라미터와 workspace를 정의하고, 이를 컨테이너의 환경 변수로 등록하여, 컨테이너 내부에서 환경 변수를 통해 파라미터와 workspace를 사용할 수 있다
- 인증 정보가 Volume으로 붙어있다면, 인증 정보 파일을 컨테이너 내로 가져온다
- clone한 데이터를 저장할 Volume에 데이터가 있다면, 내부의 데이터를 삭제한다
- Proxy 사용 시, Proxy 환경 변수로 등록한다
- test는 파일이나 문자열을 점검하고, 비교하는 명령어다. z 옵션은 문자열의 길이가 0이라면 True를 반환한다
test -z "${PARAM_HTTP_PROXY}" || export HTTP_PROXY="${PARAM_HTTP_PROXY}"
- 위 명령어는 PARAM_HTTP_PROXY의 값이 비어있지 않다면 ( test 결과가 fail 이라면 ), export HTTP_PROXY="${PARAM_HTTP_PROXY}를 실행해준다. 즉 Proxy를 사용한다면, Proxy 환경 변수를 설정해주는 것이다
- git init를 하고, 해당 repo를 clone 한다
- 작업 결과를 result에 담는다
- optional은 정의한 workspace를 반드시 넘겨 받아야 하는지 아닌지를 설정한다
- false로 설정했을 때, 해당 workspace를 넘겨 받지 못하면, 오류가 발생한다
- true로 설정하면, 해당 workspace를 넘겨 받지 못해도, 오류가 발생하지 않는다
- 위에서 workspace는 clone 데이터를 저장할 output과 GIT에 대한 인증 정보를 가지고 있는 workspace 들로 구성된다. 우리는 Public Repo를 clone하므로 인증 정보를 담는 workspace를 사용하지 않는다. optional을 True로 설정했으므로 workspace를 넘겨주지 않아도 오류가 발생하지 않는다
results:
- 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.
- result는 사용자나 파이프라인 내의 다른 Task에게 문자열 형식의 결과를 보내기 위해 사용한다
- 이는 Commit SHA, Branch 이름, 컨테이너 이미지 다이제스트와 같은 소량의 데이터를 담는데 적합하다
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: show-readme # task for show readme
spec:
workspaces: # using volume, where readme is saced
- name: source
steps:
- name: read
image: alpine:latest # we use alphin image, it will use cat for show readme file in workspace volume
script: |
#!/usr/bin/env sh
cat $(workspaces.source.path)/README.md
- clone한 repo 데이터 중 README.md 내용을 출력하는 작업이다
- alpine 이미지와 clone한 repo 데이터가 저장된 volume을 사용한다
- 컨테이너가 배포되면, cat 명령을 통해 volume에 저장된 README.md 파일 내용을 출력한다
[ec2-user@ip-100-0-1-19 tektontest]$ k get pod
NAME READY STATUS RESTARTS AGE
clone-read-run-ngwht-fetch-source-pod 0/1 Completed 0 70m
clone-read-run-ngwht-show-readme-pod 0/1 Completed 0 70m
- 각 Task 별로 TaskRun Pod가 배포되어 작업을 잘 실행하였다
[ec2-user@ip-100-0-1-19 tektontest]$ k get pr
NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME
clone-read-run-ngwht True Succeeded 72m 71m
[ec2-user@ip-100-0-1-19 tektontest]$ tkn pr list
NAME STARTED DURATION STATUS
clone-read-run-ngwht 1 hour ago 39s Succeeded
- PipelineRun이 잘 실행되었다
[ec2-user@ip-100-0-1-19 tektontest]$ tkn pr logs clone-read-run-ngwht
[fetch-source : clone] + '[' '$(workspaces.basic-auth.bound)' '=' true ]
[fetch-source : clone] + '[' '$(workspaces.ssh-directory.bound)' '=' true ]
[fetch-source : clone] + '[' '$(workspaces.ssl-ca-directory.bound)' '=' true ]
[fetch-source : clone] + CHECKOUT_DIR=/workspace/output/
[fetch-source : clone] + '[' true '=' true ]
[fetch-source : clone] + cleandir
[fetch-source : clone] + '[' -d /workspace/output/ ]
[fetch-source : clone] + rm -rf /workspace/output//lost+found
[fetch-source : clone] + rm -rf '/workspace/output//.[!.]*'
[fetch-source : clone] + rm -rf '/workspace/output//..?*'
[fetch-source : clone] + test -z
[fetch-source : clone] + test -z
.
.
.
[fetch-source : clone] + cd /workspace/output/
[fetch-source : clone] + git rev-parse HEAD
[fetch-source : clone] + RESULT_SHA=********************************
[fetch-source : clone] + EXIT_CODE=0
[fetch-source : clone] + '[' 0 '!=' 0 ]
[fetch-source : clone] + printf '%s' ********************
[fetch-source : clone] + printf '%s' https://github.com/lijahong/tektontest
[show-readme : read] # tektontest
[show-readme : read] file for clone by tekton
- log를 통해 작업 결과를 확인하자
- show-readme TASK의 경우, README.md 내용을 출력한다
- git-clone TASK의 경우, 실행한 명령어 이력을 출력한다
- fetch-source는 pipeline에서 git-clone TASK에 대해 설정한 이름이다
- result를 확인하자
- README.md 내용이 잘 출력되었다