tekton gradle build + yaml update

2024. 11. 21. 23:25·CloudNative/App Definition & Developement

openshift tekton pipeline으로 gradle build하고 빌드 결과를 별도의 manifest 저장소에 업데이트해서

gitOps가 autoSync할 수 있도록 해보자.

 

전체적인 파이프라인은 다음과 같다.

apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: sample-gradle-pipe
  namespace: sample
spec:
  params:
    - default: boot-app-gradle
      name: IMAGE_NAME
      type: string
    - default: /sample/boot-app-gradle.git
      name: GIT_REPO
      type: string
    - default: dev
      name: GIT_REVISION
      type: string
  tasks:
    - name: fetch-repository
      params:
        - name: url
          value: $(params.GIT_REPO)
        - name: revision
          value: $(params.GIT_REVISION)
        - name: deleteExisting
          value: 'true'
      taskRef:
        kind: Task
        name: git-clone
      workspaces:
        - name: output
          workspace: workspace
    - name: gradle-build
      runAfter:
        - fetch-repository
      taskRef:
        kind: Task
        name: gradle-jdk11
      workspaces:
        - name: source
          workspace: workspace
    - name: deploy
      params:
        - name: ARGS #docker build 후 빌드된 이미지 태그 정보를 가져오는 스크립트
          value:
            - >-
              mkdir -p /tmp/binary/target &&  find /tmp/src/build/libs -maxdepth
              1 -name "*.jar" -o -name "*.war" | xargs -I{} cp {}
              /tmp/binary/target/ && cp -rf /tmp/src/scouter /tmp/binary/scouter
              && cp /tmp/src/Dockerfile /tmp/binary/ && ls -rl /tmp/binary/ &&
              oc start-build boot-app-gradle --from-dir /tmp/binary --follow
              --wait && current_builds=$(oc get builds -o
              jsonpath="{.items[?(@.metadata.labels.buildconfig=='boot-app-gradle')].metadata.name}"
              | tr ' ' '_' | tr '\\\\' '\\n' | tr '_' ' ' | sort -rn | head -n
              5) && for build in $current_builds; do if oc get build $build -o
              jsonpath='{.status.phase}' | grep -q 'Complete'; then
              latest_build=$build; break; fi; done && echo $latest_build && echo
              $(oc get build $latest_build -o
              jsonpath='{.status.output.to.imageDigest}') &&  image_digest=$(oc
              get build $latest_build -o
              jsonpath='{.status.output.to.imageDigest}' | tr -d '\\n') && echo
              $image_digest && echo -n $image_digest > $(results.DIGEST.path)
      runAfter:
        - gradle-build
      taskRef:
        kind: Task
        name: ocp-cli-task
      workspaces:
        - name: source
          workspace: workspace
    - name: update-manifest # YQ를 통해 deployment.yaml의 image 태그부분을 업데이트 
      params:
        - name: repo
          value: sample/boot-app-gradle.git
        - name: app
          value: boot-app-gradle
        - name: SCRIPT
          value: >
            yq eval '.spec.template.spec.containers[0].image =
            "<이미지레지스트리정보>/sample/boot-app-gradle@$(tasks.deploy.results.DIGEST)"'
            -i ./boot-app-gradle/base/deployment.yaml && sed -i 's/ *$//'
            ./boot-app-gradle/base/deployment.yaml
      runAfter:
        - deploy
      taskRef:
        kind: Task
        name: yq
      workspaces:
        - name: source
          workspace: workspace
  workspaces:
    - name: workspace

 

각 태스크는 다음과 같다.

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  annotations:
    manifestival: new
    tekton.dev/categories: Git
    tekton.dev/displayName: git clone
    tekton.dev/pipelines.minVersion: 0.29.0
    tekton.dev/platforms: 'linux/amd64,linux/s390x,linux/ppc64le,linux/arm64'
    tekton.dev/tags: git
  name: git-clone
  namespace: sample
  labels:
    app.kubernetes.io/version: '0.8'
    operator.tekton.dev/operand-name: openshift-pipelines-addons
    operator.tekton.dev/provider-type: redhat
spec:
  description: For Sample
  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: 'false'
      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: Subdirectory inside the `output` Workspace to clone the repo into.
      name: subdirectory
      type: string
    - default: ''
      description: >-
        Define the directory patterns to match or exclude when performing a
        sparse checkout.
      name: sparseCheckoutDirectories
      type: string
    - default: 'true'
      description: >-
        Clean out the contents of the destination directory if it already exists
        before cloning.
      name: deleteExisting
      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: 'true'
      description: Log the commands that are executed during `git-clone`'s operation.
      name: verbose
      type: string
    - default: >-
        registry.redhat.io/openshift-pipelines/pipelines-git-init-rhel8@sha256:dde6d6d4b40f87ccc6737f1e317c13f6ff153155da4ebc48a2a5ebf31582f727
      description: The image providing the git-init binary that this Task runs.
      name: gitInitImage
      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 or have overridden

        the gitInitImage param with an image containing custom user
        configuration.
      name: userHome
      type: string
  results:
    - description: The precise commit SHA that was fetched by this Task.
      name: commit
      type: string
    - description: The precise URL that was fetched by this Task.
      name: url
      type: string
  steps:
    - 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: GIT_CREDENTIALS
          valueFrom:
            secretKeyRef:
              key: .git-credentials
              name: gitlab-config
        - name: GITCONFIG
          valueFrom:
            secretKeyRef:
              key: .git-config
              name: gitlab-config
        - name: GITLAB_URL
          valueFrom:
            secretKeyRef:
              key: .gitlab-url
              name: gitlab-config
      image: $(params.gitInitImage)
      name: clone
      resources: {}
      script: >
        #!/usr/bin/env sh

        set -eu


        if [ "${PARAM_VERBOSE}" = "true" ] ; then
          set -x
        fi

        if [ "true" = "true" ] ; then
          echo $GIT_CREDENTIALS > ${PARAM_USER_HOME}/.git-credentials
          echo $GITCONFIG > ${PARAM_USER_HOME}/.gitconfig

          chmod 400 "${PARAM_USER_HOME}/.git-credentials" 
          chmod 400 "${PARAM_USER_HOME}/.gitconfig"

          git config --global pack.windowMemory "200m"
          git config --global pack.packSizeLimit "200m"
          git config --global pack.threads "1"
          git config --global pack.window "0"
          git config --global http.postBuffer 3194304000
        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


        CHECKOUT_DIR="${WORKSPACE_OUTPUT_PATH}/${PARAM_SUBDIRECTORY}"


        cleandir() {
          if [ -d "${CHECKOUT_DIR}" ] ; then
            rm -rf "${CHECKOUT_DIR:?}"/*
            rm -rf "${CHECKOUT_DIR}"/.[!.]*
            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="${GITLAB_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}"


        git config --global credential.helper store


        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" "${GITLAB_URL}${PARAM_URL}" > "$(results.url.path)"
  workspaces:
    - description: The git repo will be cloned onto the volume backing this Workspace.
      name: output
    - 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
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  annotations:
    tekton.dev/categories: Build Tools
    tekton.dev/displayName: Gradle
    tekton.dev/pipelines.minVersion: 0.17.0
    tekton.dev/platforms: 'linux/amd64,linux/s390x,linux/ppc64le'
    tekton.dev/tags: build-tool
  name: gradle-jdk11
  namespace: sample
  labels:
    app.kubernetes.io/version: '0.4'
spec:
  description: This Task can be used to run a Gradle build.
  params:
    - default: >-
        docker.io/gradle:jdk11@sha256:8942456a1b0a1d3ab52fc8ebb248f13a308aac6f40423d2e5537553a69c5c7f8
      description: Gradle base image.
      name: GRADLE_IMAGE
      type: string
    - default: .
      description: The directory containing build.gradle
      name: PROJECT_DIR
      type: string
    - default:
        - build
      description: 'The gradle tasks to run (default: build)'
      name: TASKS
      type: array
  steps:
    - args:
        - $(params.TASKS)
      env:
        - name: GRADLE_USER_HOME
          value: /home/gradle
      image: $(params.GRADLE_IMAGE)
      name: gradle-tasks
      resources: {}
      script: |
        #!/usr/bin/env bash

        if [[ -f gradlew ]]; then
          cmd="./gradlew $*"
        else
          cmd="gradle $*"
        fi

        echo "Running gradle task with command below"
        echo "$cmd"
        eval "$cmd"
      volumeMounts:
        - mountPath: /home/gradle
          name: empty-dir
      workingDir: $(workspaces.source.path)/$(params.PROJECT_DIR)
  volumes:
    - emptyDir: {}
      name: empty-dir
  workspaces:
    - description: The workspace consisting of the gradle project.
      name: source
    - description: >-
        The workspace consisting of the custom gradle properties provided by the
        user.
      name: gradle-config
      optional: true
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: ocp-cli-task
  namespace: sample
spec:
  params:
    - default:
        - cd /tmp/src && pwd && ls
      description: The OpenShift CLI arguments to run
      name: ARGS
      type: array
  results:
    - description: the digest of the image built.
      name: DIGEST
      type: string
  steps:
    - args:
        - $(params.ARGS)
      command:
        - /bin/bash
        - '-c'
      env:
        - name: GIT_CREDENTIALS
          valueFrom:
            secretKeyRef:
              key: .git-credentials
              name: gitlab-config
        - name: GITCONFIG
          valueFrom:
            secretKeyRef:
              key: .git-config
              name: gitlab-config
      image: '<이미지레지스트리주소>/openshift/cli:latest' #quay.io/openshift/origin-cli:$(params.VERSION)
      name: oc
      resources: {}
  workspaces:
    - mountPath: /tmp/src
      name: source
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  annotations:
    tekton.dev/categories: Developer Tools
    tekton.dev/displayName: YQ
    tekton.dev/pipelines.minVersion: 0.12.1
    tekton.dev/platforms: linux/amd64
    tekton.dev/tags: yq
  name: yq
  namespace: sample
  labels:
    app.kubernetes.io/version: '0.4'
spec:
  description: >-
    This task can be used to replace fields in YAML files. For example for
    altering helm charts on GitOps repos.
  params:
    - default: ''
      description: The yq script to execute. Can be multiple lines for complex tasks.
      name: SCRIPT
      type: string
    - default: >-
        image-registry.openshift-image-registry.svc:5000/sample/yq-git@sha256:776657b787969e2c938360997b8bcf9c1f16fa20a83ae7ef97d28f206d4bdac6
      description: The yq image to use.
      name: image
      type: string
    - default: []
      description: >-
        (deprecated, use SCRIPT instead) A list of files to execute the
        expression on. Needs to be relative to the source workspace.
      name: files
      type: array
    - default: 'spec.template.spec.containers[0].image.name'
      description: >-
        (deprecated, use SCRIPT instead) The yq expression to apply. Can be used
        to replace yaml fields.
      name: expression
      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 or have overridden

        the gitInitImage param with an image containing custom user
        configuration.
      name: userHome
      type: string
    - name: repo
      type: string
    - name: app
      type: string
  results:
    - description: >-
        The result from your yq command. You can write to it using
        `$(results.yq.path)`
      name: yq
      type: string
  steps:
    - args:
        - '$(params.files[*])'
      env:
        - name: HOME
          value: $(params.userHome)
        - name: GIT_CREDENTIALS
          valueFrom:
            secretKeyRef:
              key: .git-credentials
              name: gitlab-config
        - name: GITCONFIG
          valueFrom:
            secretKeyRef:
              key: .git-config
              name: gitlab-config
        - name: GITLAB_URL
          valueFrom:
            secretKeyRef:
              key: .gitlab-url
              name: gitlab-config
        - name: REPO
          value: $(params.repo)
        - name: APP
          value: $(params.app)
      image: $(params.image)
      name: yq-script
      resources: {}
      script: >
        /usr/bin/env sh

        set -e

        set -x

        if [ "true" = "true" ] ; then
          echo $GIT_CREDENTIALS > ${PARAM_USER_HOME}/.git-credentials
          echo $GITCONFIG > ${PARAM_USER_HOME}/.gitconfig

          chmod 400 "${PARAM_USER_HOME}/.git-credentials" 
          chmod 400 "${PARAM_USER_HOME}/.gitconfig"

          git config --global pack.windowMemory "200m"
          git config --global pack.packSizeLimit "200m"
          git config --global pack.threads "1"
          git config --global pack.window "0"
          git config --global http.postBuffer 3194304000
          git config --global user.name root
          git config --global user.email admin@example.org
          git config --global credential.helper store
          #git config --global pull.rebase true
        fi

        git clone
        http://<id:token>@<git주소>/sample/boot-manifests.git

        cd boot-manifests

        $(params.SCRIPT)                # 변경 스크립트 실행

        cat ./$APP/base/deployment.yaml # 변경대상 YAML확인

        git add .                       # 변경소스 staging

        git commit -m "tag-updated"     # comment

        git push -u origin              # push
      securityContext:
        runAsUser: 0
      workingDir: $(workspaces.source.path)
  workspaces:
    - description: A workspace that contains the file which needs to be altered.
      name: source

 

빌드컨피그는 다음과 같다.

kind: BuildConfig
apiVersion: build.openshift.io/v1
metadata:
  name: boot-app-gradle
  namespace: sample
  labels:
    app: boot-app-gradle
spec:
  nodeSelector: null
  output:
    to:
      kind: ImageStreamTag
      namespace: sample
      name: 'boot-app-gradle:latest'
  resources: {}
  successfulBuildsHistoryLimit: 1
  failedBuildsHistoryLimit: 1
  strategy:
    type: Docker
    dockerStrategy:
      dockerfilePath: Dockerfile
  postCommit: {}
  source:
    type: Binary
    binary: {}
  runPolicy: Serial

 

이제 파이프 라인을 실행해보자.

728x90

'CloudNative > App Definition & Developement' 카테고리의 다른 글

argocd applicationSet  (2) 2024.11.26
argocd  (0) 2024.11.25
confluentinc/cp-kafka KRaft yaml (zookeeper out)  (2) 2024.11.20
confluentinc/cp-kafka, zookeeper, kafka-ui  (1) 2024.11.18
kafka-ui yaml  (1) 2024.11.08
'CloudNative/App Definition & Developement' 카테고리의 다른 글
  • argocd applicationSet
  • argocd
  • confluentinc/cp-kafka KRaft yaml (zookeeper out)
  • confluentinc/cp-kafka, zookeeper, kafka-ui
yunapapa
yunapapa
working on the cloud
    250x250
  • yunapapa
    supermoon
    yunapapa
  • 전체
    오늘
    어제
    • 분류 전체보기 (94)
      • 개발 (20)
        • java (17)
        • web (2)
        • MSX (1)
        • Go (0)
      • CloudNative (50)
        • App Definition & Developeme.. (17)
        • Orchestration & Management (4)
        • Runtime (3)
        • Provisioning (7)
        • Observability & Analysis (14)
        • event review (5)
      • AWS (7)
      • 환경관련 (17)
      • 취미생활 (0)
        • 맛집 (0)
        • 게임 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • CNCF Past Events
    • Kubernetes Korea Group
  • 공지사항

  • 인기 글

  • 태그

    Java
    gitlab
    dop-c02
    istio
    k8s
    Pinpoint
    springboot
    티스토리챌린지
    helm
    OpenShift
    devops
    AWS
    오블완
    APM
    kubernetes
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
yunapapa
tekton gradle build + yaml update
상단으로

티스토리툴바