diff --git a/pipelines/README.md b/pipelines/README.md index 41187574..7407c291 100644 --- a/pipelines/README.md +++ b/pipelines/README.md @@ -192,6 +192,9 @@ in your Git server. ### Deploy and run the GitOps pipeline +The `gitops-update-pipeline` will fetch information about the last successfuly built and tested container image for the given model +from the PipelineRun of the above Pipelines, and record information about that image in your git repo. + ```bash oc apply -k tekton/gitops-update-pipeline/ oc apply -f tekton/gitops-update-pipeline/example-pipelineruns/example-git-credentials-secret.yaml diff --git a/pipelines/tekton/gitops-update-pipeline/example-pipelineruns/gitops-update-pipelinerun-bike-rentals.yaml b/pipelines/tekton/gitops-update-pipeline/example-pipelineruns/gitops-update-pipelinerun-bike-rentals.yaml index e1aad870..b659b3f7 100644 --- a/pipelines/tekton/gitops-update-pipeline/example-pipelineruns/gitops-update-pipelinerun-bike-rentals.yaml +++ b/pipelines/tekton/gitops-update-pipeline/example-pipelineruns/gitops-update-pipelinerun-bike-rentals.yaml @@ -6,6 +6,8 @@ metadata: tekton.dev/pipeline: gitops-update-pipeline spec: params: + - name: model-name + value: bike-rentals-auto-ml - name: gitServer value: https://github.com - name: gitApiServer @@ -16,8 +18,6 @@ spec: value: ai-edge-gitops - name: gitRepoBranchBase value: main - - name: imageDigest - value: sha256:22590bbf246cd231abebc13d7b20761b7f70e614dca9e430a1069510bdba2820 - name: imageReferenceFilePath value: acm/odh-edge/apps/bike-rental-app/kustomization.yaml - name: gitTokenSecretName diff --git a/pipelines/tekton/gitops-update-pipeline/example-pipelineruns/gitops-update-pipelinerun-tensorflow-housing.yaml b/pipelines/tekton/gitops-update-pipeline/example-pipelineruns/gitops-update-pipelinerun-tensorflow-housing.yaml index fa61b207..4e141045 100644 --- a/pipelines/tekton/gitops-update-pipeline/example-pipelineruns/gitops-update-pipelinerun-tensorflow-housing.yaml +++ b/pipelines/tekton/gitops-update-pipeline/example-pipelineruns/gitops-update-pipelinerun-tensorflow-housing.yaml @@ -6,6 +6,8 @@ metadata: tekton.dev/pipeline: gitops-update-pipeline spec: params: + - name: model-name + value: tensorflow-housing - name: gitServer value: https://github.com - name: gitApiServer @@ -16,8 +18,6 @@ spec: value: ai-edge-gitops - name: gitRepoBranchBase value: main - - name: imageDigest - value: sha256:19e7312d8cbfcbf21dcab083f9ef99af2f807f156b1216a423267010b7fdd7c0 - name: imageReferenceFilePath value: acm/odh-edge/apps/tensorflow-housing-app/kustomization.yaml - name: gitTokenSecretName diff --git a/pipelines/tekton/gitops-update-pipeline/gitops-update-pipeline.yaml b/pipelines/tekton/gitops-update-pipeline/gitops-update-pipeline.yaml index 3d248ac6..19744d2e 100644 --- a/pipelines/tekton/gitops-update-pipeline/gitops-update-pipeline.yaml +++ b/pipelines/tekton/gitops-update-pipeline/gitops-update-pipeline.yaml @@ -4,6 +4,8 @@ metadata: name: gitops-update-pipeline spec: params: + - name: model-name + type: string - name: gitServer type: string - name: gitApiServer @@ -15,8 +17,6 @@ spec: - name: gitRepoBranchBase default: main type: string - - name: imageDigest - type: string - name: imageReferenceFilePath type: string - name: gitApiPrefix @@ -28,6 +28,15 @@ spec: default: token type: string tasks: + - name: retrieve-image-info + taskRef: + kind: Task + name: retrieve-image-info + params: + - name: namespace + value: $(context.pipelineRun.namespace) + - name: model-name + value: $(params.model-name) - name: git-clone params: - name: url @@ -63,7 +72,8 @@ spec: PR_BRANCH=pipeline_$(context.pipelineRun.uid) git checkout -b $PR_BRANCH - sed -i -e "s/digest: .*/digest: $(params.imageDigest)/" $(params.imageReferenceFilePath) + sed -i -e "s%newName: .*%newName: $(tasks.retrieve-image-info.results.target-registry-url)%" $(params.imageReferenceFilePath) + sed -i -e "s/digest: .*/digest: $(tasks.retrieve-image-info.results.image-sha)/" $(params.imageReferenceFilePath) if [ -z "$(git status --porcelain)" ]; then echo "Update did not cause a modification" @@ -77,6 +87,7 @@ spec: - name: VERBOSE value: "true" runAfter: + - retrieve-image-info - git-clone taskRef: kind: ClusterTask @@ -114,7 +125,8 @@ spec: | PipelineRun Name | $(context.pipelineRun.name) | | PipelinRun UID | `$(context.pipelineRun.uid)` | | File Path | `$(params.imageReferenceFilePath)` | - | New Digest | `$(params.imageDigest)` | + | Image registry | `$(tasks.retrieve-image-info.results.target-registry-url)` | + | New Digest | `$(tasks.retrieve-image-info.results.image-sha)` | - name: TITLE value: "Auto: update image ref" runAfter: diff --git a/pipelines/tekton/gitops-update-pipeline/kustomization.yaml b/pipelines/tekton/gitops-update-pipeline/kustomization.yaml index 1e23f419..76ce51db 100644 --- a/pipelines/tekton/gitops-update-pipeline/kustomization.yaml +++ b/pipelines/tekton/gitops-update-pipeline/kustomization.yaml @@ -3,4 +3,5 @@ apiVersion: kustomize.config.k8s.io/v1beta1 resources: - https://raw.githubusercontent.com/tektoncd/catalog/main/task/github-open-pr/0.2/github-open-pr.yaml + - test-mlflow-retrieve-image-info-task.yaml - gitops-update-pipeline.yaml diff --git a/pipelines/tekton/gitops-update-pipeline/test-mlflow-retrieve-image-info-task.yaml b/pipelines/tekton/gitops-update-pipeline/test-mlflow-retrieve-image-info-task.yaml new file mode 100644 index 00000000..bcc5eca6 --- /dev/null +++ b/pipelines/tekton/gitops-update-pipeline/test-mlflow-retrieve-image-info-task.yaml @@ -0,0 +1,22 @@ +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: retrieve-image-info +spec: + description: Retrieve location and SHA of the built image from the previous PipelineRun + params: + - name: namespace + type: string + - name: model-name + type: string + steps: + - name: get-image-sha + image: image-registry.openshift-image-registry.svc:5000/openshift/cli:latest + script: | + oc get -n $(params.namespace) pipelinerun --selector tekton.dev/pipeline=test-mlflow-image --sort-by=.status.completionTime -o jsonpath='{range .items[?(@.spec.params[0].name == "model-name")]}{.spec.params[?(@.name == "model-name")].value} {.status.results[?(@.name == "image-sha")].value} {.status.results[?(@.name == "target-registry-url")].value}{"\n"}{end}' | awk -v model=$(params.model-name) '$1 == model && NF == 3 { print $2, $3 }' | tail -1 | tee /dev/stderr | while read sha registry ; do echo -n "$sha" > $(results.image-sha.path) ; echo -n "$registry" > $(results.target-registry-url.path) ; done ; + test -s $(results.image-sha.path) && test -s $(results.target-registry-url.path) + results: + - name: target-registry-url + description: The target-registry-url where the image will be stored + - name: image-sha + description: The image checksum diff --git a/pipelines/tekton/test-mlflow-image-pipeline/kustomization.yaml b/pipelines/tekton/test-mlflow-image-pipeline/kustomization.yaml index 00a7d2a7..1a180dea 100644 --- a/pipelines/tekton/test-mlflow-image-pipeline/kustomization.yaml +++ b/pipelines/tekton/test-mlflow-image-pipeline/kustomization.yaml @@ -4,4 +4,5 @@ resources: - bike-rentals-test-data-cm.yaml - tensorflow-housing-test-data-cm.yaml - test-mlflow-rest-svc-task.yaml +- test-mlflow-record-image-task.yaml - test-mlflow-image-pipeline.yaml diff --git a/pipelines/tekton/test-mlflow-image-pipeline/test-mlflow-image-pipeline.yaml b/pipelines/tekton/test-mlflow-image-pipeline/test-mlflow-image-pipeline.yaml index cdbe148f..90e1ad10 100644 --- a/pipelines/tekton/test-mlflow-image-pipeline/test-mlflow-image-pipeline.yaml +++ b/pipelines/tekton/test-mlflow-image-pipeline/test-mlflow-image-pipeline.yaml @@ -19,6 +19,11 @@ spec: - name: upon-end type: string default: delete + results: + - name: target-registry-url + value: $(tasks.record-image.results.target-registry-url) + - name: image-sha + value: $(tasks.record-image.results.image-sha) tasks: - name: deploy-container params: @@ -124,18 +129,33 @@ spec: taskRef: kind: ClusterTask name: openshift-client + - name: record-image + taskRef: + kind: Task + name: record-image + params: + - name: model-name + value: $(params.model-name) + - name: model-version + value: $(params.model-version) + - name: namespace + value: $(params.target-namespace) + - name: target-registry-url + value: quay.io/$(params.target-imagerepo)/$(params.model-name) + runAfter: + - test-mlflow-rest-svc - name: skopeo-copy params: - name: srcImageURL - value: docker://image-registry.openshift-image-registry.svc:5000/$(context.pipelineRun.namespace)/$(params.model-name):$(params.model-version) + value: docker://image-registry.openshift-image-registry.svc:5000/$(context.pipelineRun.namespace)/$(params.model-name)@$(tasks.record-image.results.image-sha) - name: destImageURL - value: docker://quay.io/$(params.target-imagerepo)/$(params.model-name):$(params.model-version)-$(context.pipelineRun.uid) + value: docker://$(tasks.record-image.results.target-registry-url):$(params.model-version)-$(context.pipelineRun.uid) - name: srcTLSverify value: "true" - name: destTLSverify value: "true" runAfter: - - test-mlflow-rest-svc + - record-image taskRef: kind: ClusterTask name: skopeo-copy diff --git a/pipelines/tekton/test-mlflow-image-pipeline/test-mlflow-image-pipelinerun-bike-rental.yaml b/pipelines/tekton/test-mlflow-image-pipeline/test-mlflow-image-pipelinerun-bike-rental.yaml index b47c1071..c5182cce 100644 --- a/pipelines/tekton/test-mlflow-image-pipeline/test-mlflow-image-pipelinerun-bike-rental.yaml +++ b/pipelines/tekton/test-mlflow-image-pipeline/test-mlflow-image-pipelinerun-bike-rental.yaml @@ -1,8 +1,6 @@ apiVersion: tekton.dev/v1beta1 kind: PipelineRun metadata: - labels: - tekton.dev/pipeline: test-mlflow-image generateName: test-mlflow-image-bike-rentals- spec: params: diff --git a/pipelines/tekton/test-mlflow-image-pipeline/test-mlflow-image-pipelinerun-tensorflow-housing.yaml b/pipelines/tekton/test-mlflow-image-pipeline/test-mlflow-image-pipelinerun-tensorflow-housing.yaml index 4315e12e..27c73819 100644 --- a/pipelines/tekton/test-mlflow-image-pipeline/test-mlflow-image-pipelinerun-tensorflow-housing.yaml +++ b/pipelines/tekton/test-mlflow-image-pipeline/test-mlflow-image-pipelinerun-tensorflow-housing.yaml @@ -1,8 +1,6 @@ apiVersion: tekton.dev/v1beta1 kind: PipelineRun metadata: - labels: - tekton.dev/pipeline: test-mlflow-image generateName: test-mlflow-image-tensorflow-housing- spec: params: diff --git a/pipelines/tekton/test-mlflow-image-pipeline/test-mlflow-record-image-task.yaml b/pipelines/tekton/test-mlflow-image-pipeline/test-mlflow-record-image-task.yaml new file mode 100644 index 00000000..67c67d96 --- /dev/null +++ b/pipelines/tekton/test-mlflow-image-pipeline/test-mlflow-record-image-task.yaml @@ -0,0 +1,27 @@ +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: record-image +spec: + description: Record location and SHA of the built image + params: + - name: namespace + type: string + - name: model-name + type: string + - name: model-version + type: string + - name: target-registry-url + type: string + steps: + - name: get-image-sha + image: image-registry.openshift-image-registry.svc:5000/openshift/cli:latest + script: | + echo -n "$(params.target-registry-url)" | tee $(results.target-registry-url.path) ; + echo ; + oc get -n $(params.namespace) -o jsonpath='{.status.tags[?(@.tag == "$(params.model-version)")].items[0].image}' imagestream/$(params.model-name) | tee $(results.image-sha.path) + results: + - name: target-registry-url + description: The target-registry-url where the image will be stored + - name: image-sha + description: The image checksum