From 9c854a8b6a80bb86fbd1b4c4d149fd46037c6375 Mon Sep 17 00:00:00 2001 From: Taylor Price Date: Mon, 13 Jan 2025 10:32:50 -0700 Subject: [PATCH] chore: basic helm chart Signed-off-by: Taylor Price --- .github/workflows/update-demo-env.yml | 32 +++++++ .github/workflows/update-test-env.yml | 32 +++++++ Dockerfile | 5 +- chart/Chart.yaml | 5 + chart/templates/_helpers.tpl | 66 +++++++++++++ chart/templates/deployment.yaml | 132 ++++++++++++++++++++++++++ chart/templates/ingress.yaml | 47 +++++++++ chart/templates/secret.yaml | 46 +++++++++ chart/templates/service.yaml | 22 +++++ chart/templates/serviceaccount.yaml | 10 ++ chart/values.yaml | 83 ++++++++++++++++ run.sh | 6 -- 12 files changed, 476 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/update-demo-env.yml create mode 100644 .github/workflows/update-test-env.yml create mode 100644 chart/Chart.yaml create mode 100644 chart/templates/_helpers.tpl create mode 100644 chart/templates/deployment.yaml create mode 100644 chart/templates/ingress.yaml create mode 100644 chart/templates/secret.yaml create mode 100644 chart/templates/service.yaml create mode 100644 chart/templates/serviceaccount.yaml create mode 100644 chart/values.yaml diff --git a/.github/workflows/update-demo-env.yml b/.github/workflows/update-demo-env.yml new file mode 100644 index 000000000..9f17d1cfc --- /dev/null +++ b/.github/workflows/update-demo-env.yml @@ -0,0 +1,32 @@ +name: Update Demo Env + +permissions: + id-token: write + contents: read + packages: write + +on: + workflow_dispatch: + +jobs: + copy-tag: + runs-on: depot-ubuntu-22.04 + + steps: + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Copy to demo tag + run: | + crane tag ghcr.io/${{ github.repository }}:latest demo + crane tag docker.io/obot/${{ github.event.repository.name }}:latest demo diff --git a/.github/workflows/update-test-env.yml b/.github/workflows/update-test-env.yml new file mode 100644 index 000000000..5975693d4 --- /dev/null +++ b/.github/workflows/update-test-env.yml @@ -0,0 +1,32 @@ +name: Update Test Env + +permissions: + id-token: write + contents: read + packages: write + +on: + workflow_dispatch: + +jobs: + copy-tag: + runs-on: depot-ubuntu-22.04 + + steps: + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Copy to test tag + run: | + crane tag ghcr.io/${{ github.repository }}:latest test + crane tag docker.io/obot/${{ github.event.repository.name }}:latest test diff --git a/Dockerfile b/Dockerfile index b912ab13b..ceb6b50f9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -43,13 +43,10 @@ ENV PGDATA=/data/postgresql COPY --from=build-pgvector /usr/lib/postgresql17/vector.so /usr/lib/postgresql17/ COPY --from=build-pgvector /usr/share/postgresql17/extension/vector* /usr/share/postgresql17/extension/ -RUN apk add --no-cache git python-3.13 py3.13-pip openssh-server npm bash tini procps libreoffice docker +RUN apk add --no-cache git python-3.13 py3.13-pip npm bash tini procps libreoffice docker COPY --chmod=0755 /tools/package-chrome.sh / RUN /package-chrome.sh && rm /package-chrome.sh -RUN sed -E 's/^#(PermitRootLogin)no/\1yes/' /etc/ssh/sshd_config -i -RUN ssh-keygen -A -RUN mkdir /run/sshd && /usr/sbin/sshd COPY encryption.yaml / COPY --chmod=0755 run.sh /bin/run.sh diff --git a/chart/Chart.yaml b/chart/Chart.yaml new file mode 100644 index 000000000..c15852020 --- /dev/null +++ b/chart/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v2 +name: obot +description: A Helm chart for Obot +version: 0.1.0 +appVersion: 1.0.0 diff --git a/chart/templates/_helpers.tpl b/chart/templates/_helpers.tpl new file mode 100644 index 000000000..4c07a2394 --- /dev/null +++ b/chart/templates/_helpers.tpl @@ -0,0 +1,66 @@ +{{/* +Return the chart name and version. +*/}} +{{- define "obot.chart" -}} +{{ printf "%s-%s" .Chart.Name .Chart.Version | quote }} +{{- end -}} + +{{/* +Expand the name of the chart. +*/}} +{{- define "obot.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a fullname using the release name and the chart name. +*/}} +{{- define "obot.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name (include "obot.name" .) | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} + +{{/* +Create labels for the resources. +*/}} +{{- define "obot.labels" -}} +helm.sh/chart: {{ include "obot.chart" . }} +{{ include "obot.selectorLabels" . }} +{{- with .Chart.AppVersion }} +app.kubernetes.io/version: {{ . | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + +{{/* +Create selector labels for the resources. +*/}} +{{- define "obot.selectorLabels" -}} +app.kubernetes.io/name: {{ include "obot.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "obot.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "obot.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Set name of secret to use for credentials +*/}} +{{- define "obot.config.secretName" -}} +{{- if .Values.config.existingSecret -}} +{{- .Values.config.existingSecret -}} +{{- else -}} +{{ .Release.Name }}-config +{{- end -}} +{{- end -}} \ No newline at end of file diff --git a/chart/templates/deployment.yaml b/chart/templates/deployment.yaml new file mode 100644 index 000000000..4161c4417 --- /dev/null +++ b/chart/templates/deployment.yaml @@ -0,0 +1,132 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "obot.fullname" . }} + labels: + {{- include "obot.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicaCount }} + strategy: + type: {{ .Values.updateStrategy }} + selector: + matchLabels: + {{- include "obot.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "obot.selectorLabels" . | nindent 8 }} + spec: + serviceAccountName: {{ include "obot.serviceAccountName" . }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml .Values.imagePullSecrets | nindent 8 }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: 8080 + protocol: TCP + livenessProbe: + exec: + command: + - "true" + readinessProbe: + exec: + command: + - "true" + env: + {{- if .Values.config.awsAccessKeyID }} + - name: "AWS_ACCESS_KEY_ID" + valueFrom: + secretKeyRef: + name: {{ include "obot.config.secretName" . }} + key: awsAccessKeyID + {{- end }} + {{- if .Values.config.awsRegion }} + - name: "AWS_REGION" + valueFrom: + secretKeyRef: + name: {{ include "obot.config.secretName" . }} + key: awsRegion + {{- end }} + {{- if .Values.config.awsSecretAccessKey }} + - name: "AWS_SECRET_ACCESS_KEY" + valueFrom: + secretKeyRef: + name: {{ include "obot.config.secretName" . }} + key: awsSecretAccessKey + {{- end }} + {{- if .Values.config.baaahThreadiness }} + - name: "BAAAH_THREADINESS" + valueFrom: + secretKeyRef: + name: {{ include "obot.config.secretName" . }} + key: baaahThreadiness + {{- end }} + {{- if .Values.config.githubAuthToken }} + - name: "GITHUB_AUTH_TOKEN" + valueFrom: + secretKeyRef: + name: {{ include "obot.config.secretName" . }} + key: githubAuthToken + {{- end }} + {{- if .Values.config.obotServerAuthAdminEmails }} + - name: "OBOT_SERVER_AUTH_ADMIN_EMAILS" + valueFrom: + secretKeyRef: + name: {{ include "obot.config.secretName" . }} + key: obotServerAuthAdminEmails + {{- end }} + {{- if .Values.config.obotServerDSN }} + - name: "OBOT_SERVER_DSN" + valueFrom: + secretKeyRef: + name: {{ include "obot.config.secretName" . }} + key: obotServerDSN + {{- end }} + {{- if .Values.config.obotServerHostname }} + - name: "OBOT_SERVER_HOSTNAME" + valueFrom: + secretKeyRef: + name: {{ include "obot.config.secretName" . }} + key: obotServerHostname + {{- end }} + {{- if .Values.config.obotWorkspaceProviderType }} + - name: "OBOT_WORKSPACE_PROVIDER_TYPE" + valueFrom: + secretKeyRef: + name: {{ include "obot.config.secretName" . }} + key: obotWorkspaceProviderType + {{- end }} + {{- if .Values.config.openaiApiKey }} + - name: "OPENAI_API_KEY" + valueFrom: + secretKeyRef: + name: {{ include "obot.config.secretName" . }} + key: openaiApiKey + {{- end }} + {{- if .Values.config.workspaceProviderS3BaseEndpoint }} + - name: "WORKSPACE_PROVIDER_S3_BASE_ENDPOINT" + valueFrom: + secretKeyRef: + name: {{ include "obot.config.secretName" . }} + key: workspaceProviderS3BaseEndpoint + {{- end }} + {{- if .Values.config.workspaceProviderS3Bucket }} + - name: "WORKSPACE_PROVIDER_S3_BUCKET" + valueFrom: + secretKeyRef: + name: {{ include "obot.config.secretName" . }} + key: workspaceProviderS3Bucket + {{- end }} + {{- if .Values.extraEnv }} + {{- range $key, $value := .Values.extraEnv }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- end }} + resources: + {{- toYaml .Values.resources | nindent 12 }} diff --git a/chart/templates/ingress.yaml b/chart/templates/ingress.yaml new file mode 100644 index 000000000..f250c26c3 --- /dev/null +++ b/chart/templates/ingress.yaml @@ -0,0 +1,47 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "obot.fullname" . -}} +{{- $ingressPaths := .Values.ingress.paths -}} +{{- $extraPaths := .Values.ingress.extraPaths -}} +apiVersion: "networking.k8s.io/v1" +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + {{- include "obot.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if .Values.ingress.className }} + ingressClassName: {{ .Values.ingress.className }} +{{- end }} +{{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} +{{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ . | quote }} + http: + paths: + {{- if $extraPaths }} +{{ $extraPaths | toYaml | indent 10 }} + {{- end }} + {{- range $ingressPaths }} + - path: {{ or .path . | quote }} + pathType: {{ .pathType | quote }} + backend: + service: + name: {{ $fullName }} + port: + name: http + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/secret.yaml b/chart/templates/secret.yaml new file mode 100644 index 000000000..af9ef6052 --- /dev/null +++ b/chart/templates/secret.yaml @@ -0,0 +1,46 @@ +{{- if eq .Values.config.existingSecret "" -}} +apiVersion: v1 +data: + {{- if .Values.config.awsAccessKeyID }} + awsAccessKeyID: {{ .Values.config.awsAccessKeyID | b64enc }} + {{- end }} + {{- if .Values.config.awsRegion }} + awsRegion: {{ .Values.config.awsRegion | b64enc }} + {{- end }} + {{- if .Values.config.awsSecretAccessKey }} + awsSecretAccessKey: {{ .Values.config.awsSecretAccessKey | b64enc }} + {{- end }} + {{- if .Values.config.baaahThreadiness }} + baaahThreadiness: {{ .Values.config.baaahThreadiness | b64enc }} + {{- end }} + {{- if .Values.config.githubAuthToken }} + githubAuthToken: {{ .Values.config.githubAuthToken | b64enc }} + {{- end }} + {{- if .Values.config.obotServerAuthAdminEmails }} + obotServerAuthAdminEmails: {{ .Values.config.obotServerAuthAdminEmails | b64enc }} + {{- end }} + {{- if .Values.config.obotServerDSN }} + obotServerDSN: {{ .Values.config.obotServerDSN | b64enc }} + {{- end }} + {{- if .Values.config.obotServerHostname }} + obotServerHostname: {{ .Values.config.obotServerHostname | b64enc }} + {{- end }} + {{- if .Values.config.obotWorkspaceProviderType }} + obotWorkspaceProviderType: {{ .Values.config.obotWorkspaceProviderType | b64enc }} + {{- end }} + {{- if .Values.config.openaiApiKey }} + openaiApiKey: {{ .Values.config.openaiApiKey | b64enc }} + {{- end }} + {{- if .Values.config.workspaceProviderS3BaseEndpoint }} + workspaceProviderS3BaseEndpoint: {{ .Values.config.workspaceProviderS3BaseEndpoint | b64enc }} + {{- end }} + {{- if .Values.config.workspaceProviderS3Bucket }} + workspaceProviderS3Bucket: {{ .Values.config.workspaceProviderS3Bucket | b64enc }} + {{- end }} +kind: Secret +metadata: + labels: + {{- include "obot.labels" . | nindent 4 }} + name: {{ include "obot.config.secretName" . }} +type: Opaque +{{- end -}} \ No newline at end of file diff --git a/chart/templates/service.yaml b/chart/templates/service.yaml new file mode 100644 index 000000000..d15dfade8 --- /dev/null +++ b/chart/templates/service.yaml @@ -0,0 +1,22 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "obot.fullname" . }} + labels: + {{- include "obot.labels" . | nindent 4 }} + {{- if .Values.service.annotations }} + annotations: + {{ .Values.service.annotations | toYaml | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: 8080 + protocol: TCP + name: http + selector: + {{- include "obot.selectorLabels" . | nindent 4 }} + {{- if .Values.service.spec }} + {{ .Values.service.spec | toYaml | indent 2 }} + {{- end }} \ No newline at end of file diff --git a/chart/templates/serviceaccount.yaml b/chart/templates/serviceaccount.yaml new file mode 100644 index 000000000..c6579af4e --- /dev/null +++ b/chart/templates/serviceaccount.yaml @@ -0,0 +1,10 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "obot.serviceAccountName" . }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/chart/values.yaml b/chart/values.yaml new file mode 100644 index 000000000..373bc0d61 --- /dev/null +++ b/chart/values.yaml @@ -0,0 +1,83 @@ +# replicaCount -- The number of Obot server instances to run +replicaCount: 1 + +image: + # image.repository -- The name of the docker repository for Obot + repository: ghcr.io/obot-platform/obot-enterprise + # image.tag -- The docker tag to pull for obot + tag: latest + # image.pullPolicy -- Kubernetes image pullPolicy to use for Obot + pullPolicy: IfNotPresent + +# imagePullSecrets -- Configures kubernetes secrets to use for pulling private images +imagePullSecrets: [ ] + +# updateStrategy -- Configures what update strategy to use for the deployment (Recreate or RollingUpdate) +updateStrategy: "RollingUpdate" + +service: + # service.type -- Type of Kubernetes service to create + type: ClusterIP + # service.port -- Port for the Kubernetes service to expose + port: 80 + # service.annotations -- Extra annotations to add to service object + annotations: { } + # service.spec -- Any extra fields to add to the service object spec + spec: { } + +ingress: + # ingress.enabled -- Enables ingress creation for Obot. + enabled: false + # ingress.annotations -- Configure annotations to add to the ingress object + annotations: { } + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + # ingress.className -- Configures a preexisting ingress class to use. + className: ~ + # className: obot + paths: + - path: / + pathType: Prefix + # ingress.extraPaths -- Define complete path objects, will be inserted before regular paths. Can be useful for things like ALB Ingress Controller actions + extraPaths: [ ] + # ingress.hosts -- List of hostnames to configure the ingress with + hosts: [ ] + # - chart-example.local + # ingress.tls -- List of secrets used to configure TLS for the ingress. + tls: [ ] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +# config - A key/value object containing configuration variables to configure on the obot deployment +config: + # config.existingSecret -- The name of an existing secret to use for config instead of creating a new one + existingSecret: "" + + awsAccessKeyID: "" + awsRegion: "" + awsSecretAccessKey: "" + baaahThreadiness: "20" + githubAuthToken: "" + obotServerAuthAdminEmails: "" + obotServerDSN: "" + obotServerHostname: "" + obotWorkspaceProviderType: "s3" + openaiApiKey: "" + workspaceProviderS3BaseEndpoint: "" + workspaceProviderS3Bucket: "" + +# extraEnv -- A map of additional environment variables to set +extraEnv: { } + +# resources -- Resource requests and limits to use for Obot +resources: { } + +serviceAccount: + # serviceAccount.create - Specifies whether a service account should be created + create: false + # serviceAccount.annotation - Annotations to add to the service account + annotations: { } + # serviceAccount.name - The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" \ No newline at end of file diff --git a/run.sh b/run.sh index b57d49e0d..72c68dd52 100644 --- a/run.sh +++ b/run.sh @@ -24,12 +24,6 @@ ${OBOT_SERVER_VERSIONS} VERSIONS )" -# Only enable sshd in Render. Remove sshd entirely once we have migrated out of Render. -if [[ -v ENABLE_SSHD ]]; then - mkdir -p /run/sshd - /usr/sbin/sshd -D & -fi - mkdir -p /data/cache if [ -z "$OBOT_SERVER_DSN" ]; then