diff --git a/helm-charts/codegen-openshift-rhoai/Chart.yaml b/helm-charts/codegen-openshift-rhoai/Chart.yaml new file mode 100644 index 000000000..5f85bcc99 --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/Chart.yaml @@ -0,0 +1,15 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: v2 +name: codegen +description: A Helm chart for deploying codegen on Red Hat OpenShift with Red Hat OpenShift AI +dependencies: + - name: llm-uservice + version: 1.0.0 + repository: "file://llm-uservice" + - name: react-ui + version: 0.1.0 + repository: "file://react-ui" +type: application +version: 1.0.0 diff --git a/helm-charts/codegen-openshift-rhoai/README.md b/helm-charts/codegen-openshift-rhoai/README.md new file mode 100644 index 000000000..90394f2ff --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/README.md @@ -0,0 +1,124 @@ +# CodeGen + +Helm chart for deploying CodeGen service on Red Hat OpenShift with Red Hat OpenShift AI. + +Serving runtime template in this example uses model _ise-uiuc/Magicoder-S-DS-6.7B_ for Xeon and _meta-llama/CodeLlama-7b-hf_ for Gaudi. + +## Prerequisites + +1. **Red Hat OpenShift Cluster** with dynamic _StorageClass_ to provision _PersistentVolumes_ e.g. **OpenShift Data Foundation**) and installed Operators: **Red Hat - Authorino (Technical Preview)**, **Red Hat OpenShift Service Mesh**, **Red Hat OpenShift Serverless** and **Red Hat Openshift AI**. +2. Image registry to push there docker images (https://docs.openshift.com/container-platform/4.16/registry/securing-exposing-registry.html). +3. Access to S3-compatible object storage bucket (e.g. **OpenShift Data Foundation**, **AWS S3**) and values of access and secret access keys and S3 endpoint (https://docs.redhat.com/en/documentation/red_hat_openshift_data_foundation/4.16/html/managing_hybrid_and_multicloud_resources/accessing-the-multicloud-object-gateway-with-your-applications_rhodf#accessing-the-multicloud-object-gateway-with-your-applications_rhodf). +4. Account on https://huggingface.co/, access to model _ise-uiuc/Magicoder-S-DS-6.7B_ (for Xeon) or _meta-llama/CodeLlama-7b-hf_ (for Gaudi) and token with Read permissions. + +## Deploy model in Red Hat Openshift AI + +1. Login to OpenShift CLI and run following commands to create new serving runtime and _hf-token_ secret. + +``` +cd GenAIInfra/helm-charts/codegen-openshift-rhoai/ +export HFTOKEN="insert-your-huggingface-token-here" + +On Xeon: +helm install servingruntime tgi --set global.huggingfacehubApiToken=${HFTOKEN} + +On Gaudi: +helm install servingruntime tgi --set global.huggingfacehubApiToken=${HFTOKEN} --values tgi/gaudi-values.yaml +``` + +Verify if template has been created with `oc get template -n redhat-ods-applications` command. + +2. Find the route for **Red Hat OpenShift AI** dashboard with below command and open it in the browser: + +``` +oc get routes -A | grep rhods-dashboard +``` + +3. Go to **Data Science Project** and click **Create data science project**. Fill the **Name** and click **Create**. +4. Go to **Workbenches** tab and click **Create workbench**. Fill the **Name**, under **Notebook image** choose _Standard Data Science_, under **Cluster storage** choose _Create new persistent storage_ and change **Persistent storage size** to 40 GB. Click **Create workbench**. +5. Open newly created Jupiter notebook and run following commands to download the model and upload it on s3: + +``` +%env S3_ENDPOINT= +%env S3_ACCESS_KEY= +%env S3_SECRET_KEY= +%env HF_TOKEN= +``` + +``` +!pip install huggingface-hub +``` + +``` +import os +import boto3 +import botocore +import glob +from huggingface_hub import snapshot_download +bucket_name = 'first.bucket' +s3_endpoint = os.environ.get('S3_ENDPOINT') +s3_accesskey = os.environ.get('S3_ACCESS_KEY') +s3_secretkey = os.environ.get('S3_SECRET_KEY') +path = 'models' +hf_token = os.environ.get('HF_TOKEN') +session = boto3.session.Session() +s3_resource = session.resource('s3', + endpoint_url=s3_endpoint, + verify=False, + aws_access_key_id=s3_accesskey, + aws_secret_access_key=s3_secretkey) +bucket = s3_resource.Bucket(bucket_name) +``` + +For Xeon download _ise-uiuc/Magicoder-S-DS-6.7B_: + +``` +snapshot_download("ise-uiuc/Magicoder-S-DS-6.7B", cache_dir=f'./models', token=hf_token) +``` + +For Gaudi download _meta-llama/CodeLlama-7b-hf_: + +``` +snapshot_download("meta-llama/CodeLlama-7b-hf", cache_dir=f'./models', token=hf_token) +``` + +Upload the downloaded model to S3: + +``` +files = (file for file in glob.glob(f'{path}/**/*', recursive=True) if os.path.isfile(file) and "snapshots" in file) +for filename in files: + s3_name = filename.replace(path, '') + print(f'Uploading: {filename} to {path}{s3_name}') + bucket.upload_file(filename, f'{path}{s3_name}') +``` + +6. Go to your project in **Red Hat OpenShift AI** dashboard, then "Models" tab and click **Deploy model** under _Single-model serving platform_. Fill the **Name**, choose newly created **Serving runtime**: _Text Generation Inference Magicoder-S-DS-6.7B on CPU_ (for Xeon) or _Text Generation Inference CodeLlama-7b-hf on Gaudi_ (for Gaudi), **Model framework**: _llm_ and change **Model server size** to _Custom_: 16 CPUs and 64 Gi memory. For deployment with Gaudi select proper **Accelerator**. Click the checkbox to create external route in **Model route** section and uncheck the **Token authentication**. Under **Model location** choose _New data connection_ and fill all required fields for s3 access, **Bucket** _first.bucket_ and **Path**: _models_. Click **Deploy**. It takes about 10 minutes to get _Loaded_ status.\ + If it's not going to _Loaded_ status and revision changed status to "ProgressDeadlineExceeded" (`oc get revision`), scale model deployment to 0 and than to 1 with command `oc scale deployment.apps/ --replicas=1` and wait about 10 minutes for deployment. + +## Install the Chart + +To install the chart, back to OpenShift CLI, go to your project and run the following: + +```console +cd GenAIInfra/helm-charts/ + +export NAMESPACE="insert-your-namespace-here" +export CLUSTERDOMAIN="$(oc get Ingress.config.openshift.io/cluster -o jsonpath='{.spec.domain}' | sed 's/^apps.//')" +export MODELNAME="insert-name-of-deployed-model-here" (it refers to the *Name* from step 6 in **Deploy model in Red Hat Openshift AI**) +export PROJECT="insert-project-name-where-model-is-deployed" + +sed -i "s/insert-your-namespace-here/${NAMESPACE}/g" codegen-openshift-rhoai/llm-uservice/values.yaml + +./update_dependency.sh +helm dependency update codegen-openshift-rhoai + +helm install codegen codegen-openshift-rhoai --set image.repository=image-registry.openshift-image-registry.svc:5000/${NAMESPACE}/codegen --set llm-uservice.image.repository=image-registry.openshift-image-registry.svc:5000/${NAMESPACE}/llm-tgi --set react-ui.image.repository=image-registry.openshift-image-registry.svc:5000/${NAMESPACE}/react-ui --set global.clusterDomain=${CLUSTERDOMAIN} --set global.huggingfacehubApiToken=${HFTOKEN} --set llm-uservice.servingRuntime.name=${MODELNAME} --set llm-uservice.servingRuntime.namespace=${PROJECT} +``` + +## Verify + +To verify the installation, run the command `oc get pods` to make sure all pods are running. Wait about 5 minutes for building images. When 4 pods achieve _Completed_ status, the rest with services should go to _Running_. + +## Launch the UI + +To access the frontend, find the route for _react-ui_ with command `oc get routes` and open it in the browser. diff --git a/helm-charts/codegen-openshift-rhoai/llm-uservice/Chart.yaml b/helm-charts/codegen-openshift-rhoai/llm-uservice/Chart.yaml new file mode 100644 index 000000000..10178e8ce --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/llm-uservice/Chart.yaml @@ -0,0 +1,8 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: v2 +name: llm-uservice +description: A Helm chart for deploying llm-uservice on Red Hat OpenShift with Red Hat OpenShift AI +type: application +version: 1.0.0 diff --git a/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/_helpers.tpl b/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/_helpers.tpl new file mode 100644 index 000000000..726fca204 --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "llm-uservice.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "llm-uservice.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "llm-uservice.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "llm-uservice.labels" -}} +helm.sh/chart: {{ include "llm-uservice.chart" . }} +{{ include "llm-uservice.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "llm-uservice.selectorLabels" -}} +app.kubernetes.io/name: {{ include "llm-uservice.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/buildconfig.yaml b/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/buildconfig.yaml new file mode 100644 index 000000000..9b3d0631d --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/buildconfig.yaml @@ -0,0 +1,30 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +kind: BuildConfig +apiVersion: build.openshift.io/v1 +metadata: + name: {{ include "llm-uservice.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + output: + to: + kind: "ImageStreamTag" + name: "llm-tgi:latest" + failedBuildsHistoryLimit: 5 + successfulBuildsHistoryLimit: 5 + nodeSelector: null + postCommit: {} + resources: {} + runPolicy: SerialLatestOnly + source: + git: + ref: {{ .Values.source.gitRef }} + uri: {{ .Values.source.gitUri }} + type: {{ .Values.source.type }} + strategy: + type: {{ .Values.strategy.type }} + dockerStrategy: + dockerfilePath: {{ .Values.strategy.dockerfilePath }} + triggers: + - type: ConfigChange diff --git a/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/configmap.yaml b/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/configmap.yaml new file mode 100644 index 000000000..b8097cf47 --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/configmap.yaml @@ -0,0 +1,17 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: v1 +kind: ConfigMap +metadata: + name: create-rhoai-istio-rootca-cert-secret +data: + create-rhoai-istio-rootca-cert-secret.sh: | + #!/bin/bash + EXISTS=$(oc get secret --ignore-not-found rhoai-ca-bundle) + + if [[ -z "${EXISTS}" ]]; then + oc create secret generic -n {{ .Release.Namespace }} rhoai-ca-bundle --from-literal=tls.crt="$(oc extract secret/knative-serving-cert -n istio-system --to=- --keys=tls.crt)" + else + echo "oc get secret --ignore-not-found rhoai-ca-bundle returned non-empty string, not creating a secret" + fi diff --git a/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/deployment.yaml b/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/deployment.yaml new file mode 100644 index 000000000..17fb4e465 --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/deployment.yaml @@ -0,0 +1,66 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "llm-uservice.fullname" . }} + labels: + {{- include "llm-uservice.labels" . | nindent 4 }} + annotations: + image.openshift.io/triggers: '[{"from":{"kind":"ImageStreamTag","name":"llm-tgi:latest"},"fieldPath":"spec.template.spec.containers[?(@.name==\"codegen\")].image"}]' +spec: + replicas: 1 + selector: + matchLabels: + {{- include "llm-uservice.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "llm-uservice.selectorLabels" . | nindent 8 }} + spec: + securityContext: {} + containers: + - name: {{ .Release.Name }} + command: + - /bin/bash + - -c + - | + cp /usr/lib/ssl/cert.pem /tmp/bundle.crt && \ + cat /rhoai-ca/tls.crt | tee -a '/tmp/bundle.crt' && \ + bash ./entrypoint.sh + env: + - name: TGI_LLM_ENDPOINT + value: "https://{{ .Values.servingRuntime.name }}-{{ .Values.servingRuntime.namespace }}.apps.{{ .Values.global.clusterDomain }}" + - name: HUGGINGFACEHUB_API_TOKEN + valueFrom: + secretKeyRef: + key: HUGGING_FACE_HUB_TOKEN + name: hf-token + - name: PYTHONPATH + value: {{ .Values.PYTHONPATH | quote }} + - name: HOME + value: {{ .Values.HOME | quote }} + - name: SSL_CERT_FILE + value: /tmp/bundle.crt + securityContext: {} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: llm-uservice + containerPort: 9000 + protocol: TCP + volumeMounts: + - mountPath: /tmp/home + name: local-dir + - mountPath: /rhoai-ca + name: odh-ca-bundle + resources: {} + volumes: + - emptyDir: + sizeLimit: 5Gi + name: local-dir + - name: odh-ca-bundle + secret: + defaultMode: 420 + secretName: rhoai-ca-bundle diff --git a/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/imagestream.yaml b/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/imagestream.yaml new file mode 100644 index 000000000..781e85ef7 --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/imagestream.yaml @@ -0,0 +1,12 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +--- +apiVersion: image.openshift.io/v1 +kind: ImageStream +metadata: + name: llm-tgi + namespace: {{ .Release.Namespace }} +spec: + lookupPolicy: + local: true diff --git a/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/job.yaml b/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/job.yaml new file mode 100644 index 000000000..1effabdd6 --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/job.yaml @@ -0,0 +1,34 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: batch/v1 +kind: Job +metadata: + name: create-rhoai-istio-rootca-cert-secret +spec: + template: + spec: + containers: + - image: {{ .Values.job.image }} + command: + - /bin/bash + - -c + - | + oc wait --for=condition=ReconcileComplete=True dsc/rhods-datasciencecluster --timeout=-1s + oc wait --for condition=Ready=True knativeserving -n knative-serving knative-serving --timeout=-1s + '/tmp/create-rhoai-istio-rootca-cert-secret.sh' + name: create-rhoai-istio-rootca-cert-secret + volumeMounts: + - mountPath: /tmp/create-rhoai-istio-rootca-cert-secret.sh + name: create-rhoai-istio-rootca-cert-secret + subPath: create-rhoai-istio-rootca-cert-secret.sh + volumes: + - name: create-rhoai-istio-rootca-cert-secret + configMap: + name: create-rhoai-istio-rootca-cert-secret + defaultMode: 0755 + dnsPolicy: ClusterFirst + restartPolicy: Never + serviceAccount: {{ .Values.serviceAccountName }} + serviceAccountName: {{ .Values.serviceAccountName }} + terminationGracePeriodSeconds: 400 diff --git a/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/rbac/crb-rhoai.yaml b/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/rbac/crb-rhoai.yaml new file mode 100644 index 000000000..5bebaacbc --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/rbac/crb-rhoai.yaml @@ -0,0 +1,15 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: kubeadmin-rhoai-cluster-admin-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-admin +subjects: +- kind: User + apiGroup: rbac.authorization.k8s.io + name: 'kube:admin' diff --git a/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/rbac/role.yaml b/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/rbac/role.yaml new file mode 100644 index 000000000..f02d4ac8f --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/rbac/role.yaml @@ -0,0 +1,31 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +{{- range $key, $value := .Values.rbac.roles }} +{{- if $value.createRole }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +{{- if $value.scope.cluster }} +kind: ClusterRole +metadata: + name: {{ .name }} +{{- else }} +kind: Role +metadata: + name: {{ $value.name }} +{{- end }} +rules: + - apiGroups: +{{- range $value.apiGroups }} + - {{ . }} +{{- end }} + resources: +{{- range $value.resources }} + - {{ . }} +{{- end }} + verbs: +{{- range $value.verbs }} + - {{ . }} +{{- end }} +{{- end }} +{{- end }} diff --git a/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/rbac/rolebinding.yaml b/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/rbac/rolebinding.yaml new file mode 100644 index 000000000..4a973dff4 --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/rbac/rolebinding.yaml @@ -0,0 +1,28 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +{{- range $key, $value := .Values.rbac.roleBindings }} +{{- if $value.createBinding }} +apiVersion: rbac.authorization.k8s.io/v1 +{{- if $value.scope.cluster }} +kind: ClusterRoleBinding +{{- else }} +kind: RoleBinding +{{- end }} +metadata: + name: {{ .name }} +{{- if eq $value.scope.cluster false }} + namespace: {{ $value.scope.namespace }} +{{- end }} +subjects: +- kind: {{ $value.subjects.kind | default "ServiceAccount" }} + name: {{ $value.subjects.name }} + namespace: {{ $value.subjects.namespace }} + apiGroup: "" +roleRef: + kind: {{ $value.roleRef.kind }} + name: {{ $value.roleRef.name }} + apiGroup: rbac.authorization.k8s.io +--- +{{- end }} +{{- end }} diff --git a/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/rbac/serviceAccount.yaml b/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/rbac/serviceAccount.yaml new file mode 100644 index 000000000..2d0088e91 --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/rbac/serviceAccount.yaml @@ -0,0 +1,7 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.serviceAccountName }} diff --git a/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/service.yaml b/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/service.yaml new file mode 100644 index 000000000..06e13b8c6 --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/llm-uservice/templates/service.yaml @@ -0,0 +1,18 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: v1 +kind: Service +metadata: + name: {{ include "llm-uservice.fullname" . }} + labels: + {{- include "llm-uservice.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: 9000 + protocol: TCP + name: llm-uservice + selector: + {{- include "llm-uservice.selectorLabels" . | nindent 4 }} diff --git a/helm-charts/codegen-openshift-rhoai/llm-uservice/values.yaml b/helm-charts/codegen-openshift-rhoai/llm-uservice/values.yaml new file mode 100644 index 000000000..77c851cde --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/llm-uservice/values.yaml @@ -0,0 +1,86 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +image: + repository: "insert-your-image-here" # image-registry.openshift-image-registry.svc:5000//llm-tgi + tag: "latest" + pullPolicy: IfNotPresent + +source: + gitRef: main + gitUri: https://github.com/opea-project/GenAIComps.git + type: Git + +strategy: + type: Docker + dockerfilePath: comps/llms/text-generation/tgi/Dockerfile + +replicaCount: 1 + +PYTHONPATH: /home/user/.local/lib/python3.11/site-packages:/home/user # don't edit unless you have a good reason +HOME: /tmp/home + +service: + type: ClusterIP + port: 9000 + +servingRuntime: + name: "insert-name-of-deployed-model-here" + namespace: "insert-project-name-where-model-is-deployed" + +global: + clusterDomain: "insert-your-cluster-domain-here" + +job: + image: image-registry.openshift-image-registry.svc:5000/openshift/cli:latest + +serviceAccountName: codegen-sa + +rbac: + roles: + - name: codegen-rhoai-role + createRole: true + apiGroups: + - '""' + - '"apps"' + - '"batch"' + - '"machineconfiguration.openshift.io"' + - '"rbac.authorization.k8s.io"' + - '"security.openshift.io"' + - '"datasciencecluster.opendatahub.io"' + - '"operator.knative.dev"' + - '"build.openshift.io"' + scope: + cluster: true + resources: + - namespaces + - secrets + - datascienceclusters + - clusterrolebindings + - knativeservings + - jobs + - buildconfigs + - builds + - buildconfigs/instantiate + verbs: + - "create" + - "get" + - "list" + - "patch" + - "update" + - "use" + - "watch" + roleBindings: + - name: codegen-rhoai-rolebind + createBinding: true + scope: + cluster: true + namespace: "" + subjects: + kind: ServiceAccount + name: codegen-sa + namespace: insert-your-namespace-here + apiGroup: "" + roleRef: + kind: ClusterRole + name: codegen-rhoai-role diff --git a/helm-charts/codegen-openshift-rhoai/react-ui/.helmignore b/helm-charts/codegen-openshift-rhoai/react-ui/.helmignore new file mode 100644 index 000000000..0e8a0eb36 --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/react-ui/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm-charts/codegen-openshift-rhoai/react-ui/Chart.yaml b/helm-charts/codegen-openshift-rhoai/react-ui/Chart.yaml new file mode 100644 index 000000000..bd518d6c0 --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/react-ui/Chart.yaml @@ -0,0 +1,27 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: v2 +name: react-ui +description: A Helm chart deploying OPEA CodeGen React UI + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.0" diff --git a/helm-charts/codegen-openshift-rhoai/react-ui/templates/NOTES.txt b/helm-charts/codegen-openshift-rhoai/react-ui/templates/NOTES.txt new file mode 100644 index 000000000..027640017 --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/react-ui/templates/NOTES.txt @@ -0,0 +1,2 @@ +1. Get the application URL by running this command or opening OpenShift Console apps. +oc get route -n {{ .Release.Namespace }} {{ include "codegen-react-ui.fullname" . }} diff --git a/helm-charts/codegen-openshift-rhoai/react-ui/templates/_helpers.tpl b/helm-charts/codegen-openshift-rhoai/react-ui/templates/_helpers.tpl new file mode 100644 index 000000000..ca8230902 --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/react-ui/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "codegen-react-ui.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "codegen-react-ui.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "codegen-react-ui.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "codegen-react-ui.labels" -}} +helm.sh/chart: {{ include "codegen-react-ui.chart" . }} +{{ include "codegen-react-ui.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "codegen-react-ui.selectorLabels" -}} +app.kubernetes.io/name: {{ include "codegen-react-ui.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/helm-charts/codegen-openshift-rhoai/react-ui/templates/codegen-react-ui-bc.yaml b/helm-charts/codegen-openshift-rhoai/react-ui/templates/codegen-react-ui-bc.yaml new file mode 100644 index 000000000..dc487b8be --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/react-ui/templates/codegen-react-ui-bc.yaml @@ -0,0 +1,42 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +--- +apiVersion: image.openshift.io/v1 +kind: ImageStream +metadata: + name: react-ui +spec: + lookupPolicy: + local: true +--- +kind: BuildConfig +apiVersion: build.openshift.io/v1 +metadata: + name: react-ui +spec: + output: + to: + kind: "ImageStreamTag" + name: "react-ui:{{ .Values.image.tag }}" + failedBuildsHistoryLimit: 5 + successfulBuildsHistoryLimit: 5 + nodeSelector: null + postCommit: {} + resources: {} + runPolicy: SerialLatestOnly + source: + contextDir: {{ .Values.source.contextDir }} + git: + ref: {{ .Values.source.gitRef }} + uri: {{ .Values.source.gitUri }} + type: {{ .Values.source.type }} + strategy: + type: {{ .Values.strategy.type }} + dockerStrategy: + env: + - name: VITE_CODE_GEN_URL + value: https://codegen-react-ui-{{ .Release.Namespace }}.apps.{{ .Values.global.clusterDomain }}/v1/codegen + dockerfilePath: {{ .Values.strategy.dockerfilePath }} + triggers: + - type: ConfigChange diff --git a/helm-charts/codegen-openshift-rhoai/react-ui/templates/codegen-react-ui-cms.yaml b/helm-charts/codegen-openshift-rhoai/react-ui/templates/codegen-react-ui-cms.yaml new file mode 100644 index 000000000..fa68f3586 --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/react-ui/templates/codegen-react-ui-cms.yaml @@ -0,0 +1,55 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +--- +apiVersion: v1 +data: + default.conf: | + server { + listen 8080; + gzip on; + gzip_proxied any; + gzip_comp_level 6; + gzip_buffers 16 8k; + gzip_http_version 1.1; + gzip_types font/woff2 text/css application/javascript application/json application/font-woff application/font-tff image/gif image/png image/svg+xml application/octet-stream; + location / { + root /usr/share/nginx/html; + index index.html index.htm; + try_files $uri $uri/ /index.html =404; + location ~* \.(gif|jpe?g|png|webp|ico|svg|css|js|mp4|woff2)$ { + expires 1d; + } + } + } +kind: ConfigMap +metadata: + creationTimestamp: null + name: {{ include "codegen-react-ui.fullname" . }}-default-conf +--- +apiVersion: v1 +data: + nginx.conf: | + user nginx; + worker_processes auto; + error_log /var/log/nginx/error.log notice; + pid /tmp/nginx.pid; + events { + worker_connections 1024; + } + http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + access_log /var/log/nginx/access.log main; + sendfile on; + #tcp_nopush on; + keepalive_timeout 65; + #gzip on; + include /etc/nginx/conf.d/*.conf; + } +kind: ConfigMap +metadata: + name: {{ include "codegen-react-ui.fullname" . }}-nginx-conf diff --git a/helm-charts/codegen-openshift-rhoai/react-ui/templates/codegen-react-ui-consolelink.yaml b/helm-charts/codegen-openshift-rhoai/react-ui/templates/codegen-react-ui-consolelink.yaml new file mode 100644 index 000000000..d01a0925a --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/react-ui/templates/codegen-react-ui-consolelink.yaml @@ -0,0 +1,15 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: console.openshift.io/v1 +kind: ConsoleLink +metadata: + name: {{ include "codegen-react-ui.fullname" . }}-{{ randAlphaNum 12 | lower }} +spec: + href: https://codegen-react-ui-{{ .Release.Namespace }}.apps.{{ .Values.global.clusterDomain }} + location: ApplicationMenu + # This text will appear in a box called "Launcher" under "namespace" or "project" in the web console + text: OPEA CodeGen UI + applicationMenu: + section: Open Platform For Enterprise AI + imageURL: data:image/png;base64,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 diff --git a/helm-charts/codegen-openshift-rhoai/react-ui/templates/codegen-react-ui-deployment.yaml b/helm-charts/codegen-openshift-rhoai/react-ui/templates/codegen-react-ui-deployment.yaml new file mode 100644 index 000000000..8d428a3b5 --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/react-ui/templates/codegen-react-ui-deployment.yaml @@ -0,0 +1,85 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "codegen-react-ui.fullname" . }} + labels: + {{- include "codegen-react-ui.labels" . | nindent 4 }} + annotations: + image.openshift.io/triggers: '[{"from":{"kind":"ImageStreamTag","name":"react-ui:{{ .Values.image.tag }}"},"fieldPath":"spec.template.spec.containers[?(@.name==\"{{ .Chart.Name }}\")].image"}]' +spec: + selector: + matchLabels: + {{- include "codegen-react-ui.selectorLabels" . | nindent 8 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "codegen-react-ui.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - command: ["/bin/sh", "-c"] + args: + - | + cp -v /etc/nginx/nginx.conf /tmp/nginx.conf && \ + sed -i "s/pid .*;/pid \/tmp\/nginx.pid;/" /tmp/nginx.conf && \ + nginx -c /tmp/nginx.conf -g "daemon off;" + image: {{ .Values.image.repository }}:{{ .Values.image.tag }} + name: {{ .Chart.Name }} + ports: + - name: http + containerPort: {{ .Values.service.port }} + protocol: TCP + livenessProbe: + httpGet: + path: / + port: http + readinessProbe: + httpGet: + path: / + port: http + resources: + {{- toYaml .Values.resources | nindent 10 }} + securityContext: + {{- toYaml .Values.securityContext | nindent 10 }} + volumeMounts: + - mountPath: /var/cache/nginx/ + name: nginx-cache-dir + - mountPath: /etc/nginx/conf.d/default.conf + name: default-conf + subPath: default.conf + - mountPath: /etc/nginx/nginx.conf + name: nginx-conf + subPath: nginx.conf + volumes: + - name: nginx-cache-dir + emptyDir: {} + - name: default-conf + configMap: + name: {{ include "codegen-react-ui.fullname" . }}-default-conf + - name: nginx-conf + configMap: + name: {{ include "codegen-react-ui.fullname" . }}-nginx-conf + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/helm-charts/codegen-openshift-rhoai/react-ui/templates/codegen-react-ui-https-route.yaml b/helm-charts/codegen-openshift-rhoai/react-ui/templates/codegen-react-ui-https-route.yaml new file mode 100644 index 000000000..09ff5e8f4 --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/react-ui/templates/codegen-react-ui-https-route.yaml @@ -0,0 +1,17 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +--- +apiVersion: route.openshift.io/v1 +kind: Route +metadata: + labels: + {{- include "codegen-react-ui.selectorLabels" . | nindent 8 }} + name: {{ include "codegen-react-ui.fullname" . }} +spec: + host: codegen-react-ui-{{ .Release.Namespace }}.apps.{{ .Values.global.clusterDomain }} + tls: + termination: edge + to: + name: {{ include "codegen-react-ui.fullname" . }} +status: {} diff --git a/helm-charts/codegen-openshift-rhoai/react-ui/templates/codegen-react-ui-service.yaml b/helm-charts/codegen-openshift-rhoai/react-ui/templates/codegen-react-ui-service.yaml new file mode 100644 index 000000000..c8741bf95 --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/react-ui/templates/codegen-react-ui-service.yaml @@ -0,0 +1,19 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "codegen-react-ui.fullname" . }} + labels: + {{- include "codegen-react-ui.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "codegen-react-ui.selectorLabels" . | nindent 4 }} diff --git a/helm-charts/codegen-openshift-rhoai/react-ui/values.yaml b/helm-charts/codegen-openshift-rhoai/react-ui/values.yaml new file mode 100644 index 000000000..a267d3691 --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/react-ui/values.yaml @@ -0,0 +1,67 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +# Default values for codegen-react-ui. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +global: + clusterDomain: "insert-your-cluster-domain-here" + +image: + repository: "insert-your-image-here" # image-registry.openshift-image-registry.svc:5000//react-ui + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + +source: + contextDir: CodeGen/ui + gitRef: main + gitUri: "https://github.com/opea-project/GenAIExamples.git" + type: Git + +strategy: + type: Docker + dockerfilePath: docker/Dockerfile.react + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + port: 8080 + +resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: {} + +tolerations: [] + +affinity: {} diff --git a/helm-charts/codegen-openshift-rhoai/templates/_helpers.tpl b/helm-charts/codegen-openshift-rhoai/templates/_helpers.tpl new file mode 100644 index 000000000..7cffcef8d --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "codegen.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "codegen.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "codegen.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "codegen.labels" -}} +helm.sh/chart: {{ include "codegen.chart" . }} +{{ include "codegen.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "codegen.selectorLabels" -}} +app.kubernetes.io/name: {{ include "codegen.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/helm-charts/codegen-openshift-rhoai/templates/buildconfig.yaml b/helm-charts/codegen-openshift-rhoai/templates/buildconfig.yaml new file mode 100644 index 000000000..dc9790cd3 --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/templates/buildconfig.yaml @@ -0,0 +1,31 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +kind: BuildConfig +apiVersion: build.openshift.io/v1 +metadata: + name: {{ include "codegen.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + output: + to: + kind: "ImageStreamTag" + name: "codegen:latest" + failedBuildsHistoryLimit: 5 + successfulBuildsHistoryLimit: 5 + nodeSelector: null + postCommit: {} + resources: {} + runPolicy: SerialLatestOnly + source: + contextDir: {{ .Values.source.contextDir }} + git: + ref: {{ .Values.source.gitRef }} + uri: {{ .Values.source.gitUri }} + type: {{ .Values.source.type }} + strategy: + type: {{ .Values.strategy.type }} + dockerStrategy: + dockerfilePath: {{ .Values.strategy.dockerfilePath }} + triggers: + - type: ConfigChange diff --git a/helm-charts/codegen-openshift-rhoai/templates/deployment.yaml b/helm-charts/codegen-openshift-rhoai/templates/deployment.yaml new file mode 100644 index 000000000..88c90c8bb --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/templates/deployment.yaml @@ -0,0 +1,31 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "codegen.fullname" . }} + labels: + {{- include "codegen.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "codegen.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "codegen.selectorLabels" . | nindent 8 }} + spec: + containers: + - name: {{ .Release.Name }} + env: + - name: LLM_SERVICE_HOST_IP + value: {{ .Release.Name }}-llm-uservice + securityContext: null + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: codegen + containerPort: {{ .Values.port }} + protocol: TCP diff --git a/helm-charts/codegen-openshift-rhoai/templates/imagestream.yaml b/helm-charts/codegen-openshift-rhoai/templates/imagestream.yaml new file mode 100644 index 000000000..75b7907bb --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/templates/imagestream.yaml @@ -0,0 +1,12 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +--- +apiVersion: image.openshift.io/v1 +kind: ImageStream +metadata: + name: codegen + namespace: {{ .Release.Namespace }} +spec: + lookupPolicy: + local: true diff --git a/helm-charts/codegen-openshift-rhoai/templates/route.yaml b/helm-charts/codegen-openshift-rhoai/templates/route.yaml new file mode 100644 index 000000000..6791c88c7 --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/templates/route.yaml @@ -0,0 +1,21 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: route.openshift.io/v1 +kind: Route +metadata: + labels: + {{- include "codegen.labels" . | nindent 4 }} + name: {{ .Release.Name }}-tls +spec: + host: codegen-react-ui-{{ .Release.Namespace }}.apps.{{ .Values.global.clusterDomain }} + path: /v1/codegen + port: + targetPort: codegen + tls: + termination: edge + to: + kind: Service + name: codegen + weight: 100 + wildcardPolicy: None diff --git a/helm-charts/codegen-openshift-rhoai/templates/service.yaml b/helm-charts/codegen-openshift-rhoai/templates/service.yaml new file mode 100644 index 000000000..aec13682f --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/templates/service.yaml @@ -0,0 +1,18 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: v1 +kind: Service +metadata: + name: {{ include "codegen.fullname" . }} + labels: + {{- include "codegen.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: {{ .Values.port }} + protocol: TCP + name: codegen + selector: + {{- include "codegen.selectorLabels" . | nindent 4 }} diff --git a/helm-charts/codegen-openshift-rhoai/tgi/Chart.yaml b/helm-charts/codegen-openshift-rhoai/tgi/Chart.yaml new file mode 100644 index 000000000..b510ea0e1 --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/tgi/Chart.yaml @@ -0,0 +1,8 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: v2 +name: tgi +description: A Helm chart for deploying servingruntime for ise-uiuc/Magicoder-S-DS-6.7B model on Red Hat OpenShift with Red Hat OpenShift AI +type: application +version: 1.0.0 diff --git a/helm-charts/codegen-openshift-rhoai/tgi/gaudi-values.yaml b/helm-charts/codegen-openshift-rhoai/tgi/gaudi-values.yaml new file mode 100644 index 000000000..651ca99c6 --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/tgi/gaudi-values.yaml @@ -0,0 +1,44 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +global: + huggingfacehubApiToken: "insert-your-huggingface-token-here" + +image: + repository: ghcr.io/huggingface/tgi-gaudi + tag: 2.0.4 + +servingRuntimeName: tgi-codellama-7b-hf-gaudi +servingRuntimeDisplayName: Text Generation Inference CodeLlama-7b-hf on Gaudi + +args: + - --model-id + - /mnt/models/--meta-llama--CodeLlama-7b-hf/snapshots/b462c3c99b077d341db691ec780a33156f3c1472 + - --port=8080 + - --json-output + - --max-input-length + - "1024" + - --max-total-tokens + - "2048" + +accelerators: '''["habana.ai/gaudi"]''' + +resources: + limits: + habana.ai/gaudi: 1 + requests: + habana.ai/gaudi: 1 + +volumeMounts: + - mountPath: /data + name: model-volume + - mountPath: /var/log/habana_logs + name: logs-volume + +volumes: + - emptyDir: + sizeLimit: 300Gi + name: model-volume + - emptyDir: + sizeLimit: 500Mi + name: logs-volume diff --git a/helm-charts/codegen-openshift-rhoai/tgi/templates/hf_token_secret.yaml b/helm-charts/codegen-openshift-rhoai/tgi/templates/hf_token_secret.yaml new file mode 100644 index 000000000..7ce2d2021 --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/tgi/templates/hf_token_secret.yaml @@ -0,0 +1,10 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: v1 +kind: Secret +metadata: + name: hf-token +type: Opaque +stringData: + HUGGING_FACE_HUB_TOKEN: {{ .Values.global.huggingfacehubApiToken }} diff --git a/helm-charts/codegen-openshift-rhoai/tgi/templates/servingruntime-template.yaml b/helm-charts/codegen-openshift-rhoai/tgi/templates/servingruntime-template.yaml new file mode 100644 index 000000000..eda75fc28 --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/tgi/templates/servingruntime-template.yaml @@ -0,0 +1,52 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +--- +apiVersion: template.openshift.io/v1 +kind: Template +metadata: + annotations: + opendatahub.io/apiProtocol: REST + opendatahub.io/modelServingSupport: '["single"]' + labels: + opendatahub.io/dashboard: "true" + name: {{ .Values.servingRuntimeName }} + namespace: redhat-ods-applications +objects: +- apiVersion: serving.kserve.io/v1alpha1 + kind: ServingRuntime + labels: + opendatahub.io/dashboard: "true" + metadata: + annotations: + openshift.io/display-name: {{ .Values.servingRuntimeDisplayName }} + opendatahub.io/recommended-accelerators: {{ .Values.accelerators }} + name: {{ .Values.servingRuntimeName }} + spec: + containers: + - args: {{- toYaml .Values.args | nindent 10 }} + env: + - name: NUMBA_CACHE_DIR + value: /tmp/hf_home + - name: HF_HOME + value: /tmp/hf_home + - name: HF_HUB_CACHE + value: /mnt/models + - name: HUGGING_FACE_HUB_TOKEN + valueFrom: + secretKeyRef: + key: HUGGING_FACE_HUB_TOKEN + name: hf-token + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + name: kserve-container + ports: + - containerPort: 8080 + protocol: TCP + resources: + {{- toYaml .Values.resources | nindent 10 }} + volumeMounts: {{- toYaml .Values.volumeMounts | nindent 10 }} + multiModel: false + supportedModelFormats: + - autoSelect: true + name: llm + volumes: {{- toYaml .Values.volumes | nindent 6 }} diff --git a/helm-charts/codegen-openshift-rhoai/tgi/values.yaml b/helm-charts/codegen-openshift-rhoai/tgi/values.yaml new file mode 100644 index 000000000..15dd6d50a --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/tgi/values.yaml @@ -0,0 +1,35 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +global: + huggingfacehubApiToken: "insert-your-huggingface-token-here" + +image: + repository: ghcr.io/huggingface/text-generation-inference + tag: 2.1.0 + +servingRuntimeName: tgi-magicoder-s-ds-6.7b-cpu +servingRuntimeDisplayName: Text Generation Inference Magicoder-S-DS-6.7B on CPU + +args: + - --model-id + - /mnt/models/--ise-uiuc--Magicoder-S-DS-6.7B/snapshots/b3ed7cb1578a3643ceaf2ebf996a3d8e85f75d8f + - --port=8080 + - --json-output + - --max-input-length + - "1024" + - --max-batch-prefill-tokens + - "32256" + +accelerators: {} + +resources: {} + +volumes: + - emptyDir: + sizeLimit: 300Gi + name: model-volume + +volumeMounts: + - mountPath: /data + name: model-volume diff --git a/helm-charts/codegen-openshift-rhoai/values.yaml b/helm-charts/codegen-openshift-rhoai/values.yaml new file mode 100644 index 000000000..cec3bb2ee --- /dev/null +++ b/helm-charts/codegen-openshift-rhoai/values.yaml @@ -0,0 +1,28 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +global: + clusterDomain: "insert-your-cluster-domain-here" + +image: + repository: "insert-your-image-here" # image-registry.openshift-image-registry.svc:5000/${NAMESPACE}/codegen + tag: "latest" + pullPolicy: IfNotPresent + +source: + contextDir: CodeGen + gitRef: main + gitUri: "https://github.com/opea-project/GenAIExamples.git" + type: Git + +strategy: + type: Docker + dockerfilePath: Dockerfile + +replicaCount: 1 + +port: 7778 + +service: + type: ClusterIP + port: 7778 diff --git a/helm-charts/codegen-openshift/Chart.yaml b/helm-charts/codegen-openshift/Chart.yaml new file mode 100644 index 000000000..8f015e2b4 --- /dev/null +++ b/helm-charts/codegen-openshift/Chart.yaml @@ -0,0 +1,18 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: v2 +name: codegen +description: A Helm chart for deploying codegen on Red Hat OpenShift +dependencies: + - name: tgi + version: 1.0.0 + repository: "file://tgi" + - name: llm-uservice + version: 1.0.0 + repository: "file://llm-uservice" + - name: react-ui + version: 0.1.0 + repository: "file://react-ui" +type: application +version: 1.0.0 diff --git a/helm-charts/codegen-openshift/README.md b/helm-charts/codegen-openshift/README.md new file mode 100644 index 000000000..46030ab05 --- /dev/null +++ b/helm-charts/codegen-openshift/README.md @@ -0,0 +1,37 @@ +# CodeGen + +Helm chart for deploying CodeGen service on Red Hat OpenShift. + +# Prerequisites + +1. Red Hat OpenShift Cluster with dynamic StorageClass to provision PersistentVolumes e.g. OpenShift Data Foundation) +2. Image registry to push there docker images (https://docs.openshift.com/container-platform/4.16/registry/securing-exposing-registry.html). +3. Account on https://huggingface.co/, access to model _ise-uiuc/Magicoder-S-DS-6.7B_ (for Xeon) or _meta-llama/CodeLlama-7b-hf_ (for Gaudi) and token with Read permissions. + +## Installing the Chart + +To install the chart, login to OpenShift CLI, go to your project and run the following: + +```console +cd GenAIInfra/helm-charts/ +./update_dependency.sh +helm dependency update codegen-openshift + +export NAMESPACE="insert-your-namespace-here" +export CLUSTERDOMAIN="$(oc get Ingress.config.openshift.io/cluster -o jsonpath='{.spec.domain}' | sed 's/^apps.//')" +export HFTOKEN="insert-your-huggingface-token-here" + +# To run on Xeon +helm install codegen codegen-openshift --set image.repository=image-registry.openshift-image-registry.svc:5000/${NAMESPACE}/codegen --set llm-uservice.image.repository=image-registry.openshift-image-registry.svc:5000/${NAMESPACE}/llm-tgi --set react-ui.image.repository=image-registry.openshift-image-registry.svc:5000/${NAMESPACE}/react-ui --set global.clusterDomain=${CLUSTERDOMAIN} --set global.huggingfacehubApiToken=${HFTOKEN} + +# To run on Gaudi +helm install codegen codegen-openshift --set image.repository=image-registry.openshift-image-registry.svc:5000/${NAMESPACE}/codegen --set llm-uservice.image.repository=image-registry.openshift-image-registry.svc:5000/${NAMESPACE}/llm-tgi --set react-ui.image.repository=image-registry.openshift-image-registry.svc:5000/${NAMESPACE}/react-ui --set global.clusterDomain=${CLUSTERDOMAIN} --set global.huggingfacehubApiToken=${HFTOKEN} --values codegen-openshift/gaudi-values.yaml +``` + +## Verify + +To verify the installation, run the command `oc get pods` to make sure all pods are running. Wait about 5 minutes for building images. When 3 pods achieve _Completed_ status, the rest with services should go to _Running_. + +## Launch the UI + +To access the frontend, find the route for _react-ui_ with command `oc get routes` and open it in the browser. diff --git a/helm-charts/codegen-openshift/gaudi-values.yaml b/helm-charts/codegen-openshift/gaudi-values.yaml new file mode 100644 index 000000000..a9b5811d0 --- /dev/null +++ b/helm-charts/codegen-openshift/gaudi-values.yaml @@ -0,0 +1,62 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +global: + clusterDomain: "insert-your-cluster-domain-here" + huggingfacehubApiToken: "insert-your-huggingface-token-here" + +image: + repository: "insert-your-image-here" + tag: "latest" + pullPolicy: IfNotPresent + +source: + contextDir: CodeGen + gitRef: main + gitUri: "https://github.com/opea-project/GenAIExamples.git" + type: Git + +strategy: + type: Docker + dockerfilePath: Dockerfile + +replicaCount: 1 + +port: 7778 + +service: + type: ClusterIP + port: 7778 + +tgi: + model: + id: meta-llama/CodeLlama-7b-hf + replicaCount: 1 + port: 8080 + image: + repository: ghcr.io/huggingface/tgi-gaudi + tag: 2.0.4 + pullPolicy: IfNotPresent + service: + type: ClusterIP + resources: + limits: + habana.ai/gaudi: 1 + requests: + habana.ai/gaudi: 1 + args: + - "--max-input-length" + - "1024" + - "--max-total-tokens" + - "2048" + volumeMounts: + - mountPath: /data + name: model-volume + - mountPath: /var/log/habana_logs + name: logs-volume + volumes: + - emptyDir: + sizeLimit: 50Gi + name: model-volume + - emptyDir: + name: logs-volume diff --git a/helm-charts/codegen-openshift/llm-uservice/Chart.yaml b/helm-charts/codegen-openshift/llm-uservice/Chart.yaml new file mode 100644 index 000000000..ecf281498 --- /dev/null +++ b/helm-charts/codegen-openshift/llm-uservice/Chart.yaml @@ -0,0 +1,8 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: v2 +name: llm-uservice +description: A Helm chart for deploying llm-uservice on Red Hat OpenShift +type: application +version: 1.0.0 diff --git a/helm-charts/codegen-openshift/llm-uservice/templates/_helpers.tpl b/helm-charts/codegen-openshift/llm-uservice/templates/_helpers.tpl new file mode 100644 index 000000000..726fca204 --- /dev/null +++ b/helm-charts/codegen-openshift/llm-uservice/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "llm-uservice.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "llm-uservice.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "llm-uservice.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "llm-uservice.labels" -}} +helm.sh/chart: {{ include "llm-uservice.chart" . }} +{{ include "llm-uservice.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "llm-uservice.selectorLabels" -}} +app.kubernetes.io/name: {{ include "llm-uservice.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/helm-charts/codegen-openshift/llm-uservice/templates/buildconfig.yaml b/helm-charts/codegen-openshift/llm-uservice/templates/buildconfig.yaml new file mode 100644 index 000000000..9b3d0631d --- /dev/null +++ b/helm-charts/codegen-openshift/llm-uservice/templates/buildconfig.yaml @@ -0,0 +1,30 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +kind: BuildConfig +apiVersion: build.openshift.io/v1 +metadata: + name: {{ include "llm-uservice.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + output: + to: + kind: "ImageStreamTag" + name: "llm-tgi:latest" + failedBuildsHistoryLimit: 5 + successfulBuildsHistoryLimit: 5 + nodeSelector: null + postCommit: {} + resources: {} + runPolicy: SerialLatestOnly + source: + git: + ref: {{ .Values.source.gitRef }} + uri: {{ .Values.source.gitUri }} + type: {{ .Values.source.type }} + strategy: + type: {{ .Values.strategy.type }} + dockerStrategy: + dockerfilePath: {{ .Values.strategy.dockerfilePath }} + triggers: + - type: ConfigChange diff --git a/helm-charts/codegen-openshift/llm-uservice/templates/deployment.yaml b/helm-charts/codegen-openshift/llm-uservice/templates/deployment.yaml new file mode 100644 index 000000000..523cf9343 --- /dev/null +++ b/helm-charts/codegen-openshift/llm-uservice/templates/deployment.yaml @@ -0,0 +1,53 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "llm-uservice.fullname" . }} + labels: + {{- include "llm-uservice.labels" . | nindent 4 }} + annotations: + image.openshift.io/triggers: '[{"from":{"kind":"ImageStreamTag","name":"llm-tgi:latest"},"fieldPath":"spec.template.spec.containers[?(@.name==\"llm-tgi-server\")].image"}]' +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "llm-uservice.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "llm-uservice.selectorLabels" . | nindent 8 }} + spec: + securityContext: {} + containers: + - name: {{ .Release.Name }} + env: + - name: TGI_LLM_ENDPOINT + value: {{ .Values.TGI_LLM_ENDPOINT | quote}} + - name: HUGGINGFACEHUB_API_TOKEN + valueFrom: + secretKeyRef: + key: HUGGING_FACE_HUB_TOKEN + name: hf-token + - name: PYTHONPATH + value: {{ .Values.PYTHONPATH | quote }} + - name: HOME + value: {{ .Values.HOME | quote }} + securityContext: {} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: llm-uservice + containerPort: 9000 + protocol: TCP + startupProbe: + {{- toYaml .Values.startupProbe | nindent 12 }} + volumeMounts: + - mountPath: /tmp/home + name: local-dir + resources: {} + volumes: + - emptyDir: + sizeLimit: 5Gi + name: local-dir diff --git a/helm-charts/codegen-openshift/llm-uservice/templates/imagestream.yaml b/helm-charts/codegen-openshift/llm-uservice/templates/imagestream.yaml new file mode 100644 index 000000000..31dc5155d --- /dev/null +++ b/helm-charts/codegen-openshift/llm-uservice/templates/imagestream.yaml @@ -0,0 +1,12 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +--- +apiVersion: image.openshift.io/v1 +kind: ImageStream +metadata: + name: llm-tgi + namespace: {{ .Release.namespace }} +spec: + lookupPolicy: + local: true diff --git a/helm-charts/codegen-openshift/llm-uservice/templates/service.yaml b/helm-charts/codegen-openshift/llm-uservice/templates/service.yaml new file mode 100644 index 000000000..06e13b8c6 --- /dev/null +++ b/helm-charts/codegen-openshift/llm-uservice/templates/service.yaml @@ -0,0 +1,18 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: v1 +kind: Service +metadata: + name: {{ include "llm-uservice.fullname" . }} + labels: + {{- include "llm-uservice.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: 9000 + protocol: TCP + name: llm-uservice + selector: + {{- include "llm-uservice.selectorLabels" . | nindent 4 }} diff --git a/helm-charts/codegen-openshift/llm-uservice/values.yaml b/helm-charts/codegen-openshift/llm-uservice/values.yaml new file mode 100644 index 000000000..bbcd92c4b --- /dev/null +++ b/helm-charts/codegen-openshift/llm-uservice/values.yaml @@ -0,0 +1,36 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +image: + repository: "insert-your-image-here" + tag: "latest" + pullPolicy: IfNotPresent + +source: + gitRef: main + gitUri: https://github.com/opea-project/GenAIComps.git + type: Git + +strategy: + type: Docker + dockerfilePath: comps/llms/text-generation/tgi/Dockerfile + +replicaCount: 1 + +TGI_LLM_ENDPOINT: "http://codegen-tgi:8080" # if you change it, update also startupProbe@line 26 +PYTHONPATH: /home/user/.local/lib/python3.11/site-packages:/home/user # don't edit unless you have a good reason +HOME: /tmp/home + +startupProbe: + exec: + command: + - python + - -c + - 'import requests; req = requests.get("http://codegen-tgi:8080/info"); print(req)' + initialDelaySeconds: 5 + periodSeconds: 5 + failureThreshold: 120 + +service: + type: ClusterIP + port: 9000 diff --git a/helm-charts/codegen-openshift/react-ui/.helmignore b/helm-charts/codegen-openshift/react-ui/.helmignore new file mode 100644 index 000000000..0e8a0eb36 --- /dev/null +++ b/helm-charts/codegen-openshift/react-ui/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm-charts/codegen-openshift/react-ui/Chart.yaml b/helm-charts/codegen-openshift/react-ui/Chart.yaml new file mode 100644 index 000000000..bd518d6c0 --- /dev/null +++ b/helm-charts/codegen-openshift/react-ui/Chart.yaml @@ -0,0 +1,27 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: v2 +name: react-ui +description: A Helm chart deploying OPEA CodeGen React UI + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.0" diff --git a/helm-charts/codegen-openshift/react-ui/templates/NOTES.txt b/helm-charts/codegen-openshift/react-ui/templates/NOTES.txt new file mode 100644 index 000000000..027640017 --- /dev/null +++ b/helm-charts/codegen-openshift/react-ui/templates/NOTES.txt @@ -0,0 +1,2 @@ +1. Get the application URL by running this command or opening OpenShift Console apps. +oc get route -n {{ .Release.Namespace }} {{ include "codegen-react-ui.fullname" . }} diff --git a/helm-charts/codegen-openshift/react-ui/templates/_helpers.tpl b/helm-charts/codegen-openshift/react-ui/templates/_helpers.tpl new file mode 100644 index 000000000..ca8230902 --- /dev/null +++ b/helm-charts/codegen-openshift/react-ui/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "codegen-react-ui.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "codegen-react-ui.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "codegen-react-ui.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "codegen-react-ui.labels" -}} +helm.sh/chart: {{ include "codegen-react-ui.chart" . }} +{{ include "codegen-react-ui.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "codegen-react-ui.selectorLabels" -}} +app.kubernetes.io/name: {{ include "codegen-react-ui.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/helm-charts/codegen-openshift/react-ui/templates/codegen-react-ui-bc.yaml b/helm-charts/codegen-openshift/react-ui/templates/codegen-react-ui-bc.yaml new file mode 100644 index 000000000..dc487b8be --- /dev/null +++ b/helm-charts/codegen-openshift/react-ui/templates/codegen-react-ui-bc.yaml @@ -0,0 +1,42 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +--- +apiVersion: image.openshift.io/v1 +kind: ImageStream +metadata: + name: react-ui +spec: + lookupPolicy: + local: true +--- +kind: BuildConfig +apiVersion: build.openshift.io/v1 +metadata: + name: react-ui +spec: + output: + to: + kind: "ImageStreamTag" + name: "react-ui:{{ .Values.image.tag }}" + failedBuildsHistoryLimit: 5 + successfulBuildsHistoryLimit: 5 + nodeSelector: null + postCommit: {} + resources: {} + runPolicy: SerialLatestOnly + source: + contextDir: {{ .Values.source.contextDir }} + git: + ref: {{ .Values.source.gitRef }} + uri: {{ .Values.source.gitUri }} + type: {{ .Values.source.type }} + strategy: + type: {{ .Values.strategy.type }} + dockerStrategy: + env: + - name: VITE_CODE_GEN_URL + value: https://codegen-react-ui-{{ .Release.Namespace }}.apps.{{ .Values.global.clusterDomain }}/v1/codegen + dockerfilePath: {{ .Values.strategy.dockerfilePath }} + triggers: + - type: ConfigChange diff --git a/helm-charts/codegen-openshift/react-ui/templates/codegen-react-ui-cms.yaml b/helm-charts/codegen-openshift/react-ui/templates/codegen-react-ui-cms.yaml new file mode 100644 index 000000000..fa68f3586 --- /dev/null +++ b/helm-charts/codegen-openshift/react-ui/templates/codegen-react-ui-cms.yaml @@ -0,0 +1,55 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +--- +apiVersion: v1 +data: + default.conf: | + server { + listen 8080; + gzip on; + gzip_proxied any; + gzip_comp_level 6; + gzip_buffers 16 8k; + gzip_http_version 1.1; + gzip_types font/woff2 text/css application/javascript application/json application/font-woff application/font-tff image/gif image/png image/svg+xml application/octet-stream; + location / { + root /usr/share/nginx/html; + index index.html index.htm; + try_files $uri $uri/ /index.html =404; + location ~* \.(gif|jpe?g|png|webp|ico|svg|css|js|mp4|woff2)$ { + expires 1d; + } + } + } +kind: ConfigMap +metadata: + creationTimestamp: null + name: {{ include "codegen-react-ui.fullname" . }}-default-conf +--- +apiVersion: v1 +data: + nginx.conf: | + user nginx; + worker_processes auto; + error_log /var/log/nginx/error.log notice; + pid /tmp/nginx.pid; + events { + worker_connections 1024; + } + http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + access_log /var/log/nginx/access.log main; + sendfile on; + #tcp_nopush on; + keepalive_timeout 65; + #gzip on; + include /etc/nginx/conf.d/*.conf; + } +kind: ConfigMap +metadata: + name: {{ include "codegen-react-ui.fullname" . }}-nginx-conf diff --git a/helm-charts/codegen-openshift/react-ui/templates/codegen-react-ui-consolelink.yaml b/helm-charts/codegen-openshift/react-ui/templates/codegen-react-ui-consolelink.yaml new file mode 100644 index 000000000..eab5320b3 --- /dev/null +++ b/helm-charts/codegen-openshift/react-ui/templates/codegen-react-ui-consolelink.yaml @@ -0,0 +1,15 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: console.openshift.io/v1 +kind: ConsoleLink +metadata: + name: {{ include "codegen-react-ui.fullname" . }} +spec: + href: https://codegen-react-ui-{{ .Release.Namespace }}.apps.{{ .Values.global.clusterDomain }} + location: ApplicationMenu + # This text will appear in a box called "Launcher" under "namespace" or "project" in the web console + text: OPEA CodeGen UI + applicationMenu: + section: Open Platform For Enterprise AI + imageURL: data:image/png;base64,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 diff --git a/helm-charts/codegen-openshift/react-ui/templates/codegen-react-ui-deployment.yaml b/helm-charts/codegen-openshift/react-ui/templates/codegen-react-ui-deployment.yaml new file mode 100644 index 000000000..8d428a3b5 --- /dev/null +++ b/helm-charts/codegen-openshift/react-ui/templates/codegen-react-ui-deployment.yaml @@ -0,0 +1,85 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "codegen-react-ui.fullname" . }} + labels: + {{- include "codegen-react-ui.labels" . | nindent 4 }} + annotations: + image.openshift.io/triggers: '[{"from":{"kind":"ImageStreamTag","name":"react-ui:{{ .Values.image.tag }}"},"fieldPath":"spec.template.spec.containers[?(@.name==\"{{ .Chart.Name }}\")].image"}]' +spec: + selector: + matchLabels: + {{- include "codegen-react-ui.selectorLabels" . | nindent 8 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "codegen-react-ui.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - command: ["/bin/sh", "-c"] + args: + - | + cp -v /etc/nginx/nginx.conf /tmp/nginx.conf && \ + sed -i "s/pid .*;/pid \/tmp\/nginx.pid;/" /tmp/nginx.conf && \ + nginx -c /tmp/nginx.conf -g "daemon off;" + image: {{ .Values.image.repository }}:{{ .Values.image.tag }} + name: {{ .Chart.Name }} + ports: + - name: http + containerPort: {{ .Values.service.port }} + protocol: TCP + livenessProbe: + httpGet: + path: / + port: http + readinessProbe: + httpGet: + path: / + port: http + resources: + {{- toYaml .Values.resources | nindent 10 }} + securityContext: + {{- toYaml .Values.securityContext | nindent 10 }} + volumeMounts: + - mountPath: /var/cache/nginx/ + name: nginx-cache-dir + - mountPath: /etc/nginx/conf.d/default.conf + name: default-conf + subPath: default.conf + - mountPath: /etc/nginx/nginx.conf + name: nginx-conf + subPath: nginx.conf + volumes: + - name: nginx-cache-dir + emptyDir: {} + - name: default-conf + configMap: + name: {{ include "codegen-react-ui.fullname" . }}-default-conf + - name: nginx-conf + configMap: + name: {{ include "codegen-react-ui.fullname" . }}-nginx-conf + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/helm-charts/codegen-openshift/react-ui/templates/codegen-react-ui-https-route.yaml b/helm-charts/codegen-openshift/react-ui/templates/codegen-react-ui-https-route.yaml new file mode 100644 index 000000000..09ff5e8f4 --- /dev/null +++ b/helm-charts/codegen-openshift/react-ui/templates/codegen-react-ui-https-route.yaml @@ -0,0 +1,17 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +--- +apiVersion: route.openshift.io/v1 +kind: Route +metadata: + labels: + {{- include "codegen-react-ui.selectorLabels" . | nindent 8 }} + name: {{ include "codegen-react-ui.fullname" . }} +spec: + host: codegen-react-ui-{{ .Release.Namespace }}.apps.{{ .Values.global.clusterDomain }} + tls: + termination: edge + to: + name: {{ include "codegen-react-ui.fullname" . }} +status: {} diff --git a/helm-charts/codegen-openshift/react-ui/templates/codegen-react-ui-service.yaml b/helm-charts/codegen-openshift/react-ui/templates/codegen-react-ui-service.yaml new file mode 100644 index 000000000..c8741bf95 --- /dev/null +++ b/helm-charts/codegen-openshift/react-ui/templates/codegen-react-ui-service.yaml @@ -0,0 +1,19 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "codegen-react-ui.fullname" . }} + labels: + {{- include "codegen-react-ui.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "codegen-react-ui.selectorLabels" . | nindent 4 }} diff --git a/helm-charts/codegen-openshift/react-ui/values.yaml b/helm-charts/codegen-openshift/react-ui/values.yaml new file mode 100644 index 000000000..a36413906 --- /dev/null +++ b/helm-charts/codegen-openshift/react-ui/values.yaml @@ -0,0 +1,67 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +# Default values for codegen-react-ui. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +global: + clusterDomain: "insert-your-cluster-domain-here" + +image: + repository: "insert-your-image-here" + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + +source: + contextDir: CodeGen/ui + gitRef: main + gitUri: "https://github.com/opea-project/GenAIExamples.git" + type: Git + +strategy: + type: Docker + dockerfilePath: docker/Dockerfile.react + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + port: 8080 + +resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: {} + +tolerations: [] + +affinity: {} diff --git a/helm-charts/codegen-openshift/templates/_helpers.tpl b/helm-charts/codegen-openshift/templates/_helpers.tpl new file mode 100644 index 000000000..7cffcef8d --- /dev/null +++ b/helm-charts/codegen-openshift/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "codegen.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "codegen.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "codegen.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "codegen.labels" -}} +helm.sh/chart: {{ include "codegen.chart" . }} +{{ include "codegen.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "codegen.selectorLabels" -}} +app.kubernetes.io/name: {{ include "codegen.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/helm-charts/codegen-openshift/templates/buildconfig.yaml b/helm-charts/codegen-openshift/templates/buildconfig.yaml new file mode 100644 index 000000000..dc9790cd3 --- /dev/null +++ b/helm-charts/codegen-openshift/templates/buildconfig.yaml @@ -0,0 +1,31 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +kind: BuildConfig +apiVersion: build.openshift.io/v1 +metadata: + name: {{ include "codegen.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + output: + to: + kind: "ImageStreamTag" + name: "codegen:latest" + failedBuildsHistoryLimit: 5 + successfulBuildsHistoryLimit: 5 + nodeSelector: null + postCommit: {} + resources: {} + runPolicy: SerialLatestOnly + source: + contextDir: {{ .Values.source.contextDir }} + git: + ref: {{ .Values.source.gitRef }} + uri: {{ .Values.source.gitUri }} + type: {{ .Values.source.type }} + strategy: + type: {{ .Values.strategy.type }} + dockerStrategy: + dockerfilePath: {{ .Values.strategy.dockerfilePath }} + triggers: + - type: ConfigChange diff --git a/helm-charts/codegen-openshift/templates/deployment.yaml b/helm-charts/codegen-openshift/templates/deployment.yaml new file mode 100644 index 000000000..e4e44ad9c --- /dev/null +++ b/helm-charts/codegen-openshift/templates/deployment.yaml @@ -0,0 +1,33 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "codegen.fullname" . }} + labels: + {{- include "codegen.labels" . | nindent 4 }} + app: {{ include "codegen.fullname" . }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "codegen.selectorLabels" . | nindent 6 }} + app: {{ include "codegen.fullname" . }} + template: + metadata: + labels: + {{- include "codegen.selectorLabels" . | nindent 8 }} + app: {{ include "codegen.fullname" . }} + spec: + containers: + - name: {{ .Release.Name }} + env: + - name: LLM_SERVICE_HOST_IP + value: {{ .Release.Name }}-llm-uservice + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: codegen + containerPort: {{ .Values.port }} + protocol: TCP diff --git a/helm-charts/codegen-openshift/templates/hf_token_secret.yaml b/helm-charts/codegen-openshift/templates/hf_token_secret.yaml new file mode 100644 index 000000000..7ce2d2021 --- /dev/null +++ b/helm-charts/codegen-openshift/templates/hf_token_secret.yaml @@ -0,0 +1,10 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: v1 +kind: Secret +metadata: + name: hf-token +type: Opaque +stringData: + HUGGING_FACE_HUB_TOKEN: {{ .Values.global.huggingfacehubApiToken }} diff --git a/helm-charts/codegen-openshift/templates/imagestream.yaml b/helm-charts/codegen-openshift/templates/imagestream.yaml new file mode 100644 index 000000000..14f1f6b0d --- /dev/null +++ b/helm-charts/codegen-openshift/templates/imagestream.yaml @@ -0,0 +1,12 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +--- +apiVersion: image.openshift.io/v1 +kind: ImageStream +metadata: + name: {{ include "codegen.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + lookupPolicy: + local: true diff --git a/helm-charts/codegen-openshift/templates/route.yaml b/helm-charts/codegen-openshift/templates/route.yaml new file mode 100644 index 000000000..7e8fe0fb6 --- /dev/null +++ b/helm-charts/codegen-openshift/templates/route.yaml @@ -0,0 +1,22 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: route.openshift.io/v1 +kind: Route +metadata: + labels: + {{- include "codegen.labels" . | nindent 4 }} + app: {{ include "codegen.fullname" . }} + name: {{ .Release.Name }}-tls +spec: + host: codegen-react-ui-{{ .Release.Namespace }}.apps.{{ .Values.global.clusterDomain }} + path: /v1/codegen + port: + targetPort: codegen + tls: + termination: edge + to: + kind: Service + name: codegen + weight: 100 + wildcardPolicy: None diff --git a/helm-charts/codegen-openshift/templates/service.yaml b/helm-charts/codegen-openshift/templates/service.yaml new file mode 100644 index 000000000..104e00b95 --- /dev/null +++ b/helm-charts/codegen-openshift/templates/service.yaml @@ -0,0 +1,19 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: v1 +kind: Service +metadata: + name: {{ include "codegen.fullname" . }} + labels: + {{- include "codegen.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: {{ .Values.port }} + protocol: TCP + name: codegen + selector: + {{- include "codegen.selectorLabels" . | nindent 4 }} + app: {{ include "codegen.fullname" . }} diff --git a/helm-charts/codegen-openshift/tgi/Chart.yaml b/helm-charts/codegen-openshift/tgi/Chart.yaml new file mode 100644 index 000000000..f3856fbec --- /dev/null +++ b/helm-charts/codegen-openshift/tgi/Chart.yaml @@ -0,0 +1,8 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: v2 +name: tgi +description: A Helm chart for deploying tgi on Red Hat OpenShift +type: application +version: 1.0.0 diff --git a/helm-charts/codegen-openshift/tgi/gaudi-values.yaml b/helm-charts/codegen-openshift/tgi/gaudi-values.yaml new file mode 100644 index 000000000..97d3c6a6e --- /dev/null +++ b/helm-charts/codegen-openshift/tgi/gaudi-values.yaml @@ -0,0 +1,42 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +model: + id: meta-llama/CodeLlama-7b-hf + +replicaCount: 1 + +port: 8080 + +image: + repository: ghcr.io/huggingface/tgi-gaudi + tag: 2.0.4 + pullPolicy: IfNotPresent + +service: + type: ClusterIP + +resources: + limits: + habana.ai/gaudi: 1 + requests: + habana.ai/gaudi: 1 + +args: +- "--max-input-length" +- "1024" +- "--max-total-tokens" +- "2048" + +volumeMounts: + - mountPath: /data + name: model-volume + - mountPath: /var/log/habana_logs + name: logs-volume + +volumes: +- emptyDir: + sizeLimit: 50Gi + name: model-volume +- emptyDir: + name: logs-volume diff --git a/helm-charts/codegen-openshift/tgi/templates/_helpers.tpl b/helm-charts/codegen-openshift/tgi/templates/_helpers.tpl new file mode 100644 index 000000000..b672e8309 --- /dev/null +++ b/helm-charts/codegen-openshift/tgi/templates/_helpers.tpl @@ -0,0 +1,69 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "tgi.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "tgi.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "tgi.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Convert chart name to a string suitable as metric prefix +*/}} +{{- define "tgi.metricPrefix" -}} +{{- include "tgi.fullname" . | replace "-" "_" | regexFind "[a-zA-Z_:][a-zA-Z0-9_:]*" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "tgi.labels" -}} +helm.sh/chart: {{ include "tgi.chart" . }} +{{ include "tgi.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "tgi.selectorLabels" -}} +app.kubernetes.io/name: {{ include "tgi.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "tgi.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "tgi.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/helm-charts/codegen-openshift/tgi/templates/deployment.yaml b/helm-charts/codegen-openshift/tgi/templates/deployment.yaml new file mode 100644 index 000000000..4d93f991b --- /dev/null +++ b/helm-charts/codegen-openshift/tgi/templates/deployment.yaml @@ -0,0 +1,47 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "tgi.fullname" . }} + labels: + {{- include "tgi.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "tgi.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "tgi.selectorLabels" . | nindent 8 }} + spec: + securityContext: {} + containers: + - name: {{ .Chart.Name }} + env: + - name: MODEL_ID + value: "{{ .Values.model.id }}" + - name: PORT + value: {{ .Values.port | quote }} + - name: NUMBA_CACHE_DIR + value: /data + - name: HF_TOKEN + valueFrom: + secretKeyRef: + key: HUGGING_FACE_HUB_TOKEN + name: hf-token + securityContext: {} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + {{- toYaml .Values.args | nindent 12 }} + volumeMounts: {{- toYaml .Values.volumeMounts | nindent 10 }} + ports: + - name: http + containerPort: {{ .Values.port }} + protocol: TCP + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumes: {{- toYaml .Values.volumes | nindent 6 }} diff --git a/helm-charts/codegen-openshift/tgi/templates/service.yaml b/helm-charts/codegen-openshift/tgi/templates/service.yaml new file mode 100644 index 000000000..7ed5529a9 --- /dev/null +++ b/helm-charts/codegen-openshift/tgi/templates/service.yaml @@ -0,0 +1,18 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: v1 +kind: Service +metadata: + name: {{ include "tgi.fullname" . }} + labels: + {{- include "tgi.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: 8080 + targetPort: {{ .Values.port }} + protocol: TCP + name: tgi + selector: + {{- include "tgi.selectorLabels" . | nindent 4 }} diff --git a/helm-charts/codegen-openshift/tgi/values.yaml b/helm-charts/codegen-openshift/tgi/values.yaml new file mode 100644 index 000000000..45f8ad1ee --- /dev/null +++ b/helm-charts/codegen-openshift/tgi/values.yaml @@ -0,0 +1,30 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +model: + id: ise-uiuc/Magicoder-S-DS-6.7B + +replicaCount: 1 + +port: 8080 + +image: + repository: ghcr.io/huggingface/text-generation-inference + tag: 2.1.0 + pullPolicy: IfNotPresent + +service: + type: ClusterIP + +resources: {} + +args: [] + +volumeMounts: + - mountPath: /data + name: model-volume + +volumes: + - emptyDir: + sizeLimit: 50Gi + name: model-volume diff --git a/helm-charts/codegen-openshift/values.yaml b/helm-charts/codegen-openshift/values.yaml new file mode 100644 index 000000000..de00d09b1 --- /dev/null +++ b/helm-charts/codegen-openshift/values.yaml @@ -0,0 +1,50 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +global: + clusterDomain: "insert-your-cluster-domain-here" + huggingfacehubApiToken: "insert-your-huggingface-token-here" + +image: + repository: "insert-your-image-here" + tag: "latest" + pullPolicy: IfNotPresent + +source: + contextDir: CodeGen + gitRef: main + gitUri: "https://github.com/opea-project/GenAIExamples.git" + type: Git + +strategy: + type: Docker + dockerfilePath: Dockerfile + +replicaCount: 1 + +port: 7778 + +service: + type: ClusterIP + port: 7778 + +tgi: + model: + id: ise-uiuc/Magicoder-S-DS-6.7B + replicaCount: 1 + port: 8080 + image: + repository: ghcr.io/huggingface/text-generation-inference + tag: 2.1.0 + pullPolicy: IfNotPresent + service: + type: ClusterIP + resources: {} + args: [] + volumeMounts: + - mountPath: /data + name: model-volume + volumes: + - emptyDir: + sizeLimit: 50Gi + name: model-volume