├── .gitignore ├── README.md ├── pipeline-argocd ├── README.md ├── conf │ ├── image-updater-secret.yaml │ ├── pvc.yaml │ └── quay-secret.yaml ├── fix │ ├── github-triggerbinding.yaml │ └── pipelines-sa.yaml ├── images │ └── pipeline.png ├── install-demo.sh ├── install-operators.sh ├── pipelinerun │ └── petclinic-pipelinerun.yaml ├── pipelines │ └── petclinic-pipeline-dev.yaml ├── tasks │ ├── image-updater.yaml │ ├── int-test.yaml │ ├── maven.yaml │ ├── redeploy.yaml │ └── s2i-java-11-binary.yaml └── triggers │ ├── eventlistener-route.yaml │ ├── eventlistener.yaml │ └── triggertemplate.yaml ├── pipeline-buildpacks ├── README.md ├── conf │ ├── pvc.yaml │ └── quay-secret.yaml ├── images │ └── pipeline.png ├── pipelines │ ├── cf-nodejs-pipeline-run.yaml │ └── cf-nodejs-pipeline.yaml └── tasks │ ├── buildpacks-task.yaml │ └── oc-deploy-task.yaml ├── pipeline-s2i ├── README.md ├── apps │ └── spring-petclinic.yaml ├── conf │ ├── maven-configmap.yaml │ └── pvc.yaml ├── fix │ ├── git-clone-task.yaml │ └── github-triggerbinding.yaml ├── images │ └── pipeline.png ├── install.sh ├── kustomization.yaml ├── petclinic-pipeline-all.yaml ├── pipelinerun │ └── petclinic-pipelinerun.yaml ├── pipelines │ └── petclinic-pipeline.yaml ├── tasks │ ├── maven.yaml │ ├── redeploy.yaml │ └── s2i-java-11-binary.yaml └── triggers │ ├── eventlistener-route.yaml │ ├── eventlistener.yaml │ └── triggertemplate.yaml └── tasks ├── README.md └── smoke-test └── smoke-test.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | tmp/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tekton Pipelines Examples on OpenShift 2 | 3 | * [pipeline-buildpacks](pipeline-buildpacks): build and deploy pipeline for a [Cloud Foundry sample Node.js app](https://github.com/cloudfoundry-samples/cf-sample-app-nodejs) using Cloud-Native Buildpacks for building images 4 | 5 | * [pipeline-s2i](pipeline-s2i): build and deploy pipeline for a [Spring Boot sample application](https://github.com/spring-projects/spring-petclinic) using S2I for building images 6 | 7 | * [pipeline-argocd](pipeline-argocd): build and deploy pipeline for a [Spring Boot sample application](https://github.com/spring-projects/spring-petclinic) using S2I for building images and Argo CD for deploying to stating environment using GitOps principles and pull-requests 8 | 9 | * [tasks](tasks): a collection of Tekton Tasks 10 | -------------------------------------------------------------------------------- /pipeline-argocd/README.md: -------------------------------------------------------------------------------- 1 | # CI/CD with Tekton Pipelines and Argo CD 2 | 3 | # Instructions 4 | 5 | * Install OpenShift Pipelines Operator 6 | * Install Argo CD Operator in the `argocd` namespace 7 | * Install Argo CD in the `argocd` namespace 8 | * Run `install-demo.sh` 9 | -------------------------------------------------------------------------------- /pipeline-argocd/conf/image-updater-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | type: Opaque 4 | metadata: 5 | name: image-updater-secret 6 | data: 7 | token: ZDljNmY1OWQwNjFjODk5YWFmNjc3NjcyZThiMmQ5YmVmMWRiMzUyZg== 8 | -------------------------------------------------------------------------------- /pipeline-argocd/conf/pvc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: PersistentVolumeClaim 4 | metadata: 5 | name: app-source-pvc 6 | spec: 7 | resources: 8 | requests: 9 | storage: 1Gi 10 | volumeMode: Filesystem 11 | accessModes: 12 | - ReadWriteOnce 13 | persistentVolumeReclaimPolicy: Recycle 14 | --- 15 | apiVersion: v1 16 | kind: PersistentVolumeClaim 17 | metadata: 18 | name: spring-petclinic-maven-cache-pvc 19 | spec: 20 | resources: 21 | requests: 22 | storage: 5Gi 23 | volumeMode: Filesystem 24 | accessModes: 25 | - ReadWriteOnce 26 | persistentVolumeReclaimPolicy: Retain -------------------------------------------------------------------------------- /pipeline-argocd/conf/quay-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: quay-push-secret 5 | data: 6 | .dockerconfigjson: ewogICJhdXRocyI6IHsKICAgICJxdWF5LmlvIjogewogICAgICAiYXV0aCI6ICJjMmxoYldGcmMyRmtaU3QwWld0MGIyNDZORkZOU1V4SU9WZFdTRFZXV1RnMlRWSTNUazFGT1RBM1EwdEdVVXRPUlU1Uk1VUllTMUZSU0ZwWFdrdFlOelk1V2tNNFMwWklUMWN5UzBsVVR6UkdPUT09IiwKICAgICAgImVtYWlsIjogIiIKICAgIH0KICB9Cn0= 7 | type: kubernetes.io/dockerconfigjson -------------------------------------------------------------------------------- /pipeline-argocd/fix/github-triggerbinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: triggers.tekton.dev/v1alpha1 2 | kind: ClusterTriggerBinding 3 | metadata: 4 | name: github-push 5 | spec: 6 | params: 7 | - name: git-revision 8 | value: $(body.head_commit.id) 9 | - name: git-commit-message 10 | value: $(body.head_commit.message) 11 | - name: git-repo-url 12 | value: $(body.repository.url) 13 | - name: git-repo-name 14 | value: $(body.repository.name) 15 | - name: content-type 16 | value: $(header.Content-Type) 17 | - name: pusher-name 18 | value: $(body.pusher.name) 19 | -------------------------------------------------------------------------------- /pipeline-argocd/fix/pipelines-sa.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: pipeline 5 | imagePullSecrets: 6 | - name: quay-push-secret 7 | secrets: 8 | - name: quay-push-secret -------------------------------------------------------------------------------- /pipeline-argocd/images/pipeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siamaksade/pipelines-examples/c7d4008fde2be7b9f463fb390aef7a58de8f7779/pipeline-argocd/images/pipeline.png -------------------------------------------------------------------------------- /pipeline-argocd/install-demo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | project_name=${1:-demo} 4 | project_suffix=("ui" "qa" "perf") 5 | 6 | # deploy app in dev 7 | oc new-project $project_name-dev 8 | oc create -f https://raw.githubusercontent.com/siamaksade/spring-petclinic-config/dev/deployment.yaml -n $project_name-dev 9 | oc create -f https://raw.githubusercontent.com/siamaksade/spring-petclinic-config/dev/service.yaml -n $project_name-dev 10 | oc create -f https://raw.githubusercontent.com/siamaksade/spring-petclinic-config/dev/route.yaml -n $project_name-dev 11 | 12 | oc apply -f fix/ 13 | oc create -f conf/ -n $project_name-dev 14 | oc create -f tasks/ -n $project_name-dev 15 | oc create -f pipelines/ -n $project_name-dev 16 | oc create -f triggers/ -n $project_name-dev 17 | # oc create -f pipelinerun/ 18 | 19 | # configure argocd 20 | argocd_pwd=$(oc get secret argocd-cluster -n argocd -o jsonpath='{.data.admin\.password}' | base64 -d) 21 | argocd_url=$(oc get route argocd-server -n argocd -o template --template='{{.spec.host}}') 22 | argocd login $argocd_url --username admin --password $argocd_pwd --insecure 23 | 24 | for suffix in $project_suffix; 25 | do 26 | oc new-project $project_name-$suffix; 27 | oc policy add-role-to-user edit system:serviceaccount:argocd:argocd-application-controller -n $project_name-$suffix 28 | argocd app create spring-petclinic-$suffix --repo https://github.com/siamaksade/spring-petclinic-config --path . --dest-namespace $project_name-$suffix --dest-server https://kubernetes.default.svc --directory-recurse --revision stage 29 | argocd app sync spring-petclinic-$suffix 30 | done 31 | 32 | 33 | echo "\n\nArgoCD URL: $argocd_url\nUser: admin\nPassword: $argocd_pwd" -------------------------------------------------------------------------------- /pipeline-argocd/install-operators.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cat < 14 | Required for private GitLab and Github installations 15 | e.g. https://gitlab.example.com leave blank otherwise. 16 | default: "" 17 | - name: file-path 18 | type: string 19 | description: Path within the source-repo to update 20 | - name: image-repo 21 | type: string 22 | description: Image repo e.g. org/repo that is being updated 23 | - name: new-image-url 24 | type: string 25 | description: Image URL to populate file with e.g. myorg/my-image:c2b4eff 26 | - name: source-branch 27 | type: string 28 | description: Branch to fetch for updating 29 | default: main 30 | - name: source-repo 31 | type: string 32 | description: Git repository to update e.g. org/repo 33 | - name: branch-generate-name 34 | type: string 35 | description: > 36 | Prefix for naming automatically generated branch, if empty, this will 37 | update source-branch 38 | - name: update-key 39 | type: string 40 | description: > 41 | JSON path within the file-path to update 42 | e.g. spec.template.spec.containers.0.image 43 | - name: insecure 44 | type: string 45 | description: Allow insecure server connections when using SSL 46 | default: "false" 47 | steps: 48 | - name: update-image 49 | image: bigkevmcd/image-updater:latest 50 | args: 51 | - "update" 52 | - "--driver=$(params.driver)" 53 | - "--file-path=$(params.file-path)" 54 | - "--image-repo=$(params.image-repo)" 55 | - "--new-image-url=$(params.new-image-url)" 56 | - "--source-branch=$(params.source-branch)" 57 | - "--source-repo=$(params.source-repo)" 58 | - "--update-key=$(params.update-key)" 59 | - "--branch-generate-name=$(params.branch-generate-name)" 60 | - "--api-endpoint=$(params.api-endpoint)" 61 | - "--insecure=$(params.insecure)" 62 | env: 63 | - name: AUTH_TOKEN 64 | valueFrom: 65 | secretKeyRef: 66 | name: image-updater-secret 67 | key: token -------------------------------------------------------------------------------- /pipeline-argocd/tasks/int-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Task 3 | metadata: 4 | name: int-test 5 | spec: 6 | steps: 7 | - name: verify 8 | image: image-registry.openshift-image-registry.svc:5000/openshift/cli:latest 9 | command: ["sleep"] 10 | args: ["20"] -------------------------------------------------------------------------------- /pipeline-argocd/tasks/maven.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Task 3 | metadata: 4 | name: maven 5 | labels: 6 | operator.tekton.dev/provider-type: community 7 | spec: 8 | params: 9 | - default: 10 | - package 11 | description: maven goals to run 12 | name: GOALS 13 | type: array 14 | steps: 15 | - name: mvn-goals 16 | args: 17 | - -Dmaven.repo.local=$(workspaces.maven-cache.path) 18 | - $(params.GOALS) 19 | command: 20 | - /usr/bin/mvn 21 | image: gcr.io/cloud-builders/mvn 22 | resources: {} 23 | workingDir: $(workspaces.source.path) 24 | workspaces: 25 | - name: source 26 | - name: maven-cache 27 | -------------------------------------------------------------------------------- /pipeline-argocd/tasks/redeploy.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Task 3 | metadata: 4 | name: redeploy 5 | spec: 6 | params: 7 | - name: DEPLOYMENT 8 | type: string 9 | - name: IMAGE_URL 10 | type: string 11 | steps: 12 | - name: deploy 13 | image: image-registry.openshift-image-registry.svc:5000/openshift/cli:latest 14 | script: | 15 | #!/usr/bin/env bash 16 | 17 | echo "Deploying $(params.IMAGE_URL)" 18 | 19 | oc set image deployment/$(params.DEPLOYMENT) $(params.DEPLOYMENT)=$(params.IMAGE_URL) 20 | oc patch deployment $(params.DEPLOYMENT) -p "{\"spec\": {\"template\": {\"metadata\": { \"labels\": { \"redeploy\": \"$(date +%s)\"}}}}}" 21 | oc rollout status deployment/$(params.DEPLOYMENT) 22 | env: 23 | - name: POD_NAMESPACE 24 | valueFrom: 25 | fieldRef: 26 | fieldPath: metadata.namespace -------------------------------------------------------------------------------- /pipeline-argocd/tasks/s2i-java-11-binary.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Task 3 | metadata: 4 | name: s2i-java-11-binary 5 | spec: 6 | params: 7 | - name: PATH_CONTEXT 8 | description: The location of the path to run s2i from 9 | default: . 10 | type: string 11 | - name: TLSVERIFY 12 | description: Verify the TLS on the registry endpoint (for push/pull to a non-TLS registry) 13 | default: "false" 14 | type: string 15 | - name: OUTPUT_IMAGE 16 | type: string 17 | description: The application image url in registry 18 | workspaces: 19 | - name: source 20 | steps: 21 | - name: generate 22 | image: registry.redhat.io/ocp-tools-43-tech-preview/source-to-image-rhel8 23 | workingdir: $(workspaces.source.path)/target 24 | command: 25 | - 's2i' 26 | - 'build' 27 | - '$(params.PATH_CONTEXT)' 28 | - 'registry.access.redhat.com/openjdk/openjdk-11-rhel7' 29 | - '--image-scripts-url' 30 | - 'image:///usr/local/s2i' 31 | - '--as-dockerfile' 32 | - '/gen-source/Dockerfile.gen' 33 | volumeMounts: 34 | - name: envparams 35 | mountPath: /env-params 36 | - name: gen-source 37 | mountPath: /gen-source 38 | - name: build 39 | image: registry.redhat.io/rhel8/buildah 40 | workingdir: /gen-source 41 | command: 42 | - buildah 43 | - bud 44 | - --tls-verify=$(params.TLSVERIFY) 45 | - --layers 46 | - -f 47 | - /gen-source/Dockerfile.gen 48 | - -t 49 | - $(params.OUTPUT_IMAGE) 50 | - . 51 | volumeMounts: 52 | - name: varlibcontainers 53 | mountPath: /var/lib/containers 54 | - name: gen-source 55 | mountPath: /gen-source 56 | securityContext: 57 | privileged: true 58 | - name: push 59 | image: registry.redhat.io/rhel8/buildah 60 | command: 61 | - buildah 62 | - push 63 | - --tls-verify=$(params.TLSVERIFY) 64 | - $(params.OUTPUT_IMAGE) 65 | - docker://$(params.OUTPUT_IMAGE) 66 | volumeMounts: 67 | - name: varlibcontainers 68 | mountPath: /var/lib/containers 69 | securityContext: 70 | privileged: true 71 | volumes: 72 | - name: varlibcontainers 73 | emptyDir: {} 74 | - name: gen-source 75 | emptyDir: {} 76 | - name: envparams 77 | emptyDir: {} -------------------------------------------------------------------------------- /pipeline-argocd/triggers/eventlistener-route.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: route.openshift.io/v1 2 | kind: Route 3 | metadata: 4 | labels: 5 | app.kubernetes.io/managed-by: EventListener 6 | app.kubernetes.io/part-of: Triggers 7 | eventlistener: petclinic-event-listener 8 | name: el-petclinic-event-listener 9 | spec: 10 | port: 11 | targetPort: 8080 12 | to: 13 | kind: Service 14 | name: el-petclinic-event-listener 15 | weight: 100 -------------------------------------------------------------------------------- /pipeline-argocd/triggers/eventlistener.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: triggers.tekton.dev/v1alpha1 2 | kind: EventListener 3 | metadata: 4 | name: petclinic-event-listener 5 | spec: 6 | serviceAccountName: pipeline 7 | triggers: 8 | - bindings: 9 | - kind: ClusterTriggerBinding 10 | name: github-push 11 | template: 12 | name: trigger-template-petclinic-deploy -------------------------------------------------------------------------------- /pipeline-argocd/triggers/triggertemplate.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: triggers.tekton.dev/v1alpha1 2 | kind: TriggerTemplate 3 | metadata: 4 | name: trigger-template-petclinic-deploy 5 | spec: 6 | params: 7 | - name: git-revision 8 | - name: git-commit-message 9 | - name: git-repo-url 10 | - name: git-repo-name 11 | - name: content-type 12 | - name: pusher-name 13 | resourcetemplates: 14 | - apiVersion: tekton.dev/v1beta1 15 | kind: PipelineRun 16 | metadata: 17 | labels: 18 | tekton.dev/pipeline: petclinic-deploy 19 | name: petclinic-deploy-$(uid) 20 | spec: 21 | params: 22 | - name: APP_NAME 23 | value: spring-petclinic 24 | - name: APP_GIT_URL 25 | value: $(params.git-repo-url) 26 | - name: APP_GIT_REVISION 27 | value: $(params.git-revision) 28 | - name: APP_IMAGE_TAG 29 | value: $(params.git-revision) 30 | pipelineRef: 31 | name: petclinic-deploy-dev 32 | workspaces: 33 | - name: app-source 34 | persistentVolumeClaim: 35 | claimName: app-source-pvc 36 | - name: maven-settings 37 | configMap: 38 | name: maven-settings 39 | - name: maven-cache 40 | persistentVolumeClaim: 41 | claimName: spring-petclinic-maven-cache-pvc 42 | -------------------------------------------------------------------------------- /pipeline-buildpacks/README.md: -------------------------------------------------------------------------------- 1 | # Tekton Pipelines Example - Cloud-Native Buildpacks 2 | 3 | ![Pipeline Diagram](images/pipeline.png) 4 | 5 | Install demo: 6 | ``` 7 | $ oc new-project demo 8 | $ oc create -f tasks/ 9 | $ oc create -f conf/ 10 | $ oc create -f pipelines/cf-nodejs-pipeline.yaml 11 | ``` 12 | 13 | Start pipeline 14 | ``` 15 | $ oc create -f pipelines/cf-nodejs-pipeline-run.yaml 16 | ``` -------------------------------------------------------------------------------- /pipeline-buildpacks/conf/pvc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: PersistentVolumeClaim 4 | metadata: 5 | name: app-source-pvc 6 | spec: 7 | resources: 8 | requests: 9 | storage: 1Gi 10 | volumeMode: Filesystem 11 | accessModes: 12 | - ReadWriteOnce 13 | persistentVolumeReclaimPolicy: Recycle 14 | -------------------------------------------------------------------------------- /pipeline-buildpacks/conf/quay-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: quay-push-secret 5 | data: 6 | .dockerconfigjson: ewogICJhdXRocyI6IHsKICAgICJxdWF5LmlvIjogewogICAgICAiYXV0aCI6ICJjMmxoYldGcmMyRmtaU3QwWld0MGIyNDZORkZOU1V4SU9WZFdTRFZXV1RnMlRWSTNUazFGT1RBM1EwdEdVVXRPUlU1Uk1VUllTMUZSU0ZwWFdrdFlOelk1V2tNNFMwWklUMWN5UzBsVVR6UkdPUT09IiwKICAgICAgImVtYWlsIjogIiIKICAgIH0KICB9Cn0= 7 | type: kubernetes.io/dockerconfigjson 8 | --- 9 | apiVersion: v1 10 | kind: ServiceAccount 11 | metadata: 12 | name: pipeline 13 | imagePullSecrets: 14 | - name: quay-push-secret 15 | secrets: 16 | - name: quay-push-secret 17 | -------------------------------------------------------------------------------- /pipeline-buildpacks/images/pipeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siamaksade/pipelines-examples/c7d4008fde2be7b9f463fb390aef7a58de8f7779/pipeline-buildpacks/images/pipeline.png -------------------------------------------------------------------------------- /pipeline-buildpacks/pipelines/cf-nodejs-pipeline-run.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: PipelineRun 3 | metadata: 4 | generateName: cf-nodejs-pipeline-run- 5 | spec: 6 | pipelineRef: 7 | name: cf-nodejs-pipeline 8 | params: 9 | - name: APP_IMAGE 10 | value: quay.io/siamaksade/cf-app-nodejs:latest 11 | workspaces: 12 | - name: app-source 13 | persistentVolumeClaim: 14 | claimName: app-source-pvc -------------------------------------------------------------------------------- /pipeline-buildpacks/pipelines/cf-nodejs-pipeline.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Pipeline 3 | metadata: 4 | name: cf-nodejs-pipeline 5 | spec: 6 | workspaces: 7 | - name: app-source 8 | params: 9 | - name: APP_NAME 10 | type: string 11 | default: cf-app-nodejs 12 | description: The application deployment name 13 | - name: APP_GIT_URL 14 | type: string 15 | default: https://github.com/cloudfoundry-samples/cf-sample-app-nodejs 16 | description: The application git repository url 17 | - name: APP_IMAGE 18 | type: string 19 | default: quay.io/siamaksade/cf-app-nodejs:latest 20 | description: The application image in remote registry 21 | 22 | tasks: 23 | - name: git-clone 24 | taskRef: 25 | name: git-clone 26 | kind: ClusterTask 27 | params: 28 | - name: url 29 | value: $(params.APP_GIT_URL) 30 | - name: deleteExisting 31 | value: "true" 32 | workspaces: 33 | - name: output 34 | workspace: app-source 35 | 36 | - name: buildpacks 37 | taskRef: 38 | name: buildpacks 39 | params: 40 | - name: BUILDER_IMAGE 41 | value: gcr.io/paketo-buildpacks/builder:base 42 | # value: docker.io/cloudfoundry/cnb:bionicoc 43 | # value: gcr.io/buildpacks/builder:v1 44 | # value: heroku/buildpacks:18 45 | - name: OUTPUT_IMAGE 46 | value: $(params.APP_IMAGE) 47 | runAfter: 48 | - git-clone 49 | workspaces: 50 | - name: source 51 | workspace: app-source 52 | 53 | - name: deploy 54 | taskRef: 55 | name: oc-deploy 56 | runAfter: 57 | - buildpacks 58 | params: 59 | - name: DEPLOYMENT_NAME 60 | value: $(params.APP_NAME) 61 | - name: IMAGE_URL 62 | value: $(params.APP_IMAGE) -------------------------------------------------------------------------------- /pipeline-buildpacks/tasks/buildpacks-task.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: tekton.dev/v1beta1 3 | kind: Task 4 | metadata: 5 | name: buildpacks 6 | labels: 7 | app.kubernetes.io/version: "0.1" 8 | annotations: 9 | tekton.dev/pipelines.minVersion: "0.12.1" 10 | tekton.dev/tags: image-build 11 | tekton.dev/displayName: "buildpacks" 12 | spec: 13 | description: >- 14 | The Buildpacks task builds source into a container image and pushes it to a registry, 15 | using Cloud Native Buildpacks. 16 | 17 | Cloud Native Buildpacks are pluggable, modular tools that transform application source code 18 | into OCI images. They replace Dockerfiles in the app development lifecycle, and allow for swift 19 | rebasing of images, and give modular control over images through the use of builders, among other 20 | benefits. This command uses a builder to construct the image, and pushes it to the registry provided. 21 | 22 | params: 23 | - name: BUILDER_IMAGE 24 | description: The image on which builds will run (must include lifecycle and compatible buildpacks). 25 | - name: CACHE 26 | description: The name of the persistent app cache volume. 27 | default: empty-dir 28 | - name: CACHE_IMAGE 29 | description: The name of the persistent app cache image. 30 | default: "" 31 | - name: PLATFORM_DIR 32 | description: The name of the platform directory. 33 | default: empty-dir 34 | - name: USER_ID 35 | description: The user ID of the builder image user. 36 | default: "1000" 37 | - name: GROUP_ID 38 | description: The group ID of the builder image user. 39 | default: "1000" 40 | - name: PROCESS_TYPE 41 | description: The default process type to set on the image. 42 | default: "web" 43 | - name: SOURCE_SUBPATH 44 | description: A subpath within the `source` input where the source to build is located. 45 | default: "" 46 | - name: SKIP_RESTORE 47 | description: Do not write layer metadata or restore cached layers 48 | default: "false" 49 | - name: RUN_IMAGE 50 | description: Reference to a run image to use 51 | default: "" 52 | - name: OUTPUT_IMAGE 53 | default: "" 54 | description: Reference to the output app image in registry 55 | 56 | workspaces: 57 | - name: source 58 | 59 | stepTemplate: 60 | env: 61 | - name: CNB_PLATFORM_API 62 | value: "0.3" 63 | 64 | steps: 65 | - name: prepare 66 | image: alpine 67 | imagePullPolicy: Always 68 | command: ["/bin/sh"] 69 | args: 70 | - "-c" 71 | - |- 72 | chown -R "$(params.USER_ID):$(params.GROUP_ID)" "/tekton/home" && 73 | chown -R "$(params.USER_ID):$(params.GROUP_ID)" "/layers" && 74 | chown -R "$(params.USER_ID):$(params.GROUP_ID)" "/cache" && 75 | chown -R "$(params.USER_ID):$(params.GROUP_ID)" "$(workspaces.source.path)" 76 | volumeMounts: 77 | - name: layers-dir 78 | mountPath: /layers 79 | - name: $(params.CACHE) 80 | mountPath: /cache 81 | securityContext: 82 | privileged: true 83 | 84 | - name: create 85 | image: $(params.BUILDER_IMAGE) 86 | imagePullPolicy: Always 87 | command: ["/cnb/lifecycle/creator"] 88 | args: 89 | - "-app=$(workspaces.source.path)/$(params.SOURCE_SUBPATH)" 90 | - "-cache-dir=/cache" 91 | - "-cache-image=$(params.CACHE_IMAGE)" 92 | - "-gid=$(params.GROUP_ID)" 93 | - "-layers=/layers" 94 | - "-platform=/platform" 95 | - "-process-type=$(params.PROCESS_TYPE)" 96 | - "-skip-restore=$(params.SKIP_RESTORE)" 97 | - "-previous-image=$(params.OUTPUT_IMAGE)" 98 | - "-run-image=$(params.RUN_IMAGE)" 99 | - "-uid=$(params.USER_ID)" 100 | - "$(params.OUTPUT_IMAGE)" 101 | volumeMounts: 102 | - name: layers-dir 103 | mountPath: /layers 104 | - name: $(params.CACHE) 105 | mountPath: /cache 106 | - name: $(params.PLATFORM_DIR) 107 | mountPath: /platform 108 | 109 | volumes: 110 | - name: empty-dir 111 | emptyDir: {} 112 | - name: layers-dir 113 | emptyDir: {} -------------------------------------------------------------------------------- /pipeline-buildpacks/tasks/oc-deploy-task.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Task 3 | metadata: 4 | name: oc-deploy 5 | spec: 6 | params: 7 | - name: DEPLOYMENT_NAME 8 | type: string 9 | - name: IMAGE_URL 10 | type: string 11 | 12 | stepTemplate: 13 | volumeMounts: 14 | - name: work 15 | mountPath: /work 16 | 17 | steps: 18 | - name: extract-digest 19 | image: quay.io/siamaksade/skopeo:latest 20 | script: | 21 | #!/usr/bin/env bash 22 | skopeo inspect docker://$(params.IMAGE_URL) > /work/digest.json 23 | cat /work/digest.json | jq '.Name' | tr -d '"' > /work/image-name 24 | cat /work/digest.json | jq '.Digest' | tr -d '"' > /work/image-digest 25 | - name: deploy 26 | image: image-registry.openshift-image-registry.svc:5000/openshift/cli:latest 27 | script: | 28 | #!/usr/bin/env bash 29 | 30 | image_ref="`cat /work/image-name`@`cat /work/image-digest`" 31 | 32 | echo "Deploying $image_ref" 33 | 34 | oc set image deployment/$(inputs.params.DEPLOYMENT_NAME) $(inputs.params.DEPLOYMENT_NAME)=$image_ref 35 | oc patch deployment $(inputs.params.DEPLOYMENT_NAME) -p "{\"spec\": {\"template\": {\"metadata\": { \"labels\": { \"redeploy\": \"$(date +%s)\"}}}}}" 36 | oc rollout status deployment/$(inputs.params.DEPLOYMENT_NAME) 37 | volumes: 38 | - name: work 39 | emptyDir: {} -------------------------------------------------------------------------------- /pipeline-s2i/README.md: -------------------------------------------------------------------------------- 1 | # Tekton Pipelines Example - S2I Build 2 | 3 | ![Pipeline Diagram](images/pipeline.png) 4 | 5 | Install demo: 6 | ``` 7 | $ oc new-project demo 8 | $ oc apply -f fix 9 | $ oc create -f pipeline-s2i/petclinic-pipeline-all.yaml 10 | ``` 11 | 12 | Start pipeline 13 | ``` 14 | $ tkn p start petclinic-deploy --use-param-defaults -w name=maven-cache,claimName=maven-cache-pvc -w name=app-source,claimName=app-source-pvc -w name=maven-settings,config=maven-settings 15 | ``` -------------------------------------------------------------------------------- /pipeline-s2i/apps/spring-petclinic.yaml: -------------------------------------------------------------------------------- 1 | # petclinic app 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | labels: 6 | app: spring-petclinic 7 | app.kubernetes.io/component: web 8 | app.kubernetes.io/instance: spring-petclinic 9 | app.kubernetes.io/name: spring-petclinic 10 | app.kubernetes.io/part-of: spring-petclinic 11 | app.openshift.io/runtime: java 12 | name: spring-petclinic 13 | spec: 14 | replicas: 1 15 | selector: 16 | matchLabels: 17 | app: spring-petclinic 18 | template: 19 | metadata: 20 | labels: 21 | app: spring-petclinic 22 | spec: 23 | containers: 24 | - name: spring-petclinic 25 | imagePullPolicy: Always 26 | image: quay.io/siamaksade/spring-petclinic:latest 27 | livenessProbe: 28 | failureThreshold: 3 29 | httpGet: 30 | path: / 31 | port: 8080 32 | scheme: HTTP 33 | initialDelaySeconds: 45 34 | periodSeconds: 10 35 | successThreshold: 1 36 | timeoutSeconds: 1 37 | ports: 38 | - containerPort: 8080 39 | protocol: TCP 40 | - containerPort: 8443 41 | protocol: TCP 42 | - containerPort: 8778 43 | protocol: TCP 44 | readinessProbe: 45 | failureThreshold: 3 46 | httpGet: 47 | path: / 48 | port: 8080 49 | scheme: HTTP 50 | initialDelaySeconds: 45 51 | periodSeconds: 10 52 | successThreshold: 1 53 | timeoutSeconds: 5 54 | --- 55 | apiVersion: v1 56 | kind: Service 57 | metadata: 58 | labels: 59 | app: spring-petclinic 60 | name: spring-petclinic 61 | spec: 62 | ports: 63 | - name: 8080-tcp 64 | port: 8080 65 | protocol: TCP 66 | targetPort: 8080 67 | - name: 8443-tcp 68 | port: 8443 69 | protocol: TCP 70 | targetPort: 8443 71 | - name: 8778-tcp 72 | port: 8778 73 | protocol: TCP 74 | targetPort: 8778 75 | selector: 76 | app: spring-petclinic 77 | sessionAffinity: None 78 | type: ClusterIP 79 | --- 80 | apiVersion: route.openshift.io/v1 81 | kind: Route 82 | metadata: 83 | labels: 84 | app: spring-petclinic 85 | name: spring-petclinic 86 | spec: 87 | port: 88 | targetPort: 8080-tcp 89 | to: 90 | kind: Service 91 | name: spring-petclinic 92 | weight: 100 -------------------------------------------------------------------------------- /pipeline-s2i/conf/maven-configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: maven-settings 5 | data: 6 | settings.xml: | 7 | 8 | 9 | 27 | 28 | 52 | 55 | 61 | 62 | 70 | 71 | 78 | 79 | 84 | 85 | 89 | 90 | 91 | 96 | 97 | 111 | 112 | 113 | 117 | 118 | 131 | 132 | 139 | 140 | 141 | 152 | 153 | 165 | 166 | 167 | 188 | 189 | 218 | 219 | 253 | 254 | 255 | 263 | -------------------------------------------------------------------------------- /pipeline-s2i/conf/pvc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: PersistentVolumeClaim 4 | metadata: 5 | name: app-source-pvc 6 | spec: 7 | resources: 8 | requests: 9 | storage: 1Gi 10 | volumeMode: Filesystem 11 | accessModes: 12 | - ReadWriteOnce 13 | persistentVolumeReclaimPolicy: Recycle 14 | --- 15 | apiVersion: v1 16 | kind: PersistentVolumeClaim 17 | metadata: 18 | name: maven-cache-pvc 19 | spec: 20 | resources: 21 | requests: 22 | storage: 5Gi 23 | volumeMode: Filesystem 24 | accessModes: 25 | - ReadWriteOnce 26 | persistentVolumeReclaimPolicy: Retain -------------------------------------------------------------------------------- /pipeline-s2i/fix/git-clone-task.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: ClusterTask 3 | metadata: 4 | name: git-clone 5 | labels: 6 | operator.tekton.dev/provider-type: community 7 | spec: 8 | params: 9 | - description: git url to clone 10 | name: url 11 | type: string 12 | - default: master 13 | description: 'git revision to checkout (branch, tag, sha, ref…)' 14 | name: revision 15 | type: string 16 | - default: '' 17 | description: (optional) git refspec to fetch before checking out revision 18 | name: refspec 19 | type: string 20 | - default: 'true' 21 | description: defines if the resource should initialize and fetch the submodules 22 | name: submodules 23 | type: string 24 | - default: '1' 25 | description: >- 26 | performs a shallow clone where only the most recent commit(s) will be 27 | fetched 28 | name: depth 29 | type: string 30 | - default: 'true' 31 | description: >- 32 | defines if http.sslVerify should be set to true or false in the global 33 | git config 34 | name: sslVerify 35 | type: string 36 | - default: '' 37 | description: subdirectory inside the "output" workspace to clone the git repo into 38 | name: subdirectory 39 | type: string 40 | - default: 'false' 41 | description: >- 42 | clean out the contents of the repo's destination directory (if it 43 | already exists) before trying to clone the repo there 44 | name: deleteExisting 45 | type: string 46 | - default: '' 47 | description: git HTTP proxy server for non-SSL requests 48 | name: httpProxy 49 | type: string 50 | - default: '' 51 | description: git HTTPS proxy server for SSL requests 52 | name: httpsProxy 53 | type: string 54 | - default: '' 55 | description: git no proxy - opt out of proxying HTTP/HTTPS requests 56 | name: noProxy 57 | type: string 58 | results: 59 | - description: The precise commit SHA that was fetched by this Task 60 | name: commit 61 | steps: 62 | - image: 'quay.io/openshift-pipeline/tektoncd-pipeline-git-init:v0.14.3' 63 | name: clone 64 | resources: {} 65 | script: > 66 | CHECKOUT_DIR="$(workspaces.output.path)/$(params.subdirectory)" 67 | 68 | 69 | cleandir() { 70 | # Delete any existing contents of the repo directory if it exists. 71 | # 72 | # We don't just "rm -rf $CHECKOUT_DIR" because $CHECKOUT_DIR might be "/" 73 | # or the root of a mounted volume. 74 | if [[ -d "$CHECKOUT_DIR" ]] ; then 75 | # Delete non-hidden files and directories 76 | rm -rf "$CHECKOUT_DIR"/* 77 | # Delete files and directories starting with . but excluding .. 78 | rm -rf "$CHECKOUT_DIR"/.[!.]* 79 | # Delete files and directories starting with .. plus any other character 80 | rm -rf "$CHECKOUT_DIR"/..?* 81 | fi 82 | } 83 | 84 | 85 | if [[ "$(params.deleteExisting)" == "true" ]] ; then 86 | cleandir 87 | fi 88 | 89 | 90 | test -z "$(params.httpProxy)" || export HTTP_PROXY=$(params.httpProxy) 91 | 92 | test -z "$(params.httpsProxy)" || export 93 | HTTPS_PROXY=$(params.httpsProxy) 94 | 95 | test -z "$(params.noProxy)" || export NO_PROXY=$(params.noProxy) 96 | 97 | 98 | /ko-app/git-init \ 99 | -url "$(params.url)" \ 100 | -revision "$(params.revision)" \ 101 | -refspec "$(params.refspec)" \ 102 | -path "$CHECKOUT_DIR" \ 103 | -sslVerify="$(params.sslVerify)" \ 104 | -submodules="$(params.submodules)" \ 105 | -depth "$(params.depth)" 106 | cd "$CHECKOUT_DIR" 107 | 108 | RESULT_SHA="$(git rev-parse HEAD | tr -d '\n')" 109 | 110 | EXIT_CODE="$?" 111 | 112 | if [ "$EXIT_CODE" != 0 ] 113 | 114 | then 115 | exit $EXIT_CODE 116 | fi 117 | 118 | # Make sure we don't add a trailing newline to the result! 119 | 120 | echo -n "$RESULT_SHA" > $(results.commit.path) 121 | workspaces: 122 | - description: The git repo will be cloned onto the volume backing this workspace 123 | name: output -------------------------------------------------------------------------------- /pipeline-s2i/fix/github-triggerbinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: triggers.tekton.dev/v1alpha1 2 | kind: ClusterTriggerBinding 3 | metadata: 4 | name: github-push 5 | spec: 6 | params: 7 | - name: git-revision 8 | value: $(body.head_commit.id) 9 | - name: git-commit-message 10 | value: $(body.head_commit.message) 11 | - name: git-repo-url 12 | value: $(body.repository.url) 13 | - name: git-repo-name 14 | value: $(body.repository.name) 15 | - name: content-type 16 | value: $(header.Content-Type) 17 | - name: pusher-name 18 | value: $(body.pusher.name) 19 | -------------------------------------------------------------------------------- /pipeline-s2i/images/pipeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siamaksade/pipelines-examples/c7d4008fde2be7b9f463fb390aef7a58de8f7779/pipeline-s2i/images/pipeline.png -------------------------------------------------------------------------------- /pipeline-s2i/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # oc apply -f fix/ 4 | oc create -f apps/ 5 | oc create -f conf/ 6 | oc create -f tasks/ 7 | oc create -f pipelines/ 8 | oc create -f triggers/ 9 | # oc create -f pipelinerun/ -------------------------------------------------------------------------------- /pipeline-s2i/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - apps/spring-petclinic.yaml 3 | - conf/maven-configmap.yaml 4 | - conf/pvc.yaml 5 | - tasks/maven.yaml 6 | - tasks/redeploy.yaml 7 | - tasks/s2i-java-11-binary.yaml 8 | - pipelines/petclinic-pipeline.yaml 9 | - triggers/triggertemplate.yaml 10 | - triggers/eventlistener.yaml 11 | - triggers/eventlistener-route.yaml -------------------------------------------------------------------------------- /pipeline-s2i/petclinic-pipeline-all.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | settings.xml: | 4 | 5 | 6 | 24 | 25 | 49 | 52 | 58 | 59 | 67 | 68 | 75 | 76 | 81 | 82 | 86 | 87 | 88 | 93 | 94 | 108 | 109 | 110 | 114 | 115 | 128 | 129 | 136 | 137 | 138 | 149 | 150 | 162 | 163 | 164 | 185 | 186 | 215 | 216 | 250 | 251 | 252 | 260 | 261 | kind: ConfigMap 262 | metadata: 263 | name: maven-settings 264 | --- 265 | apiVersion: v1 266 | kind: Service 267 | metadata: 268 | labels: 269 | app: spring-petclinic 270 | name: spring-petclinic 271 | spec: 272 | ports: 273 | - name: 8080-tcp 274 | port: 8080 275 | protocol: TCP 276 | targetPort: 8080 277 | - name: 8443-tcp 278 | port: 8443 279 | protocol: TCP 280 | targetPort: 8443 281 | - name: 8778-tcp 282 | port: 8778 283 | protocol: TCP 284 | targetPort: 8778 285 | selector: 286 | app: spring-petclinic 287 | sessionAffinity: None 288 | type: ClusterIP 289 | --- 290 | apiVersion: apps/v1 291 | kind: Deployment 292 | metadata: 293 | labels: 294 | app: spring-petclinic 295 | app.kubernetes.io/component: web 296 | app.kubernetes.io/instance: spring-petclinic 297 | app.kubernetes.io/name: spring-petclinic 298 | app.kubernetes.io/part-of: spring-petclinic 299 | app.openshift.io/runtime: java 300 | name: spring-petclinic 301 | spec: 302 | replicas: 1 303 | selector: 304 | matchLabels: 305 | app: spring-petclinic 306 | template: 307 | metadata: 308 | labels: 309 | app: spring-petclinic 310 | spec: 311 | containers: 312 | - image: quay.io/siamaksade/spring-petclinic:latest 313 | imagePullPolicy: Always 314 | livenessProbe: 315 | failureThreshold: 3 316 | httpGet: 317 | path: / 318 | port: 8080 319 | scheme: HTTP 320 | initialDelaySeconds: 45 321 | periodSeconds: 10 322 | successThreshold: 1 323 | timeoutSeconds: 1 324 | name: spring-petclinic 325 | ports: 326 | - containerPort: 8080 327 | protocol: TCP 328 | - containerPort: 8443 329 | protocol: TCP 330 | - containerPort: 8778 331 | protocol: TCP 332 | readinessProbe: 333 | failureThreshold: 3 334 | httpGet: 335 | path: / 336 | port: 8080 337 | scheme: HTTP 338 | initialDelaySeconds: 45 339 | periodSeconds: 10 340 | successThreshold: 1 341 | timeoutSeconds: 5 342 | --- 343 | apiVersion: route.openshift.io/v1 344 | kind: Route 345 | metadata: 346 | labels: 347 | app.kubernetes.io/managed-by: EventListener 348 | app.kubernetes.io/part-of: Triggers 349 | eventlistener: petclinic-event-listener 350 | name: el-petclinic-event-listener 351 | spec: 352 | port: 353 | targetPort: 8080 354 | to: 355 | kind: Service 356 | name: el-petclinic-event-listener 357 | weight: 100 358 | --- 359 | apiVersion: route.openshift.io/v1 360 | kind: Route 361 | metadata: 362 | labels: 363 | app: spring-petclinic 364 | name: spring-petclinic 365 | spec: 366 | port: 367 | targetPort: 8080-tcp 368 | to: 369 | kind: Service 370 | name: spring-petclinic 371 | weight: 100 372 | --- 373 | apiVersion: tekton.dev/v1beta1 374 | kind: Pipeline 375 | metadata: 376 | name: petclinic-deploy 377 | spec: 378 | params: 379 | - default: spring-petclinic 380 | description: The application deployment name 381 | name: APP_NAME 382 | type: string 383 | - default: https://github.com/siamaksade/spring-petclinic/ 384 | description: The application git repository url 385 | name: APP_GIT_URL 386 | type: string 387 | - default: master 388 | description: The application git repository revision 389 | name: APP_GIT_REVISION 390 | type: string 391 | - default: spring-petclinic:latest 392 | description: The application image stream 393 | name: APP_IMAGE_STREAM 394 | type: string 395 | tasks: 396 | - name: git-clone 397 | params: 398 | - name: url 399 | value: $(params.APP_GIT_URL) 400 | - name: revision 401 | value: $(params.APP_GIT_REVISION) 402 | - name: deleteExisting 403 | value: "true" 404 | taskRef: 405 | kind: ClusterTask 406 | name: git-clone 407 | workspaces: 408 | - name: output 409 | workspace: app-source 410 | - name: build-jar 411 | params: 412 | - name: GOALS 413 | value: 414 | - package 415 | - -DskipTests 416 | runAfter: 417 | - git-clone 418 | taskRef: 419 | name: maven 420 | workspaces: 421 | - name: maven-cache 422 | workspace: maven-cache 423 | - name: maven-settings 424 | workspace: maven-settings 425 | - name: source 426 | workspace: app-source 427 | - name: build-image 428 | params: 429 | - name: TLSVERIFY 430 | value: "false" 431 | - name: OUTPUT_IMAGE_STREAM 432 | value: $(params.APP_IMAGE_STREAM) 433 | runAfter: 434 | - build-jar 435 | taskRef: 436 | name: s2i-java-11-binary 437 | workspaces: 438 | - name: source 439 | workspace: app-source 440 | - name: deploy 441 | params: 442 | - name: DEPLOYMENT 443 | value: $(params.APP_NAME) 444 | - name: IMAGE_STREAM 445 | value: $(params.APP_IMAGE_STREAM) 446 | runAfter: 447 | - build-image 448 | taskRef: 449 | name: redeploy 450 | workspaces: 451 | - name: maven-cache 452 | - name: maven-settings 453 | - name: app-source 454 | --- 455 | apiVersion: tekton.dev/v1beta1 456 | kind: Task 457 | metadata: 458 | name: maven 459 | spec: 460 | params: 461 | - default: 462 | - package 463 | description: maven goals to run 464 | name: GOALS 465 | type: array 466 | steps: 467 | - args: 468 | - -Dmaven.repo.local=$(workspaces.maven-cache.path) 469 | - -s 470 | - $(workspaces.maven-settings.path)/settings.xml 471 | - $(params.GOALS) 472 | command: 473 | - /usr/bin/mvn 474 | image: gcr.io/cloud-builders/mvn 475 | name: mvn 476 | workingDir: $(workspaces.source.path) 477 | workspaces: 478 | - name: source 479 | - name: maven-cache 480 | - name: maven-settings 481 | --- 482 | apiVersion: tekton.dev/v1beta1 483 | kind: Task 484 | metadata: 485 | name: redeploy 486 | spec: 487 | params: 488 | - name: DEPLOYMENT 489 | type: string 490 | - name: IMAGE_STREAM 491 | type: string 492 | steps: 493 | - env: 494 | - name: POD_NAMESPACE 495 | valueFrom: 496 | fieldRef: 497 | fieldPath: metadata.namespace 498 | image: image-registry.openshift-image-registry.svc:5000/openshift/cli:latest 499 | name: deploy 500 | script: | 501 | #!/usr/bin/env bash 502 | 503 | image_ref="image-registry.openshift-image-registry.svc:5000/$POD_NAMESPACE/$(params.IMAGE_STREAM)" 504 | 505 | echo "Deploying $image_ref" 506 | 507 | oc set image deployment/$(params.DEPLOYMENT) $(params.DEPLOYMENT)=$image_ref 508 | oc patch deployment $(params.DEPLOYMENT) -p "{\"spec\": {\"template\": {\"metadata\": { \"labels\": { \"redeploy\": \"$(date +%s)\"}}}}}" 509 | oc rollout status deployment/$(params.DEPLOYMENT) 510 | --- 511 | apiVersion: tekton.dev/v1beta1 512 | kind: Task 513 | metadata: 514 | name: s2i-java-11-binary 515 | spec: 516 | params: 517 | - default: . 518 | description: The location of the path to run s2i from 519 | name: PATH_CONTEXT 520 | type: string 521 | - default: "false" 522 | description: Verify the TLS on the registry endpoint (for push/pull to a non-TLS registry) 523 | name: TLSVERIFY 524 | type: string 525 | - description: The application image url in registry 526 | name: OUTPUT_IMAGE_STREAM 527 | type: string 528 | stepTemplate: 529 | env: 530 | - name: POD_NAMESPACE 531 | valueFrom: 532 | fieldRef: 533 | fieldPath: metadata.namespace 534 | steps: 535 | - command: 536 | - s2i 537 | - build 538 | - $(params.PATH_CONTEXT) 539 | - registry.access.redhat.com/openjdk/openjdk-11-rhel7 540 | - --image-scripts-url 541 | - image:///usr/local/s2i 542 | - --as-dockerfile 543 | - /gen-source/Dockerfile.gen 544 | image: registry.redhat.io/ocp-tools-43-tech-preview/source-to-image-rhel8 545 | name: generate 546 | volumeMounts: 547 | - mountPath: /env-params 548 | name: envparams 549 | - mountPath: /gen-source 550 | name: gen-source 551 | workingdir: $(workspaces.source.path)/target 552 | - command: 553 | - buildah 554 | - bud 555 | - --tls-verify=$(params.TLSVERIFY) 556 | - --layers 557 | - -f 558 | - /gen-source/Dockerfile.gen 559 | - -t 560 | - image-registry.openshift-image-registry.svc:5000/$(POD_NAMESPACE)/$(params.OUTPUT_IMAGE_STREAM) 561 | - . 562 | image: registry.redhat.io/rhel8/buildah 563 | name: build 564 | securityContext: 565 | privileged: true 566 | volumeMounts: 567 | - mountPath: /var/lib/containers 568 | name: varlibcontainers 569 | - mountPath: /gen-source 570 | name: gen-source 571 | workingdir: /gen-source 572 | - command: 573 | - buildah 574 | - push 575 | - --tls-verify=$(params.TLSVERIFY) 576 | - image-registry.openshift-image-registry.svc:5000/$(POD_NAMESPACE)/$(params.OUTPUT_IMAGE_STREAM) 577 | - docker://image-registry.openshift-image-registry.svc:5000/$(POD_NAMESPACE)/$(params.OUTPUT_IMAGE_STREAM) 578 | image: registry.redhat.io/rhel8/buildah 579 | name: push 580 | securityContext: 581 | privileged: true 582 | volumeMounts: 583 | - mountPath: /var/lib/containers 584 | name: varlibcontainers 585 | volumes: 586 | - emptyDir: {} 587 | name: varlibcontainers 588 | - emptyDir: {} 589 | name: gen-source 590 | - emptyDir: {} 591 | name: envparams 592 | workspaces: 593 | - name: source 594 | --- 595 | apiVersion: triggers.tekton.dev/v1alpha1 596 | kind: EventListener 597 | metadata: 598 | name: petclinic-event-listener 599 | spec: 600 | serviceAccountName: pipeline 601 | triggers: 602 | - bindings: 603 | - kind: ClusterTriggerBinding 604 | ref: github-push 605 | template: 606 | name: trigger-template-petclinic-deploy 607 | --- 608 | apiVersion: triggers.tekton.dev/v1alpha1 609 | kind: TriggerTemplate 610 | metadata: 611 | name: trigger-template-petclinic-deploy 612 | spec: 613 | params: 614 | - name: git-revision 615 | - name: git-commit-message 616 | - name: git-repo-url 617 | - name: git-repo-name 618 | - name: content-type 619 | - name: pusher-name 620 | resourcetemplates: 621 | - apiVersion: tekton.dev/v1beta1 622 | kind: PipelineRun 623 | metadata: 624 | labels: 625 | tekton.dev/pipeline: petclinic-deploy 626 | name: petclinic-deploy-$(uid) 627 | namespace: demo 628 | spec: 629 | params: 630 | - name: APP_NAME 631 | value: spring-petclinic 632 | - name: APP_GIT_URL 633 | value: https://github.com/siamaksade/spring-petclinic/ 634 | - name: APP_GIT_REVISION 635 | value: $(params.git-revision) 636 | - name: APP_IMAGE_STREAM 637 | value: spring-petclinic:$(params.git-revision) 638 | pipelineRef: 639 | name: petclinic-deploy 640 | workspaces: 641 | - name: app-source 642 | persistentVolumeClaim: 643 | claimName: app-source-pvc 644 | - name: maven-cache 645 | persistentVolumeClaim: 646 | claimName: maven-cache-pvc 647 | - configMap: 648 | name: maven-settings 649 | name: maven-settings 650 | --- 651 | apiVersion: v1 652 | kind: PersistentVolumeClaim 653 | metadata: 654 | name: app-source-pvc 655 | spec: 656 | accessModes: 657 | - ReadWriteOnce 658 | persistentVolumeReclaimPolicy: Recycle 659 | resources: 660 | requests: 661 | storage: 1Gi 662 | volumeMode: Filesystem 663 | --- 664 | apiVersion: v1 665 | kind: PersistentVolumeClaim 666 | metadata: 667 | name: maven-cache-pvc 668 | spec: 669 | accessModes: 670 | - ReadWriteOnce 671 | persistentVolumeReclaimPolicy: Retain 672 | resources: 673 | requests: 674 | storage: 5Gi 675 | volumeMode: Filesystem 676 | -------------------------------------------------------------------------------- /pipeline-s2i/pipelinerun/petclinic-pipelinerun.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: PipelineRun 3 | metadata: 4 | generateName: petclinic-deploy-run- 5 | spec: 6 | pipelineRef: 7 | name: petclinic-deploy 8 | workspaces: 9 | - name: app-source 10 | persistentVolumeClaim: 11 | claimName: app-source-pvc 12 | # volumeClaimTemplate: 13 | # spec: 14 | # accessModes: 15 | # - ReadWriteOnce 16 | # resources: 17 | # requests: 18 | # storage: 1Gi 19 | - name: maven-cache 20 | persistentVolumeClaim: 21 | claimName: maven-cache-pvc 22 | - name: maven-settings 23 | configMap: 24 | name: maven-settings -------------------------------------------------------------------------------- /pipeline-s2i/pipelines/petclinic-pipeline.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Pipeline 3 | metadata: 4 | name: petclinic-deploy 5 | spec: 6 | workspaces: 7 | - name: maven-cache 8 | - name: maven-settings 9 | - name: app-source 10 | params: 11 | - name: APP_NAME 12 | type: string 13 | default: spring-petclinic 14 | description: The application deployment name 15 | - name: APP_GIT_URL 16 | type: string 17 | default: https://github.com/siamaksade/spring-petclinic/ 18 | description: The application git repository url 19 | - name: APP_GIT_REVISION 20 | type: string 21 | default: master 22 | description: The application git repository revision 23 | - name: APP_IMAGE_STREAM 24 | type: string 25 | default: spring-petclinic:latest 26 | description: The application image stream 27 | tasks: 28 | - name: git-clone 29 | taskRef: 30 | name: git-clone 31 | kind: ClusterTask 32 | params: 33 | - name: url 34 | value: $(params.APP_GIT_URL) 35 | - name: revision 36 | value: $(params.APP_GIT_REVISION) 37 | - name: deleteExisting 38 | value: "true" 39 | workspaces: 40 | - name: output 41 | workspace: app-source 42 | - name: build-jar 43 | taskRef: 44 | name: maven 45 | params: 46 | - name: GOALS 47 | value: ["package", "-DskipTests"] 48 | runAfter: 49 | - git-clone 50 | workspaces: 51 | - name: maven-cache 52 | workspace: maven-cache 53 | - name: maven-settings 54 | workspace: maven-settings 55 | - name: source 56 | workspace: app-source 57 | - name: build-image 58 | taskRef: 59 | name: s2i-java-11-binary 60 | runAfter: 61 | - build-jar 62 | params: 63 | - name: TLSVERIFY 64 | value: "false" 65 | - name: OUTPUT_IMAGE_STREAM 66 | value: $(params.APP_IMAGE_STREAM) 67 | workspaces: 68 | - name: source 69 | workspace: app-source 70 | - name: deploy 71 | taskRef: 72 | name: redeploy 73 | runAfter: 74 | - build-image 75 | params: 76 | - name: DEPLOYMENT 77 | value: $(params.APP_NAME) 78 | - name: IMAGE_STREAM 79 | value: $(params.APP_IMAGE_STREAM) -------------------------------------------------------------------------------- /pipeline-s2i/tasks/maven.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Task 3 | metadata: 4 | name: maven 5 | spec: 6 | workspaces: 7 | - name: source 8 | - name: maven-cache 9 | - name: maven-settings 10 | params: 11 | - name: GOALS 12 | description: maven goals to run 13 | type: array 14 | default: 15 | - "package" 16 | steps: 17 | - name: mvn 18 | image: gcr.io/cloud-builders/mvn 19 | workingDir: $(workspaces.source.path) 20 | command: ["/usr/bin/mvn"] 21 | args: 22 | - -Dmaven.repo.local=$(workspaces.maven-cache.path) 23 | - -s 24 | - $(workspaces.maven-settings.path)/settings.xml 25 | - "$(params.GOALS)" -------------------------------------------------------------------------------- /pipeline-s2i/tasks/redeploy.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Task 3 | metadata: 4 | name: redeploy 5 | spec: 6 | params: 7 | - name: DEPLOYMENT 8 | type: string 9 | - name: IMAGE_STREAM 10 | type: string 11 | steps: 12 | - name: deploy 13 | image: image-registry.openshift-image-registry.svc:5000/openshift/cli:latest 14 | script: | 15 | #!/usr/bin/env bash 16 | 17 | image_ref="image-registry.openshift-image-registry.svc:5000/$POD_NAMESPACE/$(params.IMAGE_STREAM)" 18 | 19 | echo "Deploying $image_ref" 20 | 21 | oc set image deployment/$(params.DEPLOYMENT) $(params.DEPLOYMENT)=$image_ref 22 | oc patch deployment $(params.DEPLOYMENT) -p "{\"spec\": {\"template\": {\"metadata\": { \"labels\": { \"redeploy\": \"$(date +%s)\"}}}}}" 23 | oc rollout status deployment/$(params.DEPLOYMENT) 24 | env: 25 | - name: POD_NAMESPACE 26 | valueFrom: 27 | fieldRef: 28 | fieldPath: metadata.namespace -------------------------------------------------------------------------------- /pipeline-s2i/tasks/s2i-java-11-binary.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Task 3 | metadata: 4 | name: s2i-java-11-binary 5 | spec: 6 | params: 7 | - name: PATH_CONTEXT 8 | description: The location of the path to run s2i from 9 | default: . 10 | type: string 11 | - name: TLSVERIFY 12 | description: Verify the TLS on the registry endpoint (for push/pull to a non-TLS registry) 13 | default: "false" 14 | type: string 15 | - name: OUTPUT_IMAGE_STREAM 16 | type: string 17 | description: The application image url in registry 18 | workspaces: 19 | - name: source 20 | stepTemplate: 21 | env: 22 | - name: POD_NAMESPACE 23 | valueFrom: 24 | fieldRef: 25 | fieldPath: metadata.namespace 26 | steps: 27 | - name: generate 28 | image: registry.redhat.io/ocp-tools-43-tech-preview/source-to-image-rhel8 29 | workingdir: $(workspaces.source.path)/target 30 | command: 31 | - 's2i' 32 | - 'build' 33 | - '$(params.PATH_CONTEXT)' 34 | - 'registry.access.redhat.com/openjdk/openjdk-11-rhel7' 35 | - '--image-scripts-url' 36 | - 'image:///usr/local/s2i' 37 | - '--as-dockerfile' 38 | - '/gen-source/Dockerfile.gen' 39 | volumeMounts: 40 | - name: envparams 41 | mountPath: /env-params 42 | - name: gen-source 43 | mountPath: /gen-source 44 | - name: build 45 | image: registry.redhat.io/rhel8/buildah 46 | workingdir: /gen-source 47 | command: 48 | - buildah 49 | - bud 50 | - --tls-verify=$(params.TLSVERIFY) 51 | - --layers 52 | - -f 53 | - /gen-source/Dockerfile.gen 54 | - -t 55 | - image-registry.openshift-image-registry.svc:5000/$(POD_NAMESPACE)/$(params.OUTPUT_IMAGE_STREAM) 56 | - . 57 | volumeMounts: 58 | - name: varlibcontainers 59 | mountPath: /var/lib/containers 60 | - name: gen-source 61 | mountPath: /gen-source 62 | securityContext: 63 | privileged: true 64 | - name: push 65 | image: registry.redhat.io/rhel8/buildah 66 | command: 67 | - buildah 68 | - push 69 | - --tls-verify=$(params.TLSVERIFY) 70 | - image-registry.openshift-image-registry.svc:5000/$(POD_NAMESPACE)/$(params.OUTPUT_IMAGE_STREAM) 71 | - docker://image-registry.openshift-image-registry.svc:5000/$(POD_NAMESPACE)/$(params.OUTPUT_IMAGE_STREAM) 72 | volumeMounts: 73 | - name: varlibcontainers 74 | mountPath: /var/lib/containers 75 | securityContext: 76 | privileged: true 77 | volumes: 78 | - name: varlibcontainers 79 | emptyDir: {} 80 | - name: gen-source 81 | emptyDir: {} 82 | - name: envparams 83 | emptyDir: {} -------------------------------------------------------------------------------- /pipeline-s2i/triggers/eventlistener-route.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: route.openshift.io/v1 2 | kind: Route 3 | metadata: 4 | labels: 5 | app.kubernetes.io/managed-by: EventListener 6 | app.kubernetes.io/part-of: Triggers 7 | eventlistener: petclinic-event-listener 8 | name: el-petclinic-event-listener 9 | spec: 10 | port: 11 | targetPort: 8080 12 | to: 13 | kind: Service 14 | name: el-petclinic-event-listener 15 | weight: 100 -------------------------------------------------------------------------------- /pipeline-s2i/triggers/eventlistener.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: triggers.tekton.dev/v1alpha1 2 | kind: EventListener 3 | metadata: 4 | name: petclinic-event-listener 5 | spec: 6 | serviceAccountName: pipeline 7 | triggers: 8 | - bindings: 9 | - kind: ClusterTriggerBinding 10 | ref: github-push 11 | template: 12 | name: trigger-template-petclinic-deploy -------------------------------------------------------------------------------- /pipeline-s2i/triggers/triggertemplate.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: triggers.tekton.dev/v1alpha1 2 | kind: TriggerTemplate 3 | metadata: 4 | name: trigger-template-petclinic-deploy 5 | spec: 6 | params: 7 | - name: git-revision 8 | - name: git-commit-message 9 | - name: git-repo-url 10 | - name: git-repo-name 11 | - name: content-type 12 | - name: pusher-name 13 | resourcetemplates: 14 | - apiVersion: tekton.dev/v1beta1 15 | kind: PipelineRun 16 | metadata: 17 | labels: 18 | tekton.dev/pipeline: petclinic-deploy 19 | name: petclinic-deploy-$(uid) 20 | namespace: demo 21 | spec: 22 | params: 23 | - name: APP_NAME 24 | value: spring-petclinic 25 | - name: APP_GIT_URL 26 | value: 'https://github.com/siamaksade/spring-petclinic/' 27 | - name: APP_GIT_REVISION 28 | value: $(params.git-revision) 29 | - name: APP_IMAGE_STREAM 30 | value: 'spring-petclinic:$(params.git-revision)' 31 | pipelineRef: 32 | name: petclinic-deploy 33 | workspaces: 34 | - name: app-source 35 | persistentVolumeClaim: 36 | claimName: app-source-pvc 37 | - name: maven-cache 38 | persistentVolumeClaim: 39 | claimName: maven-cache-pvc 40 | - name: maven-settings 41 | configMap: 42 | name: maven-settings 43 | -------------------------------------------------------------------------------- /tasks/README.md: -------------------------------------------------------------------------------- 1 | # A Collection of Tekton Tasks 2 | 3 | 4 | * `smoke-test`: a task that checks for a string in the response body of a Kubernetes services -------------------------------------------------------------------------------- /tasks/smoke-test/smoke-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Task 3 | metadata: 4 | name: smoke-test 5 | spec: 6 | params: 7 | - name: SERVICE_NAME 8 | description: Name of the Kubernetes service to be tested 9 | type: string 10 | - name: SERVICE_PORT 11 | description: Port of the Kubernetes service to be tested 12 | type: string 13 | default: "8080" 14 | - name: NAMESPACE 15 | description: The service namespace 16 | type: string 17 | - name: MATCH_PHRASE 18 | description: The phrase to match with the service response 19 | type: string 20 | steps: 21 | - name: test 22 | image: 'image-registry.openshift-image-registry.svc:5000/openshift/cli:latest' 23 | script: | 24 | #!/usr/bin/env bash 25 | 26 | echo "Smoke-testing http://$(params.SERVICE_NAME).$(params.NAMESPACE).svc:$(params.SERVICE_PORT) for '$(params.MATCH_PHRASE)' in reponse" 27 | curl -sL http://$(params.SERVICE_NAME).$(params.NAMESPACE).svc:$(params.SERVICE_PORT) | grep "$(params.MATCH_PHRASE)" 28 | 29 | --------------------------------------------------------------------------------