From 6c5c7d4ae8af07e60570a813ebbfac7adf2e73e4 Mon Sep 17 00:00:00 2001 From: Yingchun Guo Date: Tue, 11 Jun 2024 23:43:07 -0700 Subject: [PATCH] Add docker build job in manifest e2e workflow Signed-off-by: Yingchun Guo --- .github/workflows/image-build.yaml | 42 +++++++++++++++ .github/workflows/manifest-e2e.yaml | 18 +++++-- .github/workflows/scripts/build_push.sh | 72 +++++++++++++++++++++++++ ChatQnA/tests/test_manifest_on_xeon.sh | 36 +++++++++---- CodeGen/tests/test_manifest_on_xeon.sh | 8 +-- 5 files changed, 160 insertions(+), 16 deletions(-) create mode 100644 .github/workflows/image-build.yaml create mode 100755 .github/workflows/scripts/build_push.sh diff --git a/.github/workflows/image-build.yaml b/.github/workflows/image-build.yaml new file mode 100644 index 0000000000..6ac90f81e6 --- /dev/null +++ b/.github/workflows/image-build.yaml @@ -0,0 +1,42 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +name: Image Build +permissions: read-all +on: + workflow_call: + inputs: + image-repo: + required: false + type: string + image-tag: + required: true + type: string + mega-service: + required: true + type: string + runner_lable: + required: false + type: string + default: 'docker-build' + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-image-build + +jobs: + mega-image-build: + runs-on: ${{ inputs.runner_lable }} + steps: + - name: Checkout out Repo + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Building MegaService Docker Image + id: build-megaservice-image + env: + IMAGE_REPO: ${{ inputs.image-repo }} + IMAGE_TAG: ${{ inputs.image-tag }} + mega-service: ${{ inputs.mega-service }} + run: | + .github/workflows/scripts/build_push.sh ${{ env.mega-service}} diff --git a/.github/workflows/manifest-e2e.yaml b/.github/workflows/manifest-e2e.yaml index 7e152c0f8f..e641140bf4 100644 --- a/.github/workflows/manifest-e2e.yaml +++ b/.github/workflows/manifest-e2e.yaml @@ -57,9 +57,19 @@ jobs: run_matrix=$run_matrix"]}" echo "run_matrix=${run_matrix}" >> $GITHUB_OUTPUT - manifest-test: + mega-image-build: needs: job1 if: always() && ${{ needs.job1.outputs.run_matrix.include.length }} > 0 + strategy: + matrix: ${{ fromJSON(needs.job1.outputs.run_matrix) }} + uses: ./.github/workflows/image-build.yaml + with: + image-tag: ${{ github.event.pull_request.head.sha }} + mega-service: "${{ matrix.example }}" + + manifest-test: + needs: [job1, mega-image-build] + if: always() && ${{ needs.job1.outputs.run_matrix.include.length }} > 0 strategy: matrix: ${{ fromJSON(needs.job1.outputs.run_matrix) }} runs-on: ${{ matrix.hardware }} @@ -79,12 +89,14 @@ jobs: - name: Set variables run: | + echo "IMAGE_REPO=${OPEA_IMAGE_REPO}/" >> $GITHUB_ENV + echo "IMAGE_TAG=${{ github.event.pull_request.head.sha }}" >> $GITHUB_ENV lower_example=$(echo "${{ matrix.example }}" | tr '[:upper:]' '[:lower:]') echo "NAMESPACE=$lower_example-$(date +%Y%m%d%H%M%S)" >> $GITHUB_ENV echo "ROLLOUT_TIMEOUT_SECONDS=1800s" >> $GITHUB_ENV echo "KUBECTL_TIMEOUT_SECONDS=60s" >> $GITHUB_ENV echo "should_cleanup=false" >> $GITHUB_ENV - echo "skip_validate=false" >> $GITHUB_ENV + echo "skip_validate=true" >> $GITHUB_ENV echo "NAMESPACE=$NAMESPACE" - name: Initialize manifest testing @@ -100,9 +112,9 @@ jobs: echo "Testing ${{ matrix.example }}, waiting for pod ready..." if kubectl rollout status deployment --namespace "$NAMESPACE" --timeout "$ROLLOUT_TIMEOUT_SECONDS"; then echo "Testing manifests ${{ matrix.example }}, waiting for pod ready done!" + echo "skip_validate=false" >> $GITHUB_ENV else echo "Timeout waiting for pods in namespace $NAMESPACE to be ready!" - echo "skip_validate=true" >> $GITHUB_ENV exit 1 fi sleep 60 diff --git a/.github/workflows/scripts/build_push.sh b/.github/workflows/scripts/build_push.sh new file mode 100755 index 0000000000..4ce9c16a1b --- /dev/null +++ b/.github/workflows/scripts/build_push.sh @@ -0,0 +1,72 @@ +#!/bin/bash +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +set -xe + +IMAGE_REPO=${IMAGE_REPO:-$OPEA_IMAGE_REPO} +IMAGE_TAG=${IMAGE_TAG:-latest} + +function getImagenameFromMega() { + echo $(echo "$1" | tr '[:upper:]' '[:lower:]') +} + +function checkExist() { + IMAGE_NAME=$1 + if [ $(curl -X GET http://localhost:5000/v2/opea/${IMAGE_NAME}/tags/list | grep -c ${IMAGE_TAG}) -ne 0 ]; then + echo "true" + else + echo "false" + fi +} + +function docker_build() { + # check if if IMAGE_TAG is not "latest" and the image exists in the registry + if [ $IMAGE_TAG != "latest" && $(checkExist $1) == "true" ]; then + echo "Image ${IMAGE_REPO}opea/$1:$IMAGE_TAG already exists in the registry" + return + fi + # docker_build + if [ -z "$2" ]; then + DOCKERFILE_PATH=Dockerfile + else + DOCKERFILE_PATH=$2 + fi + echo "Building ${IMAGE_REPO}opea/$1:$IMAGE_TAG using Dockerfile $DOCKERFILE_PATH" + # if https_proxy and http_proxy are set, pass them to docker build + if [ -z "$https_proxy" ]; then + docker build --no-cache -t ${IMAGE_REPO}opea/$1:$IMAGE_TAG -f $DOCKERFILE_PATH . + else + docker build --no-cache -t ${IMAGE_REPO}opea/$1:$IMAGE_TAG --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f $DOCKERFILE_PATH . + fi + docker push ${IMAGE_REPO}opea/$1:$IMAGE_TAG + docker rmi ${IMAGE_REPO}opea/$1:$IMAGE_TAG +} + +# $1 is like "apple orange pear" +for MEGA_SVC in $1; do + case $MEGA_SVC in + "ChatQnA"|"CodeGen"|"CodeTrans"|"DocSum"|"SearchQnA") + cd $MEGA_SVC/docker + IMAGE_NAME="$(getImagenameFromMega $MEGA_SVC)" + docker_build ${IMAGE_NAME} + cd ui + docker_build ${IMAGE_NAME}-ui docker/Dockerfile + ;; + "AudioQnA") + #TBD + ;; + "SearchQnA") + #TBD + ;; + "Translation") + #TBD + ;; + "VisualQnA") + #TBD + ;; + *) + echo "Unknown function: $MEGA_SVC" + ;; + esac +done diff --git a/ChatQnA/tests/test_manifest_on_xeon.sh b/ChatQnA/tests/test_manifest_on_xeon.sh index 489dedeb10..058dabcb7a 100755 --- a/ChatQnA/tests/test_manifest_on_xeon.sh +++ b/ChatQnA/tests/test_manifest_on_xeon.sh @@ -6,15 +6,17 @@ set -xe USER_ID=$(whoami) LOG_PATH=/home/$(whoami)/logs MOUNT_DIR=/home/$USER_ID/charts-mnt -# IMAGE_REPO is $OPEA_IMAGE_REPO, or else "" -IMAGE_REPO=${OPEA_IMAGE_REPO:-amr-registry.caas.intel.com/aiops} +IMAGE_REPO=${IMAGE_REPO:-} +IMAGE_TAG=${IMAGE_TAG:-latest} function init_chatqna() { # executed under path manifest/chatqna/xeon # replace the mount dir "path: /mnt" with "path: $CHART_MOUNT" find . -name '*.yaml' -type f -exec sed -i "s#path: /mnt/models#path: $MOUNT_DIR#g" {} \; + # replace megaservice image tag + find . -name '*.yaml' -type f -exec sed -i "s#image: opea/chatqna:latest#image: opea/chatqna:${IMAGE_TAG}#g" {} \; # replace the repository "image: opea/*" with "image: $IMAGE_REPO/opea/" - find . -name '*.yaml' -type f -exec sed -i "s#image: opea/*#image: $IMAGE_REPO/opea/#g" {} \; + find . -name '*.yaml' -type f -exec sed -i "s#image: opea/*#image: ${IMAGE_REPO}opea/#g" {} \; # set huggingface token find . -name '*.yaml' -type f -exec sed -i "s#\${HUGGINGFACEHUB_API_TOKEN}#$(cat /home/$USER_ID/.cache/huggingface/token)#g" {} \; } @@ -32,15 +34,29 @@ function install_chatqna { } function validate_chatqna() { + max_retry=20 # make sure microservice retriever is ready - until curl http://retriever-svc.$NAMESPACE:7000/v1/retrieval -X POST \ - -d '{"text":"What is the revenue of Nike in 2023?","embedding":"'"${your_embedding}"'"}' \ - -H 'Content-Type: application/json'; do sleep 10; done - + # try to curl retriever-svc for max_retry times + for ((i=1; i<=max_retry; i++)) + do + curl http://retriever-svc.$NAMESPACE:7000/v1/retrieval -X POST \ + -d '{"text":"What is the revenue of Nike in 2023?","embedding":"'"${your_embedding}"'"}' \ + -H 'Content-Type: application/json' && break + sleep 10 + done # make sure microservice tgi-svc is ready - until curl http://tgi-svc.$NAMESPACE:9009/generate -X POST \ - -d '{"inputs":"What is Deep Learning?","parameters":{"max_new_tokens":17, "do_sample": true}}' \ - -H 'Content-Type: application/json'; do sleep 10; done + for ((i=1; i<=max_retry; i++)) + do + curl http://tgi-svc.$NAMESPACE:9009/generate -X POST \ + -d '{"inputs":"What is Deep Learning?","parameters":{"max_new_tokens":17, "do_sample": true}}' \ + -H 'Content-Type: application/json' && break + sleep 10 + done + # if i is bigger than max_retry, then exit with error + if [ $i -gt $max_retry ]; then + echo "Microservice failed, exit with error." + exit 1 + fi # check megaservice works # generate a random logfile name to avoid conflict among multiple runners diff --git a/CodeGen/tests/test_manifest_on_xeon.sh b/CodeGen/tests/test_manifest_on_xeon.sh index ffc71d5b7c..09a507c65f 100755 --- a/CodeGen/tests/test_manifest_on_xeon.sh +++ b/CodeGen/tests/test_manifest_on_xeon.sh @@ -6,15 +6,17 @@ set -xe USER_ID=$(whoami) LOG_PATH=/home/$(whoami)/logs MOUNT_DIR=/home/$USER_ID/charts-mnt -# IMAGE_REPO is $OPEA_IMAGE_REPO, or else "" -IMAGE_REPO=${OPEA_IMAGE_REPO:-amr-registry.caas.intel.com/aiops} +IMAGE_REPO=${IMAGE_REPO:-} +IMAGE_TAG=${IMAGE_TAG:-latest} function init_codegen() { # executed under path manifest/codegen/xeon # replace the mount dir "path: /mnt/model" with "path: $CHART_MOUNT" find . -name '*.yaml' -type f -exec sed -i "s#path: /mnt#path: $MOUNT_DIR#g" {} \; + # replace megaservice image tag + find . -name '*.yaml' -type f -exec sed -i "s#image: opea/codegen:latest#image: opea/codegen:${IMAGE_TAG}#g" {} \; # replace the repository "image: opea/*" with "image: $IMAGE_REPO/opea/" - find . -name '*.yaml' -type f -exec sed -i "s#image: \"opea/*#image: \"$IMAGE_REPO/opea/#g" {} \; + find . -name '*.yaml' -type f -exec sed -i "s#image: \"opea/*#image: \"${IMAGE_REPO}opea/#g" {} \; # set huggingface token find . -name '*.yaml' -type f -exec sed -i "s#insert-your-huggingface-token-here#$(cat /home/$USER_ID/.cache/huggingface/token)#g" {} \; }